Add support for ID3v2.3

git-svn-id: http://php-reader.googlecode.com/svn/trunk@75 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
svollbehr
2008-04-14 23:57:21 +00:00
parent 793eb16082
commit 3191721e15
42 changed files with 1338 additions and 243 deletions

View File

@@ -58,21 +58,31 @@ final class ID3_ExtendedHeader extends ID3_Object
* 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 = 128;
const UPDATE = 64;
/**
* 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.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 = 64;
const CRC32 = 32;
/** A flag to denote whether or not the tag has restrictions applied on it. */
const RESTRICTED = 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;
@@ -80,6 +90,9 @@ final class ID3_ExtendedHeader extends ID3_Object
/** @var integer */
private $_flags = 0;
/** @var integer */
private $_padding;
/** @var integer */
private $_crc;
@@ -91,33 +104,44 @@ final class ID3_ExtendedHeader extends ID3_Object
* from the ID3v2 tag.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
$offset = $this->_reader->getOffset();
$this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE());
$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 =
Transform::fromInt8($this->_reader->read(1)) * (0xfffffff + 1) +
decodeSynchsafe32(Transform::fromUInt32BE($this->_reader->read(4)));
}
if ($this->hasFlag(self::RESTRICTED)) {
$this->_reader->skip(1);
$this->_restrictions = $this->_reader->readInt8(1);
/* ID3v2.3.0 ExtendedHeader */
if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
if ($this->_reader->readUInt16BE() == 0x8000)
$this->_flags = self::CRC32;
$this->_padding = $this->_reader->readUInt32BE();
if ($this->hasFlag(self::CRC32))
$this->_crc = Transform::readUInt32BE();
}
$this->_reader->skip($this->_size - $this->_reader->getOffset() - $offset);
/* ID3v2.4.0 ExtendedHeader */
else {
$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 =
Transform::fromInt8($this->_reader->read(1)) * (0xfffffff + 1) +
decodeSynchsafe32(Transform::fromUInt32BE($this->_reader->read(4)));
}
if ($this->hasFlag(self::RESTRICTED)) {
$this->_reader->skip(1);
$this->_restrictions = $this->_reader->readInt8(1);
}
}
}
/**
@@ -249,20 +273,49 @@ final class ID3_ExtendedHeader extends ID3_Object
$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; }
/**
* Returns the header raw data.
*
* @return string
*/
public function toString()
public function __toString()
{
return Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) .
Transform::toInt8(1) . Transform::toInt8($this->_flags) .
($this->hasFlag(self::UPDATE) ? "\0" : "") .
($this->hasFlag(self::CRC32) ? Transform::toInt8(5) .
Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf /* eq >>> 28 */) .
Transform::toUInt32BE(encodeSynchsafe32($this->_crc)) : "") .
($this->hasFlag(self::RESTRICTED) ?
Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : "");
/* ID3v2.3.0 ExtendedHeader */
if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
return Transform::toUInt32BE($this->_size) .
Transform::toUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) .
Transform::toUInt32BE($this->_padding) .
($this->hasFlag(self::CRC32) ? Transform::toUInt32BE($this->_crc) : "");
}
/* ID3v2.4.0 ExtendedHeader */
else {
return Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) .
Transform::toInt8(1) . Transform::toInt8($this->_flags) .
($this->hasFlag(self::UPDATE) ? "\0" : "") .
($this->hasFlag(self::CRC32) ? Transform::toInt8(5) .
Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf /*eq >>> 28*/) .
Transform::toUInt32BE(encodeSynchsafe32($this->_crc)) : "") .
($this->hasFlag(self::RESTRICTED) ?
Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : "");
}
}
}

View File

@@ -104,12 +104,16 @@ class ID3_Frame extends ID3_Object
/**
* This flag indicates whether or not unsynchronisation was applied to this
* frame.
*
* @since ID3v2.4.0
*/
const UNSYNCHRONISATION = 2;
/**
* This flag indicates that a data length indicator has been added to the
* frame.
*
* @since ID3v2.4.0
*/
const DATA_LENGTH_INDICATOR = 1;
@@ -135,17 +139,39 @@ class ID3_Frame extends ID3_Object
*
* @todo Only limited subset of flags are processed.
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null) {
$this->_identifier = substr(get_class($this), -4);
} else {
$this->_identifier = $this->_reader->readString8(4);
$this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE());
$this->_flags = $this->_reader->readUInt16BE();
/* ID3v2.3.0 Flags; convert to 2.4.0 format */
if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
$flags = $this->_reader->readUInt16BE();
if (($flags & 0x8000) == 0x8000)
$this->_flags |= self::DISCARD_ON_TAGCHANGE;
if (($flags & 0x4000) == 0x4000)
$this->_flags |= self::DISCARD_ON_FILECHANGE;
if (($flags & 0x2000) == 0x2000)
$this->_flags |= self::READ_ONLY;
if (($flags & 0x80) == 0x80)
$this->_flags |= self::COMPRESSION;
if (($flags & 0x40) == 0x40)
$this->_flags |= self::ENCRYPTION;
if (($flags & 0x20) == 0x20)
$this->_flags |= self::GROUPING_IDENTITY;
}
/* ID3v2.4.0 Flags */
else
$this->_flags = $this->_reader->readUInt16BE();
$this->_data = $this->_reader->read($this->_size);
}
}
@@ -216,8 +242,29 @@ class ID3_Frame extends ID3_Object
*/
public function __toString()
{
/* ID3v2.3.0 Flags; convert from 2.4.0 format */
if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
$flags = 0;
if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE))
$flags = $flags | 0x8000;
if ($this->hasFlag(self::DISCARD_ON_FILECHANGE))
$flags = $flags | 0x4000;
if ($this->hasFlag(self::READ_ONLY))
$flags = $flags | 0x2000;
if ($this->hasFlag(self::COMPRESSION))
$flags = $flags | 0x80;
if ($this->hasFlag(self::ENCRYPTION))
$flags = $flags | 0x40;
if ($this->hasFlag(self::GROUPING_IDENTITY))
$flags = $flags | 0x20;
}
/* ID3v2.4.0 Flags */
else
$flags = $this->_flags;
return Transform::toString8(substr($this->_identifier, 0, 4), 4) .
Transform::toUInt32BE($this->encodeSynchsafe32($this->_size)) .
Transform::toUInt16BE($this->_flags) . $this->_data;
Transform::toUInt16BE($flags) . $this->_data;
}
}

