WordPress.org

Make WordPress Core


Ignore:
Timestamp:
09/11/2014 07:06:33 PM (5 years ago)
Author:
wonderboymusic
Message:

Update getID3 library to 1.9.8.

Changes:
https://github.com/JamesHeinrich/getID3/compare/1.9.7...v1.9.8

Fixes #29627.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/module.audio-video.riff.php

    r23766 r29734  
    44//  available at http://getid3.sourceforge.net                 //
    55//            or http://www.getid3.org                         //
     6//          also https://github.com/JamesHeinrich/getID3       //
    67/////////////////////////////////////////////////////////////////
    78// See readme.txt for more details                             //
     
    2728getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true);
    2829
    29 class getid3_riff extends getid3_handler
    30 {
     30class getid3_riff extends getid3_handler {
     31
     32    protected $container = 'riff'; // default
    3133
    3234    public function Analyze() {
     
    5961
    6062            case 'FORM':  // AIFF, AIFC
    61                 $info['fileformat']   = 'aiff';
     63                //$info['fileformat']   = 'aiff';
     64                $this->container = 'aiff';
    6265                $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
    6366                $thisfile_riff[$RIFFsubtype]  = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
     
    6770            case 'SDSS':  // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
    6871            case 'RMP3':  // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
    69                 $info['fileformat']   = 'riff';
     72                //$info['fileformat']   = 'riff';
     73                $this->container = 'riff';
    7074                $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
    7175                if ($RIFFsubtype == 'RMP3') {
     
    7377                    $RIFFsubtype = 'WAVE';
    7478                }
    75                 $thisfile_riff[$RIFFsubtype]  = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
     79                if ($RIFFsubtype != 'AMV ') {
     80                    // AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
     81                    // Handled separately in ParseRIFFAMV()
     82                    $thisfile_riff[$RIFFsubtype]  = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
     83                }
    7684                if (($info['avdataend'] - $info['filesize']) == 1) {
    7785                    // LiteWave appears to incorrectly *not* pad actual output file
     
    111119
    112120                    switch ($nextRIFFheaderID) {
    113 
    114121                        case 'RIFF':
    115122                            $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset);
    116 
    117123                            if (!isset($thisfile_riff[$nextRIFFtype])) {
    118124                                $thisfile_riff[$nextRIFFtype] = array();
    119125                            }
    120126                            $thisfile_riff[$nextRIFFtype][] = $chunkdata;
     127                            break;
     128
     129                        case 'AMV ':
     130                            unset($info['riff']);
     131                            $info['amv'] = $this->ParseRIFFAMV($chunkdata['offset'] + 4, $nextRIFFoffset);
    121132                            break;
    122133
     
    153164            default:
    154165                $this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead');
    155                 unset($info['fileformat']);
     166                //unset($info['fileformat']);
    156167                return false;
    157168        }
     
    159170        $streamindex = 0;
    160171        switch ($RIFFsubtype) {
     172
     173            // http://en.wikipedia.org/wiki/Wav
    161174            case 'WAVE':
     175                $info['fileformat'] = 'wav';
     176
    162177                if (empty($thisfile_audio['bitrate_mode'])) {
    163178                    $thisfile_audio['bitrate_mode'] = 'cbr';
     
    589604                break;
    590605
     606            // http://en.wikipedia.org/wiki/Audio_Video_Interleave
    591607            case 'AVI ':
     608                $info['fileformat'] = 'avi';
     609                $info['mime_type']  = 'video/avi';
     610
    592611                $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
    593612                $thisfile_video['dataformat']   = 'avi';
    594                 $info['mime_type']      = 'video/avi';
    595613
    596614                if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
     
    826844                                            switch ($strhfccType) {
    827845                                                case 'vids':
    828                                                     $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff'));
     846                                                    $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($this->container == 'riff'));
    829847                                                    $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
    830848
     
    876894                break;
    877895
     896
     897            case 'AMV ':
     898                $info['fileformat'] = 'amv';
     899                $info['mime_type']  = 'video/amv';
     900
     901                $thisfile_video['bitrate_mode']    = 'vbr'; // it's MJPEG, presumably contant-quality encoding, thereby VBR
     902                $thisfile_video['dataformat']      = 'mjpeg';
     903                $thisfile_video['codec']           = 'mjpeg';
     904                $thisfile_video['lossless']        = false;
     905                $thisfile_video['bits_per_sample'] = 24;
     906
     907                $thisfile_audio['dataformat']   = 'adpcm';
     908                $thisfile_audio['lossless']     = false;
     909                break;
     910
     911
     912            // http://en.wikipedia.org/wiki/CD-DA
    878913            case 'CDDA':
    879                 $thisfile_audio['bitrate_mode'] = 'cbr';
     914                $info['fileformat'] = 'cda';
     915                unset($info['mime_type']);
     916
    880917                $thisfile_audio_dataformat      = 'cda';
    881                 $thisfile_audio['lossless']     = true;
    882                 unset($info['mime_type']);
    883918
    884919                $info['avdataoffset'] = 44;
     
    902937
    903938                    // hardcoded data for CD-audio
     939                    $thisfile_audio['lossless']        = true;
    904940                    $thisfile_audio['sample_rate']     = 44100;
    905941                    $thisfile_audio['channels']        = 2;
     
    910946                break;
    911947
    912 
     948            // http://en.wikipedia.org/wiki/AIFF
    913949            case 'AIFF':
    914950            case 'AIFC':
     951                $info['fileformat'] = 'aiff';
     952                $info['mime_type']  = 'audio/x-aiff';
     953
    915954                $thisfile_audio['bitrate_mode'] = 'cbr';
    916955                $thisfile_audio_dataformat      = 'aiff';
    917956                $thisfile_audio['lossless']     = true;
    918                 $info['mime_type']      = 'audio/x-aiff';
    919957
    920958                if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
     
    10291067                break;
    10301068
     1069            // http://en.wikipedia.org/wiki/8SVX
    10311070            case '8SVX':
     1071                $info['fileformat'] = '8svx';
     1072                $info['mime_type']  = 'audio/8svx';
     1073
    10321074                $thisfile_audio['bitrate_mode']    = 'cbr';
    10331075                $thisfile_audio_dataformat         = '8svx';
    10341076                $thisfile_audio['bits_per_sample'] = 8;
    10351077                $thisfile_audio['channels']        = 1; // overridden below, if need be
    1036                 $info['mime_type']                = 'audio/x-aiff';
    10371078
    10381079                if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
     
    11091150                break;
    11101151
    1111 
    11121152            case 'CDXA':
    1113                 $info['mime_type'] = 'video/mpeg';
     1153                $info['fileformat'] = 'vcd'; // Asume Video CD
     1154                $info['mime_type']  = 'video/mpeg';
     1155
    11141156                if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
    1115                     if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
    1116                         $getid3_temp = new getID3();
    1117                         $getid3_temp->openfile($this->getid3->filename);
    1118                         $getid3_mpeg = new getid3_mpeg($getid3_temp);
    1119                         $getid3_mpeg->Analyze();
    1120                         if (empty($getid3_temp->info['error'])) {
    1121                             $info['audio']   = $getid3_temp->info['audio'];
    1122                             $info['video']   = $getid3_temp->info['video'];
    1123                             $info['mpeg']    = $getid3_temp->info['mpeg'];
    1124                             $info['warning'] = $getid3_temp->info['warning'];
    1125                         }
    1126                         unset($getid3_temp, $getid3_mpeg);
    1127                     }
     1157                    getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
     1158
     1159                    $getid3_temp = new getID3();
     1160                    $getid3_temp->openfile($this->getid3->filename);
     1161                    $getid3_mpeg = new getid3_mpeg($getid3_temp);
     1162                    $getid3_mpeg->Analyze();
     1163                    if (empty($getid3_temp->info['error'])) {
     1164                        $info['audio']   = $getid3_temp->info['audio'];
     1165                        $info['video']   = $getid3_temp->info['video'];
     1166                        $info['mpeg']    = $getid3_temp->info['mpeg'];
     1167                        $info['warning'] = $getid3_temp->info['warning'];
     1168                    }
     1169                    unset($getid3_temp, $getid3_mpeg);
    11281170                }
    11291171                break;
     
    11321174            default:
    11331175                $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
    1134                 unset($info['fileformat']);
    1135                 break;
     1176                //unset($info['fileformat']);
    11361177        }
    11371178
     
    11511192                if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
    11521193                    getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
     1194
    11531195                    $getid3_temp = new getID3();
    11541196                    $getid3_temp->openfile($this->getid3->filename);
     
    12791321    }
    12801322
     1323    public function ParseRIFFAMV($startoffset, $maxoffset) {
     1324        // AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
     1325
     1326        // https://code.google.com/p/amv-codec-tools/wiki/AmvDocumentation
     1327        //typedef struct _amvmainheader {
     1328        //FOURCC fcc; // 'amvh'
     1329        //DWORD cb;
     1330        //DWORD dwMicroSecPerFrame;
     1331        //BYTE reserve[28];
     1332        //DWORD dwWidth;
     1333        //DWORD dwHeight;
     1334        //DWORD dwSpeed;
     1335        //DWORD reserve0;
     1336        //DWORD reserve1;
     1337        //BYTE bTimeSec;
     1338        //BYTE bTimeMin;
     1339        //WORD wTimeHour;
     1340        //} AMVMAINHEADER;
     1341
     1342        $info = &$this->getid3->info;
     1343        $RIFFchunk = false;
     1344
     1345        try {
     1346
     1347            $this->fseek($startoffset);
     1348            $maxoffset = min($maxoffset, $info['avdataend']);
     1349            $AMVheader = $this->fread(284);
     1350            if (substr($AMVheader,   0,  8) != 'hdrlamvh') {
     1351                throw new Exception('expecting "hdrlamv" at offset '.($startoffset +   0).', found "'.substr($AMVheader,   0, 8).'"');
     1352            }
     1353            if (substr($AMVheader,   8,  4) != "\x38\x00\x00\x00") { // "amvh" chunk size, hardcoded to 0x38 = 56 bytes
     1354                throw new Exception('expecting "0x38000000" at offset '.($startoffset +   8).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader,   8, 4)).'"');
     1355            }
     1356            $RIFFchunk = array();
     1357            $RIFFchunk['amvh']['us_per_frame']   = getid3_lib::LittleEndian2Int(substr($AMVheader,  12,  4));
     1358            $RIFFchunk['amvh']['reserved28']     =                              substr($AMVheader,  16, 28);  // null? reserved?
     1359            $RIFFchunk['amvh']['resolution_x']   = getid3_lib::LittleEndian2Int(substr($AMVheader,  44,  4));
     1360            $RIFFchunk['amvh']['resolution_y']   = getid3_lib::LittleEndian2Int(substr($AMVheader,  48,  4));
     1361            $RIFFchunk['amvh']['frame_rate_int'] = getid3_lib::LittleEndian2Int(substr($AMVheader,  52,  4));
     1362            $RIFFchunk['amvh']['reserved0']      = getid3_lib::LittleEndian2Int(substr($AMVheader,  56,  4)); // 1? reserved?
     1363            $RIFFchunk['amvh']['reserved1']      = getid3_lib::LittleEndian2Int(substr($AMVheader,  60,  4)); // 0? reserved?
     1364            $RIFFchunk['amvh']['runtime_sec']    = getid3_lib::LittleEndian2Int(substr($AMVheader,  64,  1));
     1365            $RIFFchunk['amvh']['runtime_min']    = getid3_lib::LittleEndian2Int(substr($AMVheader,  65,  1));
     1366            $RIFFchunk['amvh']['runtime_hrs']    = getid3_lib::LittleEndian2Int(substr($AMVheader,  66,  2));
     1367
     1368            $info['video']['frame_rate']   = 1000000 / $RIFFchunk['amvh']['us_per_frame'];
     1369            $info['video']['resolution_x'] = $RIFFchunk['amvh']['resolution_x'];
     1370            $info['video']['resolution_y'] = $RIFFchunk['amvh']['resolution_y'];
     1371            $info['playtime_seconds']      = ($RIFFchunk['amvh']['runtime_hrs'] * 3600) + ($RIFFchunk['amvh']['runtime_min'] * 60) + $RIFFchunk['amvh']['runtime_sec'];
     1372
     1373            // the rest is all hardcoded(?) and does not appear to be useful until you get to audio info at offset 256, even then everything is probably hardcoded
     1374
     1375            if (substr($AMVheader,  68, 20) != 'LIST'."\x00\x00\x00\x00".'strlstrh'."\x38\x00\x00\x00") {
     1376                throw new Exception('expecting "LIST<0x00000000>strlstrh<0x38000000>" at offset '.($startoffset +  68).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader,  68, 20)).'"');
     1377            }
     1378            // followed by 56 bytes of null: substr($AMVheader,  88, 56) -> 144
     1379            if (substr($AMVheader, 144,  8) != 'strf'."\x24\x00\x00\x00") {
     1380                throw new Exception('expecting "strf<0x24000000>" at offset '.($startoffset + 144).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 144,  8)).'"');
     1381            }
     1382            // followed by 36 bytes of null: substr($AMVheader, 144, 36) -> 180
     1383
     1384            if (substr($AMVheader, 188, 20) != 'LIST'."\x00\x00\x00\x00".'strlstrh'."\x30\x00\x00\x00") {
     1385                throw new Exception('expecting "LIST<0x00000000>strlstrh<0x30000000>" at offset '.($startoffset + 188).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 188, 20)).'"');
     1386            }
     1387            // followed by 48 bytes of null: substr($AMVheader, 208, 48) -> 256
     1388            if (substr($AMVheader, 256,  8) != 'strf'."\x14\x00\x00\x00") {
     1389                throw new Exception('expecting "strf<0x14000000>" at offset '.($startoffset + 256).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 256,  8)).'"');
     1390            }
     1391            // followed by 20 bytes of a modified WAVEFORMATEX:
     1392            // typedef struct {
     1393            // WORD wFormatTag;       //(Fixme: this is equal to PCM's 0x01 format code)
     1394            // WORD nChannels;        //(Fixme: this is always 1)
     1395            // DWORD nSamplesPerSec;  //(Fixme: for all known sample files this is equal to 22050)
     1396            // DWORD nAvgBytesPerSec; //(Fixme: for all known sample files this is equal to 44100)
     1397            // WORD nBlockAlign;      //(Fixme: this seems to be 2 in AMV files, is this correct ?)
     1398            // WORD wBitsPerSample;   //(Fixme: this seems to be 16 in AMV files instead of the expected 4)
     1399            // WORD cbSize;           //(Fixme: this seems to be 0 in AMV files)
     1400            // WORD reserved;
     1401            // } WAVEFORMATEX;
     1402            $RIFFchunk['strf']['wformattag']      = getid3_lib::LittleEndian2Int(substr($AMVheader,  264,  2));
     1403            $RIFFchunk['strf']['nchannels']       = getid3_lib::LittleEndian2Int(substr($AMVheader,  266,  2));
     1404            $RIFFchunk['strf']['nsamplespersec']  = getid3_lib::LittleEndian2Int(substr($AMVheader,  268,  4));
     1405            $RIFFchunk['strf']['navgbytespersec'] = getid3_lib::LittleEndian2Int(substr($AMVheader,  272,  4));
     1406            $RIFFchunk['strf']['nblockalign']     = getid3_lib::LittleEndian2Int(substr($AMVheader,  276,  2));
     1407            $RIFFchunk['strf']['wbitspersample']  = getid3_lib::LittleEndian2Int(substr($AMVheader,  278,  2));
     1408            $RIFFchunk['strf']['cbsize']          = getid3_lib::LittleEndian2Int(substr($AMVheader,  280,  2));
     1409            $RIFFchunk['strf']['reserved']        = getid3_lib::LittleEndian2Int(substr($AMVheader,  282,  2));
     1410
     1411
     1412            $info['audio']['lossless']        = false;
     1413            $info['audio']['sample_rate']     = $RIFFchunk['strf']['nsamplespersec'];
     1414            $info['audio']['channels']        = $RIFFchunk['strf']['nchannels'];
     1415            $info['audio']['bits_per_sample'] = $RIFFchunk['strf']['wbitspersample'];
     1416            $info['audio']['bitrate']         = $info['audio']['sample_rate'] * $info['audio']['channels'] * $info['audio']['bits_per_sample'];
     1417            $info['audio']['bitrate_mode']    = 'cbr';
     1418
     1419
     1420        } catch (getid3_exception $e) {
     1421            if ($e->getCode() == 10) {
     1422                $this->warning('RIFFAMV parser: '.$e->getMessage());
     1423            } else {
     1424                throw $e;
     1425            }
     1426        }
     1427
     1428        return $RIFFchunk;
     1429    }
     1430
     1431
    12811432    public function ParseRIFF($startoffset, $maxoffset) {
    12821433        $info = &$this->getid3->info;
     
    13301481                                            $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
    13311482                                            $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
    1332                                             $getid3_mp3 = new getid3_mp3($getid3_temp);
     1483                                            $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
    13331484                                            $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
    13341485                                            if (isset($getid3_temp->info['mpeg']['audio'])) {
     
    14131564                                        $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
    14141565                                        $getid3_temp->info['avdataend']    = $info['avdataend'];
    1415                                         $getid3_mp3 = new getid3_mp3($getid3_temp);
     1566                                        $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
    14161567                                        $getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
    14171568                                        if (empty($getid3_temp->info['error'])) {
     
    24272578
    24282579    private function EitherEndian2Int($byteword, $signed=false) {
    2429         if ($this->getid3->info['fileformat'] == 'riff') {
     2580        if ($this->container == 'riff') {
    24302581            return getid3_lib::LittleEndian2Int($byteword, $signed);
    24312582        }
Note: See TracChangeset for help on using the changeset viewer.