summaryrefslogtreecommitdiff
path: root/getid3/module.graphic.tiff.php
diff options
context:
space:
mode:
Diffstat (limited to 'getid3/module.graphic.tiff.php')
-rw-r--r--getid3/module.graphic.tiff.php221
1 files changed, 221 insertions, 0 deletions
diff --git a/getid3/module.graphic.tiff.php b/getid3/module.graphic.tiff.php
new file mode 100644
index 0000000..ae57cd6
--- /dev/null
+++ b/getid3/module.graphic.tiff.php
@@ -0,0 +1,221 @@
+<?php
+/////////////////////////////////////////////////////////////////
+/// getID3() by James Heinrich <info@getid3.org> //
+// available at http://getid3.sourceforge.net //
+// or http://www.getid3.org //
+/////////////////////////////////////////////////////////////////
+// See readme.txt for more details //
+/////////////////////////////////////////////////////////////////
+// //
+// module.archive.tiff.php //
+// module for analyzing TIFF files //
+// dependencies: NONE //
+// ///
+/////////////////////////////////////////////////////////////////
+
+
+class getid3_tiff
+{
+
+ function getid3_tiff(&$fd, &$ThisFileInfo) {
+
+ fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
+ $TIFFheader = fread($fd, 4);
+
+ switch (substr($TIFFheader, 0, 2)) {
+ case 'II':
+ $ThisFileInfo['tiff']['byte_order'] = 'Intel';
+ break;
+ case 'MM':
+ $ThisFileInfo['tiff']['byte_order'] = 'Motorola';
+ break;
+ default:
+ $ThisFileInfo['error'][] = 'Invalid TIFF byte order identifier ('.substr($TIFFheader, 0, 2).') at offset '.$ThisFileInfo['avdataoffset'];
+ return false;
+ break;
+ }
+
+ $ThisFileInfo['fileformat'] = 'tiff';
+ $ThisFileInfo['video']['dataformat'] = 'tiff';
+ $ThisFileInfo['video']['lossless'] = true;
+ $ThisFileInfo['tiff']['ifd'] = array();
+ $CurrentIFD = array();
+
+ $FieldTypeByteLength = array(1=>1, 2=>1, 3=>2, 4=>4, 5=>8);
+
+ $nextIFDoffset = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
+
+ while ($nextIFDoffset > 0) {
+
+ $CurrentIFD['offset'] = $nextIFDoffset;
+
+ fseek($fd, $ThisFileInfo['avdataoffset'] + $nextIFDoffset, SEEK_SET);
+ $CurrentIFD['fieldcount'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
+
+ for ($i = 0; $i < $CurrentIFD['fieldcount']; $i++) {
+ $CurrentIFD['fields'][$i]['raw']['tag'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
+ $CurrentIFD['fields'][$i]['raw']['type'] = $this->TIFFendian2Int(fread($fd, 2), $ThisFileInfo['tiff']['byte_order']);
+ $CurrentIFD['fields'][$i]['raw']['length'] = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
+ $CurrentIFD['fields'][$i]['raw']['offset'] = fread($fd, 4);
+
+ switch ($CurrentIFD['fields'][$i]['raw']['type']) {
+ case 1: // BYTE An 8-bit unsigned integer.
+ if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
+ $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 1), $ThisFileInfo['tiff']['byte_order']);
+ } else {
+ $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
+ }
+ break;
+
+ case 2: // ASCII 8-bit bytes that store ASCII codes; the last byte must be null.
+ if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
+ $CurrentIFD['fields'][$i]['value'] = substr($CurrentIFD['fields'][$i]['raw']['offset'], 3);
+ } else {
+ $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
+ }
+ break;
+
+ case 3: // SHORT A 16-bit (2-byte) unsigned integer.
+ if ($CurrentIFD['fields'][$i]['raw']['length'] <= 2) {
+ $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 2), $ThisFileInfo['tiff']['byte_order']);
+ } else {
+ $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
+ }
+ break;
+
+ case 4: // LONG A 32-bit (4-byte) unsigned integer.
+ if ($CurrentIFD['fields'][$i]['raw']['length'] <= 1) {
+ $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
+ } else {
+ $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $ThisFileInfo['tiff']['byte_order']);
+ }
+ break;
+
+ case 5: // RATIONAL Two LONG_s: the first represents the numerator of a fraction, the second the denominator.
+ break;
+ }
+ }
+
+ $ThisFileInfo['tiff']['ifd'][] = $CurrentIFD;
+ $CurrentIFD = array();
+ $nextIFDoffset = $this->TIFFendian2Int(fread($fd, 4), $ThisFileInfo['tiff']['byte_order']);
+
+ }
+
+ foreach ($ThisFileInfo['tiff']['ifd'] as $IFDid => $IFDarray) {
+ foreach ($IFDarray['fields'] as $key => $fieldarray) {
+ switch ($fieldarray['raw']['tag']) {
+ case 256: // ImageWidth
+ case 257: // ImageLength
+ case 258: // BitsPerSample
+ case 259: // Compression
+ if (!isset($fieldarray['value'])) {
+ fseek($fd, $fieldarray['offset'], SEEK_SET);
+ $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = fread($fd, $fieldarray['raw']['length'] * $FieldTypeByteLength[$fieldarray['raw']['type']]);
+
+ }
+ break;
+
+ case 270: // ImageDescription
+ case 271: // Make
+ case 272: // Model
+ case 305: // Software
+ case 306: // DateTime
+ case 315: // Artist
+ case 316: // HostComputer
+ if (isset($fieldarray['value'])) {
+ $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = $fieldarray['value'];
+ } else {
+ fseek($fd, $fieldarray['offset'], SEEK_SET);
+ $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = fread($fd, $fieldarray['raw']['length'] * $FieldTypeByteLength[$fieldarray['raw']['type']]);
+
+ }
+ break;
+ }
+ switch ($fieldarray['raw']['tag']) {
+ case 256: // ImageWidth
+ $ThisFileInfo['video']['resolution_x'] = $fieldarray['value'];
+ break;
+
+ case 257: // ImageLength
+ $ThisFileInfo['video']['resolution_y'] = $fieldarray['value'];
+ break;
+
+ case 258: // BitsPerSample
+ if (isset($fieldarray['value'])) {
+ $ThisFileInfo['video']['bits_per_sample'] = $fieldarray['value'];
+ } else {
+ $ThisFileInfo['video']['bits_per_sample'] = 0;
+ for ($i = 0; $i < $fieldarray['raw']['length']; $i++) {
+ $ThisFileInfo['video']['bits_per_sample'] += $this->TIFFendian2Int(substr($ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'], $i * $FieldTypeByteLength[$fieldarray['raw']['type']], $FieldTypeByteLength[$fieldarray['raw']['type']]), $ThisFileInfo['tiff']['byte_order']);
+ }
+ }
+ break;
+
+ case 259: // Compression
+ $ThisFileInfo['video']['codec'] = $this->TIFFcompressionMethod($fieldarray['value']);
+ break;
+
+ case 270: // ImageDescription
+ case 271: // Make
+ case 272: // Model
+ case 305: // Software
+ case 306: // DateTime
+ case 315: // Artist
+ case 316: // HostComputer
+ @$ThisFileInfo['tiff']['comments'][$this->TIFFcommentName($fieldarray['raw']['tag'])][] = $ThisFileInfo['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'];
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+
+ function TIFFendian2Int($bytestring, $byteorder) {
+ if ($byteorder == 'Intel') {
+ return getid3_lib::LittleEndian2Int($bytestring);
+ } elseif ($byteorder == 'Motorola') {
+ return getid3_lib::BigEndian2Int($bytestring);
+ }
+ return false;
+ }
+
+ function TIFFcompressionMethod($id) {
+ static $TIFFcompressionMethod = array();
+ if (empty($TIFFcompressionMethod)) {
+ $TIFFcompressionMethod = array(
+ 1 => 'Uncompressed',
+ 2 => 'Huffman',
+ 3 => 'Fax - CCITT 3',
+ 5 => 'LZW',
+ 32773 => 'PackBits',
+ );
+ }
+ return (isset($TIFFcompressionMethod[$id]) ? $TIFFcompressionMethod[$id] : 'unknown/invalid ('.$id.')');
+ }
+
+ function TIFFcommentName($id) {
+ static $TIFFcommentName = array();
+ if (empty($TIFFcommentName)) {
+ $TIFFcommentName = array(
+ 270 => 'imagedescription',
+ 271 => 'make',
+ 272 => 'model',
+ 305 => 'software',
+ 306 => 'datetime',
+ 315 => 'artist',
+ 316 => 'hostcomputer',
+ );
+ }
+ return (isset($TIFFcommentName[$id]) ? $TIFFcommentName[$id] : 'unknown/invalid ('.$id.')');
+ }
+
+}
+
+
+?> \ No newline at end of file