Make WordPress Core

Changeset 51901


Ignore:
Timestamp:
10/10/2021 01:15:16 AM (3 years ago)
Author:
SergeyBiryukov
Message:

External Libraries: Revert [51900] for now to investigate test failures.

See #54162.

Location:
trunk/src/wp-includes/ID3
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/getid3.lib.php

    r51900 r51901  
    243243     * ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
    244244     *
    245      * @link https://web.archive.org/web/20120325162206/http://www.psc.edu/general/software/packages/ieee/ieee.php
     245     * @link http://www.psc.edu/general/software/packages/ieee/ieee.html
    246246     * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
    247247     *
     
    295295        if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
    296296            // Not a Number
    297             $floatvalue = NAN;
     297            $floatvalue = false;
    298298        } elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) {
    299299            if ($signbit == '1') {
    300                 $floatvalue = -INF;
     300                $floatvalue = '-infinity';
    301301            } else {
    302                 $floatvalue = INF;
     302                $floatvalue = '+infinity';
    303303            }
    304304        } elseif (($exponent == 0) && ($fraction == 0)) {
     
    428428     */
    429429    public static function Dec2Bin($number) {
    430         if (!is_numeric($number)) {
    431             // https://github.com/JamesHeinrich/getID3/issues/299
    432             trigger_error('TypeError: Dec2Bin(): Argument #1 ($number) must be numeric, '.gettype($number).' given', E_USER_WARNING);
    433             return '';
    434         }
    435         $bytes = array();
    436430        while ($number >= 256) {
    437             $bytes[] = (int) (($number / 256) - (floor($number / 256))) * 256;
     431            $bytes[] = (($number / 256) - (floor($number / 256))) * 256;
    438432            $number = floor($number / 256);
    439433        }
    440         $bytes[] = (int) $number;
     434        $bytes[] = $number;
    441435        $binstring = '';
    442         foreach ($bytes as $i => $byte) {
    443             $binstring = (($i == count($bytes) - 1) ? decbin($byte) : str_pad(decbin($byte), 8, '0', STR_PAD_LEFT)).$binstring;
     436        for ($i = 0; $i < count($bytes); $i++) {
     437            $binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring;
    444438        }
    445439        return $binstring;
     
    672666        //   $foo['path']['to']['my'] = 'file.txt';
    673667        $ArrayPath = ltrim($ArrayPath, $Separator);
    674         $ReturnedArray = array();
    675668        if (($pos = strpos($ArrayPath, $Separator)) !== false) {
    676669            $ReturnedArray[substr($ArrayPath, 0, $pos)] = self::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
     
    15461539        // Copy all entries from ['tags'] into common ['comments']
    15471540        if (!empty($ThisFileInfo['tags'])) {
    1548 
    1549             // Some tag types can only support limited character sets and may contain data in non-standard encoding (usually ID3v1)
    1550             // and/or poorly-transliterated tag values that are also in tag formats that do support full-range character sets
    1551             // To make the output more user-friendly, process the potentially-problematic tag formats last to enhance the chance that
    1552             // the first entries in [comments] are the most correct and the "bad" ones (if any) come later.
    1553             // https://github.com/JamesHeinrich/getID3/issues/338
    1554             $processLastTagTypes = array('id3v1','riff');
    1555             foreach ($processLastTagTypes as $processLastTagType) {
    1556                 if (isset($ThisFileInfo['tags'][$processLastTagType])) {
    1557                     // bubble ID3v1 to the end, if present to aid in detecting bad ID3v1 encodings
    1558                     $temp = $ThisFileInfo['tags'][$processLastTagType];
    1559                     unset($ThisFileInfo['tags'][$processLastTagType]);
    1560                     $ThisFileInfo['tags'][$processLastTagType] = $temp;
    1561                     unset($temp);
    1562                 }
     1541            if (isset($ThisFileInfo['tags']['id3v1'])) {
     1542                // bubble ID3v1 to the end, if present to aid in detecting bad ID3v1 encodings
     1543                $ID3v1 = $ThisFileInfo['tags']['id3v1'];
     1544                unset($ThisFileInfo['tags']['id3v1']);
     1545                $ThisFileInfo['tags']['id3v1'] = $ID3v1;
     1546                unset($ID3v1);
    15631547            }
    15641548            foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
     
    15791563                                        break 2;
    15801564                                    }
    1581 
    1582                                     if (function_exists('mb_convert_encoding')) {
    1583                                         if (trim($value) == trim(substr(mb_convert_encoding($existingvalue, $ThisFileInfo['id3v1']['encoding'], $ThisFileInfo['encoding']), 0, 30))) {
    1584                                             // value stored in ID3v1 appears to be probably the multibyte value transliterated (badly) into ISO-8859-1 in ID3v1.
    1585                                             // As an example, Foobar2000 will do this if you tag a file with Chinese or Arabic or Cyrillic or something that doesn't fit into ISO-8859-1 the ID3v1 will consist of mostly "?" characters, one per multibyte unrepresentable character
    1586                                             break 2;
    1587                                         }
     1565                                }
     1566                                if (function_exists('mb_convert_encoding')) {
     1567                                    if (trim($value) == trim(substr(mb_convert_encoding($existingvalue, $ThisFileInfo['id3v1']['encoding'], $ThisFileInfo['encoding']), 0, 30))) {
     1568                                        // value stored in ID3v1 appears to be probably the multibyte value transliterated (badly) into ISO-8859-1 in ID3v1.
     1569                                        // As an example, Foobar2000 will do this if you tag a file with Chinese or Arabic or Cyrillic or something that doesn't fit into ISO-8859-1 the ID3v1 will consist of mostly "?" characters, one per multibyte unrepresentable character
     1570                                        break 2;
    15881571                                    }
    15891572                                }
     
    15911574                            } elseif (!is_array($value)) {
    15921575
    1593                                 $newvaluelength   =    strlen(trim($value));
    1594                                 $newvaluelengthMB = mb_strlen(trim($value));
     1576                                $newvaluelength = strlen(trim($value));
    15951577                                foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
    1596                                     $oldvaluelength   =    strlen(trim($existingvalue));
    1597                                     $oldvaluelengthMB = mb_strlen(trim($existingvalue));
    1598                                     if (($newvaluelengthMB == $oldvaluelengthMB) && ($existingvalue == getid3_lib::iconv_fallback('UTF-8', 'ASCII', $value))) {
    1599                                         // https://github.com/JamesHeinrich/getID3/issues/338
    1600                                         // check for tags containing extended characters that may have been forced into limited-character storage (e.g. UTF8 values into ASCII)
    1601                                         // which will usually display unrepresentable characters as "?"
    1602                                         $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
    1603                                         break;
    1604                                     }
     1578                                    $oldvaluelength = strlen(trim($existingvalue));
    16051579                                    if ((strlen($existingvalue) > 10) && ($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
    16061580                                        $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
     
    16281602
    16291603            // attempt to standardize spelling of returned keys
    1630             if (!empty($ThisFileInfo['comments'])) {
    1631                 $StandardizeFieldNames = array(
    1632                     'tracknumber' => 'track_number',
    1633                     'track'       => 'track_number',
    1634                 );
    1635                 foreach ($StandardizeFieldNames as $badkey => $goodkey) {
    1636                     if (array_key_exists($badkey, $ThisFileInfo['comments']) && !array_key_exists($goodkey, $ThisFileInfo['comments'])) {
    1637                         $ThisFileInfo['comments'][$goodkey] = $ThisFileInfo['comments'][$badkey];
    1638                         unset($ThisFileInfo['comments'][$badkey]);
    1639                     }
     1604            $StandardizeFieldNames = array(
     1605                'tracknumber' => 'track_number',
     1606                'track'       => 'track_number',
     1607            );
     1608            foreach ($StandardizeFieldNames as $badkey => $goodkey) {
     1609                if (array_key_exists($badkey, $ThisFileInfo['comments']) && !array_key_exists($goodkey, $ThisFileInfo['comments'])) {
     1610                    $ThisFileInfo['comments'][$goodkey] = $ThisFileInfo['comments'][$badkey];
     1611                    unset($ThisFileInfo['comments'][$badkey]);
    16401612                }
    16411613            }
     
    17631735     */
    17641736    public static function getFileSizeSyscall($path) {
    1765         $commandline = null;
    17661737        $filesize = false;
    17671738
     
    18251796     * @return string
    18261797     */
    1827     public static function mb_basename($path, $suffix = '') {
     1798    public static function mb_basename($path, $suffix = null) {
    18281799        $splited = preg_split('#/#', rtrim($path, '/ '));
    18291800        return substr(basename('X'.$splited[count($splited) - 1], $suffix), 1);
  • trunk/src/wp-includes/ID3/getid3.php

    r51900 r51901  
    1717if (!defined('GETID3_INCLUDEPATH')) {
    1818    define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
     19}
     20// Workaround Bug #39923 (https://bugs.php.net/bug.php?id=39923)
     21if (!defined('IMG_JPG') && defined('IMAGETYPE_JPEG')) {
     22    define('IMG_JPG', IMAGETYPE_JPEG);
    1923}
    2024if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE
     
    5458            $basedir .= DIRECTORY_SEPARATOR;
    5559        }
    56         if (strpos($temp_dir, $basedir) === 0) {
     60        if (preg_match('#^'.preg_quote($basedir).'#', $temp_dir)) {
    5761            $found_valid_tempdir = true;
    5862            break;
     
    211215    public $option_fread_buffer_size = 32768;
    212216
    213 
    214 
    215     // module-specific options
    216 
    217     /** archive.rar
    218      * if true use PHP RarArchive extension, if false (non-extension parsing not yet written in getID3)
    219      *
    220      * @var bool
    221      */
    222     public $options_archive_rar_use_php_rar_extension = true;
    223 
    224     /** archive.gzip
    225      * Optional file list - disable for speed.
    226      * Decode gzipped files, if possible, and parse recursively (.tar.gz for example).
    227      *
    228      * @var bool
    229      */
    230     public $options_archive_gzip_parse_contents = false;
    231 
    232     /** audio.midi
    233      * if false only parse most basic information, much faster for some files but may be inaccurate
    234      *
    235      * @var bool
    236      */
    237     public $options_audio_midi_scanwholefile = true;
    238 
    239     /** audio.mp3
    240      * Forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow,
    241      * unrecommended, but may provide data from otherwise-unusable files.
    242      *
    243      * @var bool
    244      */
    245     public $options_audio_mp3_allow_bruteforce = false;
    246 
    247     /** audio.mp3
    248      * number of frames to scan to determine if MPEG-audio sequence is valid
    249      * Lower this number to 5-20 for faster scanning
    250      * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams
    251      *
     217    // Public variables
     218
     219    /**
     220     * Filename of file being analysed.
     221     *
     222     * @var string
     223     */
     224    public $filename;
     225
     226    /**
     227     * Filepointer to file being analysed.
     228     *
     229     * @var resource
     230     */
     231    public $fp;
     232
     233    /**
     234     * Result array.
     235     *
     236     * @var array
     237     */
     238    public $info;
     239
     240    /**
     241     * @var string
     242     */
     243    public $tempdir = GETID3_TEMP_DIR;
     244
     245    /**
    252246     * @var int
    253247     */
    254     public $options_audio_mp3_mp3_valid_check_frames = 50;
    255 
    256     /** audio.wavpack
    257      * Avoid scanning all frames (break after finding ID_RIFF_HEADER and ID_CONFIG_BLOCK,
    258      * significantly faster for very large files but other data may be missed
    259      *
    260      * @var bool
    261      */
    262     public $options_audio_wavpack_quick_parsing = false;
    263 
    264     /** audio-video.flv
    265      * Break out of the loop if too many frames have been scanned; only scan this
    266      * many if meta frame does not contain useful duration.
    267      *
    268      * @var int
    269      */
    270     public $options_audiovideo_flv_max_frames = 100000;
    271 
    272     /** audio-video.matroska
    273      * If true, do not return information about CLUSTER chunks, since there's a lot of them
    274      * and they're not usually useful [default: TRUE].
    275      *
    276      * @var bool
    277      */
    278     public $options_audiovideo_matroska_hide_clusters    = true;
    279 
    280     /** audio-video.matroska
    281      * True to parse the whole file, not only header [default: FALSE].
    282      *
    283      * @var bool
    284      */
    285     public $options_audiovideo_matroska_parse_whole_file = false;
    286 
    287     /** audio-video.quicktime
    288      * return all parsed data from all atoms if true, otherwise just returned parsed metadata
    289      *
    290      * @var bool
    291      */
    292     public $options_audiovideo_quicktime_ReturnAtomData  = false;
    293 
    294     /** audio-video.quicktime
    295      * return all parsed data from all atoms if true, otherwise just returned parsed metadata
    296      *
    297      * @var bool
    298      */
    299     public $options_audiovideo_quicktime_ParseAllPossibleAtoms = false;
    300 
    301     /** audio-video.swf
    302      * return all parsed tags if true, otherwise do not return tags not parsed by getID3
    303      *
    304      * @var bool
    305      */
    306     public $options_audiovideo_swf_ReturnAllTagData = false;
    307 
    308     /** graphic.bmp
    309      * return BMP palette
    310      *
    311      * @var bool
    312      */
    313     public $options_graphic_bmp_ExtractPalette = false;
    314 
    315     /** graphic.bmp
    316      * return image data
    317      *
    318      * @var bool
    319      */
    320     public $options_graphic_bmp_ExtractData    = false;
    321 
    322     /** graphic.png
    323      * If data chunk is larger than this do not read it completely (getID3 only needs the first
    324      * few dozen bytes for parsing).
    325      *
    326      * @var int
    327      */
    328     public $options_graphic_png_max_data_bytes = 10000000;
    329 
    330     /** misc.pdf
    331      * return full details of PDF Cross-Reference Table (XREF)
    332      *
    333      * @var bool
    334      */
    335     public $options_misc_pdf_returnXREF = false;
    336 
    337     /** misc.torrent
    338      * Assume all .torrent files are less than 1MB and just read entire thing into memory for easy processing.
    339      * Override this value if you need to process files larger than 1MB
    340      *
    341      * @var int
    342      */
    343     public $options_misc_torrent_max_torrent_filesize = 1048576;
    344 
    345 
    346 
    347     // Public variables
    348 
    349     /**
    350      * Filename of file being analysed.
    351      *
     248    public $memory_limit = 0;
     249
     250    /**
    352251     * @var string
    353252     */
    354     public $filename;
    355 
    356     /**
    357      * Filepointer to file being analysed.
    358      *
    359      * @var resource
    360      */
    361     public $fp;
    362 
    363     /**
    364      * Result array.
    365      *
    366      * @var array
    367      */
    368     public $info;
     253    protected $startup_error   = '';
    369254
    370255    /**
    371256     * @var string
    372257     */
    373     public $tempdir = GETID3_TEMP_DIR;
    374 
    375     /**
    376      * @var int
    377      */
    378     public $memory_limit = 0;
    379 
    380     /**
    381      * @var string
    382      */
    383     protected $startup_error   = '';
    384 
    385     /**
    386      * @var string
    387      */
    388258    protected $startup_warning = '';
    389259
    390     const VERSION           = '1.9.21-202109171300';
     260    const VERSION           = '1.9.20-202006061653';
    391261    const FREAD_BUFFER_SIZE = 32768;
    392262
     
    768638            }
    769639            $class = new $class_name($this);
    770 
    771             // set module-specific options
    772             foreach (get_object_vars($this) as $getid3_object_vars_key => $getid3_object_vars_value) {
    773                 if (preg_match('#^options_([^_]+)_([^_]+)_(.+)$#i', $getid3_object_vars_key, $matches)) {
    774                     list($dummy, $GOVgroup, $GOVmodule, $GOVsetting) = $matches;
    775                     $GOVgroup = (($GOVgroup == 'audiovideo') ? 'audio-video' : $GOVgroup); // variable names can only contain 0-9a-z_ so standardize here
    776                     if (($GOVgroup == $determined_format['group']) && ($GOVmodule == $determined_format['module'])) {
    777                         $class->$GOVsetting = $getid3_object_vars_value;
    778                     }
    779                 }
    780             }
    781 
    782640            $class->Analyze();
    783641            unset($class);
     
    14941352                            'module'    => 'msoffice',
    14951353                            'mime_type' => 'application/octet-stream',
    1496                             'fail_id3'  => 'ERROR',
    1497                             'fail_ape'  => 'ERROR',
    1498                         ),
    1499 
    1500                 // TORRENT             - .torrent
    1501                 'torrent' => array(
    1502                             'pattern'   => '^(d8\\:announce|d7\\:comment)',
    1503                             'group'     => 'misc',
    1504                             'module'    => 'torrent',
    1505                             'mime_type' => 'application/x-bittorrent',
    15061354                            'fail_id3'  => 'ERROR',
    15071355                            'fail_ape'  => 'ERROR',
     
    16421490                            $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed!
    16431491                        }
    1644                         if (isset($value) && $value !== "") {
     1492                        if ($value) {
    16451493                            if (!is_numeric($key)) {
    16461494                                $this->info['tags'][trim($tag_name)][trim($tag_key)][$key] = $value;
     
    22492097                    break;
    22502098            }
    2251             return 0; // fseek returns 0 on success
    2252         }
    2253 
    2254         $pos = $bytes;
    2255         if ($whence == SEEK_CUR) {
    2256             $pos = $this->ftell() + $bytes;
    2257         } elseif ($whence == SEEK_END) {
    2258             $pos = $this->getid3->info['filesize'] + $bytes;
    2259         }
    2260         if (!getid3_lib::intValueSupported($pos)) {
    2261             throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10);
    2262         }
    2263 
    2264         // https://github.com/JamesHeinrich/getID3/issues/327
    2265         $result = fseek($this->getid3->fp, $bytes, $whence);
    2266         if ($result !== 0) { // fseek returns 0 on success
    2267             throw new getid3_exception('cannot fseek('.$pos.'). resource/stream does not appear to support seeking', 10);
    2268         }
    2269         return $result;
     2099            return 0;
     2100        } else {
     2101            $pos = $bytes;
     2102            if ($whence == SEEK_CUR) {
     2103                $pos = $this->ftell() + $bytes;
     2104            } elseif ($whence == SEEK_END) {
     2105                $pos = $this->getid3->info['filesize'] + $bytes;
     2106            }
     2107            if (!getid3_lib::intValueSupported($pos)) {
     2108                throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10);
     2109            }
     2110        }
     2111        return fseek($this->getid3->fp, $bytes, $whence);
    22702112    }
    22712113
     
    23832225     */
    23842226    public function saveAttachment($name, $offset, $length, $image_mime=null) {
    2385         $fp_dest = null;
    2386         $dest = null;
    23872227        try {
    23882228
  • trunk/src/wp-includes/ID3/module.audio-video.asf.php

    r51900 r51901  
    9494        $thisfile_asf_streambitratepropertiesobject = array();
    9595        $thisfile_asf_codeclistobject = array();
    96         $StreamPropertiesObjectData = array();
    9796
    9897        for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
     
    285284                    $offset += 2;
    286285                    if ($thisfile_asf_headerextensionobject['reserved_2'] != 6) {
    287                         $this->warning('header_extension_object.reserved_2 ('.$thisfile_asf_headerextensionobject['reserved_2'].') does not match expected value of "6"');
     286                        $this->warning('header_extension_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_headerextensionobject['reserved_2']).') does not match expected value of "6"');
    288287                        //return false;
    289288                        break;
     
    537536                    $offset += 2;
    538537                    if ($thisfile_asf_markerobject['reserved_2'] != 0) {
    539                         $this->warning('marker_object.reserved_2 ('.$thisfile_asf_markerobject['reserved_2'].') does not match expected value of "0"');
     538                        $this->warning('marker_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_markerobject['reserved_2']).') does not match expected value of "0"');
    540539                        break;
    541540                    }
     
    11951194                    $offset += 2;
    11961195                    if ($thisfile_asf_dataobject['reserved'] != 0x0101) {
    1197                         $this->warning('data_object.reserved (0x'.sprintf('%04X', $thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"');
     1196                        $this->warning('data_object.reserved ('.getid3_lib::PrintHexBytes($thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"');
    11981197                        //return false;
    11991198                        break;
  • trunk/src/wp-includes/ID3/module.audio-video.flv.php

    r51900 r51901  
    162162
    163163                        $FLVvideoHeader = $this->fread(11);
    164                         $PictureSizeEnc = array();
    165164
    166165                        if ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H264) {
  • trunk/src/wp-includes/ID3/module.audio-video.matroska.php

    r51900 r51901  
    225225     * @var bool
    226226     */
    227     public $hide_clusters    = true;
     227    public static $hide_clusters    = true;
    228228
    229229    /**
     
    232232     * @var bool
    233233     */
    234     public $parse_whole_file = false;
     234    public static $parse_whole_file = false;
    235235
    236236    /*
     
    587587
    588588                    while ($this->getEBMLelement($element_data, $top_element['end'])) {
    589                         if ($element_data['id'] != EBML_ID_CLUSTER || !$this->hide_clusters) { // collect clusters only if required
     589                        if ($element_data['id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
    590590                            $info['matroska']['segments'][] = $element_data;
    591591                        }
     
    619619                                                break;
    620620                                            }
    621                                             if (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !$this->hide_clusters) { // collect clusters only if required
     621                                            if (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !self::$hide_clusters) { // collect clusters only if required
    622622                                                $info['matroska']['seek'][] = $seek_entry;
    623623                                            }
     
    906906
    907907                            case EBML_ID_CUES: // A top-level element to speed seeking access. All entries are local to the segment. Should be mandatory for non "live" streams.
    908                                 if ($this->hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
     908                                if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
    909909                                    $this->current_offset = $element_data['end'];
    910910                                    break;
     
    12471247                                    $this->current_offset = $subelement['end'];
    12481248                                }
    1249                                 if (!$this->hide_clusters) {
     1249                                if (!self::$hide_clusters) {
    12501250                                    $info['matroska']['cluster'][] = $cluster_entry;
    12511251                                }
    12521252
    12531253                                // check to see if all the data we need exists already, if so, break out of the loop
    1254                                 if (!$this->parse_whole_file) {
     1254                                if (!self::$parse_whole_file) {
    12551255                                    if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
    12561256                                        if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
  • trunk/src/wp-includes/ID3/module.audio-video.quicktime.php

    r51900 r51901  
    2525{
    2626
    27     /** audio-video.quicktime
    28      * return all parsed data from all atoms if true, otherwise just returned parsed metadata
    29      *
    30      * @var bool
    31      */
    32     public $ReturnAtomData        = false;
    33 
    34     /** audio-video.quicktime
    35      * return all parsed data from all atoms if true, otherwise just returned parsed metadata
    36      *
    37      * @var bool
    38      */
     27    public $ReturnAtomData        = true;
    3928    public $ParseAllPossibleAtoms = false;
    4029
     
    182171        }
    183172
    184         if (!isset($info['bitrate']) && !empty($info['playtime_seconds'])) {
     173        if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
    185174            $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
    186175        }
     
    572561                                                $atom_structure['data'] = substr($boxdata, 8);
    573562                                                if ($atomname == 'covr') {
    574                                                     if (!empty($atom_structure['data'])) {
    575                                                         $atom_structure['image_mime'] = 'image/unknown'; // provide default MIME type to ensure array keys exist
    576                                                         if (function_exists('getimagesizefromstring') && ($getimagesize = getimagesizefromstring($atom_structure['data'])) && !empty($getimagesize['mime'])) {
    577                                                             $atom_structure['image_mime'] = $getimagesize['mime'];
    578                                                         } else {
    579                                                             // if getimagesizefromstring is not available, or fails for some reason, fall back to simple detection of common image formats
    580                                                             $ImageFormatSignatures = array(
    581                                                                 'image/jpeg' => "\xFF\xD8\xFF",
    582                                                                 'image/png'  => "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A",
    583                                                                 'image/gif'  => 'GIF',
    584                                                             );
    585                                                             foreach ($ImageFormatSignatures as $mime => $image_format_signature) {
    586                                                                 if (substr($atom_structure['data'], 0, strlen($image_format_signature)) == $image_format_signature) {
    587                                                                     $atom_structure['image_mime'] = $mime;
    588                                                                     break;
    589                                                                 }
    590                                                             }
    591                                                         }
    592                                                         $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
    593                                                     } else {
    594                                                         $this->warning('Unknown empty "covr" image at offset '.$baseoffset);
     563                                                    // not a foolproof check, but better than nothing
     564                                                    if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
     565                                                        $atom_structure['image_mime'] = 'image/jpeg';
     566                                                    } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
     567                                                        $atom_structure['image_mime'] = 'image/png';
     568                                                    } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
     569                                                        $atom_structure['image_mime'] = 'image/gif';
    595570                                                    }
     571                                                    $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
    596572                                                }
    597573                                                break;
     
    753729                    $atom_structure['flags']['slide_show']   = (bool) $atom_structure['slide_show_flag'];
    754730
    755                     $ptv_lookup = array(
    756                         0 => 'normal',
    757                         1 => 'double',
    758                         2 => 'half',
    759                         3 => 'full',
    760                         4 => 'current'
    761                     );
     731                    $ptv_lookup[0] = 'normal';
     732                    $ptv_lookup[1] = 'double';
     733                    $ptv_lookup[2] = 'half';
     734                    $ptv_lookup[3] = 'full';
     735                    $ptv_lookup[4] = 'current';
    762736                    if (isset($ptv_lookup[$atom_structure['display_size_raw']])) {
    763737                        $atom_structure['display_size'] = $ptv_lookup[$atom_structure['display_size_raw']];
     
    935909                                        $atom_structure['sample_description_table'][$i]['video_color_table_id']    =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68,  2));
    936910
    937                                         $atom_structure['sample_description_table'][$i]['video_pixel_color_type']  = (((int) $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
     911                                        $atom_structure['sample_description_table'][$i]['video_pixel_color_type']  = (($atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
    938912                                        $atom_structure['sample_description_table'][$i]['video_pixel_color_name']  = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']);
    939913
     
    941915                                            $info['quicktime']['video']['codec_fourcc']        = $atom_structure['sample_description_table'][$i]['data_format'];
    942916                                            $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']);
    943                                             $info['quicktime']['video']['codec']               = (((int) $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']);
     917                                            $info['quicktime']['video']['codec']               = (($atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']);
    944918                                            $info['quicktime']['video']['color_depth']         = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'];
    945919                                            $info['quicktime']['video']['color_depth_name']    = $atom_structure['sample_description_table'][$i]['video_pixel_color_name'];
     
    16251599
    16261600                case 'NCDT':
    1627                     // https://exiftool.org/TagNames/Nikon.html
     1601                    // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
    16281602                    // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
    16291603                    $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms);
     
    16311605                case 'NCTH': // Nikon Camera THumbnail image
    16321606                case 'NCVW': // Nikon Camera preVieW image
    1633                 case 'NCM1': // Nikon Camera preview iMage 1
    1634                 case 'NCM2': // Nikon Camera preview iMage 2
    1635                     // https://exiftool.org/TagNames/Nikon.html
     1607                    // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
    16361608                    if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) {
    1637                         $descriptions = array(
    1638                             'NCTH' => 'Nikon Camera Thumbnail Image',
    1639                             'NCVW' => 'Nikon Camera Preview Image',
    1640                             'NCM1' => 'Nikon Camera Preview Image 1',
    1641                             'NCM2' => 'Nikon Camera Preview Image 2',
    1642                         );
    16431609                        $atom_structure['data'] = $atom_data;
    16441610                        $atom_structure['image_mime'] = 'image/jpeg';
    1645                         $atom_structure['description'] = isset($descriptions[$atomname]) ? $descriptions[$atomname] : 'Nikon preview image';
    1646                         $info['quicktime']['comments']['picture'][] = array(
    1647                             'image_mime' => $atom_structure['image_mime'],
    1648                             'data' => $atom_data,
    1649                             'description' => $atom_structure['description']
    1650                         );
    1651                     }
    1652                     break;
    1653                 case 'NCTG': // Nikon - https://exiftool.org/TagNames/Nikon.html#NCTG
    1654                     getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.nikon-nctg.php', __FILE__, true);
    1655                     $nikonNCTG = new getid3_tag_nikon_nctg($this->getid3);
    1656 
    1657                     $atom_structure['data'] = $nikonNCTG->parse($atom_data);
    1658                     break;
    1659                 case 'NCHD': // Nikon:MakerNoteVersion  - https://exiftool.org/TagNames/Nikon.html
    1660                     $makerNoteVersion = '';
    1661                     for ($i = 0, $iMax = strlen($atom_data); $i < $iMax; ++$i) {
    1662                         if (ord($atom_data[$i]) >= 0x00 && ord($atom_data[$i]) <= 0x1F) {
    1663                             $makerNoteVersion .= ' '.ord($atom_data[$i]);
    1664                         } else {
    1665                             $makerNoteVersion .= $atom_data[$i];
    1666                         }
    1667                     }
    1668                     $makerNoteVersion = rtrim($makerNoteVersion, "\x00");
    1669                     $atom_structure['data'] = array(
    1670                         'MakerNoteVersion' => $makerNoteVersion
    1671                     );
    1672                     break;
    1673                 case 'NCDB': // Nikon                   - https://exiftool.org/TagNames/Nikon.html
    1674                 case 'CNCV': // Canon:CompressorVersion - https://exiftool.org/TagNames/Canon.html
     1611                        $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image'));
     1612                        $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_data, 'description'=>$atom_structure['description']);
     1613                    }
     1614                    break;
     1615                case 'NCTG': // Nikon - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
     1616                    $atom_structure['data'] = $this->QuicktimeParseNikonNCTG($atom_data);
     1617                    break;
     1618                case 'NCHD': // Nikon:MakerNoteVersion  - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
     1619                case 'NCDB': // Nikon                   - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
     1620                case 'CNCV': // Canon:CompressorVersion - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html
    16751621                    $atom_structure['data'] = $atom_data;
    16761622                    break;
     
    16791625                    // some kind of metacontainer, may contain a big data dump such as:
    16801626                    // mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4
    1681                     // https://xhelmboyx.tripod.com/formats/qti-layout.txt
     1627                    // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
    16821628
    16831629                    $atom_structure['version']   =          getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
     
    17761722                                    'debug_list'     => '',      // Used to debug variables stored as comma delimited strings
    17771723                            );
    1778                             $debug_structure = array();
    17791724                            $debug_structure['debug_items'] = array();
    17801725                            // Can start loop here to decode all sensor data in 32 Byte chunks:
     
    20952040     */
    20962041    public function QuicktimeParseContainerAtom($atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
    2097         $atom_structure = array();
     2042        $atom_structure  = false;
    20982043        $subatomoffset  = 0;
    20992044        $subatomcounter = 0;
     
    21132058                    continue;
    21142059                }
    2115                 break;
     2060                return $atom_structure;
    21162061            }
    21172062            if (strlen($subatomdata) < ($subatomsize - 8)) {
     
    21192064                // this may be because we are refusing to parse large subatoms, or it may be because this atom had its size set too large
    21202065                // so we passed in the start of a following atom incorrectly?
    2121                 break;
     2066                return $atom_structure;
    21222067            }
    21232068            $atom_structure[$subatomcounter++] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms);
    21242069            $subatomoffset += $subatomsize;
    21252070        }
    2126 
    2127         if (empty($atom_structure)) {
    2128             return false;
    2129         }
    2130 
    21312071        return $atom_structure;
    21322072    }
     
    26132553        if (empty($QuicktimeContentRatingLookup)) {
    26142554            $QuicktimeContentRatingLookup[0]  = 'None';
    2615             $QuicktimeContentRatingLookup[1]  = 'Explicit';
    26162555            $QuicktimeContentRatingLookup[2]  = 'Clean';
    2617             $QuicktimeContentRatingLookup[4]  = 'Explicit (old)';
     2556            $QuicktimeContentRatingLookup[4]  = 'Explicit';
    26182557        }
    26192558        return (isset($QuicktimeContentRatingLookup[$rtng]) ? $QuicktimeContentRatingLookup[$rtng] : 'invalid');
     
    26662605        }
    26672606        return (isset($QuicktimeStoreFrontCodeLookup[$sfid]) ? $QuicktimeStoreFrontCodeLookup[$sfid] : 'invalid');
     2607    }
     2608
     2609    /**
     2610     * @param string $atom_data
     2611     *
     2612     * @return array
     2613     */
     2614    public function QuicktimeParseNikonNCTG($atom_data) {
     2615        // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
     2616        // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
     2617        // Data is stored as records of:
     2618        // * 4 bytes record type
     2619        // * 2 bytes size of data field type:
     2620        //     0x0001 = flag   (size field *= 1-byte)
     2621        //     0x0002 = char   (size field *= 1-byte)
     2622        //     0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
     2623        //     0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
     2624        //     0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
     2625        //     0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
     2626        //     0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
     2627        // * 2 bytes data size field
     2628        // * ? bytes data (string data may be null-padded; datestamp fields are in the format "2011:05:25 20:24:15")
     2629        // all integers are stored BigEndian
     2630
     2631        $NCTGtagName = array(
     2632            0x00000001 => 'Make',
     2633            0x00000002 => 'Model',
     2634            0x00000003 => 'Software',
     2635            0x00000011 => 'CreateDate',
     2636            0x00000012 => 'DateTimeOriginal',
     2637            0x00000013 => 'FrameCount',
     2638            0x00000016 => 'FrameRate',
     2639            0x00000022 => 'FrameWidth',
     2640            0x00000023 => 'FrameHeight',
     2641            0x00000032 => 'AudioChannels',
     2642            0x00000033 => 'AudioBitsPerSample',
     2643            0x00000034 => 'AudioSampleRate',
     2644            0x02000001 => 'MakerNoteVersion',
     2645            0x02000005 => 'WhiteBalance',
     2646            0x0200000b => 'WhiteBalanceFineTune',
     2647            0x0200001e => 'ColorSpace',
     2648            0x02000023 => 'PictureControlData',
     2649            0x02000024 => 'WorldTime',
     2650            0x02000032 => 'UnknownInfo',
     2651            0x02000083 => 'LensType',
     2652            0x02000084 => 'Lens',
     2653        );
     2654
     2655        $offset = 0;
     2656        $data = null;
     2657        $datalength = strlen($atom_data);
     2658        $parsed = array();
     2659        while ($offset < $datalength) {
     2660            $record_type       = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4));  $offset += 4;
     2661            $data_size_type    = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
     2662            $data_size         = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
     2663            switch ($data_size_type) {
     2664                case 0x0001: // 0x0001 = flag   (size field *= 1-byte)
     2665                    $data = getid3_lib::BigEndian2Int(substr($atom_data, $offset, $data_size * 1));
     2666                    $offset += ($data_size * 1);
     2667                    break;
     2668                case 0x0002: // 0x0002 = char   (size field *= 1-byte)
     2669                    $data = substr($atom_data, $offset, $data_size * 1);
     2670                    $offset += ($data_size * 1);
     2671                    $data = rtrim($data, "\x00");
     2672                    break;
     2673                case 0x0003: // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
     2674                    $data = '';
     2675                    for ($i = $data_size - 1; $i >= 0; $i--) {
     2676                        $data .= substr($atom_data, $offset + ($i * 2), 2);
     2677                    }
     2678                    $data = getid3_lib::BigEndian2Int($data);
     2679                    $offset += ($data_size * 2);
     2680                    break;
     2681                case 0x0004: // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
     2682                    $data = '';
     2683                    for ($i = $data_size - 1; $i >= 0; $i--) {
     2684                        $data .= substr($atom_data, $offset + ($i * 4), 4);
     2685                    }
     2686                    $data = getid3_lib::BigEndian2Int($data);
     2687                    $offset += ($data_size * 4);
     2688                    break;
     2689                case 0x0005: // 0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
     2690                    $data = array();
     2691                    for ($i = 0; $i < $data_size; $i++) {
     2692                        $numerator    = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 0, 4));
     2693                        $denomninator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 4, 4));
     2694                        if ($denomninator == 0) {
     2695                            $data[$i] = false;
     2696                        } else {
     2697                            $data[$i] = (double) $numerator / $denomninator;
     2698                        }
     2699                    }
     2700                    $offset += (8 * $data_size);
     2701                    if (count($data) == 1) {
     2702                        $data = $data[0];
     2703                    }
     2704                    break;
     2705                case 0x0007: // 0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
     2706                    $data = substr($atom_data, $offset, $data_size * 1);
     2707                    $offset += ($data_size * 1);
     2708                    break;
     2709                case 0x0008: // 0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
     2710                    $data = substr($atom_data, $offset, $data_size * 2);
     2711                    $offset += ($data_size * 2);
     2712                    break;
     2713                default:
     2714                    echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br>';
     2715                    break 2;
     2716            }
     2717
     2718            switch ($record_type) {
     2719                case 0x00000011: // CreateDate
     2720                case 0x00000012: // DateTimeOriginal
     2721                    $data = strtotime($data);
     2722                    break;
     2723                case 0x0200001e: // ColorSpace
     2724                    switch ($data) {
     2725                        case 1:
     2726                            $data = 'sRGB';
     2727                            break;
     2728                        case 2:
     2729                            $data = 'Adobe RGB';
     2730                            break;
     2731                    }
     2732                    break;
     2733                case 0x02000023: // PictureControlData
     2734                    $PictureControlAdjust = array(0=>'default', 1=>'quick', 2=>'full');
     2735                    $FilterEffect = array(0x80=>'off', 0x81=>'yellow', 0x82=>'orange',    0x83=>'red', 0x84=>'green',  0xff=>'n/a');
     2736                    $ToningEffect = array(0x80=>'b&w', 0x81=>'sepia',  0x82=>'cyanotype', 0x83=>'red', 0x84=>'yellow', 0x85=>'green', 0x86=>'blue-green', 0x87=>'blue', 0x88=>'purple-blue', 0x89=>'red-purple', 0xff=>'n/a');
     2737                    $data = array(
     2738                        'PictureControlVersion'     =>                           substr($data,  0,  4),
     2739                        'PictureControlName'        =>                     rtrim(substr($data,  4, 20), "\x00"),
     2740                        'PictureControlBase'        =>                     rtrim(substr($data, 24, 20), "\x00"),
     2741                        //'?'                       =>                           substr($data, 44,  4),
     2742                        'PictureControlAdjust'      => $PictureControlAdjust[ord(substr($data, 48,  1))],
     2743                        'PictureControlQuickAdjust' =>                       ord(substr($data, 49,  1)),
     2744                        'Sharpness'                 =>                       ord(substr($data, 50,  1)),
     2745                        'Contrast'                  =>                       ord(substr($data, 51,  1)),
     2746                        'Brightness'                =>                       ord(substr($data, 52,  1)),
     2747                        'Saturation'                =>                       ord(substr($data, 53,  1)),
     2748                        'HueAdjustment'             =>                       ord(substr($data, 54,  1)),
     2749                        'FilterEffect'              =>         $FilterEffect[ord(substr($data, 55,  1))],
     2750                        'ToningEffect'              =>         $ToningEffect[ord(substr($data, 56,  1))],
     2751                        'ToningSaturation'          =>                       ord(substr($data, 57,  1)),
     2752                    );
     2753                    break;
     2754                case 0x02000024: // WorldTime
     2755                    // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#WorldTime
     2756                    // timezone is stored as offset from GMT in minutes
     2757                    $timezone = getid3_lib::BigEndian2Int(substr($data, 0, 2));
     2758                    if ($timezone & 0x8000) {
     2759                        $timezone = 0 - (0x10000 - $timezone);
     2760                    }
     2761                    $timezone /= 60;
     2762
     2763                    $dst = (bool) getid3_lib::BigEndian2Int(substr($data, 2, 1));
     2764                    switch (getid3_lib::BigEndian2Int(substr($data, 3, 1))) {
     2765                        case 2:
     2766                            $datedisplayformat = 'D/M/Y'; break;
     2767                        case 1:
     2768                            $datedisplayformat = 'M/D/Y'; break;
     2769                        case 0:
     2770                        default:
     2771                            $datedisplayformat = 'Y/M/D'; break;
     2772                    }
     2773
     2774                    $data = array('timezone'=>floatval($timezone), 'dst'=>$dst, 'display'=>$datedisplayformat);
     2775                    break;
     2776                case 0x02000083: // LensType
     2777                    $data = array(
     2778                        //'_'  => $data,
     2779                        'mf' => (bool) ($data & 0x01),
     2780                        'd'  => (bool) ($data & 0x02),
     2781                        'g'  => (bool) ($data & 0x04),
     2782                        'vr' => (bool) ($data & 0x08),
     2783                    );
     2784                    break;
     2785            }
     2786            $tag_name = (isset($NCTGtagName[$record_type]) ? $NCTGtagName[$record_type] : '0x'.str_pad(dechex($record_type), 8, '0', STR_PAD_LEFT));
     2787            $parsed[$tag_name] = $data;
     2788        }
     2789        return $parsed;
    26682790    }
    26692791
  • trunk/src/wp-includes/ID3/module.audio-video.riff.php

    r51900 r51901  
    5757        $thisfile_riff_WAVE        = array();
    5858
    59         $Original                 = array();
    6059        $Original['avdataoffset'] = $info['avdataoffset'];
    6160        $Original['avdataend']    = $info['avdataend'];
     
    298297                    $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
    299298
    300                     $thisfile_riff_WAVE_bext_0['title']          =                              substr($thisfile_riff_WAVE_bext_0['data'],   0, 256);
    301                     $thisfile_riff_WAVE_bext_0['author']         =                              substr($thisfile_riff_WAVE_bext_0['data'], 256,  32);
    302                     $thisfile_riff_WAVE_bext_0['reference']      =                              substr($thisfile_riff_WAVE_bext_0['data'], 288,  32);
    303                     foreach (array('title','author','reference') as $bext_key) {
    304                         // Some software (notably Logic Pro) may not blank existing data before writing a null-terminated string to the offsets
    305                         // assigned for text fields, resulting in a null-terminated string (or possibly just a single null) followed by garbage
    306                         // Keep only string as far as first null byte, discard rest of fixed-width data
    307                         // https://github.com/JamesHeinrich/getID3/issues/263
    308                         $null_terminator_offset = strpos($thisfile_riff_WAVE_bext_0[$bext_key], "\x00");
    309                         $thisfile_riff_WAVE_bext_0[$bext_key] = substr($thisfile_riff_WAVE_bext_0[$bext_key], 0, $null_terminator_offset);
    310                     }
    311 
     299                    $thisfile_riff_WAVE_bext_0['title']          =                         trim(substr($thisfile_riff_WAVE_bext_0['data'],   0, 256));
     300                    $thisfile_riff_WAVE_bext_0['author']         =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 256,  32));
     301                    $thisfile_riff_WAVE_bext_0['reference']      =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 288,  32));
    312302                    $thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
    313303                    $thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
     
    318308                    if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
    319309                        if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
    320                             $bext_timestamp = array();
    321310                            list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
    322311                            list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
     
    463452                }
    464453
    465                 if (isset($thisfile_riff_WAVE['guan'][0]['data'])) {
    466                     // shortcut
    467                     $thisfile_riff_WAVE_guan_0 = &$thisfile_riff_WAVE['guan'][0];
    468                     if (!empty($thisfile_riff_WAVE_guan_0['data']) && (substr($thisfile_riff_WAVE_guan_0['data'], 0, 14) == 'GUANO|Version:')) {
    469                         $thisfile_riff['guano'] = array();
    470                         foreach (explode("\n", $thisfile_riff_WAVE_guan_0['data']) as $line) {
    471                             if ($line) {
    472                                 @list($key, $value) = explode(':', $line, 2);
    473                                 if (substr($value, 0, 3) == '[{"') {
    474                                     if ($decoded = @json_decode($value, true)) {
    475                                         if (!empty($decoded) && (count($decoded) == 1)) {
    476                                             $value = $decoded[0];
    477                                         } else {
    478                                             $value = $decoded;
    479                                         }
    480                                     }
    481                                 }
    482                                 $thisfile_riff['guano'] = array_merge_recursive($thisfile_riff['guano'], getid3_lib::CreateDeepArray($key, '|', $value));
    483                             }
    484                         }
    485 
    486                         // https://www.wildlifeacoustics.com/SCHEMA/GUANO.html
    487                         foreach ($thisfile_riff['guano'] as $key => $value) {
    488                             switch ($key) {
    489                                 case 'Loc Position':
    490                                     if (preg_match('#^([\\+\\-]?[0-9]+\\.[0-9]+) ([\\+\\-]?[0-9]+\\.[0-9]+)$#', $value, $matches)) {
    491                                         list($dummy, $latitude, $longitude) = $matches;
    492                                         $thisfile_riff['comments']['gps_latitude'][0]  = floatval($latitude);
    493                                         $thisfile_riff['comments']['gps_longitude'][0] = floatval($longitude);
    494                                         $thisfile_riff['guano'][$key] = floatval($latitude).' '.floatval($longitude);
    495                                     }
    496                                     break;
    497                                 case 'Loc Elevation': // Elevation/altitude above mean sea level in meters
    498                                     $thisfile_riff['comments']['gps_altitude'][0] = floatval($value);
    499                                     $thisfile_riff['guano'][$key] = (float) $value;
    500                                     break;
    501                                 case 'Filter HP':        // High-pass filter frequency in kHz
    502                                 case 'Filter LP':        // Low-pass filter frequency in kHz
    503                                 case 'Humidity':         // Relative humidity as a percentage
    504                                 case 'Length':           // Recording length in seconds
    505                                 case 'Loc Accuracy':     // Estimated Position Error in meters
    506                                 case 'Temperature Ext':  // External temperature in degrees Celsius outside the recorder's housing
    507                                 case 'Temperature Int':  // Internal temperature in degrees Celsius inside the recorder's housing
    508                                     $thisfile_riff['guano'][$key] = (float) $value;
    509                                     break;
    510                                 case 'Samplerate':       // Recording sample rate, Hz
    511                                 case 'TE':               // Time-expansion factor. If not specified, then 1 (no time-expansion a.k.a. direct-recording) is assumed.
    512                                     $thisfile_riff['guano'][$key] = (int) $value;
    513                                     break;
    514                             }
    515                         }
    516 
    517                     } else {
    518                         $this->warning('RIFF.guan data not in expected format');
    519                     }
    520                 }
     454
    521455
    522456                if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
     
    800734                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
    801735                    if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
    802                         $thisfile_riff_raw_strf_strhfccType_streamindex = null;
    803736                        for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
    804737                            if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
     
    11371070                    getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
    11381071                    $getid3_temp = new getID3();
    1139                     $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1072                    $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    11401073                    $getid3_id3v2 = new getid3_id3v2($getid3_temp);
    11411074                    $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
     
    12401173
    12411174                    $getid3_temp = new getID3();
    1242                     $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1175                    $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    12431176                    $getid3_mpeg = new getid3_mpeg($getid3_temp);
    12441177                    $getid3_mpeg->Analyze();
     
    13261259
    13271260                    $getid3_temp = new getID3();
    1328                     $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1261                    $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    13291262                    $getid3_id3v2 = new getid3_id3v2($getid3_temp);
    13301263                    $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
     
    15821515        $RIFFchunk = false;
    15831516        $FoundAllChunksWeNeed = false;
    1584         $LISTchunkParent = null;
    1585         $LISTchunkMaxOffset = null;
    1586         $AC3syncwordBytes = pack('n', getid3_ac3::syncword); // 0x0B77 -> "\x0B\x77"
    15871517
    15881518        try {
     
    16281558                                        if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
    16291559                                            $getid3_temp = new getID3();
    1630                                             $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1560                                            $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    16311561                                            $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
    16321562                                            $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
     
    16461576                                        }
    16471577
    1648                                     } elseif (strpos($FirstFourBytes, $AC3syncwordBytes) === 0) {
     1578                                    } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
     1579
    16491580                                        // AC3
    16501581                                        $getid3_temp = new getID3();
    1651                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1582                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    16521583                                        $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
    16531584                                        $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
     
    17101641                                    if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
    17111642                                        $getid3_temp = new getID3();
    1712                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1643                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    17131644                                        $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
    17141645                                        $getid3_temp->info['avdataend']    = $info['avdataend'];
     
    17221653                                    }
    17231654
    1724                                 } elseif (($isRegularAC3 = (substr($testData, 0, 2) == $AC3syncwordBytes)) || substr($testData, 8, 2) == strrev($AC3syncwordBytes)) {
     1655                                } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
    17251656
    17261657                                    // This is probably AC-3 data
    17271658                                    $getid3_temp = new getID3();
    17281659                                    if ($isRegularAC3) {
    1729                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1660                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    17301661                                        $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
    17311662                                        $getid3_temp->info['avdataend']    = $info['avdataend'];
     
    17431674                                            $ac3_data .= substr($testData, 8 + $i + 0, 1);
    17441675                                        }
    1745                                         $getid3_ac3->getid3->info['avdataoffset'] = 0;
    1746                                         $getid3_ac3->getid3->info['avdataend']    = strlen($ac3_data);
    17471676                                        $getid3_ac3->AnalyzeString($ac3_data);
    17481677                                    }
     
    17631692                                    // This is probably DTS data
    17641693                                    $getid3_temp = new getID3();
    1765                                     $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
     1694                                    $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
    17661695                                    $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
    17671696                                    $getid3_dts = new getid3_dts($getid3_temp);
     
    18041733                            case 'MEXT':
    18051734                            case 'DISP':
    1806                             case 'wamd':
    1807                             case 'guan':
    18081735                                // always read data in
    18091736                            case 'JUNK':
     
    21502077    public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
    21512078
    2152         $parsed                    = array();
    21532079        $parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
    21542080        $parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
  • trunk/src/wp-includes/ID3/module.audio.flac.php

    r51900 r51901  
    403403        $info = &$this->getid3->info;
    404404
    405         $picture = array();
    406405        $picture['typeid']         = getid3_lib::BigEndian2Int($this->fread(4));
    407406        $picture['picturetype']    = self::pictureTypeLookup($picture['typeid']);
  • trunk/src/wp-includes/ID3/module.audio.mp3.php

    r51900 r51901  
    1919}
    2020
     21// number of frames to scan to determine if MPEG-audio sequence is valid
     22// Lower this number to 5-20 for faster scanning
     23// Increase this number to 50+ for most accurate detection of valid VBR/CBR
     24// mpeg-audio streams
     25define('GETID3_MP3_VALID_CHECK_FRAMES', 35);
     26
    2127
    2228class getid3_mp3 extends getid3_handler
     
    3137
    3238    /**
    33      * number of frames to scan to determine if MPEG-audio sequence is valid
    34      * Lower this number to 5-20 for faster scanning
    35      * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams
    36      *
    37      * @var int
    38      */
    39     public $mp3_valid_check_frames = 50;
    40 
    41     /**
    4239     * @return bool
    4340     */
     
    5956        }
    6057
    61         $CurrentDataLAMEversionString = null;
    6258        if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) {
    6359
     
    126122                    $PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3"  "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
    127123                    if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) {
    128                         if (!empty($info['audio']['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version']) && ($info['audio']['encoder'] == $info['mpeg']['audio']['LAME']['short_version'])) {
    129                             if (preg_match('#^LAME[0-9\\.]+#', $PossiblyLongerLAMEversion_NewString, $matches)) {
    130                                 // "LAME3.100" -> "LAME3.100.1", but avoid including "(alpha)" and similar
    131                                 $info['mpeg']['audio']['LAME']['short_version'] = $matches[0];
    132                             }
    133                         }
    134124                        $info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
    135125                    }
     
    306296
    307297            if ($info['audio']['bitrate_mode'] == 'cbr') {
    308                 $encoder_options = strtoupper($info['audio']['bitrate_mode']).round($info['audio']['bitrate'] / 1000);
     298                $encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
    309299            } else {
    310300                $encoder_options = strtoupper($info['audio']['bitrate_mode']);
     
    499489            $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
    500490        } else {
    501             $this->warning('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
     491            $this->error('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
    502492            return false;
    503493        }
     
    733723                    $thisfile_mpeg_audio_lame['long_version']  = substr($headerstring, $VBRidOffset + 120, 20);
    734724                    $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
    735 
    736                     //$thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
    737                     $thisfile_mpeg_audio_lame['numeric_version'] = '';
    738                     if (preg_match('#^LAME([0-9\\.a-z]*)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
     725                    $thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
     726                    if (preg_match('#^LAME([0-9\\.a-z]+)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
    739727                        $thisfile_mpeg_audio_lame['short_version']   = $matches[0];
    740728                        $thisfile_mpeg_audio_lame['numeric_version'] = $matches[1];
    741729                    }
    742                     if (strlen($thisfile_mpeg_audio_lame['numeric_version']) > 0) {
    743                         foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
    744                             $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
     730                    foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
     731                        $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
     732                    }
     733
     734                    //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
     735                    if ((($thisfile_mpeg_audio_lame['integer_version'][0] * 1000) + $thisfile_mpeg_audio_lame['integer_version'][1]) >= 3090) { // cannot use string version compare, may have "LAME3.90" or "LAME3.100" -- see https://github.com/JamesHeinrich/getID3/issues/207
     736
     737                        // extra 11 chars are not part of version string when LAMEtag present
     738                        unset($thisfile_mpeg_audio_lame['long_version']);
     739
     740                        // It the LAME tag was only introduced in LAME v3.90
     741                        // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
     742
     743                        // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
     744                        // are assuming a 'Xing' identifier offset of 0x24, which is the case for
     745                        // MPEG-1 non-mono, but not for other combinations
     746                        $LAMEtagOffsetContant = $VBRidOffset - 0x24;
     747
     748                        // shortcuts
     749                        $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
     750                        $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
     751                        $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
     752                        $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
     753                        $thisfile_mpeg_audio_lame['raw'] = array();
     754                        $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
     755
     756                        // byte $9B  VBR Quality
     757                        // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
     758                        // Actually overwrites original Xing bytes
     759                        unset($thisfile_mpeg_audio['VBR_scale']);
     760                        $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
     761
     762                        // bytes $9C-$A4  Encoder short VersionString
     763                        $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
     764
     765                        // byte $A5  Info Tag revision + VBR method
     766                        $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
     767
     768                        $thisfile_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
     769                        $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
     770                        $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
     771                        $thisfile_mpeg_audio['bitrate_mode']        = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
     772
     773                        // byte $A6  Lowpass filter value
     774                        $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
     775
     776                        // bytes $A7-$AE  Replay Gain
     777                        // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
     778                        // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
     779                        if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
     780                            // LAME 3.94a16 and later - 9.23 fixed point
     781                            // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
     782                            $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
     783                        } else {
     784                            // LAME 3.94a15 and earlier - 32-bit floating point
     785                            // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
     786                            $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
    745787                        }
    746                         //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
    747                         if ((($thisfile_mpeg_audio_lame['integer_version'][0] * 1000) + $thisfile_mpeg_audio_lame['integer_version'][1]) >= 3090) { // cannot use string version compare, may have "LAME3.90" or "LAME3.100" -- see https://github.com/JamesHeinrich/getID3/issues/207
    748 
    749                             // extra 11 chars are not part of version string when LAMEtag present
    750                             unset($thisfile_mpeg_audio_lame['long_version']);
    751 
    752                             // It the LAME tag was only introduced in LAME v3.90
    753                             // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
    754 
    755                             // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
    756                             // are assuming a 'Xing' identifier offset of 0x24, which is the case for
    757                             // MPEG-1 non-mono, but not for other combinations
    758                             $LAMEtagOffsetContant = $VBRidOffset - 0x24;
    759 
    760                             // shortcuts
    761                             $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
    762                             $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
    763                             $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
    764                             $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
    765                             $thisfile_mpeg_audio_lame['raw'] = array();
    766                             $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
    767 
    768                             // byte $9B  VBR Quality
    769                             // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
    770                             // Actually overwrites original Xing bytes
    771                             unset($thisfile_mpeg_audio['VBR_scale']);
    772                             $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
    773 
    774                             // bytes $9C-$A4  Encoder short VersionString
    775                             $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
    776 
    777                             // byte $A5  Info Tag revision + VBR method
    778                             $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
    779 
    780                             $thisfile_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
    781                             $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
    782                             $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
    783                             $thisfile_mpeg_audio['bitrate_mode']        = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
    784 
    785                             // byte $A6  Lowpass filter value
    786                             $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
    787 
    788                             // bytes $A7-$AE  Replay Gain
    789                             // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
    790                             // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
    791                             if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
    792                                 // LAME 3.94a16 and later - 9.23 fixed point
    793                                 // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
    794                                 $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
    795                             } else {
    796                                 // LAME 3.94a15 and earlier - 32-bit floating point
    797                                 // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
    798                                 $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
     788                        if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
     789                            unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     790                        } else {
     791                            $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     792                        }
     793
     794                        $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
     795                        $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
     796
     797
     798                        if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
     799
     800                            $thisfile_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
     801                            $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
     802                            $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
     803                            $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
     804                            $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
     805                            $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
     806                            $thisfile_mpeg_audio_lame_RGAD_track['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']);
     807
     808                            if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
     809                                $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    799810                            }
    800                             if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
    801                                 unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
    802                             } else {
    803                                 $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     811                            $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
     812                            $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
     813                        } else {
     814                            unset($thisfile_mpeg_audio_lame_RGAD['track']);
     815                        }
     816                        if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
     817
     818                            $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
     819                            $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
     820                            $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
     821                            $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
     822                            $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
     823                            $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
     824                            $thisfile_mpeg_audio_lame_RGAD_album['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']);
     825
     826                            if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
     827                                $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    804828                            }
    805 
    806                             $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
    807                             $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
    808 
    809 
    810                             if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
    811 
    812                                 $thisfile_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
    813                                 $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
    814                                 $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
    815                                 $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
    816                                 $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
    817                                 $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
    818                                 $thisfile_mpeg_audio_lame_RGAD_track['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']);
    819 
    820                                 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
    821                                     $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    822                                 }
    823                                 $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
    824                                 $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
    825                             } else {
    826                                 unset($thisfile_mpeg_audio_lame_RGAD['track']);
    827                             }
    828                             if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
    829 
    830                                 $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
    831                                 $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
    832                                 $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
    833                                 $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
    834                                 $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
    835                                 $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
    836                                 $thisfile_mpeg_audio_lame_RGAD_album['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']);
    837 
    838                                 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
    839                                     $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    840                                 }
    841                                 $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
    842                                 $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
    843                             } else {
    844                                 unset($thisfile_mpeg_audio_lame_RGAD['album']);
    845                             }
    846                             if (empty($thisfile_mpeg_audio_lame_RGAD)) {
    847                                 unset($thisfile_mpeg_audio_lame['RGAD']);
    848                             }
    849 
    850 
    851                             // byte $AF  Encoding flags + ATH Type
    852                             $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
    853                             $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
    854                             $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
    855                             $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
    856                             $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
    857                             $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
    858 
    859                             // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
    860                             $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
    861                             if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
    862                                 $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
    863                             } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
    864                                 // ignore
    865                             } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
    866                                 $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
    867                             }
    868 
    869                             // bytes $B1-$B3  Encoder delays
    870                             $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
    871                             $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
    872                             $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
    873 
    874                             // byte $B4  Misc
    875                             $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
    876                             $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
    877                             $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
    878                             $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
    879                             $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
    880                             $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
    881                             $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
    882                             $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
    883                             $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
    884 
    885                             // byte $B5  MP3 Gain
    886                             $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
    887                             $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
    888                             $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
    889 
    890                             // bytes $B6-$B7  Preset and surround info
    891                             $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
    892                             // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
    893                             $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
    894                             $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
    895                             $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
    896                             $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
    897                             if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
    898                                 $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
    899                             }
    900                             if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
    901                                 // this may change if 3.90.4 ever comes out
    902                                 $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
    903                             }
    904 
    905                             // bytes $B8-$BB  MusicLength
    906                             $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
    907                             $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
    908 
    909                             // bytes $BC-$BD  MusicCRC
    910                             $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
    911 
    912                             // bytes $BE-$BF  CRC-16 of Info Tag
    913                             $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
    914 
    915 
    916                             // LAME CBR
    917                             if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
    918 
    919                                 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
    920                                 $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
    921                                 $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
    922                                 //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
    923                                 //  $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
    924                                 //}
    925 
    926                             }
    927 
     829                            $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
     830                            $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
     831                        } else {
     832                            unset($thisfile_mpeg_audio_lame_RGAD['album']);
    928833                        }
     834                        if (empty($thisfile_mpeg_audio_lame_RGAD)) {
     835                            unset($thisfile_mpeg_audio_lame['RGAD']);
     836                        }
     837
     838
     839                        // byte $AF  Encoding flags + ATH Type
     840                        $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
     841                        $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
     842                        $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
     843                        $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
     844                        $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
     845                        $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
     846
     847                        // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
     848                        $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
     849                        if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
     850                            $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
     851                        } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
     852                            // ignore
     853                        } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
     854                            $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
     855                        }
     856
     857                        // bytes $B1-$B3  Encoder delays
     858                        $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
     859                        $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
     860                        $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
     861
     862                        // byte $B4  Misc
     863                        $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
     864                        $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
     865                        $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
     866                        $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
     867                        $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
     868                        $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
     869                        $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
     870                        $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
     871                        $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
     872
     873                        // byte $B5  MP3 Gain
     874                        $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
     875                        $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
     876                        $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
     877
     878                        // bytes $B6-$B7  Preset and surround info
     879                        $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
     880                        // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
     881                        $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
     882                        $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
     883                        $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
     884                        $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
     885                        if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
     886                            $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
     887                        }
     888                        if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
     889                            // this may change if 3.90.4 ever comes out
     890                            $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
     891                        }
     892
     893                        // bytes $B8-$BB  MusicLength
     894                        $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
     895                        $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
     896
     897                        // bytes $BC-$BD  MusicCRC
     898                        $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
     899
     900                        // bytes $BE-$BF  CRC-16 of Info Tag
     901                        $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
     902
     903
     904                        // LAME CBR
     905                        if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
     906
     907                            $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
     908                            $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
     909                            $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
     910                            //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
     911                            //  $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
     912                            //}
     913
     914                        }
     915
    929916                    }
    930917                }
     
    10221009            if (!$this->RecursiveFrameScanning($offset, $nextframetestoffset, $ScanAsCBR)) {
    10231010                return false;
    1024             }
    1025             if (!empty($this->getid3->info['mp3_validity_check_bitrates']) && !empty($thisfile_mpeg_audio['bitrate_mode']) && ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') && !empty($thisfile_mpeg_audio['VBR_bitrate'])) {
    1026                 // https://github.com/JamesHeinrich/getID3/issues/287
    1027                 if (count(array_keys($this->getid3->info['mp3_validity_check_bitrates'])) == 1) {
    1028                     list($cbr_bitrate_in_short_scan) = array_keys($this->getid3->info['mp3_validity_check_bitrates']);
    1029                     $deviation_cbr_from_header_bitrate = abs($thisfile_mpeg_audio['VBR_bitrate'] - $cbr_bitrate_in_short_scan) / $cbr_bitrate_in_short_scan;
    1030                     if ($deviation_cbr_from_header_bitrate < 0.01) {
    1031                         // VBR header bitrate may differ slightly from true bitrate of frames, perhaps accounting for overhead of VBR header frame itself?
    1032                         // If measured CBR bitrate is within 1% of specified bitrate in VBR header then assume that file is truly CBR
    1033                         $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
    1034                         //$this->warning('VBR header ignored, assuming CBR '.round($cbr_bitrate_in_short_scan / 1000).'kbps based on scan of '.$this->mp3_valid_check_frames.' frames');
    1035                     }
    1036                 }
    1037             }
    1038             if (isset($this->getid3->info['mp3_validity_check_bitrates'])) {
    1039                 unset($this->getid3->info['mp3_validity_check_bitrates']);
    10401011            }
    10411012
     
    11601131        $this->decodeMPEGaudioHeader($offset, $firstframetestarray, false);
    11611132
    1162         $info['mp3_validity_check_bitrates'] = array();
    1163         for ($i = 0; $i < $this->mp3_valid_check_frames; $i++) {
    1164             // check next (default: 50) frames for validity, to make sure we haven't run across a false synch
     1133        for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) {
     1134            // check next GETID3_MP3_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch
    11651135            if (($nextframetestoffset + 4) >= $info['avdataend']) {
    11661136                // end of file
     
    11701140            $nextframetestarray = array('error' => array(), 'warning' => array(), 'avdataend' => $info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
    11711141            if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) {
    1172                 getid3_lib::safe_inc($info['mp3_validity_check_bitrates'][$nextframetestarray['mpeg']['audio']['bitrate']]);
    11731142                if ($ScanAsCBR) {
    11741143                    // force CBR mode, used for trying to pick out invalid audio streams with valid(?) VBR headers, or VBR streams with no VBR header
     
    13051274        $LongMPEGpaddingLookup        = array();
    13061275        $LongMPEGfrequencyLookup      = array();
    1307         $Distribution                 = array();
    13081276        $Distribution['bitrate']      = array();
    13091277        $Distribution['frequency']    = array();
     
    14661434        $sync_seek_buffer_size = strlen($header);
    14671435        $SynchSeekOffset = 0;
    1468         $SyncSeekAttempts = 0;
    1469         $SyncSeekAttemptsMax = 1000;
    1470         $FirstFrameThisfileInfo = null;
    14711436        while ($SynchSeekOffset < $sync_seek_buffer_size) {
    14721437            if ((($avdataoffset + $SynchSeekOffset)  < $info['avdataend']) && !feof($this->getid3->fp)) {
     
    15071472            }
    15081473
    1509             if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // possible synch detected
    1510                 if (++$SyncSeekAttempts >= $SyncSeekAttemptsMax) {
    1511                     // https://github.com/JamesHeinrich/getID3/issues/286
    1512                     // corrupt files claiming to be MP3, with a large number of 0xFF bytes near the beginning, can cause this loop to take a very long time
    1513                     // should have escape condition to avoid spending too much time scanning a corrupt file
    1514                     // if a synch's not found within the first 128k bytes, then give up
    1515                     $this->error('Could not find valid MPEG audio synch after scanning '.$SyncSeekAttempts.' candidate offsets');
    1516                     if (isset($info['audio']['bitrate'])) {
    1517                         unset($info['audio']['bitrate']);
    1518                     }
    1519                     if (isset($info['mpeg']['audio'])) {
    1520                         unset($info['mpeg']['audio']);
    1521                     }
    1522                     if (empty($info['mpeg'])) {
    1523                         unset($info['mpeg']);
    1524                     }
    1525                     return false;
    1526                 }
     1474            if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // synch detected
    15271475                $FirstFrameAVDataOffset = null;
    15281476                if (!isset($FirstFrameThisfileInfo) && !isset($info['mpeg']['audio'])) {
     
    15641512                                $info = $dummy;
    15651513                                $info['avdataoffset'] = $GarbageOffsetEnd;
    1566                                 $this->warning('apparently-valid VBR header not used because could not find '.$this->mp3_valid_check_frames.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd);
     1514                                $this->warning('apparently-valid VBR header not used because could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd);
    15671515                            } else {
    1568                                 $this->warning('using data from VBR header even though could not find '.$this->mp3_valid_check_frames.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')');
     1516                                $this->warning('using data from VBR header even though could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')');
    15691517                            }
    15701518                        }
     
    16111559                        for ($current_segment = 0; $current_segment < $max_scan_segments; $current_segment++) {
    16121560                            $frames_scanned_this_segment = 0;
    1613                             $scan_start_offset = array();
    16141561                            if ($this->ftell() >= $info['avdataend']) {
    16151562                                break;
     
    19411888        }
    19421889
    1943         $MPEGrawHeader = array();
    19441890        $MPEGrawHeader['synch']         = (getid3_lib::BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4;
    19451891        $MPEGrawHeader['version']       = (ord($Header4Bytes[1]) & 0x18) >> 3; //    BB
  • trunk/src/wp-includes/ID3/module.audio.ogg.php

    r51900 r51901  
    530530    public function ParseOggPageHeader() {
    531531        // http://xiph.org/ogg/vorbis/doc/framing.html
    532         $oggheader = array();
    533532        $oggheader['page_start_offset'] = $this->ftell(); // where we started from in the file
    534533
     
    682681                $VorbisCommentPage++;
    683682
    684                 if ($oggpageinfo = $this->ParseOggPageHeader()) {
    685                     $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
    686 
    687                     // First, save what we haven't read yet
    688                     $AsYetUnusedData = substr($commentdata, $commentdataoffset);
    689 
    690                     // Then take that data off the end
    691                     $commentdata     = substr($commentdata, 0, $commentdataoffset);
    692 
    693                     // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
    694                     $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
    695                     $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
    696 
    697                     // Finally, stick the unused data back on the end
    698                     $commentdata .= $AsYetUnusedData;
    699 
    700                     //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
    701                     if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
    702                         $this->warning('undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
    703                         break;
    704                     }
    705                     $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
    706                     if ($readlength <= 0) {
    707                         $this->warning('invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
    708                         break;
    709                     }
    710                     $commentdata .= $this->fread($readlength);
    711 
    712                     //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
    713                 } else {
    714                     $this->warning('failed to ParseOggPageHeader() at offset '.$this->ftell());
     683                $oggpageinfo = $this->ParseOggPageHeader();
     684                $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
     685
     686                // First, save what we haven't read yet
     687                $AsYetUnusedData = substr($commentdata, $commentdataoffset);
     688
     689                // Then take that data off the end
     690                $commentdata     = substr($commentdata, 0, $commentdataoffset);
     691
     692                // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
     693                $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
     694                $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
     695
     696                // Finally, stick the unused data back on the end
     697                $commentdata .= $AsYetUnusedData;
     698
     699                //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
     700                if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
     701                    $this->warning('undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
    715702                    break;
    716703                }
     704                $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
     705                if ($readlength <= 0) {
     706                    $this->warning('invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
     707                    break;
     708                }
     709                $commentdata .= $this->fread($readlength);
     710
     711                //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
    717712            }
    718713            $ThisFileInfo_ogg_comments_raw[$i]['offset'] = $commentdataoffset;
  • trunk/src/wp-includes/ID3/module.tag.apetag.php

    r51900 r51901  
    361361
    362362        // shortcut
    363         $headerfooterinfo = array();
    364363        $headerfooterinfo['raw'] = array();
    365364        $headerfooterinfo_raw = &$headerfooterinfo['raw'];
     
    391390        // All are set to zero on creation and ignored on reading."
    392391        // http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
    393         $flags                      = array();
    394392        $flags['header']            = (bool) ($rawflagint & 0x80000000);
    395393        $flags['footer']            = (bool) ($rawflagint & 0x40000000);
  • trunk/src/wp-includes/ID3/module.tag.id3v1.php

    r51900 r51901  
    3232        }
    3333
    34         if($info['filesize'] < 256) {
    35             $this->fseek(-128, SEEK_END);
    36             $preid3v1 = '';
    37             $id3v1tag = $this->fread(128);
    38         } else {
    39             $this->fseek(-256, SEEK_END);
    40             $preid3v1 = $this->fread(128);
    41             $id3v1tag = $this->fread(128);
    42         }
    43 
     34        $this->fseek(-256, SEEK_END);
     35        $preid3v1 = $this->fread(128);
     36        $id3v1tag = $this->fread(128);
    4437
    4538        if (substr($id3v1tag, 0, 3) == 'TAG') {
     
    4740            $info['avdataend'] = $info['filesize'] - 128;
    4841
    49             $ParsedID3v1            = array();
    5042            $ParsedID3v1['title']   = $this->cutfield(substr($id3v1tag,   3, 30));
    5143            $ParsedID3v1['artist']  = $this->cutfield(substr($id3v1tag,  33, 30));
     
    306298            146  => 'JPop',
    307299            147  => 'Synthpop',
    308             148 => 'Abstract',
    309             149 => 'Art Rock',
    310             150 => 'Baroque',
    311             151 => 'Bhangra',
    312             152 => 'Big Beat',
    313             153 => 'Breakbeat',
    314             154 => 'Chillout',
    315             155 => 'Downtempo',
    316             156 => 'Dub',
    317             157 => 'EBM',
    318             158 => 'Eclectic',
    319             159 => 'Electro',
    320             160 => 'Electroclash',
    321             161 => 'Emo',
    322             162 => 'Experimental',
    323             163 => 'Garage',
    324             164 => 'Global',
    325             165 => 'IDM',
    326             166 => 'Illbient',
    327             167 => 'Industro-Goth',
    328             168 => 'Jam Band',
    329             169 => 'Krautrock',
    330             170 => 'Leftfield',
    331             171 => 'Lounge',
    332             172 => 'Math Rock',
    333             173 => 'New Romantic',
    334             174 => 'Nu-Breakz',
    335             175 => 'Post-Punk',
    336             176 => 'Post-Rock',
    337             177 => 'Psytrance',
    338             178 => 'Shoegaze',
    339             179 => 'Space Rock',
    340             180 => 'Trop Rock',
    341             181 => 'World Music',
    342             182 => 'Neoclassical',
    343             183 => 'Audiobook',
    344             184 => 'Audio Theatre',
    345             185 => 'Neue Deutsche Welle',
    346             186 => 'Podcast',
    347             187 => 'Indie-Rock',
    348             188 => 'G-Funk',
    349             189 => 'Dubstep',
    350             190 => 'Garage Rock',
    351             191 => 'Psybient',
    352300
    353301            255  => 'Unknown',
  • trunk/src/wp-includes/ID3/module.tag.id3v2.php

    r51900 r51901  
    346346                if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) {
    347347
    348                     $parsedFrame                    = array();
     348                    unset($parsedFrame);
    349349                    $parsedFrame['frame_name']      = $frame_name;
    350350                    $parsedFrame['frame_flags_raw'] = $frame_flags;
     
    979979
    980980        } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USLT')) || // 4.8   USLT Unsynchronised lyric/text transcription
    981                 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) {    // 4.9   ULT  Unsynchronised lyric/text transcription
     981                (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) {     // 4.9   ULT  Unsynchronised lyric/text transcription
    982982            //   There may be more than one 'Unsynchronised lyrics/text transcription' frame
    983983            //   in each tag, but only one with the same language and content descriptor.
     
    995995                $frame_textencoding_terminator = "\x00";
    996996            }
    997             if (strlen($parsedFrame['data']) >= (4 + strlen($frame_textencoding_terminator))) {  // shouldn't be an issue but badly-written files have been spotted in the wild with not only no contents but also missing the required language field, see https://github.com/JamesHeinrich/getID3/issues/315
    998                 $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
    999                 $frame_offset += 3;
    1000                 $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
    1001                 if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    1002                     $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    1003                 }
    1004                 $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
    1005                 $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']);
    1006                 $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
    1007                 $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator);
    1008 
    1009                 $parsedFrame['encodingid']   = $frame_textencoding;
    1010                 $parsedFrame['encoding']     = $this->TextEncodingNameLookup($frame_textencoding);
    1011 
    1012                 $parsedFrame['language']     = $frame_language;
    1013                 $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
    1014                 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
    1015                     $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']);
    1016                 }
    1017             } else {
    1018                 $this->warning('Invalid data in frame "'.$parsedFrame['frame_name'].'" at offset '.$parsedFrame['dataoffset']);
     997            $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
     998            $frame_offset += 3;
     999            $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1000            if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
     1001                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
     1002            }
     1003            $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
     1004            $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']);
     1005            $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
     1006            $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator);
     1007
     1008            $parsedFrame['encodingid']   = $frame_textencoding;
     1009            $parsedFrame['encoding']     = $this->TextEncodingNameLookup($frame_textencoding);
     1010
     1011            $parsedFrame['language']     = $frame_language;
     1012            $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
     1013            if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
     1014                $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']);
    10191015            }
    10201016            unset($parsedFrame['data']);
     
    13751371            }
    13761372
    1377             $frame_imagetype = null;
    1378             $frame_mimetype = null;
    13791373            if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) {
    13801374                $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3);
     
    19631957            $parsedFrame['peakamplitude'] = getid3_lib::BigEndian2Float(substr($parsedFrame['data'], $frame_offset, 4));
    19641958            $frame_offset += 4;
    1965             foreach (array('track','album') as $rgad_entry_type) {
    1966                 $rg_adjustment_word = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
    1967                 $frame_offset += 2;
    1968                 $parsedFrame['raw'][$rgad_entry_type]['name']       = ($rg_adjustment_word & 0xE000) >> 13;
    1969                 $parsedFrame['raw'][$rgad_entry_type]['originator'] = ($rg_adjustment_word & 0x1C00) >> 10;
    1970                 $parsedFrame['raw'][$rgad_entry_type]['signbit']    = ($rg_adjustment_word & 0x0200) >>  9;
    1971                 $parsedFrame['raw'][$rgad_entry_type]['adjustment'] = ($rg_adjustment_word & 0x0100);
    1972             }
     1959            $rg_track_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2));
     1960            $frame_offset += 2;
     1961            $rg_album_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2));
     1962            $frame_offset += 2;
     1963            $parsedFrame['raw']['track']['name']       = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 0, 3));
     1964            $parsedFrame['raw']['track']['originator'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 3, 3));
     1965            $parsedFrame['raw']['track']['signbit']    = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 6, 1));
     1966            $parsedFrame['raw']['track']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 7, 9));
     1967            $parsedFrame['raw']['album']['name']       = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 0, 3));
     1968            $parsedFrame['raw']['album']['originator'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 3, 3));
     1969            $parsedFrame['raw']['album']['signbit']    = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 6, 1));
     1970            $parsedFrame['raw']['album']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 7, 9));
    19731971            $parsedFrame['track']['name']       = getid3_lib::RGADnameLookup($parsedFrame['raw']['track']['name']);
    19741972            $parsedFrame['track']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['track']['originator']);
     
    24472445            TND Dinars
    24482446            TOP Pa'anga
    2449             TRL Liras (old)
    2450             TRY Liras
     2447            TRL Liras
    24512448            TTD Dollars
    24522449            TVD Tuvalu Dollars
     
    26492646            TOP Tonga
    26502647            TRL Turkey
    2651             TRY Turkey
    26522648            TTD Trinidad and Tobago
    26532649            TVD Tuvalu
  • trunk/src/wp-includes/ID3/module.tag.lyrics3.php

    r51900 r51901  
    3434
    3535        $this->fseek((0 - 128 - 9 - 6), SEEK_END);          // end - ID3v1 - "LYRICSEND" - [Lyrics3size]
    36         $lyrics3offset = null;
    37         $lyrics3version = null;
    38         $lyrics3size   = null;
    3936        $lyrics3_id3v1 = $this->fread(128 + 9 + 6);
    4037        $lyrics3lsz    = (int) substr($lyrics3_id3v1, 0, 6); // Lyrics3size
  • trunk/src/wp-includes/ID3/readme.txt

    r51900 r51901  
    626626* http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
    627627* http://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
    628 * https://fileformats.fandom.com/wiki/Torrent_file
Note: See TracChangeset for help on using the changeset viewer.