View File

@@ -60,7 +60,7 @@ require_once("ID3/Frame.php");
final class ID3_Frame_AENC extends ID3_Frame
{
/** @var string */
private $_id;
private $_owner;
/** @var integer */
private $_previewStart;
@@ -75,15 +75,16 @@ final class ID3_Frame_AENC extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
list($this->_owner, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
$this->_previewStart = substr($this->_data, 0, 2);
$this->_previewLength = substr($this->_data, 2, 2);
$this->_encryptionInfo = substr($this->_data, 4);
@@ -94,14 +95,14 @@ final class ID3_Frame_AENC extends ID3_Frame
*
* @return string
*/
public function getIdentifier() { return $this->_id; }
public function getOwner() { return $this->_owner; }
/**
* Sets the owner identifier string.
*
* @param string $id The owner identifier string.
* @param string $owner The owner identifier string.
*/
public function setIdentifier($id) { $this->_id = $id; }
public function setOwner($owner) { $this->_owner = $owner; }
/**
* Returns the pointer to an unencrypted part of the audio in frames.
@@ -162,7 +163,7 @@ final class ID3_Frame_AENC extends ID3_Frame
public function __toString()
{
$this->setData
($this->_id . "\0" . Transform::toInt16BE($this->_previewStart) .
($this->_owner . "\0" . Transform::toInt16BE($this->_previewStart) .
Transform::toInt16BE($this->_previewLength) . $this->_encryptionInfo);
return parent::__toString();
}

View File

@@ -97,10 +97,11 @@ final class ID3_Frame_APIC extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
@@ -108,7 +109,7 @@ final class ID3_Frame_APIC extends ID3_Frame
$this->_encoding = Transform::fromInt8($this->_data[0]);
$this->_mimeType = substr
($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1);
$this->_pictureType = Transform::fromInt8($this->_data[$pos++]);
$this->_imageType = Transform::fromInt8($this->_data[$pos++]);
$this->_data = substr($this->_data, $pos);
switch ($this->_encoding) {

View File

@@ -77,10 +77,11 @@ final class ID3_Frame_ASPI extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
throw new ID3_Exception("Write not supported yet");

View File

@@ -58,13 +58,14 @@ abstract class ID3_Frame_AbstractLink extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader !== null)
$this->_link = preg_split("/\\x00/", $this->_data, 1);
$this->_link = implode(preg_split("/\\x00/", $this->_data, 1), "");
}
/**
@@ -88,7 +89,7 @@ abstract class ID3_Frame_AbstractLink extends ID3_Frame
*/
public function __toString()
{
$this->setData($link);
$this->setData($this->_link);
return parent::__toString();
}
}

View File

@@ -53,20 +53,29 @@ require_once("ID3/Encoding.php");
abstract class ID3_Frame_AbstractText extends ID3_Frame
implements ID3_Encoding
{
/** @var integer */
private $_encoding = ID3_Encoding::UTF8;
/**
* The text encoding.
*
* @var integer
*/
protected $_encoding = ID3_Encoding::UTF8;
/** @var string */
private $_text;
/**
* The text array.
*
* @var string
*/
protected $_text;
/**
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -76,10 +76,11 @@ final class ID3_Frame_COMM extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -104,10 +104,11 @@ final class ID3_Frame_COMR extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -69,7 +69,7 @@ require_once("ID3/Frame.php");
final class ID3_Frame_ENCR extends ID3_Frame
{
/** @var string */
private $_id;
private $_owner;
/** @var integer */
private $_method;
@@ -81,15 +81,16 @@ final class ID3_Frame_ENCR extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
list($this->_owner, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
$this->_method = Transform::fromInt8($this->_data[0]);
$this->_encryptionData = substr($this->_data, 1);
}
@@ -99,14 +100,14 @@ final class ID3_Frame_ENCR extends ID3_Frame
*
* @return string
*/
public function getIdentifier() { return $this->_id; }
public function getOwner() { return $this->_owner; }
/**
* Sets the owner identifier string.
*
* @param string $id The owner identifier string.
* @param string $owner The owner identifier string.
*/
public function setIdentifier($id) { $this->_id = $id; }
public function setOwner($owner) { $this->_owner = $owner; }
/**
* Returns the method symbol.
@@ -147,7 +148,7 @@ final class ID3_Frame_ENCR extends ID3_Frame
public function __toString()
{
parent::setData
($this->_id . "\0" . Transform::toInt8($this->_method) .
($this->_owner . "\0" . Transform::toInt8($this->_method) .
$this->_encryptionData);
return parent::__toString();
}

View File

@@ -82,10 +82,11 @@ final class ID3_Frame_EQU2 extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
@@ -96,8 +97,8 @@ final class ID3_Frame_EQU2 extends ID3_Frame
for ($i = 0; $i < strlen($this->_data); $i += 8)
$this->_adjustments
[Transform::fromInt16BE(substr($this->_data, $j, 2)) / 2] =
Transform::fromInt16BE(substr($this->_data, $j + 2, 2)) / 512;
[Transform::fromInt16BE(substr($this->_data, $i, 2)) / 2] =
Transform::fromInt16BE(substr($this->_data, $i + 2, 2)) / 512;
sort($this->_adjustments);
}
@@ -151,7 +152,8 @@ final class ID3_Frame_EQU2 extends ID3_Frame
* have a value from 0 to 32767 Hz, and the adjustment +/- 64 dB with a
* precision of 0.001953125 dB.
*
* @return Array
* @param integer $frequency The frequency, in hertz.
* @param integer $adjustment The adjustment, in dB.
*/
public function addAdjustment($frequency, $adjustment)
{
@@ -173,4 +175,19 @@ final class ID3_Frame_EQU2 extends ID3_Frame
$this->_adjustments[$frequency * 2] = $adjustment * 512;
sort($this->_adjustments);
}
/**
* Returns the frame raw data.
*
* @return string
*/
public function __toString()
{
$data = Transform::toInt8($this->_interpolation) . $this->_device . "\0";
foreach ($this->_adjustments as $frequency => $adjustment)
$data .=
Transform::toInt16BE($frequency) . Transform::toInt16BE($adjustment);
$this->setData($data);
return parent::__toString();
}
}

132
src/ID3/Frame/EQUA.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame.php");
/**#@-*/
/**
* The <i>Equalisation</i> frame is another subjective, alignment frame. It
* allows the user to predefine an equalisation curve within the audio file.
* There may only be one EQUA frame in each tag.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_EQUA extends ID3_Frame
{
/** @var Array */
private $_adjustments;
/**
* Constructs the class with given parameters and parses object related data.
*
* @param 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;
$adjustmentBits = Transform::fromInt8($this->_data[0]); //16
for ($i = 1; $i < strlen($this->_data); $i += 4) {
$frequency = Transform::fromInt16BE(substr($this->_data, $i, 2));
$this->_adjustments[($frequency & 0x7fff)] =
($frequency & 0x2000) == 0x2000 ?
Transform::fromInt16BE(substr($this->_data, $j + 2, 2)) :
-Transform::fromInt16BE(substr($this->_data, $j + 2, 2));
}
}
/**
* Returns the array containing adjustments having frequencies as keys and
* their corresponding adjustments as values.
*
* @return Array
*/
public function getAdjustments() { return $this->_adjustments; }
/**
* Adds a volume adjustment setting for given frequency. The frequency can
* have a value from 0 to 32767 Hz.
*
* @param integer $frequency The frequency, in hertz.
* @param integer $adjustment The adjustment, in dB.
*/
public function addAdjustment($frequency, $adjustment)
{
$this->_adjustments[$frequency] = $adjustment;
}
/**
* Sets the adjustments array. The array must have frequencies as keys and
* their corresponding adjustments as values. The frequency can have a value
* from 0 to 32767 Hz. One frequency should only be described once in the
* frame.
*
* @param Array $adjustments The adjustments array.
*/
public function setAdjustments($adjustments)
{
$this->_adjustments = $adjustments;
}
/**
* Returns the frame raw data.
*
* @return string
*/
public function __toString()
{
$data = Transform::toInt8(16);
foreach ($this->_adjustments as $frequency => $adjustment)
$data .= Transform::toInt16BE
($adjustment > 0 ? $frequency | 0x2000 : $frequency & ~0x2000) .
Transform::toInt16BE(abs($adjustment));
$this->setData($data);
return parent::__toString();
}
}

