PageRenderTime 22ms CodeModel.GetById 7ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Zend/Media/Iso14496/Box/Iloc.php

http://php-reader.googlecode.com/
PHP | 245 lines | 124 code | 11 blank | 110 comment | 35 complexity | 8eae80ae9690e4527e01348990d8d22a MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 25 * POSSIBILITY OF SUCH DAMAGE.
 26 *
 27 * @category   Zend
 28 * @package    Zend_Media
 29 * @subpackage ISO14496
 30 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) 
 31 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 32 * @version    $Id: Iloc.php 177 2010-03-09 13:13:34Z svollbehr $
 33 */
 34
 35/**#@+ @ignore */
 36require_once 'Zend/Media/Iso14496/Box.php';
 37/**#@-*/
 38
 39/**
 40 * The <i>The Item Location Box</i> provides a directory of resources in this or
 41 * other files, by locating their containing file, their offset within that
 42 * file, and their length. Placing this in binary format enables common handling
 43 * of this data, even by systems which do not understand the particular metadata
 44 * system (handler) used. For example, a system might integrate all the
 45 * externally referenced metadata resources into one file, re-adjusting file
 46 * offsets and file references accordingly.
 47 *
 48 * Items may be stored fragmented into extents, e.g. to enable interleaving. An
 49 * extent is a contiguous subset of the bytes of the resource; the resource is
 50 * formed by concatenating the extents. If only one extent is used then either
 51 * or both of the offset and length may be implied:
 52 *
 53 *   o If the offset is not identified (the field has a length of zero), then
 54 *     the beginning of the file (offset 0) is implied.
 55 *   o If the length is not specified, or specified as zero, then the entire
 56 *     file length is implied. References into the same file as this metadata,
 57 *     or items divided into more than one extent, should have an explicit
 58 *     offset and length, or use a MIME type requiring a different
 59 *     interpretation of the file, to avoid infinite recursion.
 60 *
 61 * The size of the item is the sum of the extentLengths. Note: extents may be
 62 * interleaved with the chunks defined by the sample tables of tracks.
 63 *
 64 * The dataReferenceIndex may take the value 0, indicating a reference into the
 65 * same file as this metadata, or an index into the dataReference table.
 66 *
 67 * Some referenced data may itself use offset/length techniques to address
 68 * resources within it (e.g. an MP4 file might be included in this way).
 69 * Normally such offsets are relative to the beginning of the containing file.
 70 * The field base offset provides an additional offset for offset calculations
 71 * within that contained data. For example, if an MP4 file is included within a
 72 * file formatted to this specification, then normally data-offsets within that
 73 * MP4 section are relative to the beginning of file; baseOffset adds to those
 74 * offsets.
 75 *
 76 * @category   Zend
 77 * @package    Zend_Media
 78 * @subpackage ISO14496
 79 * @author     Sven Vollbehr <sven@vollbehr.eu>
 80 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) 
 81 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 82 * @version    $Id: Iloc.php 177 2010-03-09 13:13:34Z svollbehr $
 83 */
 84final class Zend_Media_Iso14496_Box_Iloc extends Zend_Media_Iso14496_Box
 85{
 86    /** @var Array */
 87    private $_items = array();
 88
 89    /**
 90     * Constructs the class with given parameters and reads box related data
 91     * from the ISO Base Media file.
 92     *
 93     * @param Zend_Io_Reader $reader  The reader object.
 94     * @param Array          $options The options array.
 95     */
 96    public function __construct($reader, &$options = array())
 97    {
 98        parent::__construct($reader, $options);
 99
100        $offsetSize = (($tmp = $this->_reader->readUInt16BE()) >> 12) & 0xf;
101        $lengthSize = ($tmp >> 8) & 0xf;
102        $baseOffsetSize = ($tmp >> 4) & 0xf;
103        $itemCount = $this->_reader->readUInt16BE();
104        for ($i = 0; $i < $itemCount; $i++) {
105            $item = array();
106            $item['itemId'] = $this->_reader->readUInt16BE();
107            $item['dataReferenceIndex'] = $this->_reader->readUInt16BE();
108            $item['baseOffset'] =
109                ($baseOffsetSize == 4 ? $this->_reader->readUInt32BE() :
110                 ($baseOffsetSize == 8 ? $this->_reader->readInt64BE() : 0));
111            $extentCount = $this->_reader->readUInt16BE();
112            $item['extents'] = array();
113            for ($j = 0; $j < $extentCount; $j++) {
114                $extent = array();
115                $extent['offset'] =
116                    ($offsetSize == 4 ? $this->_reader->readUInt32BE() :
117                     ($offsetSize == 8 ? $this->_reader->readInt64BE() : 0));
118                $extent['length'] =
119                    ($lengthSize == 4 ? $this->_reader->readUInt32BE() :
120                     ($lengthSize == 8 ? $this->_reader->readInt64BE() : 0));
121                $item['extents'][] = $extent;
122            }
123            $this->_items[] = $item;
124        }
125    }
126
127    /**
128     * Returns the array of items. Each entry has the following keys set:
129     * itemId, dataReferenceIndex, baseOffset, and extents.
130     *
131     * @return Array
132     */
133    public function getItems()
134    {
135        return $this->_items;
136    }
137
138    /**
139     * Sets the array of items. Each entry must have the following keys set:
140     * itemId, dataReferenceIndex, baseOffset, and extents.
141     *
142     * @return Array
143     */
144    public function setItems($items)
145    {
146        $this->_items = $items;
147    }
148
149    /**
150     * Returns the box heap size in bytes.
151     *
152     * @return integer
153     */
154    public function getHeapSize()
155    {
156        $totalSize = 4;
157        for ($i = 0; $i < count($this->_itemId); $i++) {
158            $totalSize += 6;
159            if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) {
160                    $totalSize += 8;
161            } else {
162                    $totalSize += 4;
163            }
164            $extentCount = count($this->_itemId[$i]['extents']);
165            for ($j = 0; $j < $extentCount; $j++) {
166                if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) {
167                    $totalSize += 8 * $extentCount;
168                } else {
169                    $totalSize += 4 * $extentCount;
170                }
171                if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) {
172                    $totalSize += 8 * $extentCount;
173                } else {
174                    $totalSize += 4 * $extentCount;
175                }
176            }
177        }
178        return parent::getHeapSize() + $totalSize;
179    }
180
181    /**
182     * Writes the box data.
183     *
184     * @param Zend_Io_Writer $writer The writer object.
185     * @return void
186     */
187    protected function _writeData($writer)
188    {
189        parent::_writeData($writer);
190
191        $offsetSize = 4;
192        $lengthSize = 4;
193        $baseOffsetSize = 4;
194
195        $itemCount = count($this->_itemId);
196        for ($i = 0; $i < $itemCount; $i++) {
197            if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) {
198                    $baseOffsetSize = 8;
199            }
200            for ($j = 0; $j < count($this->_itemId[$i]['extents']); $j++) {
201                if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) {
202                    $offsetSize = 8;
203                }
204                if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) {
205                    $lengthSize = 8;
206                }
207            }
208        }
209
210        $writer->writeUInt16BE
211            ((($offsetSize & 0xf) << 12) | (($lengthSize & 0xf) << 8) |
212             (($baseOffsetSize & 0xf) << 4))
213               ->writeUInt16BE($itemCount);
214        for ($i = 0; $i < $itemCount; $i++) {
215            $writer->writeUInt16BE($this->_itemId[$i]['itemId'])
216                   ->writeUInt16BE($this->_itemId[$i]['dataReferenceIndex']);
217            if ($baseOffsetSize == 4) {
218                $writer->writeUInt32BE($this->_itemId[$i]['baseOffset']);
219            }
220            if ($baseOffsetSize == 8) {
221                $writer->writeInt64BE($this->_itemId[$i]['baseOffset']);
222            }
223            $writer->writeUInt16BE
224                    ($extentCount = count($this->_itemId[$i]['extents']));
225            for ($j = 0; $j < $extentCount; $j++) {
226                if ($offsetSize == 4) {
227                    $writer->writeUInt32BE
228                            ($this->_itemId[$i]['extents'][$j]['offset']);
229                }
230                if ($offsetSize == 8) {
231                    $writer->writeInt64BE
232                            ($this->_itemId[$i]['extents'][$j]['offset']);
233                }
234                if ($offsetSize == 4) {
235                    $writer->writeUInt32BE
236                            ($this->_itemId[$i]['extents'][$j]['length']);
237                }
238                if ($offsetSize == 8) {
239                    $writer->writeInt64BE
240                            ($this->_itemId[$i]['extents'][$j]['length']);
241                }
242            }
243        }
244    }
245}