Add Zend_Media_Id3v2 class proposal
git-svn-id: http://php-reader.googlecode.com/svn/branches/zend@153 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
348
src/Zend/Media/Id3/ExtendedHeader.php
Normal file
348
src/Zend/Media/Id3/ExtendedHeader.php
Normal file
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Media
|
||||
* @subpackage ID3
|
||||
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**#@+ @ignore */
|
||||
require_once 'Zend/Media/Id3/Object.php';
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* The extended header contains information that can provide further insight in
|
||||
* the structure of the tag, but is not vital to the correct parsing of the tag
|
||||
* information; hence the extended header is optional.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Media
|
||||
* @subpackage ID3
|
||||
* @author Sven Vollbehr <sven@vollbehr.eu>
|
||||
* @author Ryan Butterfield <buttza@gmail.com>
|
||||
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
* @version $Id$
|
||||
*/
|
||||
final class Zend_Media_Id3_ExtendedHeader extends Zend_Media_Id3_Object
|
||||
{
|
||||
/**
|
||||
* A flag to denote that the present tag is an update of a tag found earlier
|
||||
* in the present file or stream. If frames defined as unique are found in
|
||||
* the present tag, they are to override any corresponding ones found in the
|
||||
* earlier tag. This flag has no corresponding data.
|
||||
*
|
||||
* @since ID3v2.4.0
|
||||
*/
|
||||
const UPDATE = 64;
|
||||
|
||||
/**
|
||||
* @since ID3v2.4.0 A flag to denote that a CRC-32 data is included in the
|
||||
* extended header. The CRC is calculated on all the data between the header
|
||||
* and footer as indicated by the header's tag length field, minus the
|
||||
* extended header. Note that this includes the padding (if there is any),
|
||||
* but excludes the footer. The CRC-32 is stored as an 35 bit synchsafe
|
||||
* integer, leaving the upper four bits always zeroed.
|
||||
*
|
||||
* @since ID3v2.3.0 The CRC is calculated before unsynchronisation on the
|
||||
* data between the extended header and the padding, i.e. the frames and
|
||||
* only the frames.
|
||||
*/
|
||||
const CRC32 = 32;
|
||||
|
||||
/**
|
||||
* A flag to denote whether or not the tag has restrictions applied on it.
|
||||
*
|
||||
* @since ID3v2.4.0
|
||||
*/
|
||||
const RESTRICTED = 16;
|
||||
|
||||
/** @var integer */
|
||||
private $_size;
|
||||
|
||||
/** @var integer */
|
||||
private $_flags = 0;
|
||||
|
||||
/** @var integer */
|
||||
private $_padding;
|
||||
|
||||
/** @var integer */
|
||||
private $_crc;
|
||||
|
||||
/** @var integer */
|
||||
private $_restrictions = 0;
|
||||
|
||||
/**
|
||||
* Constructs the class with given parameters and reads object related data
|
||||
* from the ID3v2 tag.
|
||||
*
|
||||
* @param Zend_Io_Reader $reader The reader object.
|
||||
* @param Array $options The options array.
|
||||
*/
|
||||
public function __construct($reader = null, &$options = array())
|
||||
{
|
||||
parent::__construct($reader, $options);
|
||||
|
||||
if ($reader === null)
|
||||
return;
|
||||
|
||||
$offset = $this->_reader->getOffset();
|
||||
$this->_size = $this->_reader->readUInt32BE();
|
||||
|
||||
/* ID3v2.3.0 ExtendedHeader */
|
||||
if ($this->getOption('version', 4) < 4) {
|
||||
if ($this->_reader->readUInt16BE() == 0x8000) {
|
||||
$this->_flags = self::CRC32;
|
||||
}
|
||||
$this->_padding = $this->_reader->readUInt32BE();
|
||||
if ($this->hasFlag(self::CRC32)) {
|
||||
$this->_crc = $this->_reader->readUInt32BE();
|
||||
}
|
||||
}
|
||||
|
||||
/* ID3v2.4.0 ExtendedHeader */
|
||||
else {
|
||||
$this->_size = $this->_decodeSynchsafe32($this->_size);
|
||||
$this->_reader->skip(1);
|
||||
$this->_flags = $this->_reader->readInt8();
|
||||
if ($this->hasFlag(self::UPDATE)) {
|
||||
$this->_reader->skip(1);
|
||||
}
|
||||
if ($this->hasFlag(self::CRC32)) {
|
||||
$this->_reader->skip(1);
|
||||
$this->_crc =
|
||||
$this->_reader->readInt8() * (0xfffffff + 1) +
|
||||
_decodeSynchsafe32($this->_reader->readUInt32BE());
|
||||
}
|
||||
if ($this->hasFlag(self::RESTRICTED)) {
|
||||
$this->_reader->skip(1);
|
||||
$this->_restrictions = $this->_reader->readInt8();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extended header size in bytes.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not the flag is set. Returns <var>true</var> if the
|
||||
* flag is set, <var>false</var> otherwise.
|
||||
*
|
||||
* @param integer $flag The flag to query.
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasFlag($flag)
|
||||
{
|
||||
return ($this->_flags & $flag) == $flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags byte.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getFlags($flags)
|
||||
{
|
||||
return $this->_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flags byte.
|
||||
*
|
||||
* @param integer $flags The flags byte.
|
||||
*/
|
||||
public function setFlags($flags)
|
||||
{
|
||||
$this->_flags = $flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CRC-32 data.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCrc()
|
||||
{
|
||||
if ($this->hasFlag(self::CRC32)) {
|
||||
return $this->_crc;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the CRC-32 should be generated upon tag write.
|
||||
*
|
||||
* @param boolean $useCrc Whether CRC-32 should be generated.
|
||||
*/
|
||||
public function useCrc($useCrc)
|
||||
{
|
||||
if ($useCrc) {
|
||||
$this->setFlags($this->getFlags() | self::CRC32);
|
||||
} else {
|
||||
$this->setFlags($this->getFlags() & ~self::CRC32);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CRC-32. The CRC-32 value is calculated of all the frames in the
|
||||
* tag and includes padding.
|
||||
*
|
||||
* @param integer $crc The 32-bit CRC value.
|
||||
*/
|
||||
public function setCrc($crc)
|
||||
{
|
||||
if (is_bool($crc)) {
|
||||
$this->useCrc($crc);
|
||||
} else {
|
||||
$this->_crc = $crc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the restrictions. For some applications it might be desired to
|
||||
* restrict a tag in more ways than imposed by the ID3v2 specification. Note
|
||||
* that the presence of these restrictions does not affect how the tag is
|
||||
* decoded, merely how it was restricted before encoding. If this flag is
|
||||
* set the tag is restricted as follows:
|
||||
*
|
||||
* <pre>
|
||||
* Restrictions %ppqrrstt
|
||||
*
|
||||
* p - Tag size restrictions
|
||||
*
|
||||
* 00 No more than 128 frames and 1 MB total tag size.
|
||||
* 01 No more than 64 frames and 128 KB total tag size.
|
||||
* 10 No more than 32 frames and 40 KB total tag size.
|
||||
* 11 No more than 32 frames and 4 KB total tag size.
|
||||
*
|
||||
* q - Text encoding restrictions
|
||||
*
|
||||
* 0 No restrictions
|
||||
* 1 Strings are only encoded with ISO-8859-1 or UTF-8.
|
||||
*
|
||||
* r - Text fields size restrictions
|
||||
*
|
||||
* 00 No restrictions
|
||||
* 01 No string is longer than 1024 characters.
|
||||
* 10 No string is longer than 128 characters.
|
||||
* 11 No string is longer than 30 characters.
|
||||
*
|
||||
* Note that nothing is said about how many bytes is used to represent
|
||||
* those characters, since it is encoding dependent. If a text frame
|
||||
* consists of more than one string, the sum of the strungs is restricted
|
||||
* as stated.
|
||||
*
|
||||
* s - Image encoding restrictions
|
||||
*
|
||||
* 0 No restrictions
|
||||
* 1 Images are encoded only with PNG [PNG] or JPEG [JFIF].
|
||||
*
|
||||
* t - Image size restrictions
|
||||
*
|
||||
* 00 No restrictions
|
||||
* 01 All images are 256x256 pixels or smaller.
|
||||
* 10 All images are 64x64 pixels or smaller.
|
||||
* 11 All images are exactly 64x64 pixels, unless required otherwise.
|
||||
* </pre>
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getRestrictions()
|
||||
{
|
||||
return $this->_restrictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the restrictions byte. See {@link #getRestrictions} for more.
|
||||
*
|
||||
* @param integer $restrictions The restrictions byte.
|
||||
*/
|
||||
public function setRestrictions($restrictions)
|
||||
{
|
||||
$this->_restrictions = $restrictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total padding size, or simply the total tag size excluding
|
||||
* the frames and the headers.
|
||||
*
|
||||
* @return integer
|
||||
* @deprecated ID3v2.3.0
|
||||
*/
|
||||
public function getPadding()
|
||||
{
|
||||
return $this->_padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total padding size, or simply the total tag size excluding the
|
||||
* frames and the headers.
|
||||
*
|
||||
* @param integer $padding The padding size.
|
||||
* @deprecated ID3v2.3.0
|
||||
*/
|
||||
public function setPadding($padding)
|
||||
{
|
||||
return $this->_padding = $padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the header data.
|
||||
*
|
||||
* @param Zend_Io_Writer $writer The writer object.
|
||||
* @return void
|
||||
*/
|
||||
public function write($writer)
|
||||
{
|
||||
/* ID3v2.3.0 ExtendedHeader */
|
||||
if ($this->getOption('version', 4) < 4) {
|
||||
$writer->writeUInt32BE($this->_size)
|
||||
->writeUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0)
|
||||
->writeUInt32BE($this->_padding);
|
||||
if ($this->hasFlag(self::CRC32)) {
|
||||
$writer->writeUInt32BE($this->_crc);
|
||||
}
|
||||
}
|
||||
|
||||
/* ID3v2.4.0 ExtendedHeader */
|
||||
else {
|
||||
$writer->writeUInt32BE($this->_encodeSynchsafe32($this->_size))
|
||||
->writeInt8(1)
|
||||
->writeInt8($this->_flags);
|
||||
if ($this->hasFlag(self::UPDATE)) {
|
||||
$writer->write("\0");
|
||||
}
|
||||
if ($this->hasFlag(self::CRC32)) {
|
||||
$writer->writeInt8(5)
|
||||
->writeInt8
|
||||
($this->_crc & 0xf0000000 >> 28 & 0xf /*eq >>> 28*/)
|
||||
->writeUInt32BE($this->_encodeSynchsafe32($this->_crc));
|
||||
}
|
||||
if ($this->hasFlag(self::RESTRICTED)) {
|
||||
$writer->writeInt8(1)
|
||||
->writeInt8($this->_restrictions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user