View File

@@ -94,10 +94,11 @@ final class ID3_Frame_ETCO extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -73,10 +73,11 @@ final class ID3_Frame_GEOB extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -56,7 +56,7 @@ require_once("ID3/Frame.php");
* a digital signature. There may be several GRID frames in a tag but only one
* containing the same symbol and only one containing the same owner identifier.
* The group symbol must be used somewhere in the tag. See
* {@link ID3_Frame#GROUPING_IDENTITY} for more information.
* {@link ID3_Frame#GROUPING_ownerENTITY} for more information.
*
* @package php-reader
* @subpackage ID3
@@ -68,7 +68,7 @@ require_once("ID3/Frame.php");
final class ID3_Frame_GRID extends ID3_Frame
{
/** @var string */
private $_id;
private $_owner;
/** @var integer */
private $_group;
@@ -80,15 +80,16 @@ final class ID3_Frame_GRID extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
list($this->_owner, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
$this->_group = Transform::fromInt8($this->_data[0]);
$this->_groupData = substr($this->_data, 1);
}
@@ -98,14 +99,14 @@ final class ID3_Frame_GRID extends ID3_Frame
*
* @return string
*/
public function getIdentifier() { return $this->_id; }
public function getOwner() { return $this->_owner; }
/**
* Sets the owner identifier string.
*
* @param string $id The owner identifier string.
* @param string $owner The owner identifier string.
*/
public function setIdentifier($id) { $this->_id = $id; }
public function setOwner($owner) { $this->_owner = $owner; }
/**
* Returns the group symbol.
@@ -143,7 +144,7 @@ final class ID3_Frame_GRID extends ID3_Frame
public function __toString()
{
parent::setData
($this->_id . "\0" . Transform::toInt8($this->_group) .
($this->_owner . "\0" . Transform::toInt8($this->_group) .
$this->_groupData);
return parent::__toString();
}

168
src/ID3/Frame/IPLS.php Normal file
View File

@@ -0,0 +1,168 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame.php");
require_once("ID3/Encoding.php");
/**#@-*/
/**
* The <i>Involved people list</i> is a frame containing the names of those
* involved, and how they were involved. There may only be one IPLS frame in
* each tag.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_IPLS extends ID3_Frame
implements ID3_Encoding
{
/** @var integer */
private $_encoding = ID3_Encoding::UTF8;
/** @var Array */
private $_people = array();
/**
* Constructs the class with given parameters and parses object related data.
*
* @param 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;
$this->_encoding = Transform::fromInt8($this->_data[0]);
$data = array();
switch ($this->_encoding) {
case self::UTF16:
$data = preg_split
("/\\x00\\x00/", Transform::fromString16($this->_data));
break;
case self::UTF16BE:
$data = preg_split
("/\\x00\\x00/", Transform::fromString16BE($this->_data));
break;
default:
$data = preg_split("/\\x00/", $this->_data);
}
for ($i = 0; $i < count($data); $i+=2)
$this->_people[] = array($data[$i] => @$data[$i + 1]);
}
/**
* Returns the text encoding.
*
* @return integer
*/
public function getEncoding() { return $this->_encoding; }
/**
* Sets the text encoding.
*
* @see ID3_Encoding
* @param integer $encoding The text encoding.
*/
public function setEncoding($encoding) { $this->_encoding = $encoding; }
/**
* Returns the involved people list as an array. For each person, the array
* contains an entry, which too is an associate array with involvement as its
* key and involvee as its value.
*
* @return Array
*/
public function getPeople() { return $this->_people; }
/**
* Adds a person with his involvement.
*
* @return string
*/
public function addPerson($involvement, $person)
{
$this->_people[] = array($involvement => $person);
}
/**
* Sets the involved people list array. For each person, the array must
* contain an associate array with involvement as its key and involvee as its
* value.
*
* @param Array $people The involved people list.
*/
public function setPeople($people) { $this->_people = $people; }
/**
* Returns the frame raw data.
*
* @return string
*/
public function __toString()
{
$data = Transform::toInt8($this->_encoding);
foreach ($this->_people as $entry) {
foreach ($entry as $key => $val) {
switch ($this->_encoding) {
case self::UTF16:
$data .= Transform::toString16($key . "\0\0" . $val . "\0\0");
break;
case self::UTF16BE:
$data .= Transform::toString16BE($key . "\0\0" . $val . "\0\0");
break;
case self::UTF16LE:
$data .= Transform::toString16LE($key . "\0\0" . $val . "\0\0");
break;
default:
$data .= $key . "\0" . $val . "\0";
}
}
}
$this->setData($data);
return parent::__toString();
}
}

View File

@@ -98,10 +98,11 @@ final class ID3_Frame_LINK extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -85,10 +85,11 @@ final class ID3_Frame_MLLT extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
throw new ID3_Exception("Write not supported yet");

View File

@@ -76,10 +76,11 @@ final class ID3_Frame_OWNE extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -60,10 +60,11 @@ final class ID3_Frame_PCNT extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -65,7 +65,7 @@ require_once("ID3/Frame.php");
final class ID3_Frame_POPM extends ID3_Frame
{
/** @var string */
private $_id;
private $_owner;
/** @var integer */
private $_rating = 0;
@@ -77,15 +77,16 @@ final class ID3_Frame_POPM extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
list($this->_owner, $this->_data) = preg_split("/\\x00/", $this->_data, 2);
$this->_rating = Transform::fromInt8($this->_data[0]);
$this->_data = substr($this->_data, 1);
@@ -96,18 +97,18 @@ final class ID3_Frame_POPM extends ID3_Frame
}
/**
* Returns the user identifier string.
* Returns the owner identifier string.
*
* @return string
*/
public function getIdentifier() { return $this->_id; }
public function getOwner() { return $this->_owner; }
/**
* Sets the user identifier string.
* Sets the owner identifier string.
*
* @param string $id The user identifier string.
* @param string $owner The owner identifier string.
*/
public function setIdentifier($id) { return $this->_id = $id; }
public function setOwner($owner) { return $this->_owner = $owner; }
/**
* Returns the user rating.
@@ -150,7 +151,7 @@ final class ID3_Frame_POPM extends ID3_Frame
public function __toString()
{
$this->setData
($this->_id . "\0" . Transform::toInt8($this->_rating) .
($this->_owner . "\0" . Transform::toInt8($this->_rating) .
($this->_counter > 4294967295 ?
Transform::toInt64BE($this->_counter) :
($this->_counter > 0 ? Transform::toInt32BE($this->_counter) : 0)));

View File

@@ -66,10 +66,11 @@ final class ID3_Frame_POSS extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -59,7 +59,7 @@ require_once("ID3/Frame.php");
final class ID3_Frame_PRIV extends ID3_Frame
{
/** @var string */
private $_id;
private $_owner;
/** @var string */
private $_privateData;
@@ -68,15 +68,16 @@ final class ID3_Frame_PRIV extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
list($this->_id, $this->_privateData) =
list($this->_owner, $this->_privateData) =
preg_split("/\\x00/", $this->_data, 2);
}
@@ -85,14 +86,14 @@ final class ID3_Frame_PRIV extends ID3_Frame
*
* @return string
*/
public function getIdentifier() { return $this->_id; }
public function getOwner() { return $this->_owner; }
/**
* Sets the owner identifier string.
*
* @param string $id The owner identifier string.
* @param string $owner The owner identifier string.
*/
public function setIdentifier($id) { $this->_id = $id; }
public function setOwner($owner) { $this->_owner = $owner; }
/**
* Returns the private binary data associated with the frame.
@@ -115,7 +116,7 @@ final class ID3_Frame_PRIV extends ID3_Frame
*/
public function __toString()
{
parent::setData($this->_id . "\0" . $this->_privateData);
parent::setData($this->_owner . "\0" . $this->_privateData);
return parent::__toString();
}
}

