4d1bd33ce4333ddefb4568e2e420b01a9e37106b
[yaffs-website] / lsolesen / pel / src / PelJpegMarker.php
1 <?php
2
3 /*
4  * PEL: PHP Exif Library.
5  * A library with support for reading and
6  * writing all Exif headers in JPEG and TIFF images using PHP.
7  *
8  * Copyright (C) 2004, 2006 Martin Geisler.
9  * Copyright (C) 2017 Johannes Weberhofer.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program in the file COPYING; if not, write to the
23  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
24  * Boston, MA 02110-1301 USA
25  */
26 namespace lsolesen\pel;
27
28 /**
29  * Classes for dealing with JPEG markers.
30  *
31  * This class defines the constants to be used whenever one refers to
32  * a JPEG marker. All the methods defined are static, and they all
33  * operate on one argument which should be one of the class constants.
34  * They will all be denoted by PelJpegMarker in the documentation.
35  *
36  * @author Martin Geisler <mgeisler@users.sourceforge.net>
37  * @author Johannes Weberhofer <jweberhofer@weberhofer.at>
38  *
39  * @license http://www.gnu.org/licenses/gpl.html GNU General Public
40  *          License (GPL)
41  * @package PEL
42  */
43 class PelJpegMarker
44 {
45
46     /**
47      * Encoding (baseline)
48      */
49     const SOF0 = 0xC0;
50
51     /**
52      * Encoding (extended sequential)
53      */
54     const SOF1 = 0xC1;
55
56     /**
57      * Encoding (progressive)
58      */
59     const SOF2 = 0xC2;
60
61     /**
62      * Encoding (lossless)
63      */
64     const SOF3 = 0xC3;
65
66     /**
67      * Define Huffman table
68      */
69     const DHT = 0xC4;
70
71     /**
72      * Encoding (differential sequential)
73      */
74     const SOF5 = 0xC5;
75
76     /**
77      * Encoding (differential progressive)
78      */
79     const SOF6 = 0xC6;
80
81     /**
82      * Encoding (differential lossless)
83      */
84     const SOF7 = 0xC7;
85
86     /**
87      * Extension
88      */
89     const JPG = 0xC8;
90
91     /**
92      * Encoding (extended sequential, arithmetic)
93      */
94     const SOF9 = 0xC9;
95
96     /**
97      * Encoding (progressive, arithmetic)
98      */
99     const SOF10 = 0xCA;
100
101     /**
102      * Encoding (lossless, arithmetic)
103      */
104     const SOF11 = 0xCB;
105
106     /**
107      * Define arithmetic coding conditioning
108      */
109     const DAC = 0xCC;
110
111     /**
112      * Encoding (differential sequential, arithmetic)
113      */
114     const SOF13 = 0xCD;
115
116     /**
117      * Encoding (differential progressive, arithmetic)
118      */
119     const SOF14 = 0xCE;
120
121     /**
122      * Encoding (differential lossless, arithmetic)
123      */
124     const SOF15 = 0xCF;
125
126     /**
127      * Restart 0
128      */
129     const RST0 = 0xD0;
130
131     /**
132      * Restart 1
133      */
134     const RST1 = 0xD1;
135
136     /**
137      * Restart 2
138      */
139     const RST2 = 0xD2;
140
141     /**
142      * Restart 3
143      */
144     const RST3 = 0xD3;
145
146     /**
147      * Restart 4
148      */
149     const RST4 = 0xD4;
150
151     /**
152      * Restart 5
153      */
154     const RST5 = 0xD5;
155
156     /**
157      * Restart 6
158      */
159     const RST6 = 0xD6;
160
161     /**
162      * Restart 7
163      */
164     const RST7 = 0xD7;
165
166     /**
167      * Start of image
168      */
169     const SOI = 0xD8;
170
171     /**
172      * End of image
173      */
174     const EOI = 0xD9;
175
176     /**
177      * Start of scan
178      */
179     const SOS = 0xDA;
180
181     /**
182      * Define quantization table
183      */
184     const DQT = 0xDB;
185
186     /**
187      * Define number of lines
188      */
189     const DNL = 0xDC;
190
191     /**
192      * Define restart interval
193      */
194     const DRI = 0xDD;
195
196     /**
197      * Define hierarchical progression
198      */
199     const DHP = 0xDE;
200
201     /**
202      * Expand reference component
203      */
204     const EXP = 0xDF;
205
206     /**
207      * Application segment 0
208      */
209     const APP0 = 0xE0;
210
211     /**
212      * Application segment 1
213      *
214      * When a JPEG image contains Exif data, the data will normally be
215      * stored in this section and a call to {@link PelJpeg::getExif()}
216      * will return a {@link PelExif} object representing it.
217      */
218     const APP1 = 0xE1;
219
220     /**
221      * Application segment 2
222      */
223     const APP2 = 0xE2;
224
225     /**
226      * Application segment 3
227      */
228     const APP3 = 0xE3;
229
230     /**
231      * Application segment 4
232      */
233     const APP4 = 0xE4;
234
235     /**
236      * Application segment 5
237      */
238     const APP5 = 0xE5;
239
240     /**
241      * Application segment 6
242      */
243     const APP6 = 0xE6;
244
245     /**
246      * Application segment 7
247      */
248     const APP7 = 0xE7;
249
250     /**
251      * Application segment 8
252      */
253     const APP8 = 0xE8;
254
255     /**
256      * Application segment 9
257      */
258     const APP9 = 0xE9;
259
260     /**
261      * Application segment 10
262      */
263     const APP10 = 0xEA;
264
265     /**
266      * Application segment 11
267      */
268     const APP11 = 0xEB;
269
270     /**
271      * Application segment 12
272      */
273     const APP12 = 0xEC;
274
275     /**
276      * Application segment 13
277      */
278     const APP13 = 0xED;
279
280     /**
281      * Application segment 14
282      */
283     const APP14 = 0xEE;
284
285     /**
286      * Application segment 15
287      */
288     const APP15 = 0xEF;
289
290     /**
291      * Extension 0
292      */
293     const JPG0 = 0xF0;
294
295     /**
296      * Extension 1
297      */
298     const JPG1 = 0xF1;
299
300     /**
301      * Extension 2
302      */
303     const JPG2 = 0xF2;
304
305     /**
306      * Extension 3
307      */
308     const JPG3 = 0xF3;
309
310     /**
311      * Extension 4
312      */
313     const JPG4 = 0xF4;
314
315     /**
316      * Extension 5
317      */
318     const JPG5 = 0xF5;
319
320     /**
321      * Extension 6
322      */
323     const JPG6 = 0xF6;
324
325     /**
326      * Extension 7
327      */
328     const JPG7 = 0xF7;
329
330     /**
331      * Extension 8
332      */
333     const JPG8 = 0xF8;
334
335     /**
336      * Extension 9
337      */
338     const JPG9 = 0xF9;
339
340     /**
341      * Extension 10
342      */
343     const JPG10 = 0xFA;
344
345     /**
346      * Extension 11
347      */
348     const JPG11 = 0xFB;
349
350     /**
351      * Extension 12
352      */
353     const JPG12 = 0xFC;
354
355     /**
356      * Extension 13
357      */
358     const JPG13 = 0xFD;
359
360     /**
361      * Comment
362      */
363     const COM = 0xFE;
364
365     /**
366      * Values for marker's short names
367      */
368     protected static $jpegMarkerShort = array(
369         self::SOF0 => 'SOF0',
370         self::SOF1 => 'SOF1',
371         self::SOF2 => 'SOF2',
372         self::SOF3 => 'SOF3',
373         self::SOF5 => 'SOF5',
374         self::SOF6 => 'SOF6',
375         self::SOF7 => 'SOF7',
376         self::SOF9 => 'SOF9',
377         self::SOF10 => 'SOF10',
378         self::SOF11 => 'SOF11',
379         self::SOF13 => 'SOF13',
380         self::SOF14 => 'SOF14',
381         self::SOF15 => 'SOF15',
382         self::SOI => 'SOI',
383         self::EOI => 'EOI',
384         self::SOS => 'SOS',
385         self::COM => 'COM',
386         self::DHT => 'DHT',
387         self::JPG => 'JPG',
388         self::DAC => 'DAC',
389         self::RST0 => 'RST0',
390         self::RST1 => 'RST1',
391         self::RST2 => 'RST2',
392         self::RST3 => 'RST3',
393         self::RST4 => 'RST4',
394         self::RST5 => 'RST5',
395         self::RST6 => 'RST6',
396         self::RST7 => 'RST7',
397         self::DQT => 'DQT',
398         self::DNL => 'DNL',
399         self::DRI => 'DRI',
400         self::DHP => 'DHP',
401         self::EXP => 'EXP',
402         self::APP0 => 'APP0',
403         self::APP1 => 'APP1',
404         self::APP2 => 'APP2',
405         self::APP3 => 'APP3',
406         self::APP4 => 'APP4',
407         self::APP5 => 'APP5',
408         self::APP6 => 'APP6',
409         self::APP7 => 'APP7',
410         self::APP8 => 'APP8',
411         self::APP9 => 'APP9',
412         self::APP10 => 'APP10',
413         self::APP11 => 'APP11',
414         self::APP12 => 'APP12',
415         self::APP13 => 'APP13',
416         self::APP14 => 'APP14',
417         self::APP15 => 'APP15',
418         self::JPG0 => 'JPG0',
419         self::JPG1 => 'JPG1',
420         self::JPG2 => 'JPG2',
421         self::JPG3 => 'JPG3',
422         self::JPG4 => 'JPG4',
423         self::JPG5 => 'JPG5',
424         self::JPG6 => 'JPG6',
425         self::JPG7 => 'JPG7',
426         self::JPG8 => 'JPG8',
427         self::JPG9 => 'JPG9',
428         self::JPG10 => 'JPG10',
429         self::JPG11 => 'JPG11',
430         self::JPG12 => 'JPG12',
431         self::JPG13 => 'JPG13',
432         self::COM => 'COM'
433     );
434
435     /**
436      * Values for marker's descriptions names.
437      */
438     protected static $jpegMarkerDescriptions = array(
439         self::SOF0 => 'Encoding (baseline)',
440         self::SOF1 => 'Encoding (extended sequential)',
441         self::SOF2 => 'Encoding (progressive)',
442         self::SOF3 => 'Encoding (lossless)',
443         self::SOF5 => 'Encoding (differential sequential)',
444         self::SOF6 => 'Encoding (differential progressive)',
445         self::SOF7 => 'Encoding (differential lossless)',
446         self::SOF9 => 'Encoding (extended sequential, arithmetic)',
447         self::SOF10 => 'Encoding (progressive, arithmetic)',
448         self::SOF11 => 'Encoding (lossless, arithmetic)',
449         self::SOF13 => 'Encoding (differential sequential, arithmetic)',
450         self::SOF14 => 'Encoding (differential progressive, arithmetic)',
451         self::SOF15 => 'Encoding (differential lossless, arithmetic)',
452         self::SOI => 'Start of image',
453         self::EOI => 'End of image',
454         self::SOS => 'Start of scan',
455         self::COM => 'Comment',
456         self::DHT => 'Define Huffman table',
457         self::JPG => 'Extension',
458         self::DAC => 'Define arithmetic coding conditioning',
459         'RST' => 'Restart %d',
460         self::DQT => 'Define quantization table',
461         self::DNL => 'Define number of lines',
462         self::DRI => 'Define restart interval',
463         self::DHP => 'Define hierarchical progression',
464         self::EXP => 'Expand reference component',
465         'APP' => 'Application segment %d',
466         'JPG' => 'Extension %d',
467         self::COM => 'Comment'
468     );
469
470     /**
471      * Check if a byte is a valid JPEG marker.
472      * If the byte is recognized true is returned, otherwise false will be returned.
473      *
474      * @param integer $marker
475      *            the marker as defined in {@link PelJpegMarker}
476      *
477      * @return boolean
478      */
479     public static function isValid($marker)
480     {
481         return ($marker >= self::SOF0 && $marker <= self::COM);
482     }
483
484     /**
485      * Turn a JPEG marker into bytes.
486      * This will be a string with just a single byte since all JPEG markers are simply single bytes.
487      *
488      * @param integer $marker
489      *            the marker as defined in {@link PelJpegMarker}
490      *
491      * @return string
492      */
493     public static function getBytes($marker)
494     {
495         return chr($marker);
496     }
497
498     /**
499      * Return the short name for a marker, e.g., 'SOI' for the Start
500      * of Image marker.
501      *
502      * @param integer $marker
503      *            the marker as defined in {@link PelJpegMarker}
504      *
505      * @return string
506      */
507     public static function getName($marker)
508     {
509         if (array_key_exists($marker, self::$jpegMarkerShort)) {
510             return self::$jpegMarkerShort[$marker];
511         } else {
512             return Pel::fmt('Unknown marker: 0x%02X', $marker);
513         }
514     }
515
516     /**
517      * Returns a description of a JPEG marker.
518      *
519      * @param integer $marker
520      *            the marker as defined in {@link PelJpegMarker}
521      *
522      * @return string
523      */
524     public static function getDescription($marker)
525     {
526         if (array_key_exists($marker, self::$jpegMarkerShort)) {
527             if (array_key_exists($marker, self::$jpegMarkerDescriptions)) {
528                 return self::$jpegMarkerDescriptions[$marker];
529             } else {
530                 $splitted = preg_split(
531                     "/(\d+)/",
532                     self::$jpegMarkerShort[$marker],
533                     - 1,
534                     PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
535                 if ((count($splitted) == 2) && array_key_exists($splitted[0], self::$jpegMarkerDescriptions)) {
536                     return Pel::fmt(self::$jpegMarkerDescriptions[$splitted[0]], $splitted[1]);
537                 }
538             }
539         }
540         return Pel::fmt('Unknown marker: 0x%02X', $marker);
541     }
542 }