123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- <?php
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (!defined('GETID3_INCLUDEPATH')) {
- exit;
- }
-
- 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;
- }
-
- $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']['valoff'] = $this->fread(4);
- $CurrentIFD['fields'][$i]['raw']['tag_name'] = $this->TIFFcommentName($CurrentIFD['fields'][$i]['raw']['tag']);
-
- switch ($CurrentIFD['fields'][$i]['raw']['type']) {
- case 1:
- if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
- $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['valoff'], 0, 1), $info['tiff']['byte_order']);
- } else {
- $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- }
- break;
-
- case 2:
- if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
- $CurrentIFD['fields'][$i]['value'] = substr($CurrentIFD['fields'][$i]['raw']['valoff'], 3);
- } else {
- $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- }
- break;
-
- case 3:
- if ($CurrentIFD['fields'][$i]['raw']['length'] <= 2) {
- $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['valoff'], 0, 2), $info['tiff']['byte_order']);
- } else {
- $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- }
- break;
-
- case 4:
- if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
- $CurrentIFD['fields'][$i]['value'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- } else {
- $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- }
- break;
-
- case 5:
- case 7:
- $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
- break;
-
-
-
-
- case 6:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- default:
- $this->warning('unhandled IFD field type '.$CurrentIFD['fields'][$i]['raw']['type'].' for IFD entry '.$i);
- 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:
- case 257:
- case 258:
- case 259:
- 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:
- case 271:
- case 272:
- case 305:
- case 306:
- case 315:
- case 316:
- 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;
- case 700:
- $XMPmagic = '<?xpacket';
- $this->fseek($fieldarray['offset']);
- $xmpkey = (isset($info['tiff']['XMP']) ? count($info['tiff']['XMP']) : 0);
- $info['tiff']['XMP'][$xmpkey]['raw'] = $this->fread($fieldarray['raw']['length']);
- if (substr($info['tiff']['XMP'][$xmpkey]['raw'], 0, strlen($XMPmagic)) != $XMPmagic) {
- $this->warning('did not find expected XMP data at offset '.$fieldarray['offset']);
- unset($info['tiff']['XMP'][$xmpkey]['raw']);
- }
- break;
- }
- switch ($fieldarray['raw']['tag']) {
- case 256:
- $info['video']['resolution_x'] = $fieldarray['value'];
- break;
-
- case 257:
- $info['video']['resolution_y'] = $fieldarray['value'];
- break;
-
- case 258:
- 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:
- $info['video']['codec'] = $this->TIFFcompressionMethod($fieldarray['value']);
- break;
-
- case 270:
- case 271:
- case 272:
- case 305:
- case 306:
- case 315:
- case 316:
- $TIFFcommentName = strtolower($fieldarray['raw']['tag_name']);
- 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(
- 0x0001 => 'Uncompressed',
- 0x0002 => 'Huffman',
- 0x0003 => 'CCITT T.4',
- 0x0004 => 'CCITT T.6',
- 0x0005 => 'LZW',
- 0x0006 => 'JPEG-old',
- 0x0007 => 'JPEG',
- 0x0008 => 'deflate',
- 0x0009 => 'JBIG ITU-T T.85',
- 0x000A => 'JBIG ITU-T T.43',
- 0x7FFE => 'NeXT RLE 2-bit',
- 0x8005 => 'PackBits',
- 0x8029 => 'ThunderScan RLE 4-bit',
- 0x807F => 'RasterPadding',
- 0x8080 => 'RLE-LW',
- 0x8081 => 'RLE-CT',
- 0x8082 => 'RLE-BL',
- 0x80B2 => 'deflate-PK',
- 0x80B3 => 'Kodak-DCS',
- 0x8765 => 'JBIG',
- 0x8798 => 'JPEG2000',
- 0x8799 => 'Nikon NEF',
- 0x879B => 'JBIG2',
- );
- }
- return (isset($TIFFcompressionMethod[$id]) ? $TIFFcompressionMethod[$id] : 'unknown/invalid ('.$id.')');
- }
-
-
-
- public function TIFFcommentName($id) {
-
- static $TIFFcommentName = array();
- if (empty($TIFFcommentName)) {
- $TIFFcommentName = array(
- 254 => 'NewSubfileType',
- 255 => 'SubfileType',
- 256 => 'ImageWidth',
- 257 => 'ImageLength',
- 258 => 'BitsPerSample',
- 259 => 'Compression',
- 262 => 'PhotometricInterpretation',
- 263 => 'Threshholding',
- 264 => 'CellWidth',
- 265 => 'CellLength',
- 266 => 'FillOrder',
- 269 => 'DocumentName',
- 270 => 'ImageDescription',
- 271 => 'Make',
- 272 => 'Model',
- 273 => 'StripOffsets',
- 274 => 'Orientation',
- 277 => 'SamplesPerPixel',
- 278 => 'RowsPerStrip',
- 279 => 'StripByteCounts',
- 280 => 'MinSampleValue',
- 281 => 'MaxSampleValue',
- 282 => 'XResolution',
- 283 => 'YResolution',
- 284 => 'PlanarConfiguration',
- 285 => 'PageName',
- 286 => 'XPosition',
- 287 => 'YPosition',
- 288 => 'FreeOffsets',
- 289 => 'FreeByteCounts',
- 290 => 'GrayResponseUnit',
- 291 => 'GrayResponseCurve',
- 292 => 'T4Options',
- 293 => 'T6Options',
- 296 => 'ResolutionUnit',
- 297 => 'PageNumber',
- 301 => 'TransferFunction',
- 305 => 'Software',
- 306 => 'DateTime',
- 315 => 'Artist',
- 316 => 'HostComputer',
- 317 => 'Predictor',
- 318 => 'WhitePoint',
- 319 => 'PrimaryChromaticities',
- 320 => 'ColorMap',
- 321 => 'HalftoneHints',
- 322 => 'TileWidth',
- 323 => 'TileLength',
- 324 => 'TileOffsets',
- 325 => 'TileByteCounts',
- 326 => 'BadFaxLines',
- 327 => 'CleanFaxData',
- 328 => 'ConsecutiveBadFaxLines',
- 330 => 'SubIFDs',
- 332 => 'InkSet',
- 333 => 'InkNames',
- 334 => 'NumberOfInks',
- 336 => 'DotRange',
- 337 => 'TargetPrinter',
- 338 => 'ExtraSamples',
- 339 => 'SampleFormat',
- 340 => 'SMinSampleValue',
- 341 => 'SMaxSampleValue',
- 342 => 'TransferRange',
- 343 => 'ClipPath',
- 344 => 'XClipPathUnits',
- 345 => 'YClipPathUnits',
- 346 => 'Indexed',
- 347 => 'JPEGTables',
- 351 => 'OPIProxy',
- 400 => 'GlobalParametersIFD',
- 401 => 'ProfileType',
- 402 => 'FaxProfile',
- 403 => 'CodingMethods',
- 404 => 'VersionYear',
- 405 => 'ModeNumber',
- 433 => 'Decode',
- 434 => 'DefaultImageColor',
- 512 => 'JPEGProc',
- 513 => 'JPEGInterchangeFormat',
- 514 => 'JPEGInterchangeFormatLngth',
- 515 => 'JPEGRestartInterval',
- 517 => 'JPEGLosslessPredictors',
- 518 => 'JPEGPointTransforms',
- 519 => 'JPEGQTables',
- 520 => 'JPEGDCTables',
- 521 => 'JPEGACTables',
- 529 => 'YCbCrCoefficients',
- 530 => 'YCbCrSubSampling',
- 531 => 'YCbCrPositioning',
- 532 => 'ReferenceBlackWhite',
- 559 => 'StripRowCounts',
- 700 => 'XMP',
-
- 32781 => 'ImageID',
- 33432 => 'Copyright',
- 34732 => 'ImageLayer',
-
-
- 32932 => 'Wang Annotation',
- 33445 => 'MD FileTag',
- 33446 => 'MD ScalePixel',
- 33447 => 'MD ColorTable',
- 33448 => 'MD LabName',
- 33449 => 'MD SampleInfo',
- 33450 => 'MD PrepDate',
- 33451 => 'MD PrepTime',
- 33452 => 'MD FileUnits',
- 33550 => 'ModelPixelScaleTag',
- 33723 => 'IPTC',
- 33918 => 'INGR Packet Data Tag',
- 33919 => 'INGR Flag Registers',
- 33920 => 'IrasB Transformation Matrix',
- 33922 => 'ModelTiepointTag',
- 34264 => 'ModelTransformationTag',
- 34377 => 'Photoshop',
- 34665 => 'Exif IFD',
- 34675 => 'ICC Profile',
- 34735 => 'GeoKeyDirectoryTag',
- 34736 => 'GeoDoubleParamsTag',
- 34737 => 'GeoAsciiParamsTag',
- 34853 => 'GPS IFD',
- 34908 => 'HylaFAX FaxRecvParams',
- 34909 => 'HylaFAX FaxSubAddress',
- 34910 => 'HylaFAX FaxRecvTime',
- 37724 => 'ImageSourceData',
- 40965 => 'Interoperability IFD',
- 42112 => 'GDAL_METADATA',
- 42113 => 'GDAL_NODATA',
- 50215 => 'Oce Scanjob Description',
- 50216 => 'Oce Application Selector',
- 50217 => 'Oce Identification Number',
- 50218 => 'Oce ImageLogic Characteristics',
- 50706 => 'DNGVersion',
- 50707 => 'DNGBackwardVersion',
- 50708 => 'UniqueCameraModel',
- 50709 => 'LocalizedCameraModel',
- 50710 => 'CFAPlaneColor',
- 50711 => 'CFALayout',
- 50712 => 'LinearizationTable',
- 50713 => 'BlackLevelRepeatDim',
- 50714 => 'BlackLevel',
- 50715 => 'BlackLevelDeltaH',
- 50716 => 'BlackLevelDeltaV',
- 50717 => 'WhiteLevel',
- 50718 => 'DefaultScale',
- 50719 => 'DefaultCropOrigin',
- 50720 => 'DefaultCropSize',
- 50721 => 'ColorMatrix1',
- 50722 => 'ColorMatrix2',
- 50723 => 'CameraCalibration1',
- 50724 => 'CameraCalibration2',
- 50725 => 'ReductionMatrix1',
- 50726 => 'ReductionMatrix2',
- 50727 => 'AnalogBalance',
- 50728 => 'AsShotNeutral',
- 50729 => 'AsShotWhiteXY',
- 50730 => 'BaselineExposure',
- 50731 => 'BaselineNoise',
- 50732 => 'BaselineSharpness',
- 50733 => 'BayerGreenSplit',
- 50734 => 'LinearResponseLimit',
- 50735 => 'CameraSerialNumber',
- 50736 => 'LensInfo',
- 50737 => 'ChromaBlurRadius',
- 50738 => 'AntiAliasStrength',
- 50740 => 'DNGPrivateData',
- 50741 => 'MakerNoteSafety',
- 50778 => 'CalibrationIlluminant1',
- 50779 => 'CalibrationIlluminant2',
- 50780 => 'BestQualityScale',
- 50784 => 'Alias Layer Metadata',
- 50908 => 'TIFF_RSID',
- 50909 => 'GEO_METADATA',
-
-
- 33434 => 'ExposureTime',
- 33437 => 'FNumber',
- 34850 => 'ExposureProgram',
- 34852 => 'SpectralSensitivity',
- 34855 => 'ISOSpeedRatings',
- 34856 => 'OECF',
- 36864 => 'ExifVersion',
- 36867 => 'DateTimeOriginal',
- 36868 => 'DateTimeDigitized',
- 37121 => 'ComponentsConfiguration',
- 37122 => 'CompressedBitsPerPixel',
- 37377 => 'ShutterSpeedValue',
- 37378 => 'ApertureValue',
- 37379 => 'BrightnessValue',
- 37380 => 'ExposureBiasValue',
- 37381 => 'MaxApertureValue',
- 37382 => 'SubjectDistance',
- 37383 => 'MeteringMode',
- 37384 => 'LightSource',
- 37385 => 'Flash',
- 37386 => 'FocalLength',
- 37396 => 'SubjectArea',
- 37500 => 'MakerNote',
- 37510 => 'UserComment',
- 37520 => 'SubsecTime',
- 37521 => 'SubsecTimeOriginal',
- 37522 => 'SubsecTimeDigitized',
- 40960 => 'FlashpixVersion',
- 40961 => 'ColorSpace',
- 40962 => 'PixelXDimension',
- 40963 => 'PixelYDimension',
- 40964 => 'RelatedSoundFile',
- 41483 => 'FlashEnergy',
- 41484 => 'SpatialFrequencyResponse',
- 41486 => 'FocalPlaneXResolution',
- 41487 => 'FocalPlaneYResolution',
- 41488 => 'FocalPlaneResolutionUnit',
- 41492 => 'SubjectLocation',
- 41493 => 'ExposureIndex',
- 41495 => 'SensingMethod',
- 41728 => 'FileSource',
- 41729 => 'SceneType',
- 41730 => 'CFAPattern',
- 41985 => 'CustomRendered',
- 41986 => 'ExposureMode',
- 41987 => 'WhiteBalance',
- 41988 => 'DigitalZoomRatio',
- 41989 => 'FocalLengthIn35mmFilm',
- 41990 => 'SceneCaptureType',
- 41991 => 'GainControl',
- 41992 => 'Contrast',
- 41993 => 'Saturation',
- 41994 => 'Sharpness',
- 41995 => 'DeviceSettingDescription',
- 41996 => 'SubjectDistanceRange',
- 42016 => 'ImageUniqueID',
- );
- }
- return (isset($TIFFcommentName[$id]) ? $TIFFcommentName[$id] : 'unknown/invalid ('.$id.')');
- }
-
-
- }
|