View File

@@ -91,10 +91,11 @@ final class ID3_Frame_RBUF extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -83,10 +83,11 @@ final class ID3_Frame_RVA2 extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

208
src/ID3/Frame/RVAD.php Normal file
View File

@@ -0,0 +1,208 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame.php");
/**#@-*/
/**
* The <i>Relative volume adjustment</i> frame is a more subjective function
* than the previous ones. It allows the user to say how much he wants to
* increase/decrease the volume on each channel while the file is played. The
* purpose is to be able to align all files to a reference volume, so that you
* don't have to change the volume constantly. This frame may also be used to
* balance adjust the audio.
*
* There may only be one RVAD frame in each tag.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_RVAD extends ID3_Frame
{
/** @var Array */
private $_adjustments;
/**
* Constructs the class with given parameters and parses object related data.
*
* @param 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;
$flags = Transform::fromInt8($this->_data[0]);
$descriptionBits = Transform::fromInt8($this->_data[0]); //16
$this->_adjustments["right"] =
($flags & 0x20) == 0x20 ?
Transform::fromUInt16BE(substr($this->_data, 0, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 0, 2));
$this->_adjustments["left"] =
($flags & 0x10) == 0x10 ?
Transform::fromUInt16BE(substr($this->_data, 2, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 2, 2));
$this->_adjustments["peakRight"] =
Transform::fromUInt16BE(substr($this->_data, 4, 2));
$this->_adjustments["peakLeft"] =
Transform::fromUInt16BE(substr($this->_data, 6, 2));
if ($this->getSize() <= 8)
return;
$this->_adjustments["rightBack"] =
($flags & 0x8) == 0x8 ?
Transform::fromUInt16BE(substr($this->_data, 8, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 8, 2));
$this->_adjustments["leftBack"] =
($flags & 0x4) == 0x4 ?
Transform::fromUInt16BE(substr($this->_data, 10, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 10, 2));
$this->_adjustments["peakRightBack"] =
Transform::fromUInt16BE(substr($this->_data, 12, 2));
$this->_adjustments["peakLeftBack"] =
Transform::fromUInt16BE(substr($this->_data, 14, 2));
if ($this->getSize() <= 16)
return;
$this->_adjustments["center"] =
($flags & 0x2) == 0x2 ?
Transform::fromUInt16BE(substr($this->_data, 16, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 16, 2));
$this->_adjustments["peakCenter"] =
Transform::fromUInt16BE(substr($this->_data, 18, 2));
if ($this->getSize() <= 20)
return;
$this->_adjustments["bass"] =
($flags & 0x1) == 0x1 ?
Transform::fromUInt16BE(substr($this->_data, 20, 2)) :
-Transform::fromUInt16BE(substr($this->_data, 20, 2));
$this->_adjustments["peakBass"] =
Transform::fromUInt16BE(substr($this->_data, 22, 2));
}
/**
* Returns the array containing the volume adjustments. The array must contain
* the following keys: right, left, peakRight, peakLeft. It may optionally
* contain the following keys: rightBack, leftBack, peakRightBack,
* peakLeftBack, center, peakCenter, bass, and peakBass.
*
* @return Array
*/
public function getAdjustments() { return $this->_adjustments; }
/**
* Sets the array of volume adjustments. The array must contain the following
* keys: right, left, peakRight, peakLeft. It may optionally contain the
* following keys: rightBack, leftBack, peakRightBack, peakLeftBack, center,
* peakCenter, bass, and peakBass.
*
* @param Array $adjustments The volume adjustments array.
*/
public function setAdjustments($adjustments)
{
$this->_adjustments = $adjustments;
}
/**
* Returns the frame raw data.
*
* @return string
*/
public function __toString()
{
$flags = 0;
if ($this->_adjustments["right"] > 0)
$flags = $flags | 0x20;
if ($this->_adjustments["left"] > 0)
$flags = $flags | 0x10;
$data = Transform::toInt8(16) .
Transform::toUInt16BE(abs($this->_adjustments["right"])) .
Transform::toUInt16BE(abs($this->_adjustments["left"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakRight"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakLeft"]));
if (isset($this->_adjustments["rightBack"]) &&
isset($this->_adjustments["leftBack"]) &&
isset($this->_adjustments["peakRightBack"]) &&
isset($this->_adjustments["peakLeftBack"])) {
if ($this->_adjustments["rightBack"] > 0)
$flags = $flags | 0x8;
if ($this->_adjustments["leftBack"] > 0)
$flags = $flags | 0x4;
$data .=
Transform::toUInt16BE(abs($this->_adjustments["rightBack"])) .
Transform::toUInt16BE(abs($this->_adjustments["leftBack"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakRightBack"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakLeftBack"]));
}
if (isset($this->_adjustments["center"]) &&
isset($this->_adjustments["peakCenter"])) {
if ($this->_adjustments["center"] > 0)
$flags = $flags | 0x2;
$data .=
Transform::toUInt16BE(abs($this->_adjustments["center"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakCenter"]));
}
if (isset($this->_adjustments["bass"]) &&
isset($this->_adjustments["peakBass"])) {
if ($this->_adjustments["bass"] > 0)
$flags = $flags | 0x1;
$data .=
Transform::toUInt16BE(abs($this->_adjustments["bass"])) .
Transform::toUInt16BE(abs($this->_adjustments["peakBass"]));
}
$this->setData(Transform::toInt8($flags) . $data);
return parent::__toString();
}
}

View File

@@ -99,10 +99,11 @@ final class ID3_Frame_RVRB extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -62,10 +62,11 @@ final class ID3_Frame_SEEK extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -67,10 +67,11 @@ final class ID3_Frame_SIGN extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -93,10 +93,11 @@ final class ID3_Frame_SYLT extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

View File

@@ -79,10 +79,11 @@ final class ID3_Frame_SYTC extends ID3_Frame
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;

55
src/ID3/Frame/TDAT.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Date</i> frame is a numeric string in the DDMM format containing the
* date for the recording. This field is always four characters long.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TDAT extends ID3_Frame_AbstractText {}

55
src/ID3/Frame/TIME.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Time</i> frame is a numeric string in the HHMM format containing the
* time for the recording. This field is always four characters long.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TIME extends ID3_Frame_AbstractText {}

57
src/ID3/Frame/TORY.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Original release year</i> frame is intended for the year when the
* original recording, if for example the music in the file should be a cover of
* a previously released song, was released. The field is formatted as in the
* {@link ID3_Frame_TYER} frame.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TORY extends ID3_Frame_AbstractText {}

57
src/ID3/Frame/TRDA.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Recording dates</i> frame is intended to be used as complement to
* the {@link ID3_Frame_TYER}, {@link ID3_Frame_TDAT} and {@link ID3_Frame_TIME}
* frames. E.g. "4th-7th June, 12th June" in combination with the
* {@link ID3_Frame_TYER} frame.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TRDA extends ID3_Frame_AbstractText {}

55
src/ID3/Frame/TSIZ.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Size</i> frame contains the size of the audiofile in bytes, excluding
* the ID3v2 tag, represented as a numeric string.
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TSIZ extends ID3_Frame_AbstractText {}

View File

@@ -56,4 +56,87 @@ require_once("ID3/Frame/AbstractText.php");
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
*/
final class ID3_Frame_TXXX extends ID3_Frame_AbstractText {}
final class ID3_Frame_TXXX extends ID3_Frame_AbstractText
{
/** @var string */
private $_description;
/**
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader, $options);
switch ($this->_encoding) {
case self::UTF16:
list($this->_description, $this->_text) =
preg_split("/\\x00\\x00/", $this->_data);
$this->_description = Transform::fromString16($this->_description);
$this->_text = array(Transform::fromString16($this->_text));
break;
case self::UTF16BE:
list($this->_description, $this->_text) =
preg_split("/\\x00\\x00/", $this->_data);
$this->_description = Transform::fromString16BE($this->_description);
$this->_text = array(Transform::fromString16BE($this->_text));
break;
default:
list($this->_description, $this->_text) =
preg_split("/\\x00/", $this->_data);
$this->_text = array($this->_text);
}
}
/**
* Returns the description text.
*
* @return string
*/
public function getDescription() { return $this->_description; }
/**
* Sets the description text using given encoding.
*
* @param string $description The content description text.
* @param integer $encoding The text encoding.
*/
public function setDescription($description, $encoding = false)
{
$this->_description = $description;
if ($encoding !== false)
$this->_encoding = $encoding;
}
/**
* Returns the frame raw data.
*
* @return string
*/
public function __toString()
{
$data = Transform::toInt8($this->_encoding);
switch ($this->_encoding) {
case self::UTF16:
$data .= Transform::toString16($this->_description) . "\0\0" .
Transform::toString16($this->_text[0]);
break;
case self::UTF16BE:
$data .= Transform::toString16BE($this->_description) . "\0\0" .
Transform::toString16BE($this->_text[0]);
break;
case self::UTF16LE:
$data .= Transform::toString16LE($this->_description) . "\0\0" .
Transform::toString16LE($this->_text[0]);
break;
default:
$data .= $this->_description . "\0" . $this->_text[0];
}
$this->setData($data);
return parent::__toString();
}
}

55
src/ID3/Frame/TYER.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* PHP Reader Library
*
* Copyright (c) 2008 The PHP Reader Project Workgroup. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the project workgroup nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package php-reader
* @subpackage ID3
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Id$
* @deprecated ID3v2.3.0
*/
/**#@+ @ignore */
require_once("ID3/Frame/AbstractText.php");
/**#@-*/
/**
* The <i>Year</i> frame is a numeric string with a year of the recording. This
* frames is always four characters long (until the year 10000).
*
* @package php-reader
* @subpackage ID3
* @author Sven Vollbehr <svollbehr@gmail.com>
* @copyright Copyright (c) 2008 The PHP Reader Project Workgroup
* @license http://code.google.com/p/php-reader/wiki/License New BSD License
* @version $Rev$
* @deprecated ID3v2.3.0
*/
final class ID3_Frame_TYER extends ID3_Frame_AbstractText {}

View File

@@ -67,10 +67,11 @@ final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink
* Constructs the class with given parameters and parses object related data.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
parent::__construct($reader, $options);
if ($reader === null)
return;
@@ -89,8 +90,6 @@ final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink
preg_split("/\\x00\\x00/", $this->_data, 2);
$this->_description = Transform::fromString16BE($this->_description);
break;
case self::UTF8:
case self::ISO88591:
default:
list($this->_description, $this->_link) =
preg_split("/\\x00/", $this->_data);

View File

@@ -40,12 +40,8 @@ require_once("ID3/Object.php");
/**#@-*/
/**
* The first part of the ID3v2 tag is the 10 byte tag header. The first three
* bytes of the tag are always "ID3", to indicate that this is an ID3v2 tag,
* directly followed by the two version bytes. The first byte of ID3v2 version
* is its major version, while the second byte is its revision number. All
* revisions are backwards compatible while major versions are not. The version
* is followed by the ID3v2 flags field, of which currently four flags are used.
* The first part of the ID3v2 tag is the 10 byte tag header. The header
* contains information about the tag version and options.
*
* @package php-reader
* @subpackage ID3
@@ -58,24 +54,25 @@ final class ID3_Header extends ID3_Object
{
/** A flag to denote whether or not unsynchronisation is applied on all
frames */
const UNSYNCHRONISATION = 256;
const UNSYNCHRONISATION = 128;
/** A flag to denote whether or not the header is followed by an extended
header */
const EXTENDEDHEADER = 128;
const EXTENDEDHEADER = 64;
/** A flag used as an experimental indicator. This flag shall always be set
when the tag is in an experimental stage. */
const EXPERIMENTAL = 64;
const EXPERIMENTAL = 32;
/** A flag to denote whether a footer is present at the very end of the tag */
const FOOTER = 32;
/**
* A flag to denote whether a footer is present at the very end of the tag.
*
* @since ID3v2.4.0
*/
const FOOTER = 16;
/** @var integer */
private $_version = 4;
/** @var integer */
private $_revision = 0;
private $_version = 4.0;
/** @var integer */
private $_flags = 0;
@@ -88,33 +85,42 @@ final class ID3_Header extends ID3_Object
* from the ID3v2 tag.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader);
if ($reader === null)
return;
$this->_version = $this->_reader->readInt8();
$this->_revision = $this->_reader->readInt8();
$this->_version = $options["version"] =
$this->_reader->readInt8() + $this->_reader->readInt8() / 10;
$this->_flags = $this->_reader->readInt8();
$this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE());
$this->setOptions($options);
}
/**
* Returns the tag major version number.
* Returns the tag version number. The version number is in the form of
* major.revision.
*
* @return integer
*/
public function getVersion() { return $this->_version; }
/**
* Returns the tag revision number.
* Sets the tag version number. Supported version numbers are 3.0 and 4.0
* for ID3v2.3.0 and ID3v2.4.0 standards, respectively.
*
* @return integer
* @param integer $version The tag version number in the form of
* major.revision.
*/
public function getRevision() { return $this->_revision; }
public function setVersion($version)
{
$this->_version = $this->_options["version"] = $version;
}
/**
* Checks whether or not the flag is set. Returns <var>true</var> if the flag
@@ -159,10 +165,10 @@ final class ID3_Header extends ID3_Object
*
* @return string
*/
protected function __toString()
public function __toString()
{
return Transform::toInt8($this->_version) .
Transform::toInt8($this->_revision) .
return Transform::toInt8(floor($this->_version)) .
Transform::toInt8(($this->_version - floor($this->_version)) * 10) .
Transform::toInt8($this->_flags) .
Transform::toUInt32BE($this->encodeSynchsafe32($this->_size));
}

