X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/vendor/james-heinrich/getid3/getid3/module.graphic.tiff.php diff --git a/vendor/james-heinrich/getid3/getid3/module.graphic.tiff.php b/vendor/james-heinrich/getid3/getid3/module.graphic.tiff.php new file mode 100644 index 00000000..90dcb5c8 --- /dev/null +++ b/vendor/james-heinrich/getid3/getid3/module.graphic.tiff.php @@ -0,0 +1,225 @@ + // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +// also https://github.com/JamesHeinrich/getID3 // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.archive.tiff.php // +// module for analyzing TIFF files // +// dependencies: NONE // +// /// +///////////////////////////////////////////////////////////////// + + +class getid3_tiff extends getid3_handler +{ + + public function Analyze() { + $info = &$this->getid3->info; + + $this->fseek($info['avdataoffset']); + $TIFFheader = $this->fread(4); + + switch (substr($TIFFheader, 0, 2)) { + case 'II': + $info['tiff']['byte_order'] = 'Intel'; + break; + case 'MM': + $info['tiff']['byte_order'] = 'Motorola'; + break; + default: + $this->error('Invalid TIFF byte order identifier ('.substr($TIFFheader, 0, 2).') at offset '.$info['avdataoffset']); + return false; + break; + } + + $info['fileformat'] = 'tiff'; + $info['video']['dataformat'] = 'tiff'; + $info['video']['lossless'] = true; + $info['tiff']['ifd'] = array(); + $CurrentIFD = array(); + + $FieldTypeByteLength = array(1=>1, 2=>1, 3=>2, 4=>4, 5=>8); + + $nextIFDoffset = $this->TIFFendian2Int($this->fread(4), $info['tiff']['byte_order']); + + while ($nextIFDoffset > 0) { + + $CurrentIFD['offset'] = $nextIFDoffset; + + $this->fseek($info['avdataoffset'] + $nextIFDoffset); + $CurrentIFD['fieldcount'] = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']); + + for ($i = 0; $i < $CurrentIFD['fieldcount']; $i++) { + $CurrentIFD['fields'][$i]['raw']['tag'] = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']); + $CurrentIFD['fields'][$i]['raw']['type'] = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']); + $CurrentIFD['fields'][$i]['raw']['length'] = $this->TIFFendian2Int($this->fread(4), $info['tiff']['byte_order']); + $CurrentIFD['fields'][$i]['raw']['offset'] = $this->fread(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), $info['tiff']['byte_order']); + } else { + $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['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'], $info['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), $info['tiff']['byte_order']); + } else { + $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['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'], $info['tiff']['byte_order']); + } else { + $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']); + } + break; + + case 5: // RATIONAL Two LONG_s: the first represents the numerator of a fraction, the second the denominator. + break; + } + } + + $info['tiff']['ifd'][] = $CurrentIFD; + $CurrentIFD = array(); + $nextIFDoffset = $this->TIFFendian2Int($this->fread(4), $info['tiff']['byte_order']); + + } + + foreach ($info['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'])) { + $this->fseek($fieldarray['offset']); + $info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = $this->fread($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'])) { + $info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = $fieldarray['value']; + } else { + $this->fseek($fieldarray['offset']); + $info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'] = $this->fread($fieldarray['raw']['length'] * $FieldTypeByteLength[$fieldarray['raw']['type']]); + + } + break; + } + switch ($fieldarray['raw']['tag']) { + case 256: // ImageWidth + $info['video']['resolution_x'] = $fieldarray['value']; + break; + + case 257: // ImageLength + $info['video']['resolution_y'] = $fieldarray['value']; + break; + + case 258: // BitsPerSample + if (isset($fieldarray['value'])) { + $info['video']['bits_per_sample'] = $fieldarray['value']; + } else { + $info['video']['bits_per_sample'] = 0; + for ($i = 0; $i < $fieldarray['raw']['length']; $i++) { + $info['video']['bits_per_sample'] += $this->TIFFendian2Int(substr($info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data'], $i * $FieldTypeByteLength[$fieldarray['raw']['type']], $FieldTypeByteLength[$fieldarray['raw']['type']]), $info['tiff']['byte_order']); + } + } + break; + + case 259: // Compression + $info['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 + $TIFFcommentName = $this->TIFFcommentName($fieldarray['raw']['tag']); + if (isset($info['tiff']['comments'][$TIFFcommentName])) { + $info['tiff']['comments'][$TIFFcommentName][] = $info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data']; + } else { + $info['tiff']['comments'][$TIFFcommentName] = array($info['tiff']['ifd'][$IFDid]['fields'][$key]['raw']['data']); + } + break; + + default: + break; + } + } + } + + return true; + } + + + public function TIFFendian2Int($bytestring, $byteorder) { + if ($byteorder == 'Intel') { + return getid3_lib::LittleEndian2Int($bytestring); + } elseif ($byteorder == 'Motorola') { + return getid3_lib::BigEndian2Int($bytestring); + } + return false; + } + + public 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.')'); + } + + public 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.')'); + } + +}