Пример #1
0
 /**
  * Parse the Frame Flags
  *
  * @return array
  * @throws Zend_Id3_Adapter_Id3v2_Frame_Exception
  */
 private function _parseFrameFlags()
 {
     $flags = array();
     switch ($this->_tagVersion) {
         /**
          * v2.3 Frame Header Flags
          * %abc00000 %ijk00000
          */
         case 3:
             $flags['TagAlterPreservation'] = (bool) ($this->_data['frame_flags_raw'] & 0x8000);
             // a - Tag alter preservation
             $flags['FileAlterPreservation'] = (bool) ($this->_data['frame_flags_raw'] & 0x4000);
             // b - File alter preservation
             $flags['ReadOnly'] = (bool) ($this->_data['frame_flags_raw'] & 0x2000);
             // c - Read only
             $flags['compression'] = (bool) ($this->_data['frame_flags_raw'] & 0x80);
             // i - Compression
             $flags['Encryption'] = (bool) ($this->_data['frame_flags_raw'] & 0x40);
             // j - Encryption
             $flags['GroupingIdentity'] = (bool) ($this->_data['frame_flags_raw'] & 0x20);
             // k - Grouping identity
             break;
             /**
              * v2.4 Frame Header Flags
              * %0abc0000 %0h00kmnp
              */
         /**
          * v2.4 Frame Header Flags
          * %0abc0000 %0h00kmnp
          */
         case 4:
             $flags['TagAlterPreservation'] = (bool) ($this->_data['frame_flags_raw'] & 0x4000);
             // a - Tag alter preservation
             $flags['FileAlterPreservation'] = (bool) ($this->_data['frame_flags_raw'] & 0x2000);
             // b - File alter preservation
             $flags['ReadOnly'] = (bool) ($this->_data['frame_flags_raw'] & 0x1000);
             // c - Read only
             $flags['GroupingIdentity'] = (bool) ($this->_data['frame_flags_raw'] & 0x40);
             // h - Grouping identity
             $flags['compression'] = (bool) ($this->_data['frame_flags_raw'] & 0x8);
             // k - Compression
             $flags['Encryption'] = (bool) ($this->_data['frame_flags_raw'] & 0x4);
             // m - Encryption
             $flags['Unsynchronisation'] = (bool) ($this->_data['frame_flags_raw'] & 0x2);
             // n - Unsynchronisation
             $flags['DataLengthIndicator'] = (bool) ($this->_data['frame_flags_raw'] & 0x1);
             // p - Data length indicator
             // Frame-level de-unsynchronisation - ID3v2.4
             if ($flags['Unsynchronisation']) {
                 $this->_data['data'] = str_replace("ÿ", "ÿ", $this->_data['data']);
             }
             break;
     }
     /**
      * Frame-Level de-compression
      */
     if ($flags['compression']) {
         $this->_data['decompressed_size'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($this->_data['data'], 0, 4));
         if (!function_exists('gzuncompress')) {
             include_once 'Zend/Id3/Adapter/Id3v2/Frame/Exception.php';
             throw new Zend_Id3_Adapter_Id3v2_Frame_Exception('gzuncompress() support required to decompress ID3v2 frame "' . $this->_data['frame_name'] . '"');
         } elseif ($decompressed_data = @gzuncompress(substr($this->_data['data'], 4))) {
             $this->_data['data'] = $decompressed_data;
         } else {
             include_once 'Zend/Id3/Adapter/Id3v2/Frame/Exception.php';
             throw new Zend_Id3_Adapter_Id3v2_Frame_Exception('gzuncompress() failed on compressed contents of ID3v2 frame "' . $this->_data['frame_name'] . '"');
         }
     }
     return $flags;
 }
Пример #2
0
 /**
  * Parse frame out from v2.3 and higher tags
  *
  * Frame ID  $xx xx xx xx (four characters)
  * Size      $xx xx xx xx (32-bit integer in v2.3, 28-bit synchsafe in v2.4+)
  * Flags     $xx xx
  *
  * @param string $frameData
  */
 protected function _getFrame($frameData)
 {
     $info = array();
     // take next 10 bytes for header
     $info['frameHeader'] = substr($frameData, 0, 10);
     // and leave the rest in $frame_data
     $info['frameData'] = substr($frameData, 10);
     $info['frameName'] = substr($info['frameHeader'], 0, 4);
     $info['frameSize'] = $this->_tagVersion == 3 ? Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4)) : Zend_Id3_ByteConvert::bigEndianSyncSafe2Int(substr($info['frameHeader'], 4, 4));
     if ($info['frameSize'] < strlen($frameData) + 4) {
         $arrBrokenMP3extFrames = array("" . 'MP3', "" . 'MP', ' MP3', 'MP3e');
         $nextFrameID = substr($frameData, $info['frameSize'], 4);
         if ($this->_isValidID3v2FrameName($nextFrameID)) {
             // next frame is OK
         } else {
             if (in_array($info['frameName'], $arrBrokenMP3extFrames)) {
                 // MP3ext known broken frames - "ok" for the purposes of this test
             } else {
                 if ($this->_tagVersion == 4 && $this->_isValidID3v2FrameName(substr($info['frameData'], Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4)), 4), 3)) {
                     $this->_tagVersion = 3;
                     $info['frameSize'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4));
                     // 32-bit integer
                 }
             }
         }
     }
     $info['frameFlag'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 8, 2));
     // padding encountered
     if ($info['frameName'] == "") {
         return $this->_parsePadding($info['frameData'], $info['frameHeader']);
     }
     return $info;
 }