View File

@@ -59,19 +59,35 @@ abstract class ID3_Object
*
* @var Array
*/
protected $_options = array();
protected $_options;
/**
* Constructs the class with given parameters and reads object related data
* from the ID3v2 tag.
*
* @param Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader = null)
public function __construct($reader = null, &$options = array())
{
$this->_reader = $reader;
$this->_options = $options;
}
/**
* Returns the options array.
*
* @return Array
*/
public function getOptions() { return $this->_options; }
/**
* Sets the options array. See {@link ID3v2} class for available options.
*
* @param Array $options The options array.
*/
public function setOptions(&$options) { $this->_options = $options; }
/**
* Magic function so that $obj->value will work.
*
@@ -110,9 +126,12 @@ abstract class ID3_Object
*/
protected function encodeSynchsafe32($val)
{
for ($i = 0, $mask = 0xffffff00; $i < 4; $i++, $mask <<= 8)
$val = ($val << 1 & $mask) | ($val << 1 & ~$mask) >> 1;
return $val & 0x7fffffff;
if (!isset($this->_options["version"]) || $this->_options["version"] >= 4) {
for ($i = 0, $mask = 0xffffff00; $i < 4; $i++, $mask <<= 8)
$val = ($val << 1 & $mask) | ($val << 1 & ~$mask) >> 1;
return $val & 0x7fffffff;
}
return $val;
}
/**
@@ -123,8 +142,9 @@ abstract class ID3_Object
*/
protected function decodeSynchsafe32($val)
{
for ($i = 0, $mask = 0xff000000; $i < 3; $i++, $mask >>= 8)
$val = ($val & $mask) >> 1 | ($val & ~$mask);
if (!isset($this->_options["version"]) || $this->_options["version"] >= 4)
for ($i = 0, $mask = 0xff000000; $i < 3; $i++, $mask >>= 8)
$val = ($val & $mask) >> 1 | ($val & ~$mask);
return $val;
}
}

