source: branches/MootoolsFileManager-Update/plugins/MootoolsFileManager/mootools-filemanager/Assets/Connector/Assets/getid3/module.tag.xmp.php @ 1300

Last change on this file since 1300 was 1300, checked in by gogo, 8 years ago

Update the MootoolsFileManager? to the latest cpojer with some modifications.
Add a demo for the MFM examples/mootools-file-manager.php
Change the default config for ImageManager? and ExtendedFileManager? for added security.

File size: 19.7 KB
Line 
1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at http://getid3.sourceforge.net                 //
5//            or http://www.getid3.org                         //
6/////////////////////////////////////////////////////////////////
7// See readme.txt for more details                             //
8/////////////////////////////////////////////////////////////////
9//                                                             //
10// module.tag.xmp.php                                          //
11// module for analyzing XMP metadata (e.g. in JPEG files)      //
12// dependencies: NONE                                          //
13//                                                             //
14/////////////////////////////////////////////////////////////////
15//                                                             //
16// Module originally written [2009-Mar-26] by                  //
17//      Nigel Barnes <ngbarnesØhotmail*com>                    //
18// Bundled into getID3 with permission                         //
19//   called by getID3 in module.graphic.jpg.php                //
20//                                                            ///
21/////////////////////////////////////////////////////////////////
22
23/**************************************************************************************************
24 * SWISScenter Source                                                              Nigel Barnes
25 *
26 *      Provides functions for reading information from the 'APP1' Extensible Metadata
27 *      Platform (XMP) segment of JPEG format files.
28 *      This XMP segment is XML based and contains the Resource Description Framework (RDF)
29 *      data, which itself can contain the Dublin Core Metadata Initiative (DCMI) information.
30 *
31 *      This code uses segments from the JPEG Metadata Toolkit project by Evan Hunter.
32 *************************************************************************************************/
33class Image_XMP
34{
35        /**
36        * @var string
37        * The name of the image file that contains the XMP fields to extract and modify.
38        * @see Image_XMP()
39        */
40        var $_sFilename = null;
41
42        /**
43        * @var array
44        * The XMP fields that were extracted from the image or updated by this class.
45        * @see getAllTags()
46        */
47        var $_aXMP = array();
48
49        /**
50        * @var boolean
51        * True if an APP1 segment was found to contain XMP metadata.
52        * @see isValid()
53        */
54        var $_bXMPParse = false;
55
56        /**
57        * Returns the status of XMP parsing during instantiation
58        *
59        * You'll normally want to call this method before trying to get XMP fields.
60        *
61        * @return boolean
62        * Returns true if an APP1 segment was found to contain XMP metadata.
63        */
64        function isValid()
65        {
66                return $this->_bXMPParse;
67        }
68
69        /**
70        * Get a copy of all XMP tags extracted from the image
71        *
72        * @return array - An array of XMP fields as it extracted by the XMPparse() function
73        */
74        function getAllTags()
75        {
76                return $this->_aXMP;
77        }
78
79        /**
80        * Reads all the JPEG header segments from an JPEG image file into an array
81        *
82        * @param string $filename - the filename of the JPEG file to read
83        * @return array $headerdata - Array of JPEG header segments
84        * @return boolean FALSE - if headers could not be read
85        */
86        function _get_jpeg_header_data($filename)
87        {
88                // prevent refresh from aborting file operations and hosing file
89                ignore_user_abort(true);
90
91                // Attempt to open the jpeg file - the at symbol supresses the error message about
92                // not being able to open files. The file_exists would have been used, but it
93                // does not work with files fetched over http or ftp.
94                ob_start();
95                $filehnd = fopen($filename, 'rb');
96                $errormessage = ob_get_contents();
97                ob_end_clean();
98
99                // Check if the file opened successfully
100                if (!$filehnd)
101                {
102                        // Could't open the file - exit
103                        echo '<p>Could not open file '.htmlentities($filename).'</p>'."\n";
104                        return false;
105                }
106
107                // Read the first two characters
108                $data = fread($filehnd, 2);
109
110                // Check that the first two characters are 0xFF 0xD8  (SOI - Start of image)
111                if ($data != "\xFF\xD8")
112                {
113                        // No SOI (FF D8) at start of file - This probably isn't a JPEG file - close file and return;
114                        echo '<p>This probably is not a JPEG file</p>'."\n";
115                        fclose($filehnd);
116                        return false;
117                }
118
119                // Read the third character
120                $data = fread($filehnd, 2);
121
122                // Check that the third character is 0xFF (Start of first segment header)
123                if ($data{0} != "\xFF")
124                {
125                        // NO FF found - close file and return - JPEG is probably corrupted
126                        fclose($filehnd);
127                        return false;
128                }
129
130                // Flag that we havent yet hit the compressed image data
131                $hit_compressed_image_data = false;
132
133                // Cycle through the file until, one of: 1) an EOI (End of image) marker is hit,
134                //                                       2) we have hit the compressed image data (no more headers are allowed after data)
135                //                                       3) or end of file is hit
136
137                while (($data{1} != "\xD9") && (!$hit_compressed_image_data) && (!feof($filehnd)))
138                {
139                        // Found a segment to look at.
140                        // Check that the segment marker is not a Restart marker - restart markers don't have size or data after them
141                        if ((ord($data{1}) < 0xD0) || (ord($data{1}) > 0xD7))
142                        {
143                                // Segment isn't a Restart marker
144                                // Read the next two bytes (size)
145                                $sizestr = fread($filehnd, 2);
146
147                                // convert the size bytes to an integer
148                                $decodedsize = unpack('nsize', $sizestr);
149
150                                // Save the start position of the data
151                                $segdatastart = ftell($filehnd);
152
153                                // Read the segment data with length indicated by the previously read size
154                                $segdata = fread($filehnd, $decodedsize['size'] - 2);
155
156                                // Store the segment information in the output array
157                                $headerdata[] = array(
158                                        'SegType'      => ord($data{1}),
159                                        'SegName'      => $GLOBALS['JPEG_Segment_Names'][ord($data{1})],
160                                        'SegDataStart' => $segdatastart,
161                                        'SegData'      => $segdata,
162                                );
163                        }
164
165                        // If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows
166                        if ($data{1} == "\xDA")
167                        {
168                                // Flag that we have hit the compressed image data - exit loop as no more headers available.
169                                $hit_compressed_image_data = true;
170                        }
171                        else
172                        {
173                                // Not an SOS - Read the next two bytes - should be the segment marker for the next segment
174                                $data = fread($filehnd, 2);
175
176                                // Check that the first byte of the two is 0xFF as it should be for a marker
177                                if ($data{0} != "\xFF")
178                                {
179                                        // NO FF found - close file and return - JPEG is probably corrupted
180                                        fclose($filehnd);
181                                        return false;
182                                }
183                        }
184                }
185
186                // Close File
187                fclose($filehnd);
188                // Alow the user to abort from now on
189                ignore_user_abort(false);
190
191                // Return the header data retrieved
192                return $headerdata;
193        }
194
195
196        /**
197        * Retrieves XMP information from an APP1 JPEG segment and returns the raw XML text as a string.
198        *
199        * @param string $filename - the filename of the JPEG file to read
200        * @return string $xmp_data - the string of raw XML text
201        * @return boolean FALSE - if an APP 1 XMP segment could not be found, or if an error occured
202        */
203        function _get_XMP_text($filename)
204        {
205                //Get JPEG header data
206                $jpeg_header_data = $this->_get_jpeg_header_data($filename);
207
208                //Cycle through the header segments
209                for ($i = 0; $i < count($jpeg_header_data); $i++)
210                {
211                        // If we find an APP1 header,
212                        if (strcmp($jpeg_header_data[$i]['SegName'], 'APP1') == 0)
213                        {
214                                // And if it has the Adobe XMP/RDF label (http://ns.adobe.com/xap/1.0/\x00) ,
215                                if (strncmp($jpeg_header_data[$i]['SegData'], 'http://ns.adobe.com/xap/1.0/'."\x00", 29) == 0)
216                                {
217                                        // Found a XMP/RDF block
218                                        // Return the XMP text
219                                        $xmp_data = substr($jpeg_header_data[$i]['SegData'], 29);
220
221                                        return $xmp_data;
222                                }
223                        }
224                }
225                return false;
226        }
227
228        /**
229        * Parses a string containing XMP data (XML), and returns an array
230        * which contains all the XMP (XML) information.
231        *
232        * @param string $xml_text - a string containing the XMP data (XML) to be parsed
233        * @return array $xmp_array - an array containing all xmp details retrieved.
234        * @return boolean FALSE - couldn't parse the XMP data
235        */
236        function read_XMP_array_from_text($xmltext)
237        {
238                // Check if there actually is any text to parse
239                if (trim($xmltext) == '')
240                {
241                        return false;
242                }
243
244                // Create an instance of a xml parser to parse the XML text
245                $xml_parser = xml_parser_create('UTF-8');
246
247                // 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
248
249                // We would like to remove unneccessary white space, but this will also
250                // remove things like newlines (&#xA;) in the XML values, so white space
251                // will have to be removed later
252                if (xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0) == false)
253                {
254                        // Error setting case folding - destroy the parser and return
255                        xml_parser_free($xml_parser);
256                        return false;
257                }
258
259                // to use XML code correctly we have to turn case folding
260                // (uppercasing) off. XML is case sensitive and upper
261                // casing is in reality XML standards violation
262                if (xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0) == false)
263                {
264                        // Error setting case folding - destroy the parser and return
265                        xml_parser_free($xml_parser);
266                        return false;
267                }
268
269                // Parse the XML text into a array structure
270                if (xml_parse_into_struct($xml_parser, $xmltext, $values, $tags) == 0)
271                {
272                        // Error Parsing XML - destroy the parser and return
273                        xml_parser_free($xml_parser);
274                        return false;
275                }
276
277                // Destroy the xml parser
278                xml_parser_free($xml_parser);
279
280                // Clear the output array
281                $xmp_array = array();
282
283                // The XMP data has now been parsed into an array ...
284
285                // Cycle through each of the array elements
286                $current_property = ''; // current property being processed
287                $container_index = -1; // -1 = no container open, otherwise index of container content
288                foreach ($values as $xml_elem)
289                {
290                        // Syntax and Class names
291                        switch ($xml_elem['tag'])
292                        {
293                                case 'x:xmpmeta':
294                                        // only defined attribute is x:xmptk written by Adobe XMP Toolkit; value is the version of the toolkit
295                                        break;
296
297                                case 'rdf:RDF':
298                                        // required element immediately within x:xmpmeta; no data here
299                                        break;
300
301                                case 'rdf:Description':
302                                        switch ($xml_elem['type'])
303                                        {
304                                                case 'open':
305                                                case 'complete':
306                                                        if (array_key_exists('attributes', $xml_elem))
307                                                        {
308                                                                // rdf:Description may contain wanted attributes
309                                                                foreach (array_keys($xml_elem['attributes']) as $key)
310                                                                {
311                                                                        // Check whether we want this details from this attribute
312                                                                        if (in_array($key, $GLOBALS['XMP_tag_captions']))
313                                                                        {
314                                                                                // Attribute wanted
315                                                                                $xmp_array[$key] = $xml_elem['attributes'][$key];
316                                                                        }
317                                                                }
318                                                        }
319                                                case 'cdata':
320                                                case 'close':
321                                                        break;
322                                        }
323
324                                case 'rdf:ID':
325                                case 'rdf:nodeID':
326                                        // Attributes are ignored
327                                        break;
328
329                                case 'rdf:li':
330                                        // Property member
331                                        if ($xml_elem['type'] == 'complete')
332                                        {
333                                                if (array_key_exists('attributes', $xml_elem))
334                                                {
335                                                        // If Lang Alt (language alternatives) then ensure we take the default language
336                                                        if ($xml_elem['attributes']['xml:lang'] != 'x-default')
337                                                        {
338                                                                break;
339                                                        }
340                                                }
341                                                if ($current_property != '')
342                                                {
343                                                        $xmp_array[$current_property][$container_index] = $xml_elem['value'];
344                                                        $container_index += 1;
345                                                }
346                                        //else unidentified attribute!!
347                                        }
348                                        break;
349
350                                case 'rdf:Seq':
351                                case 'rdf:Bag':
352                                case 'rdf:Alt':
353                                        // Container found
354                                        switch ($xml_elem['type'])
355                                        {
356                                                case 'open':
357                                                        $container_index = 0;
358                                                        break;
359                                                case 'close':
360                                                        $container_index = -1;
361                                                        break;
362                                                case 'cdata':
363                                                        break;
364                                        }
365                                        break;
366
367                                default:
368                                        // Check whether we want the details from this attribute
369                                        if (in_array($xml_elem['tag'], $GLOBALS['XMP_tag_captions']))
370                                        {
371                                                switch ($xml_elem['type'])
372                                                {
373                                                        case 'open':
374                                                                // open current element
375                                                                $current_property = $xml_elem['tag'];
376                                                                break;
377
378                                                        case 'close':
379                                                                // close current element
380                                                                $current_property = '';
381                                                                break;
382
383                                                        case 'complete':
384                                                                // store attribute value
385                                                                $xmp_array[$xml_elem['tag']] = (isset($xml_elem['value']) ? $xml_elem['value'] : '');
386                                                                break;
387
388                                                        case 'cdata':
389                                                                // ignore
390                                                                break;
391                                                }
392                                        }
393                                        break;
394                        }
395
396                }
397                return $xmp_array;
398        }
399
400
401        /**
402        * Constructor
403        *
404        * @param string - Name of the image file to access and extract XMP information from.
405        */
406        function Image_XMP($sFilename)
407        {
408                $this->_sFilename = $sFilename;
409
410                if (is_file($this->_sFilename))
411                {
412                        // Get XMP data
413                        $xmp_data = $this->_get_XMP_text($sFilename);
414                        if ($xmp_data)
415                        {
416                                $this->_aXMP = $this->read_XMP_array_from_text($xmp_data);
417                                $this->_bXMPParse = true;
418                        }
419                }
420        }
421
422}
423
424/**
425* Global Variable: XMP_tag_captions
426*
427* The Property names of all known XMP fields.
428* Note: this is a full list with unrequired properties commented out.
429*/
430$GLOBALS['XMP_tag_captions'] = array(
431// IPTC Core
432        'Iptc4xmpCore:CiAdrCity',
433        'Iptc4xmpCore:CiAdrCtry',
434        'Iptc4xmpCore:CiAdrExtadr',
435        'Iptc4xmpCore:CiAdrPcode',
436        'Iptc4xmpCore:CiAdrRegion',
437        'Iptc4xmpCore:CiEmailWork',
438        'Iptc4xmpCore:CiTelWork',
439        'Iptc4xmpCore:CiUrlWork',
440        'Iptc4xmpCore:CountryCode',
441        'Iptc4xmpCore:CreatorContactInfo',
442        'Iptc4xmpCore:IntellectualGenre',
443        'Iptc4xmpCore:Location',
444        'Iptc4xmpCore:Scene',
445        'Iptc4xmpCore:SubjectCode',
446// Dublin Core Schema
447        'dc:contributor',
448        'dc:coverage',
449        'dc:creator',
450        'dc:date',
451        'dc:description',
452        'dc:format',
453        'dc:identifier',
454        'dc:language',
455        'dc:publisher',
456        'dc:relation',
457        'dc:rights',
458        'dc:source',
459        'dc:subject',
460        'dc:title',
461        'dc:type',
462// XMP Basic Schema
463        'xmp:Advisory',
464        'xmp:BaseURL',
465        'xmp:CreateDate',
466        'xmp:CreatorTool',
467        'xmp:Identifier',
468        'xmp:Label',
469        'xmp:MetadataDate',
470        'xmp:ModifyDate',
471        'xmp:Nickname',
472        'xmp:Rating',
473        'xmp:Thumbnails',
474        'xmpidq:Scheme',
475// XMP Rights Management Schema
476        'xmpRights:Certificate',
477        'xmpRights:Marked',
478        'xmpRights:Owner',
479        'xmpRights:UsageTerms',
480        'xmpRights:WebStatement',
481// These are not in spec but Photoshop CS seems to use them
482        'xap:Advisory',
483        'xap:BaseURL',
484        'xap:CreateDate',
485        'xap:CreatorTool',
486        'xap:Identifier',
487        'xap:MetadataDate',
488        'xap:ModifyDate',
489        'xap:Nickname',
490        'xap:Rating',
491        'xap:Thumbnails',
492        'xapidq:Scheme',
493        'xapRights:Certificate',
494        'xapRights:Copyright',
495        'xapRights:Marked',
496        'xapRights:Owner',
497        'xapRights:UsageTerms',
498        'xapRights:WebStatement',
499// XMP Media Management Schema
500        'xapMM:DerivedFrom',
501        'xapMM:DocumentID',
502        'xapMM:History',
503        'xapMM:InstanceID',
504        'xapMM:ManagedFrom',
505        'xapMM:Manager',
506        'xapMM:ManageTo',
507        'xapMM:ManageUI',
508        'xapMM:ManagerVariant',
509        'xapMM:RenditionClass',
510        'xapMM:RenditionParams',
511        'xapMM:VersionID',
512        'xapMM:Versions',
513        'xapMM:LastURL',
514        'xapMM:RenditionOf',
515        'xapMM:SaveID',
516// XMP Basic Job Ticket Schema
517        'xapBJ:JobRef',
518// XMP Paged-Text Schema
519        'xmpTPg:MaxPageSize',
520        'xmpTPg:NPages',
521        'xmpTPg:Fonts',
522        'xmpTPg:Colorants',
523        'xmpTPg:PlateNames',
524// Adobe PDF Schema
525        'pdf:Keywords',
526        'pdf:PDFVersion',
527        'pdf:Producer',
528// Photoshop Schema
529        'photoshop:AuthorsPosition',
530        'photoshop:CaptionWriter',
531        'photoshop:Category',
532        'photoshop:City',
533        'photoshop:Country',
534        'photoshop:Credit',
535        'photoshop:DateCreated',
536        'photoshop:Headline',
537        'photoshop:History',
538// Not in XMP spec
539        'photoshop:Instructions',
540        'photoshop:Source',
541        'photoshop:State',
542        'photoshop:SupplementalCategories',
543        'photoshop:TransmissionReference',
544        'photoshop:Urgency',
545// EXIF Schemas
546        'tiff:ImageWidth',
547        'tiff:ImageLength',
548        'tiff:BitsPerSample',
549        'tiff:Compression',
550        'tiff:PhotometricInterpretation',
551        'tiff:Orientation',
552        'tiff:SamplesPerPixel',
553        'tiff:PlanarConfiguration',
554        'tiff:YCbCrSubSampling',
555        'tiff:YCbCrPositioning',
556        'tiff:XResolution',
557        'tiff:YResolution',
558        'tiff:ResolutionUnit',
559        'tiff:TransferFunction',
560        'tiff:WhitePoint',
561        'tiff:PrimaryChromaticities',
562        'tiff:YCbCrCoefficients',
563        'tiff:ReferenceBlackWhite',
564        'tiff:DateTime',
565        'tiff:ImageDescription',
566        'tiff:Make',
567        'tiff:Model',
568        'tiff:Software',
569        'tiff:Artist',
570        'tiff:Copyright',
571        'exif:ExifVersion',
572        'exif:FlashpixVersion',
573        'exif:ColorSpace',
574        'exif:ComponentsConfiguration',
575        'exif:CompressedBitsPerPixel',
576        'exif:PixelXDimension',
577        'exif:PixelYDimension',
578        'exif:MakerNote',
579        'exif:UserComment',
580        'exif:RelatedSoundFile',
581        'exif:DateTimeOriginal',
582        'exif:DateTimeDigitized',
583        'exif:ExposureTime',
584        'exif:FNumber',
585        'exif:ExposureProgram',
586        'exif:SpectralSensitivity',
587        'exif:ISOSpeedRatings',
588        'exif:OECF',
589        'exif:ShutterSpeedValue',
590        'exif:ApertureValue',
591        'exif:BrightnessValue',
592        'exif:ExposureBiasValue',
593        'exif:MaxApertureValue',
594        'exif:SubjectDistance',
595        'exif:MeteringMode',
596        'exif:LightSource',
597        'exif:Flash',
598        'exif:FocalLength',
599        'exif:SubjectArea',
600        'exif:FlashEnergy',
601        'exif:SpatialFrequencyResponse',
602        'exif:FocalPlaneXResolution',
603        'exif:FocalPlaneYResolution',
604        'exif:FocalPlaneResolutionUnit',
605        'exif:SubjectLocation',
606        'exif:SensingMethod',
607        'exif:FileSource',
608        'exif:SceneType',
609        'exif:CFAPattern',
610        'exif:CustomRendered',
611        'exif:ExposureMode',
612        'exif:WhiteBalance',
613        'exif:DigitalZoomRatio',
614        'exif:FocalLengthIn35mmFilm',
615        'exif:SceneCaptureType',
616        'exif:GainControl',
617        'exif:Contrast',
618        'exif:Saturation',
619        'exif:Sharpness',
620        'exif:DeviceSettingDescription',
621        'exif:SubjectDistanceRange',
622        'exif:ImageUniqueID',
623        'exif:GPSVersionID',
624        'exif:GPSLatitude',
625        'exif:GPSLongitude',
626        'exif:GPSAltitudeRef',
627        'exif:GPSAltitude',
628        'exif:GPSTimeStamp',
629        'exif:GPSSatellites',
630        'exif:GPSStatus',
631        'exif:GPSMeasureMode',
632        'exif:GPSDOP',
633        'exif:GPSSpeedRef',
634        'exif:GPSSpeed',
635        'exif:GPSTrackRef',
636        'exif:GPSTrack',
637        'exif:GPSImgDirectionRef',
638        'exif:GPSImgDirection',
639        'exif:GPSMapDatum',
640        'exif:GPSDestLatitude',
641        'exif:GPSDestLongitude',
642        'exif:GPSDestBearingRef',
643        'exif:GPSDestBearing',
644        'exif:GPSDestDistanceRef',
645        'exif:GPSDestDistance',
646        'exif:GPSProcessingMethod',
647        'exif:GPSAreaInformation',
648        'exif:GPSDifferential',
649        'stDim:w',
650        'stDim:h',
651        'stDim:unit',
652        'xapGImg:height',
653        'xapGImg:width',
654        'xapGImg:format',
655        'xapGImg:image',
656        'stEvt:action',
657        'stEvt:instanceID',
658        'stEvt:parameters',
659        'stEvt:softwareAgent',
660        'stEvt:when',
661        'stRef:instanceID',
662        'stRef:documentID',
663        'stRef:versionID',
664        'stRef:renditionClass',
665        'stRef:renditionParams',
666        'stRef:manager',
667        'stRef:managerVariant',
668        'stRef:manageTo',
669        'stRef:manageUI',
670        'stVer:comments',
671        'stVer:event',
672        'stVer:modifyDate',
673        'stVer:modifier',
674        'stVer:version',
675        'stJob:name',
676        'stJob:id',
677        'stJob:url',
678// Exif Flash
679        'exif:Fired',
680        'exif:Return',
681        'exif:Mode',
682        'exif:Function',
683        'exif:RedEyeMode',
684// Exif OECF/SFR
685        'exif:Columns',
686        'exif:Rows',
687        'exif:Names',
688        'exif:Values',
689// Exif CFAPattern
690        'exif:Columns',
691        'exif:Rows',
692        'exif:Values',
693// Exif DeviceSettings
694        'exif:Columns',
695        'exif:Rows',
696        'exif:Settings',
697);
698
699
700/**
701* Global Variable: JPEG_Segment_Names
702*
703* The names of the JPEG segment markers, indexed by their marker number
704*/
705$GLOBALS['JPEG_Segment_Names'] = array(
706        0x01 => 'TEM',
707        0x02 => 'RES',
708        0xC0 => 'SOF0',
709        0xC1 => 'SOF1',
710        0xC2 => 'SOF2',
711        0xC3 => 'SOF4',
712        0xC4 => 'DHT',
713        0xC5 => 'SOF5',
714        0xC6 => 'SOF6',
715        0xC7 => 'SOF7',
716        0xC8 => 'JPG',
717        0xC9 => 'SOF9',
718        0xCA => 'SOF10',
719        0xCB => 'SOF11',
720        0xCC => 'DAC',
721        0xCD => 'SOF13',
722        0xCE => 'SOF14',
723        0xCF => 'SOF15',
724        0xD0 => 'RST0',
725        0xD1 => 'RST1',
726        0xD2 => 'RST2',
727        0xD3 => 'RST3',
728        0xD4 => 'RST4',
729        0xD5 => 'RST5',
730        0xD6 => 'RST6',
731        0xD7 => 'RST7',
732        0xD8 => 'SOI',
733        0xD9 => 'EOI',
734        0xDA => 'SOS',
735        0xDB => 'DQT',
736        0xDC => 'DNL',
737        0xDD => 'DRI',
738        0xDE => 'DHP',
739        0xDF => 'EXP',
740        0xE0 => 'APP0',
741        0xE1 => 'APP1',
742        0xE2 => 'APP2',
743        0xE3 => 'APP3',
744        0xE4 => 'APP4',
745        0xE5 => 'APP5',
746        0xE6 => 'APP6',
747        0xE7 => 'APP7',
748        0xE8 => 'APP8',
749        0xE9 => 'APP9',
750        0xEA => 'APP10',
751        0xEB => 'APP11',
752        0xEC => 'APP12',
753        0xED => 'APP13',
754        0xEE => 'APP14',
755        0xEF => 'APP15',
756        0xF0 => 'JPG0',
757        0xF1 => 'JPG1',
758        0xF2 => 'JPG2',
759        0xF3 => 'JPG3',
760        0xF4 => 'JPG4',
761        0xF5 => 'JPG5',
762        0xF6 => 'JPG6',
763        0xF7 => 'JPG7',
764        0xF8 => 'JPG8',
765        0xF9 => 'JPG9',
766        0xFA => 'JPG10',
767        0xFB => 'JPG11',
768        0xFC => 'JPG12',
769        0xFD => 'JPG13',
770        0xFE => 'COM',
771);
772
773?>
Note: See TracBrowser for help on using the repository browser.