File indexing completed on 2025-05-04 05:28:44
0001 <?php 0002 ///////////////////////////////////////////////////////////////// 0003 /// getID3() by James Heinrich <info@getid3.org> // 0004 // available at http://getid3.sourceforge.net // 0005 // or http://www.getid3.org // 0006 // also https://github.com/JamesHeinrich/getID3 // 0007 ///////////////////////////////////////////////////////////////// 0008 // See readme.txt for more details // 0009 ///////////////////////////////////////////////////////////////// 0010 // // 0011 // module.tag.xmp.php // 0012 // module for analyzing XMP metadata (e.g. in JPEG files) // 0013 // dependencies: NONE // 0014 // // 0015 ///////////////////////////////////////////////////////////////// 0016 // // 0017 // Module originally written [2009-Mar-26] by // 0018 // Nigel Barnes <ngbarnesĂhotmail*com> // 0019 // Bundled into getID3 with permission // 0020 // called by getID3 in module.graphic.jpg.php // 0021 // /// 0022 ///////////////////////////////////////////////////////////////// 0023 0024 /************************************************************************************************** 0025 * SWISScenter Source Nigel Barnes 0026 * 0027 * Provides functions for reading information from the 'APP1' Extensible Metadata 0028 * Platform (XMP) segment of JPEG format files. 0029 * This XMP segment is XML based and contains the Resource Description Framework (RDF) 0030 * data, which itself can contain the Dublin Core Metadata Initiative (DCMI) information. 0031 * 0032 * This code uses segments from the JPEG Metadata Toolkit project by Evan Hunter. 0033 *************************************************************************************************/ 0034 class Image_XMP 0035 { 0036 /** 0037 * @var string 0038 * The name of the image file that contains the XMP fields to extract and modify. 0039 * @see Image_XMP() 0040 */ 0041 public $_sFilename = null; 0042 0043 /** 0044 * @var array 0045 * The XMP fields that were extracted from the image or updated by this class. 0046 * @see getAllTags() 0047 */ 0048 public $_aXMP = array(); 0049 0050 /** 0051 * @var boolean 0052 * True if an APP1 segment was found to contain XMP metadata. 0053 * @see isValid() 0054 */ 0055 public $_bXMPParse = false; 0056 0057 /** 0058 * Returns the status of XMP parsing during instantiation 0059 * 0060 * You'll normally want to call this method before trying to get XMP fields. 0061 * 0062 * @return boolean 0063 * Returns true if an APP1 segment was found to contain XMP metadata. 0064 */ 0065 public function isValid() 0066 { 0067 return $this->_bXMPParse; 0068 } 0069 0070 /** 0071 * Get a copy of all XMP tags extracted from the image 0072 * 0073 * @return array - An array of XMP fields as it extracted by the XMPparse() function 0074 */ 0075 public function getAllTags() 0076 { 0077 return $this->_aXMP; 0078 } 0079 0080 /** 0081 * Reads all the JPEG header segments from an JPEG image file into an array 0082 * 0083 * @param string $filename - the filename of the JPEG file to read 0084 * @return array $headerdata - Array of JPEG header segments 0085 * @return boolean FALSE - if headers could not be read 0086 */ 0087 public function _get_jpeg_header_data($filename) 0088 { 0089 // prevent refresh from aborting file operations and hosing file 0090 ignore_user_abort(true); 0091 0092 // Attempt to open the jpeg file - the at symbol supresses the error message about 0093 // not being able to open files. The file_exists would have been used, but it 0094 // does not work with files fetched over http or ftp. 0095 if (is_readable($filename) && is_file($filename) && ($filehnd = fopen($filename, 'rb'))) { 0096 // great 0097 } else { 0098 return false; 0099 } 0100 0101 // Read the first two characters 0102 $data = fread($filehnd, 2); 0103 0104 // Check that the first two characters are 0xFF 0xD8 (SOI - Start of image) 0105 if ($data != "\xFF\xD8") 0106 { 0107 // No SOI (FF D8) at start of file - This probably isn't a JPEG file - close file and return; 0108 echo '<p>This probably is not a JPEG file</p>'."\n"; 0109 fclose($filehnd); 0110 return false; 0111 } 0112 0113 // Read the third character 0114 $data = fread($filehnd, 2); 0115 0116 // Check that the third character is 0xFF (Start of first segment header) 0117 if ($data{0} != "\xFF") 0118 { 0119 // NO FF found - close file and return - JPEG is probably corrupted 0120 fclose($filehnd); 0121 return false; 0122 } 0123 0124 // Flag that we havent yet hit the compressed image data 0125 $hit_compressed_image_data = false; 0126 0127 // Cycle through the file until, one of: 1) an EOI (End of image) marker is hit, 0128 // 2) we have hit the compressed image data (no more headers are allowed after data) 0129 // 3) or end of file is hit 0130 0131 while (($data{1} != "\xD9") && (!$hit_compressed_image_data) && (!feof($filehnd))) 0132 { 0133 // Found a segment to look at. 0134 // Check that the segment marker is not a Restart marker - restart markers don't have size or data after them 0135 if ((ord($data{1}) < 0xD0) || (ord($data{1}) > 0xD7)) 0136 { 0137 // Segment isn't a Restart marker 0138 // Read the next two bytes (size) 0139 $sizestr = fread($filehnd, 2); 0140 0141 // convert the size bytes to an integer 0142 $decodedsize = unpack('nsize', $sizestr); 0143 0144 // Save the start position of the data 0145 $segdatastart = ftell($filehnd); 0146 0147 // Read the segment data with length indicated by the previously read size 0148 $segdata = fread($filehnd, $decodedsize['size'] - 2); 0149 0150 // Store the segment information in the output array 0151 $headerdata[] = array( 0152 'SegType' => ord($data{1}), 0153 'SegName' => $GLOBALS['JPEG_Segment_Names'][ord($data{1})], 0154 'SegDataStart' => $segdatastart, 0155 'SegData' => $segdata, 0156 ); 0157 } 0158 0159 // If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows 0160 if ($data{1} == "\xDA") 0161 { 0162 // Flag that we have hit the compressed image data - exit loop as no more headers available. 0163 $hit_compressed_image_data = true; 0164 } 0165 else 0166 { 0167 // Not an SOS - Read the next two bytes - should be the segment marker for the next segment 0168 $data = fread($filehnd, 2); 0169 0170 // Check that the first byte of the two is 0xFF as it should be for a marker 0171 if ($data{0} != "\xFF") 0172 { 0173 // NO FF found - close file and return - JPEG is probably corrupted 0174 fclose($filehnd); 0175 return false; 0176 } 0177 } 0178 } 0179 0180 // Close File 0181 fclose($filehnd); 0182 // Alow the user to abort from now on 0183 ignore_user_abort(false); 0184 0185 // Return the header data retrieved 0186 return $headerdata; 0187 } 0188 0189 0190 /** 0191 * Retrieves XMP information from an APP1 JPEG segment and returns the raw XML text as a string. 0192 * 0193 * @param string $filename - the filename of the JPEG file to read 0194 * @return string $xmp_data - the string of raw XML text 0195 * @return boolean FALSE - if an APP 1 XMP segment could not be found, or if an error occured 0196 */ 0197 public function _get_XMP_text($filename) 0198 { 0199 //Get JPEG header data 0200 $jpeg_header_data = $this->_get_jpeg_header_data($filename); 0201 0202 //Cycle through the header segments 0203 for ($i = 0; $i < count($jpeg_header_data); $i++) 0204 { 0205 // If we find an APP1 header, 0206 if (strcmp($jpeg_header_data[$i]['SegName'], 'APP1') == 0) 0207 { 0208 // And if it has the Adobe XMP/RDF label (http://ns.adobe.com/xap/1.0/\x00) , 0209 if (strncmp($jpeg_header_data[$i]['SegData'], 'http://ns.adobe.com/xap/1.0/'."\x00", 29) == 0) 0210 { 0211 // Found a XMP/RDF block 0212 // Return the XMP text 0213 $xmp_data = substr($jpeg_header_data[$i]['SegData'], 29); 0214 0215 return trim($xmp_data); // trim() should not be neccesary, but some files found in the wild with null-terminated block (known samples from Apple Aperture) causes problems elsewhere (see http://www.getid3.org/phpBB3/viewtopic.php?f=4&t=1153) 0216 } 0217 } 0218 } 0219 return false; 0220 } 0221 0222 /** 0223 * Parses a string containing XMP data (XML), and returns an array 0224 * which contains all the XMP (XML) information. 0225 * 0226 * @param $xmltext 0227 * 0228 * @return array $xmp_array - an array containing all xmp details retrieved. 0229 */ 0230 public function read_XMP_array_from_text($xmltext) 0231 { 0232 // Check if there actually is any text to parse 0233 if (trim($xmltext) == '') 0234 { 0235 return false; 0236 } 0237 0238 // Create an instance of a xml parser to parse the XML text 0239 $xml_parser = xml_parser_create('UTF-8'); 0240 0241 // Change: Fixed problem that caused the whitespace (especially newlines) to be destroyed when converting xml text to an xml array, as of revision 1.10 0242 0243 // We would like to remove unneccessary white space, but this will also 0244 // remove things like newlines (
) in the XML values, so white space 0245 // will have to be removed later 0246 if (xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0) == false) 0247 { 0248 // Error setting case folding - destroy the parser and return 0249 xml_parser_free($xml_parser); 0250 return false; 0251 } 0252 0253 // to use XML code correctly we have to turn case folding 0254 // (uppercasing) off. XML is case sensitive and upper 0255 // casing is in reality XML standards violation 0256 if (xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0) == false) 0257 { 0258 // Error setting case folding - destroy the parser and return 0259 xml_parser_free($xml_parser); 0260 return false; 0261 } 0262 0263 // Parse the XML text into a array structure 0264 if (xml_parse_into_struct($xml_parser, $xmltext, $values, $tags) == 0) 0265 { 0266 // Error Parsing XML - destroy the parser and return 0267 xml_parser_free($xml_parser); 0268 return false; 0269 } 0270 0271 // Destroy the xml parser 0272 xml_parser_free($xml_parser); 0273 0274 // Clear the output array 0275 $xmp_array = array(); 0276 0277 // The XMP data has now been parsed into an array ... 0278 0279 // Cycle through each of the array elements 0280 $current_property = ''; // current property being processed 0281 $container_index = -1; // -1 = no container open, otherwise index of container content 0282 foreach ($values as $xml_elem) 0283 { 0284 // Syntax and Class names 0285 switch ($xml_elem['tag']) 0286 { 0287 case 'x:xmpmeta': 0288 // only defined attribute is x:xmptk written by Adobe XMP Toolkit; value is the version of the toolkit 0289 break; 0290 0291 case 'rdf:RDF': 0292 // required element immediately within x:xmpmeta; no data here 0293 break; 0294 0295 case 'rdf:Description': 0296 switch ($xml_elem['type']) 0297 { 0298 case 'open': 0299 case 'complete': 0300 if (array_key_exists('attributes', $xml_elem)) 0301 { 0302 // rdf:Description may contain wanted attributes 0303 foreach (array_keys($xml_elem['attributes']) as $key) 0304 { 0305 // Check whether we want this details from this attribute 0306 // if (in_array($key, $GLOBALS['XMP_tag_captions'])) 0307 if (true) 0308 { 0309 // Attribute wanted 0310 $xmp_array[$key] = $xml_elem['attributes'][$key]; 0311 } 0312 } 0313 } 0314 case 'cdata': 0315 case 'close': 0316 break; 0317 } 0318 0319 case 'rdf:ID': 0320 case 'rdf:nodeID': 0321 // Attributes are ignored 0322 break; 0323 0324 case 'rdf:li': 0325 // Property member 0326 if ($xml_elem['type'] == 'complete') 0327 { 0328 if (array_key_exists('attributes', $xml_elem)) 0329 { 0330 // If Lang Alt (language alternatives) then ensure we take the default language 0331 if (isset($xml_elem['attributes']['xml:lang']) && ($xml_elem['attributes']['xml:lang'] != 'x-default')) 0332 { 0333 break; 0334 } 0335 } 0336 if ($current_property != '') 0337 { 0338 $xmp_array[$current_property][$container_index] = (isset($xml_elem['value']) ? $xml_elem['value'] : ''); 0339 $container_index += 1; 0340 } 0341 //else unidentified attribute!! 0342 } 0343 break; 0344 0345 case 'rdf:Seq': 0346 case 'rdf:Bag': 0347 case 'rdf:Alt': 0348 // Container found 0349 switch ($xml_elem['type']) 0350 { 0351 case 'open': 0352 $container_index = 0; 0353 break; 0354 case 'close': 0355 $container_index = -1; 0356 break; 0357 case 'cdata': 0358 break; 0359 } 0360 break; 0361 0362 default: 0363 // Check whether we want the details from this attribute 0364 // if (in_array($xml_elem['tag'], $GLOBALS['XMP_tag_captions'])) 0365 if (true) 0366 { 0367 switch ($xml_elem['type']) 0368 { 0369 case 'open': 0370 // open current element 0371 $current_property = $xml_elem['tag']; 0372 break; 0373 0374 case 'close': 0375 // close current element 0376 $current_property = ''; 0377 break; 0378 0379 case 'complete': 0380 // store attribute value 0381 $xmp_array[$xml_elem['tag']] = (isset($xml_elem['attributes']) ? $xml_elem['attributes'] : (isset($xml_elem['value']) ? $xml_elem['value'] : '')); 0382 break; 0383 0384 case 'cdata': 0385 // ignore 0386 break; 0387 } 0388 } 0389 break; 0390 } 0391 0392 } 0393 return $xmp_array; 0394 } 0395 0396 0397 /** 0398 * Constructor 0399 * 0400 * @param string - Name of the image file to access and extract XMP information from. 0401 */ 0402 public function Image_XMP($sFilename) 0403 { 0404 $this->_sFilename = $sFilename; 0405 0406 if (is_file($this->_sFilename)) 0407 { 0408 // Get XMP data 0409 $xmp_data = $this->_get_XMP_text($sFilename); 0410 if ($xmp_data) 0411 { 0412 $this->_aXMP = $this->read_XMP_array_from_text($xmp_data); 0413 $this->_bXMPParse = true; 0414 } 0415 } 0416 } 0417 0418 } 0419 0420 /** 0421 * Global Variable: XMP_tag_captions 0422 * 0423 * The Property names of all known XMP fields. 0424 * Note: this is a full list with unrequired properties commented out. 0425 */ 0426 /* 0427 $GLOBALS['XMP_tag_captions'] = array( 0428 // IPTC Core 0429 'Iptc4xmpCore:CiAdrCity', 0430 'Iptc4xmpCore:CiAdrCtry', 0431 'Iptc4xmpCore:CiAdrExtadr', 0432 'Iptc4xmpCore:CiAdrPcode', 0433 'Iptc4xmpCore:CiAdrRegion', 0434 'Iptc4xmpCore:CiEmailWork', 0435 'Iptc4xmpCore:CiTelWork', 0436 'Iptc4xmpCore:CiUrlWork', 0437 'Iptc4xmpCore:CountryCode', 0438 'Iptc4xmpCore:CreatorContactInfo', 0439 'Iptc4xmpCore:IntellectualGenre', 0440 'Iptc4xmpCore:Location', 0441 'Iptc4xmpCore:Scene', 0442 'Iptc4xmpCore:SubjectCode', 0443 // Dublin Core Schema 0444 'dc:contributor', 0445 'dc:coverage', 0446 'dc:creator', 0447 'dc:date', 0448 'dc:description', 0449 'dc:format', 0450 'dc:identifier', 0451 'dc:language', 0452 'dc:publisher', 0453 'dc:relation', 0454 'dc:rights', 0455 'dc:source', 0456 'dc:subject', 0457 'dc:title', 0458 'dc:type', 0459 // XMP Basic Schema 0460 'xmp:Advisory', 0461 'xmp:BaseURL', 0462 'xmp:CreateDate', 0463 'xmp:CreatorTool', 0464 'xmp:Identifier', 0465 'xmp:Label', 0466 'xmp:MetadataDate', 0467 'xmp:ModifyDate', 0468 'xmp:Nickname', 0469 'xmp:Rating', 0470 'xmp:Thumbnails', 0471 'xmpidq:Scheme', 0472 // XMP Rights Management Schema 0473 'xmpRights:Certificate', 0474 'xmpRights:Marked', 0475 'xmpRights:Owner', 0476 'xmpRights:UsageTerms', 0477 'xmpRights:WebStatement', 0478 // These are not in spec but Photoshop CS seems to use them 0479 'xap:Advisory', 0480 'xap:BaseURL', 0481 'xap:CreateDate', 0482 'xap:CreatorTool', 0483 'xap:Identifier', 0484 'xap:MetadataDate', 0485 'xap:ModifyDate', 0486 'xap:Nickname', 0487 'xap:Rating', 0488 'xap:Thumbnails', 0489 'xapidq:Scheme', 0490 'xapRights:Certificate', 0491 'xapRights:Copyright', 0492 'xapRights:Marked', 0493 'xapRights:Owner', 0494 'xapRights:UsageTerms', 0495 'xapRights:WebStatement', 0496 // XMP Media Management Schema 0497 'xapMM:DerivedFrom', 0498 'xapMM:DocumentID', 0499 'xapMM:History', 0500 'xapMM:InstanceID', 0501 'xapMM:ManagedFrom', 0502 'xapMM:Manager', 0503 'xapMM:ManageTo', 0504 'xapMM:ManageUI', 0505 'xapMM:ManagerVariant', 0506 'xapMM:RenditionClass', 0507 'xapMM:RenditionParams', 0508 'xapMM:VersionID', 0509 'xapMM:Versions', 0510 'xapMM:LastURL', 0511 'xapMM:RenditionOf', 0512 'xapMM:SaveID', 0513 // XMP Basic Job Ticket Schema 0514 'xapBJ:JobRef', 0515 // XMP Paged-Text Schema 0516 'xmpTPg:MaxPageSize', 0517 'xmpTPg:NPages', 0518 'xmpTPg:Fonts', 0519 'xmpTPg:Colorants', 0520 'xmpTPg:PlateNames', 0521 // Adobe PDF Schema 0522 'pdf:Keywords', 0523 'pdf:PDFVersion', 0524 'pdf:Producer', 0525 // Photoshop Schema 0526 'photoshop:AuthorsPosition', 0527 'photoshop:CaptionWriter', 0528 'photoshop:Category', 0529 'photoshop:City', 0530 'photoshop:Country', 0531 'photoshop:Credit', 0532 'photoshop:DateCreated', 0533 'photoshop:Headline', 0534 'photoshop:History', 0535 // Not in XMP spec 0536 'photoshop:Instructions', 0537 'photoshop:Source', 0538 'photoshop:State', 0539 'photoshop:SupplementalCategories', 0540 'photoshop:TransmissionReference', 0541 'photoshop:Urgency', 0542 // EXIF Schemas 0543 'tiff:ImageWidth', 0544 'tiff:ImageLength', 0545 'tiff:BitsPerSample', 0546 'tiff:Compression', 0547 'tiff:PhotometricInterpretation', 0548 'tiff:Orientation', 0549 'tiff:SamplesPerPixel', 0550 'tiff:PlanarConfiguration', 0551 'tiff:YCbCrSubSampling', 0552 'tiff:YCbCrPositioning', 0553 'tiff:XResolution', 0554 'tiff:YResolution', 0555 'tiff:ResolutionUnit', 0556 'tiff:TransferFunction', 0557 'tiff:WhitePoint', 0558 'tiff:PrimaryChromaticities', 0559 'tiff:YCbCrCoefficients', 0560 'tiff:ReferenceBlackWhite', 0561 'tiff:DateTime', 0562 'tiff:ImageDescription', 0563 'tiff:Make', 0564 'tiff:Model', 0565 'tiff:Software', 0566 'tiff:Artist', 0567 'tiff:Copyright', 0568 'exif:ExifVersion', 0569 'exif:FlashpixVersion', 0570 'exif:ColorSpace', 0571 'exif:ComponentsConfiguration', 0572 'exif:CompressedBitsPerPixel', 0573 'exif:PixelXDimension', 0574 'exif:PixelYDimension', 0575 'exif:MakerNote', 0576 'exif:UserComment', 0577 'exif:RelatedSoundFile', 0578 'exif:DateTimeOriginal', 0579 'exif:DateTimeDigitized', 0580 'exif:ExposureTime', 0581 'exif:FNumber', 0582 'exif:ExposureProgram', 0583 'exif:SpectralSensitivity', 0584 'exif:ISOSpeedRatings', 0585 'exif:OECF', 0586 'exif:ShutterSpeedValue', 0587 'exif:ApertureValue', 0588 'exif:BrightnessValue', 0589 'exif:ExposureBiasValue', 0590 'exif:MaxApertureValue', 0591 'exif:SubjectDistance', 0592 'exif:MeteringMode', 0593 'exif:LightSource', 0594 'exif:Flash', 0595 'exif:FocalLength', 0596 'exif:SubjectArea', 0597 'exif:FlashEnergy', 0598 'exif:SpatialFrequencyResponse', 0599 'exif:FocalPlaneXResolution', 0600 'exif:FocalPlaneYResolution', 0601 'exif:FocalPlaneResolutionUnit', 0602 'exif:SubjectLocation', 0603 'exif:SensingMethod', 0604 'exif:FileSource', 0605 'exif:SceneType', 0606 'exif:CFAPattern', 0607 'exif:CustomRendered', 0608 'exif:ExposureMode', 0609 'exif:WhiteBalance', 0610 'exif:DigitalZoomRatio', 0611 'exif:FocalLengthIn35mmFilm', 0612 'exif:SceneCaptureType', 0613 'exif:GainControl', 0614 'exif:Contrast', 0615 'exif:Saturation', 0616 'exif:Sharpness', 0617 'exif:DeviceSettingDescription', 0618 'exif:SubjectDistanceRange', 0619 'exif:ImageUniqueID', 0620 'exif:GPSVersionID', 0621 'exif:GPSLatitude', 0622 'exif:GPSLongitude', 0623 'exif:GPSAltitudeRef', 0624 'exif:GPSAltitude', 0625 'exif:GPSTimeStamp', 0626 'exif:GPSSatellites', 0627 'exif:GPSStatus', 0628 'exif:GPSMeasureMode', 0629 'exif:GPSDOP', 0630 'exif:GPSSpeedRef', 0631 'exif:GPSSpeed', 0632 'exif:GPSTrackRef', 0633 'exif:GPSTrack', 0634 'exif:GPSImgDirectionRef', 0635 'exif:GPSImgDirection', 0636 'exif:GPSMapDatum', 0637 'exif:GPSDestLatitude', 0638 'exif:GPSDestLongitude', 0639 'exif:GPSDestBearingRef', 0640 'exif:GPSDestBearing', 0641 'exif:GPSDestDistanceRef', 0642 'exif:GPSDestDistance', 0643 'exif:GPSProcessingMethod', 0644 'exif:GPSAreaInformation', 0645 'exif:GPSDifferential', 0646 'stDim:w', 0647 'stDim:h', 0648 'stDim:unit', 0649 'xapGImg:height', 0650 'xapGImg:width', 0651 'xapGImg:format', 0652 'xapGImg:image', 0653 'stEvt:action', 0654 'stEvt:instanceID', 0655 'stEvt:parameters', 0656 'stEvt:softwareAgent', 0657 'stEvt:when', 0658 'stRef:instanceID', 0659 'stRef:documentID', 0660 'stRef:versionID', 0661 'stRef:renditionClass', 0662 'stRef:renditionParams', 0663 'stRef:manager', 0664 'stRef:managerVariant', 0665 'stRef:manageTo', 0666 'stRef:manageUI', 0667 'stVer:comments', 0668 'stVer:event', 0669 'stVer:modifyDate', 0670 'stVer:modifier', 0671 'stVer:version', 0672 'stJob:name', 0673 'stJob:id', 0674 'stJob:url', 0675 // Exif Flash 0676 'exif:Fired', 0677 'exif:Return', 0678 'exif:Mode', 0679 'exif:Function', 0680 'exif:RedEyeMode', 0681 // Exif OECF/SFR 0682 'exif:Columns', 0683 'exif:Rows', 0684 'exif:Names', 0685 'exif:Values', 0686 // Exif CFAPattern 0687 'exif:Columns', 0688 'exif:Rows', 0689 'exif:Values', 0690 // Exif DeviceSettings 0691 'exif:Columns', 0692 'exif:Rows', 0693 'exif:Settings', 0694 ); 0695 */ 0696 0697 /** 0698 * Global Variable: JPEG_Segment_Names 0699 * 0700 * The names of the JPEG segment markers, indexed by their marker number 0701 */ 0702 $GLOBALS['JPEG_Segment_Names'] = array( 0703 0x01 => 'TEM', 0704 0x02 => 'RES', 0705 0xC0 => 'SOF0', 0706 0xC1 => 'SOF1', 0707 0xC2 => 'SOF2', 0708 0xC3 => 'SOF4', 0709 0xC4 => 'DHT', 0710 0xC5 => 'SOF5', 0711 0xC6 => 'SOF6', 0712 0xC7 => 'SOF7', 0713 0xC8 => 'JPG', 0714 0xC9 => 'SOF9', 0715 0xCA => 'SOF10', 0716 0xCB => 'SOF11', 0717 0xCC => 'DAC', 0718 0xCD => 'SOF13', 0719 0xCE => 'SOF14', 0720 0xCF => 'SOF15', 0721 0xD0 => 'RST0', 0722 0xD1 => 'RST1', 0723 0xD2 => 'RST2', 0724 0xD3 => 'RST3', 0725 0xD4 => 'RST4', 0726 0xD5 => 'RST5', 0727 0xD6 => 'RST6', 0728 0xD7 => 'RST7', 0729 0xD8 => 'SOI', 0730 0xD9 => 'EOI', 0731 0xDA => 'SOS', 0732 0xDB => 'DQT', 0733 0xDC => 'DNL', 0734 0xDD => 'DRI', 0735 0xDE => 'DHP', 0736 0xDF => 'EXP', 0737 0xE0 => 'APP0', 0738 0xE1 => 'APP1', 0739 0xE2 => 'APP2', 0740 0xE3 => 'APP3', 0741 0xE4 => 'APP4', 0742 0xE5 => 'APP5', 0743 0xE6 => 'APP6', 0744 0xE7 => 'APP7', 0745 0xE8 => 'APP8', 0746 0xE9 => 'APP9', 0747 0xEA => 'APP10', 0748 0xEB => 'APP11', 0749 0xEC => 'APP12', 0750 0xED => 'APP13', 0751 0xEE => 'APP14', 0752 0xEF => 'APP15', 0753 0xF0 => 'JPG0', 0754 0xF1 => 'JPG1', 0755 0xF2 => 'JPG2', 0756 0xF3 => 'JPG3', 0757 0xF4 => 'JPG4', 0758 0xF5 => 'JPG5', 0759 0xF6 => 'JPG6', 0760 0xF7 => 'JPG7', 0761 0xF8 => 'JPG8', 0762 0xF9 => 'JPG9', 0763 0xFA => 'JPG10', 0764 0xFB => 'JPG11', 0765 0xFC => 'JPG12', 0766 0xFD => 'JPG13', 0767 0xFE => 'COM', 0768 );