View File

@@ -107,8 +107,17 @@ final class ID3v2
/** @var string */
private $_filename;
/** @var Array */
private $_options;
/**
* Constructs the ID3v2 class with given file and options.
* Constructs the ID3v2 class with given file and options. The options array
* may also be given as the only parameter.
*
* The following options are currently recognized:
* o version -- The ID3v2 tag version to use in write operation. This option
* is automatically set when a tag is read from a file and defaults to
* version 4.0 for tag write.
*
* @todo Only limited subset of flags are processed.
* @todo Utilize the SEEK frame and search for a footer to find the tag
@@ -123,30 +132,52 @@ final class ID3v2
$filename = false;
}
$this->_options = &$options;
if (($this->_filename = $filename) === false ||
file_exists($filename) === false) {
$this->_header = new ID3_Header();
return;
}
$this->_header = new ID3_Header(null, $options);
} else {
$this->_reader = new Reader($filename);
if ($this->_reader->readString8(3) != "ID3")
throw new ID3_Exception
("File does not contain ID3v2 tag: " . $filename);
$this->_reader = new Reader($filename);
$this->_header = new ID3_Header($this->_reader, $options);
if ($this->_header->getVersion() < 3 || $this->_header->getVersion() > 4)
throw new ID3_Exception
("File does not contain ID3v2 tag of supported version: " . $filename);
if ($this->_header->hasFlag(ID3_Header::EXTENDEDHEADER))
$this->_extendedHeader =
new ID3_ExtendedHeader($this->_reader, $options);
if ($this->_header->hasFlag(ID3_Header::FOOTER))
$this->_footer = &$this->_header; // skip footer, and rather copy header
if ($this->_reader->readString8(3) != "ID3")
throw new ID3_Exception("File does not contain ID3v2 tag: " . $filename);
while (true) {
$offset = $this->_reader->getOffset();
$this->_header = new ID3_Header($this->_reader);
if ($this->_header->getVersion() > 4)
throw new ID3_Exception
("File does not contain ID3v2 tag of supported version: " . $filename);
if ($this->_header->hasFlag(ID3_Header::EXTENDEDHEADER))
$this->_extendedHeader = new ID3_ExtendedHeader($this->_reader);
if ($this->_header->hasFlag(ID3_Header::FOOTER))
$this->_footer = &$this->_header; // skip footer, and rather copy header
// Jump off the loop if we reached the end of the tag
if ($offset - 10 >= $this->_header->getSize() -
($this->hasFooter() ? 10 : 0))
break;
while ($frame = $this->nextFrame()) {
if (!isset($this->_frames[$frame->identifier]))
$this->_frames[$frame->identifier] = array();
$this->_frames[$frame->identifier][] = $frame;
// Jump off the loop if we reached the last frame
if ($this->_reader->available() < 4 || Transform::fromUInt32BE
($identifier = $this->_reader->read(4)) == 0)
break;
$this->_reader->setOffset($offset);
if (@fopen($filename = "ID3/Frame/" .
strtoupper($identifier) . ".php", "r", true) !== false)
require_once($filename);
if (class_exists($classname = "ID3_Frame_" . $identifier))
$frame = new $classname($this->_reader, $options);
else
$frame = new ID3_Frame($this->_reader, $options);
if (!isset($this->_frames[$frame->getIdentifier()]))
$this->_frames[$frame->getIdentifier()] = array();
$this->_frames[$frame->getIdentifier()][] = $frame;
}
}
}
@@ -192,56 +223,11 @@ final class ID3v2
if (is_subclass_of($extendedHeader, "ID3_ExtendedHeader")) {
$this->_header->flags =
$this->_header->flags | ID3_Header::EXTENDEDHEADER;
$this->_extendedHeader->setOptions($this->_options);
$this->_extendedHeader = $extendedHeader;
} else throw new ID3_Exception("Invalid argument");
}
/**
* Checks whether there are frames left in the tag. Returns <var>true</var> if
* there are frames left in the tag, <var>false</var> otherwise.
*
* @return boolean
*/
protected function hasFrames()
{
$offset = $this->_reader->getOffset();
// Return false if we reached the end of the tag
if ($offset - 10 >= $this->_header->getSize() -
($this->hasFooter() ? 10 : 0))
return false;
// Return false if we reached the last frame, true otherwise
$res = $this->_reader->readUInt32BE() != 0;
$this->_reader->setOffset($offset);
return $res;
}
/**
* Returns the next ID3 frame or <var>false</var> if end of tag has been
* reached. Returned objects are of the type ID3_Frame or of any of its child
* types.
*
* @return ID3_Frame|false
*/
protected function nextFrame()
{
$frame = false;
if ($this->hasFrames()) {
$offset = $this->_reader->getOffset();
$identifier = $this->_reader->readString8(4);
$this->_reader->setOffset($offset);
if (@fopen($filename = "ID3/Frame/" .
strtoupper($identifier) . ".php", "r", true) !== false)
require_once($filename);
if (class_exists($classname = "ID3_Frame_" . $identifier))
$frame = new $classname($this->_reader);
else
$frame = new ID3_Frame($this->_reader);
}
return $frame;
}
/**
* Checks whether there is a frame given as an argument defined in the tag.
* Returns <var>true</var> if one ore more frames are present,
@@ -299,6 +285,7 @@ final class ID3v2
*/
public function addFrame($frame)
{
$frame->setOptions($this->_options);
if (!$this->hasFrame($frame->getIdentifier()))
$this->_frames[$frame->getIdentifier()] = array();
return $this->_frames[$frame->getIdentifier()][] = $frame;
@@ -446,9 +433,13 @@ final class ID3v2
else
$padlen = ceil(log(0.2 * ($datalen / 1024 + 10), 10) * 1024);
}
$data = str_pad($data, $datalen + $padlen, "\0");
/* ID3v2.4.0 CRC calculated w/ padding */
if (!isset($this->_options["version"]) || $this->_options["version"] >= 4)
$data = str_pad($data, $datalen + $padlen, "\0");
if ($this->hasExtendedHeader()) {
$this->_extendedHeader->setPadding($padlen);
if ($this->_extendedHeader->hasFlag(ID3_ExtendedHeader::CRC32)) {
$crc = crc32($data);
if ($crc & 0x80000000)
@@ -458,6 +449,10 @@ final class ID3v2
$data = $this->getExtendedHeader() . $data;
}
/* ID3v2.3.0 CRC calculated w/o padding */
if (isset($this->_options["version"]) && $this->_options["version"] < 4)
$data = str_pad($data, $datalen + $padlen, "\0");
$this->_header->setSize(strlen($data));
return "ID3" . $this->_header . $data .