Пример #3
0
 /**
  *
  */
 protected function _proccessExtendedFrameHeader($frameData)
 {
     $extendedHeaderOffset = 0;
     switch ($this->_tagMajorVersion) {
         /**
          * v2.3 definition:
          *
          * Extended header size  $xx xx xx xx   // 32-bit integer
          * Extended Flags        $xx xx
          * %x0000000 %00000000 // v2.3
          *     x - CRC data present
          * Size of padding       $xx xx xx xx
          */
         case 3:
             $this->_tagInfo['id3v2']['exthead']['length'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 4), 0);
             $extendedHeaderOffset += 4;
             $this->_tagInfo['id3v2']['exthead']['flag_bytes'] = 2;
             $this->_tagInfo['id3v2']['exthead']['flag_raw'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, $this->_tagInfo['id3v2']['exthead']['flag_bytes']));
             $extendedHeaderOffset += $this->_tagInfo['id3v2']['exthead']['flag_bytes'];
             $this->_tagInfo['id3v2']['exthead']['flags']['crc'] = (bool) ($this->_tagInfo['id3v2']['exthead']['flag_raw'] & 0x8000);
             $this->_tagInfo['id3v2']['exthead']['padding_size'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 4));
             $extendedHeaderOffset += 4;
             if ($this->_tagInfo['id3v2']['exthead']['flags']['crc']) {
                 $this->_tagInfo['id3v2']['exthead']['flag_data']['crc'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 4));
                 $extendedHeaderOffset += 4;
             }
             $extendedHeaderOffset += $this->_tagInfo['id3v2']['exthead']['padding_size'];
             break;
             /**
              * v2.4 definition:
              *
              * Extended header size   4 * %0xxxxxxx  *  28-bit synchsafe integer
              * Number of flag bytes       $01
              * Extended Flags             $xx
              *      %0bcd0000  *  v2.4
              *      b - Tag is an update
              *          Flag data length       $00
              *      c - CRC data present
              *          Flag data length       $05
              *          Total frame CRC    5 * %0xxxxxxx
              *      d - Tag restrictions
              *          Flag data length       $01
              */
         /**
          * v2.4 definition:
          *
          * Extended header size   4 * %0xxxxxxx  *  28-bit synchsafe integer
          * Number of flag bytes       $01
          * Extended Flags             $xx
          *      %0bcd0000  *  v2.4
          *      b - Tag is an update
          *          Flag data length       $00
          *      c - CRC data present
          *          Flag data length       $05
          *          Total frame CRC    5 * %0xxxxxxx
          *      d - Tag restrictions
          *          Flag data length       $01
          */
         case 4:
             $this->_tagInfo['id3v2']['exthead']['length'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 4), 1);
             $extendedHeaderOffset += 4;
             $this->_tagInfo['id3v2']['exthead']['flag_bytes'] = 1;
             $this->_tagInfo['id3v2']['exthead']['flag_raw'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, $this->_tagInfo['id3v2']['exthead']['flag_bytes']));
             $extendedHeaderOffset += $this->_tagInfo['id3v2']['exthead']['flag_bytes'];
             $this->_tagInfo['id3v2']['exthead']['flags']['update'] = (bool) ($this->_tagInfo['id3v2']['exthead']['flag_raw'] & 0x4000);
             $this->_tagInfo['id3v2']['exthead']['flags']['crc'] = (bool) ($this->_tagInfo['id3v2']['exthead']['flag_raw'] & 0x2000);
             $this->_tagInfo['id3v2']['exthead']['flags']['restrictions'] = (bool) ($this->_tagInfo['id3v2']['exthead']['flag_raw'] & 0x1000);
             if ($this->_tagInfo['id3v2']['exthead']['flags']['crc']) {
                 $this->_tagInfo['id3v2']['exthead']['flag_data']['crc'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 5), 1);
                 $extendedHeaderOffset += 5;
             }
             if ($this->_tagInfo['id3v2']['exthead']['flags']['restrictions']) {
                 // %ppqrrstt
                 $restrictionsByte = Zend_Id3_ByteConvert::bigEndian2Int(substr($frameData, $extendedHeaderOffset, 1));
                 $extendedHeaderOffset += 1;
                 $this->_tagInfo['id3v2']['exthead']['flags']['restrictions']['tagsize'] = ($restrictionsByte && 0xc0) >> 6;
                 // p - Tag size restrictions
                 $this->_tagInfo['id3v2']['exthead']['flags']['restrictions']['textenc'] = ($restrictionsByte && 0x20) >> 5;
                 // q - Text encoding restrictions
                 $this->_tagInfo['id3v2']['exthead']['flags']['restrictions']['textsize'] = ($restrictionsByte && 0x18) >> 3;
                 // r - Text fields size restrictions
                 $this->_tagInfo['id3v2']['exthead']['flags']['restrictions']['imgenc'] = ($restrictionsByte && 0x4) >> 2;
                 // s - Image encoding restrictions
                 $this->_tagInfo['id3v2']['exthead']['flags']['restrictions']['imgsize'] = ($restrictionsByte && 0x3) >> 0;
                 // t - Image size restrictions
             }
             break;
     }
     $this->_frameDataOffset += $extendedHeaderOffset;
     $frameData = substr($frameData, $extendedHeaderOffset);
     return $frameData;
 }