Initial commit.
[pdfium.git] / core / src / fxcodec / libjpeg / fpdfapi_jdmarker.c
1 #if !defined(_FX_JPEG_TURBO_)\r
2 /*\r
3  * jdmarker.c\r
4  *\r
5  * Copyright (C) 1991-1998, Thomas G. Lane.\r
6  * This file is part of the Independent JPEG Group's software.\r
7  * For conditions of distribution and use, see the accompanying README file.\r
8  *\r
9  * This file contains routines to decode JPEG datastream markers.\r
10  * Most of the complexity arises from our desire to support input\r
11  * suspension: if not all of the data for a marker is available,\r
12  * we must exit back to the application.  On resumption, we reprocess\r
13  * the marker.\r
14  */\r
15 \r
16 #define JPEG_INTERNALS\r
17 #include "jinclude.h"\r
18 #include "jpeglib.h"\r
19 \r
20 \r
21 typedef enum {                  /* JPEG marker codes */\r
22   M_SOF0  = 0xc0,\r
23   M_SOF1  = 0xc1,\r
24   M_SOF2  = 0xc2,\r
25   M_SOF3  = 0xc3,\r
26   \r
27   M_SOF5  = 0xc5,\r
28   M_SOF6  = 0xc6,\r
29   M_SOF7  = 0xc7,\r
30   \r
31   M_JPG   = 0xc8,\r
32   M_SOF9  = 0xc9,\r
33   M_SOF10 = 0xca,\r
34   M_SOF11 = 0xcb,\r
35   \r
36   M_SOF13 = 0xcd,\r
37   M_SOF14 = 0xce,\r
38   M_SOF15 = 0xcf,\r
39   \r
40   M_DHT   = 0xc4,\r
41   \r
42   M_DAC   = 0xcc,\r
43   \r
44   M_RST0  = 0xd0,\r
45   M_RST1  = 0xd1,\r
46   M_RST2  = 0xd2,\r
47   M_RST3  = 0xd3,\r
48   M_RST4  = 0xd4,\r
49   M_RST5  = 0xd5,\r
50   M_RST6  = 0xd6,\r
51   M_RST7  = 0xd7,\r
52   \r
53   M_SOI   = 0xd8,\r
54   M_EOI   = 0xd9,\r
55   M_SOS   = 0xda,\r
56   M_DQT   = 0xdb,\r
57   M_DNL   = 0xdc,\r
58   M_DRI   = 0xdd,\r
59   M_DHP   = 0xde,\r
60   M_EXP   = 0xdf,\r
61   \r
62   M_APP0  = 0xe0,\r
63   M_APP1  = 0xe1,\r
64   M_APP2  = 0xe2,\r
65   M_APP3  = 0xe3,\r
66   M_APP4  = 0xe4,\r
67   M_APP5  = 0xe5,\r
68   M_APP6  = 0xe6,\r
69   M_APP7  = 0xe7,\r
70   M_APP8  = 0xe8,\r
71   M_APP9  = 0xe9,\r
72   M_APP10 = 0xea,\r
73   M_APP11 = 0xeb,\r
74   M_APP12 = 0xec,\r
75   M_APP13 = 0xed,\r
76   M_APP14 = 0xee,\r
77   M_APP15 = 0xef,\r
78   \r
79   M_JPG0  = 0xf0,\r
80   M_JPG13 = 0xfd,\r
81   M_COM   = 0xfe,\r
82   \r
83   M_TEM   = 0x01,\r
84   \r
85   M_ERROR = 0x100\r
86 } JPEG_MARKER;\r
87 \r
88 \r
89 /* Private state */\r
90 \r
91 typedef struct {\r
92   struct jpeg_marker_reader pub; /* public fields */\r
93 \r
94   /* Application-overridable marker processing methods */\r
95   jpeg_marker_parser_method process_COM;\r
96   jpeg_marker_parser_method process_APPn[16];\r
97 \r
98   /* Limit on marker data length to save for each marker type */\r
99   unsigned int length_limit_COM;\r
100   unsigned int length_limit_APPn[16];\r
101 \r
102   /* Status of COM/APPn marker saving */\r
103   jpeg_saved_marker_ptr cur_marker;     /* NULL if not processing a marker */\r
104   unsigned int bytes_read;              /* data bytes read so far in marker */\r
105   /* Note: cur_marker is not linked into marker_list until it's all read. */\r
106 } my_marker_reader;\r
107 \r
108 typedef my_marker_reader * my_marker_ptr;\r
109 \r
110 \r
111 /*\r
112  * Macros for fetching data from the data source module.\r
113  *\r
114  * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect\r
115  * the current restart point; we update them only when we have reached a\r
116  * suitable place to restart if a suspension occurs.\r
117  */\r
118 \r
119 /* Declare and initialize local copies of input pointer/count */\r
120 #define INPUT_VARS(cinfo)  \\r
121         struct jpeg_source_mgr * datasrc = (cinfo)->src;  \\r
122         const JOCTET * next_input_byte = datasrc->next_input_byte;  \\r
123         size_t bytes_in_buffer = datasrc->bytes_in_buffer\r
124 \r
125 /* Unload the local copies --- do this only at a restart boundary */\r
126 #define INPUT_SYNC(cinfo)  \\r
127         ( datasrc->next_input_byte = next_input_byte,  \\r
128           datasrc->bytes_in_buffer = bytes_in_buffer )\r
129 \r
130 /* Reload the local copies --- used only in MAKE_BYTE_AVAIL */\r
131 #define INPUT_RELOAD(cinfo)  \\r
132         ( next_input_byte = datasrc->next_input_byte,  \\r
133           bytes_in_buffer = datasrc->bytes_in_buffer )\r
134 \r
135 /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.\r
136  * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,\r
137  * but we must reload the local copies after a successful fill.\r
138  */\r
139 #define MAKE_BYTE_AVAIL(cinfo,action)  \\r
140         if (bytes_in_buffer == 0) {  \\r
141           if (! (*datasrc->fill_input_buffer) (cinfo))  \\r
142             { action; }  \\r
143           INPUT_RELOAD(cinfo);  \\r
144         }\r
145 \r
146 /* Read a byte into variable V.\r
147  * If must suspend, take the specified action (typically "return FALSE").\r
148  */\r
149 #define INPUT_BYTE(cinfo,V,action)  \\r
150         MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \\r
151                   bytes_in_buffer--; \\r
152                   V = GETJOCTET(*next_input_byte++); )\r
153 \r
154 /* As above, but read two bytes interpreted as an unsigned 16-bit integer.\r
155  * V should be declared unsigned int or perhaps INT32.\r
156  */\r
157 #define INPUT_2BYTES(cinfo,V,action)  \\r
158         MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \\r
159                   bytes_in_buffer--; \\r
160                   V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \\r
161                   MAKE_BYTE_AVAIL(cinfo,action); \\r
162                   bytes_in_buffer--; \\r
163                   V += GETJOCTET(*next_input_byte++); )\r
164 \r
165 \r
166 /*\r
167  * Routines to process JPEG markers.\r
168  *\r
169  * Entry condition: JPEG marker itself has been read and its code saved\r
170  *   in cinfo->unread_marker; input restart point is just after the marker.\r
171  *\r
172  * Exit: if return TRUE, have read and processed any parameters, and have\r
173  *   updated the restart point to point after the parameters.\r
174  *   If return FALSE, was forced to suspend before reaching end of\r
175  *   marker parameters; restart point has not been moved.  Same routine\r
176  *   will be called again after application supplies more input data.\r
177  *\r
178  * This approach to suspension assumes that all of a marker's parameters\r
179  * can fit into a single input bufferload.  This should hold for "normal"\r
180  * markers.  Some COM/APPn markers might have large parameter segments\r
181  * that might not fit.  If we are simply dropping such a marker, we use\r
182  * skip_input_data to get past it, and thereby put the problem on the\r
183  * source manager's shoulders.  If we are saving the marker's contents\r
184  * into memory, we use a slightly different convention: when forced to\r
185  * suspend, the marker processor updates the restart point to the end of\r
186  * what it's consumed (ie, the end of the buffer) before returning FALSE.\r
187  * On resumption, cinfo->unread_marker still contains the marker code,\r
188  * but the data source will point to the next chunk of marker data.\r
189  * The marker processor must retain internal state to deal with this.\r
190  *\r
191  * Note that we don't bother to avoid duplicate trace messages if a\r
192  * suspension occurs within marker parameters.  Other side effects\r
193  * require more care.\r
194  */\r
195 \r
196 \r
197 LOCAL(boolean)\r
198 get_soi (j_decompress_ptr cinfo)\r
199 /* Process an SOI marker */\r
200 {\r
201   int i;\r
202   \r
203   TRACEMS(cinfo, 1, JTRC_SOI);\r
204 \r
205   if (cinfo->marker->saw_SOI)\r
206     ERREXIT(cinfo, JERR_SOI_DUPLICATE);\r
207 \r
208   /* Reset all parameters that are defined to be reset by SOI */\r
209 \r
210   for (i = 0; i < NUM_ARITH_TBLS; i++) {\r
211     cinfo->arith_dc_L[i] = 0;\r
212     cinfo->arith_dc_U[i] = 1;\r
213     cinfo->arith_ac_K[i] = 5;\r
214   }\r
215   cinfo->restart_interval = 0;\r
216 \r
217   /* Set initial assumptions for colorspace etc */\r
218 \r
219   cinfo->jpeg_color_space = JCS_UNKNOWN;\r
220   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */\r
221 \r
222   cinfo->saw_JFIF_marker = FALSE;\r
223   cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */\r
224   cinfo->JFIF_minor_version = 1;\r
225   cinfo->density_unit = 0;\r
226   cinfo->X_density = 1;\r
227   cinfo->Y_density = 1;\r
228   cinfo->saw_Adobe_marker = FALSE;\r
229   cinfo->Adobe_transform = 0;\r
230 \r
231   cinfo->marker->saw_SOI = TRUE;\r
232 \r
233   return TRUE;\r
234 }\r
235 \r
236 \r
237 LOCAL(boolean)\r
238 get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)\r
239 /* Process a SOFn marker */\r
240 {\r
241   INT32 length;\r
242   int c, ci;\r
243   jpeg_component_info * compptr;\r
244   /* LiuSunliang added 20111209 */\r
245   JDIMENSION image_width, image_height;\r
246   INPUT_VARS(cinfo);\r
247 \r
248   cinfo->progressive_mode = is_prog;\r
249   cinfo->arith_code = is_arith;\r
250 \r
251   INPUT_2BYTES(cinfo, length, return FALSE);\r
252 \r
253   INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);\r
254   INPUT_2BYTES(cinfo, image_height, return FALSE);\r
255   INPUT_2BYTES(cinfo, image_width, return FALSE);\r
256   INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);\r
257 \r
258   if (image_width <= JPEG_MAX_DIMENSION)\r
259           cinfo->image_width = image_width;\r
260  \r
261   if (image_height <= JPEG_MAX_DIMENSION)\r
262           cinfo->image_height = image_height;\r
263 \r
264   length -= 8;\r
265 \r
266   TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,\r
267            (int) cinfo->image_width, (int) cinfo->image_height,\r
268            cinfo->num_components);\r
269 \r
270   if (cinfo->marker->saw_SOF)\r
271     ERREXIT(cinfo, JERR_SOF_DUPLICATE);\r
272 \r
273   /* We don't support files in which the image height is initially specified */\r
274   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */\r
275   /* might as well have a general sanity check. */\r
276   if (cinfo->image_height <= 0 || cinfo->image_width <= 0\r
277       || cinfo->num_components <= 0)\r
278     ERREXIT(cinfo, JERR_EMPTY_IMAGE);\r
279 \r
280   if (length != (cinfo->num_components * 3))\r
281     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
282 \r
283   if (cinfo->comp_info == NULL) /* do only once, even if suspend */\r
284     cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)\r
285                         ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
286                          cinfo->num_components * SIZEOF(jpeg_component_info));\r
287   \r
288   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
289        ci++, compptr++) {\r
290     compptr->component_index = ci;\r
291     INPUT_BYTE(cinfo, compptr->component_id, return FALSE);\r
292         /* XYQ 2008-03-25: Adobe CMYK JPEG has serious flaw: the K channel has same component id as C channel */\r
293         {\r
294                 int i;\r
295                 for (i = 0; i < ci; i ++)\r
296                         if (compptr->component_id == cinfo->comp_info[i].component_id) break;\r
297                 if (i < ci)\r
298                         /* Found the error! We replace the id with something unlikely used elsewhere */\r
299                         compptr->component_id += 0xf0;\r
300         }\r
301         /* end of modification */\r
302     INPUT_BYTE(cinfo, c, return FALSE);\r
303     compptr->h_samp_factor = (c >> 4) & 15;\r
304     compptr->v_samp_factor = (c     ) & 15;\r
305     INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);\r
306 \r
307     TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,\r
308              compptr->component_id, compptr->h_samp_factor,\r
309              compptr->v_samp_factor, compptr->quant_tbl_no);\r
310   }\r
311 \r
312   cinfo->marker->saw_SOF = TRUE;\r
313 \r
314   INPUT_SYNC(cinfo);\r
315   return TRUE;\r
316 }\r
317 \r
318 \r
319 LOCAL(boolean)\r
320 get_sos (j_decompress_ptr cinfo)\r
321 /* Process a SOS marker */\r
322 {\r
323   INT32 length;\r
324   int i, ci, n, c, cc;\r
325   jpeg_component_info * compptr;\r
326   INPUT_VARS(cinfo);\r
327 \r
328   if (! cinfo->marker->saw_SOF)\r
329     ERREXIT(cinfo, JERR_SOS_NO_SOF);\r
330 \r
331   INPUT_2BYTES(cinfo, length, return FALSE);\r
332 \r
333   INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */\r
334 \r
335   TRACEMS1(cinfo, 1, JTRC_SOS, n);\r
336 \r
337   if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)\r
338     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
339 \r
340   cinfo->comps_in_scan = n;\r
341 \r
342   /* Collect the component-spec parameters */\r
343 \r
344   for (i = 0; i < n; i++) {\r
345     INPUT_BYTE(cinfo, cc, return FALSE);\r
346     INPUT_BYTE(cinfo, c, return FALSE);\r
347     \r
348         /* XYQ 2008-03-25: Adobe CMYK JPEG has serious flaw: the K channel has same component id as C channel */\r
349         {\r
350                 int j;\r
351                 for (j = 0; j < i; j ++)\r
352                         if (cc == cinfo->cur_comp_info[j]->component_id) break;\r
353                 if (j < i)\r
354                         /* found the error! */\r
355                         cc += 0xf0;\r
356         }\r
357         /* end of modification */\r
358     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
359          ci++, compptr++) {\r
360       if (cc == compptr->component_id)\r
361         goto id_found;\r
362     }\r
363 \r
364     ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);\r
365 \r
366   id_found:\r
367 \r
368     cinfo->cur_comp_info[i] = compptr;\r
369     compptr->dc_tbl_no = (c >> 4) & 15;\r
370     compptr->ac_tbl_no = (c     ) & 15;\r
371     \r
372     TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,\r
373              compptr->dc_tbl_no, compptr->ac_tbl_no);\r
374         /* This CSi (cc) should differ from the previous CSi */\r
375     for (ci = 0; ci < i; ci++) {\r
376       if (cinfo->cur_comp_info[ci] == compptr)\r
377         ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);\r
378     }\r
379   }\r
380 \r
381   /* Collect the additional scan parameters Ss, Se, Ah/Al. */\r
382   INPUT_BYTE(cinfo, c, return FALSE);\r
383   cinfo->Ss = c;\r
384   INPUT_BYTE(cinfo, c, return FALSE);\r
385   cinfo->Se = c;\r
386   INPUT_BYTE(cinfo, c, return FALSE);\r
387   cinfo->Ah = (c >> 4) & 15;\r
388   cinfo->Al = (c     ) & 15;\r
389 \r
390   TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,\r
391            cinfo->Ah, cinfo->Al);\r
392 \r
393   /* Prepare to scan data & restart markers */\r
394   cinfo->marker->next_restart_num = 0;\r
395 \r
396   /* Count another SOS marker */\r
397   cinfo->input_scan_number++;\r
398 \r
399   INPUT_SYNC(cinfo);\r
400   return TRUE;\r
401 }\r
402 \r
403 \r
404 #ifdef D_ARITH_CODING_SUPPORTED\r
405 \r
406 LOCAL(boolean)\r
407 get_dac (j_decompress_ptr cinfo)\r
408 /* Process a DAC marker */\r
409 {\r
410   INT32 length;\r
411   int index, val;\r
412   INPUT_VARS(cinfo);\r
413 \r
414   INPUT_2BYTES(cinfo, length, return FALSE);\r
415   length -= 2;\r
416   \r
417   while (length > 0) {\r
418     INPUT_BYTE(cinfo, index, return FALSE);\r
419     INPUT_BYTE(cinfo, val, return FALSE);\r
420 \r
421     length -= 2;\r
422 \r
423     TRACEMS2(cinfo, 1, JTRC_DAC, index, val);\r
424 \r
425     if (index < 0 || index >= (2*NUM_ARITH_TBLS))\r
426       ERREXIT1(cinfo, JERR_DAC_INDEX, index);\r
427 \r
428     if (index >= NUM_ARITH_TBLS) { /* define AC table */\r
429       cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;\r
430     } else {                    /* define DC table */\r
431       cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);\r
432       cinfo->arith_dc_U[index] = (UINT8) (val >> 4);\r
433       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])\r
434         ERREXIT1(cinfo, JERR_DAC_VALUE, val);\r
435     }\r
436   }\r
437 \r
438   if (length != 0)\r
439     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
440 \r
441   INPUT_SYNC(cinfo);\r
442   return TRUE;\r
443 }\r
444 \r
445 #else /* ! D_ARITH_CODING_SUPPORTED */\r
446 \r
447 #define get_dac(cinfo)  skip_variable(cinfo)\r
448 \r
449 #endif /* D_ARITH_CODING_SUPPORTED */\r
450 \r
451 \r
452 LOCAL(boolean)\r
453 get_dht (j_decompress_ptr cinfo)\r
454 /* Process a DHT marker */\r
455 {\r
456   INT32 length;\r
457   UINT8 bits[17];\r
458   UINT8 huffval[256];\r
459   int i, index, count;\r
460   JHUFF_TBL **htblptr;\r
461   INPUT_VARS(cinfo);\r
462 \r
463   INPUT_2BYTES(cinfo, length, return FALSE);\r
464   length -= 2;\r
465   \r
466   while (length > 16) {\r
467     INPUT_BYTE(cinfo, index, return FALSE);\r
468 \r
469     TRACEMS1(cinfo, 1, JTRC_DHT, index);\r
470       \r
471     bits[0] = 0;\r
472     count = 0;\r
473     for (i = 1; i <= 16; i++) {\r
474       INPUT_BYTE(cinfo, bits[i], return FALSE);\r
475       count += bits[i];\r
476     }\r
477 \r
478     length -= 1 + 16;\r
479 \r
480     TRACEMS8(cinfo, 2, JTRC_HUFFBITS,\r
481              bits[1], bits[2], bits[3], bits[4],\r
482              bits[5], bits[6], bits[7], bits[8]);\r
483     TRACEMS8(cinfo, 2, JTRC_HUFFBITS,\r
484              bits[9], bits[10], bits[11], bits[12],\r
485              bits[13], bits[14], bits[15], bits[16]);\r
486 \r
487     /* Here we just do minimal validation of the counts to avoid walking\r
488      * off the end of our table space.  jdhuff.c will check more carefully.\r
489      */\r
490     if (count > 256 || ((INT32) count) > length)\r
491       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);\r
492 \r
493     for (i = 0; i < count; i++)\r
494       INPUT_BYTE(cinfo, huffval[i], return FALSE);\r
495 \r
496     length -= count;\r
497 \r
498     if (index & 0x10) {         /* AC table definition */\r
499       index -= 0x10;\r
500       htblptr = &cinfo->ac_huff_tbl_ptrs[index];\r
501     } else {                    /* DC table definition */\r
502       htblptr = &cinfo->dc_huff_tbl_ptrs[index];\r
503     }\r
504 \r
505     if (index < 0 || index >= NUM_HUFF_TBLS)\r
506       ERREXIT1(cinfo, JERR_DHT_INDEX, index);\r
507 \r
508     if (*htblptr == NULL)\r
509       *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);\r
510   \r
511     MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));\r
512     MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));\r
513   }\r
514 \r
515   if (length != 0)\r
516     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
517 \r
518   INPUT_SYNC(cinfo);\r
519   return TRUE;\r
520 }\r
521 \r
522 \r
523 LOCAL(boolean)\r
524 get_dqt (j_decompress_ptr cinfo)\r
525 /* Process a DQT marker */\r
526 {\r
527   INT32 length;\r
528   int n, i, prec;\r
529   unsigned int tmp;\r
530   JQUANT_TBL *quant_ptr;\r
531   INPUT_VARS(cinfo);\r
532 \r
533   INPUT_2BYTES(cinfo, length, return FALSE);\r
534   length -= 2;\r
535 \r
536   while (length > 0) {\r
537     INPUT_BYTE(cinfo, n, return FALSE);\r
538     prec = n >> 4;\r
539     n &= 0x0F;\r
540 \r
541     TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);\r
542 \r
543     if (n >= NUM_QUANT_TBLS)\r
544       ERREXIT1(cinfo, JERR_DQT_INDEX, n);\r
545       \r
546     if (cinfo->quant_tbl_ptrs[n] == NULL)\r
547       cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);\r
548     quant_ptr = cinfo->quant_tbl_ptrs[n];\r
549 \r
550     for (i = 0; i < DCTSIZE2; i++) {\r
551       if (prec)\r
552         INPUT_2BYTES(cinfo, tmp, return FALSE);\r
553       else\r
554         INPUT_BYTE(cinfo, tmp, return FALSE);\r
555       /* We convert the zigzag-order table to natural array order. */\r
556       quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;\r
557     }\r
558 \r
559     if (cinfo->err->trace_level >= 2) {\r
560       for (i = 0; i < DCTSIZE2; i += 8) {\r
561         TRACEMS8(cinfo, 2, JTRC_QUANTVALS,\r
562                  quant_ptr->quantval[i],   quant_ptr->quantval[i+1],\r
563                  quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],\r
564                  quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],\r
565                  quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);\r
566       }\r
567     }\r
568 \r
569     length -= DCTSIZE2+1;\r
570     if (prec) length -= DCTSIZE2;\r
571   }\r
572 \r
573   if (length != 0)\r
574     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
575 \r
576   INPUT_SYNC(cinfo);\r
577   return TRUE;\r
578 }\r
579 \r
580 \r
581 LOCAL(boolean)\r
582 get_dri (j_decompress_ptr cinfo)\r
583 /* Process a DRI marker */\r
584 {\r
585   INT32 length;\r
586   unsigned int tmp;\r
587   INPUT_VARS(cinfo);\r
588 \r
589   INPUT_2BYTES(cinfo, length, return FALSE);\r
590   \r
591   if (length != 4)\r
592     ERREXIT(cinfo, JERR_BAD_LENGTH);\r
593 \r
594   INPUT_2BYTES(cinfo, tmp, return FALSE);\r
595 \r
596   TRACEMS1(cinfo, 1, JTRC_DRI, tmp);\r
597 \r
598   cinfo->restart_interval = tmp;\r
599 \r
600   INPUT_SYNC(cinfo);\r
601   return TRUE;\r
602 }\r
603 \r
604 \r
605 /*\r
606  * Routines for processing APPn and COM markers.\r
607  * These are either saved in memory or discarded, per application request.\r
608  * APP0 and APP14 are specially checked to see if they are\r
609  * JFIF and Adobe markers, respectively.\r
610  */\r
611 \r
612 #define APP0_DATA_LEN   14      /* Length of interesting data in APP0 */\r
613 #define APP14_DATA_LEN  12      /* Length of interesting data in APP14 */\r
614 #define APPN_DATA_LEN   14      /* Must be the largest of the above!! */\r
615 \r
616 \r
617 LOCAL(void)\r
618 examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,\r
619               unsigned int datalen, INT32 remaining)\r
620 /* Examine first few bytes from an APP0.\r
621  * Take appropriate action if it is a JFIF marker.\r
622  * datalen is # of bytes at data[], remaining is length of rest of marker data.\r
623  */\r
624 {\r
625   INT32 totallen = (INT32) datalen + remaining;\r
626 \r
627   if (datalen >= APP0_DATA_LEN &&\r
628       GETJOCTET(data[0]) == 0x4A &&\r
629       GETJOCTET(data[1]) == 0x46 &&\r
630       GETJOCTET(data[2]) == 0x49 &&\r
631       GETJOCTET(data[3]) == 0x46 &&\r
632       GETJOCTET(data[4]) == 0) {\r
633     /* Found JFIF APP0 marker: save info */\r
634     cinfo->saw_JFIF_marker = TRUE;\r
635     cinfo->JFIF_major_version = GETJOCTET(data[5]);\r
636     cinfo->JFIF_minor_version = GETJOCTET(data[6]);\r
637     cinfo->density_unit = GETJOCTET(data[7]);\r
638     cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);\r
639     cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);\r
640     /* Check version.\r
641      * Major version must be 1, anything else signals an incompatible change.\r
642      * (We used to treat this as an error, but now it's a nonfatal warning,\r
643      * because some bozo at Hijaak couldn't read the spec.)\r
644      * Minor version should be 0..2, but process anyway if newer.\r
645      */\r
646     if (cinfo->JFIF_major_version != 1)\r
647       WARNMS2(cinfo, JWRN_JFIF_MAJOR,\r
648               cinfo->JFIF_major_version, cinfo->JFIF_minor_version);\r
649     /* Generate trace messages */\r
650     TRACEMS5(cinfo, 1, JTRC_JFIF,\r
651              cinfo->JFIF_major_version, cinfo->JFIF_minor_version,\r
652              cinfo->X_density, cinfo->Y_density, cinfo->density_unit);\r
653     /* Validate thumbnail dimensions and issue appropriate messages */\r
654     if (GETJOCTET(data[12]) | GETJOCTET(data[13]))\r
655       TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,\r
656                GETJOCTET(data[12]), GETJOCTET(data[13]));\r
657     totallen -= APP0_DATA_LEN;\r
658     if (totallen !=\r
659         ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))\r
660       TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);\r
661   } else if (datalen >= 6 &&\r
662       GETJOCTET(data[0]) == 0x4A &&\r
663       GETJOCTET(data[1]) == 0x46 &&\r
664       GETJOCTET(data[2]) == 0x58 &&\r
665       GETJOCTET(data[3]) == 0x58 &&\r
666       GETJOCTET(data[4]) == 0) {\r
667     /* Found JFIF "JFXX" extension APP0 marker */\r
668     /* The library doesn't actually do anything with these,\r
669      * but we try to produce a helpful trace message.\r
670      */\r
671     switch (GETJOCTET(data[5])) {\r
672     case 0x10:\r
673       TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);\r
674       break;\r
675     case 0x11:\r
676       TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);\r
677       break;\r
678     case 0x13:\r
679       TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);\r
680       break;\r
681     default:\r
682       TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,\r
683                GETJOCTET(data[5]), (int) totallen);\r
684       break;\r
685     }\r
686   } else {\r
687     /* Start of APP0 does not match "JFIF" or "JFXX", or too short */\r
688     TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);\r
689   }\r
690 }\r
691 \r
692 \r
693 LOCAL(void)\r
694 examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,\r
695                unsigned int datalen, INT32 remaining)\r
696 /* Examine first few bytes from an APP14.\r
697  * Take appropriate action if it is an Adobe marker.\r
698  * datalen is # of bytes at data[], remaining is length of rest of marker data.\r
699  */\r
700 {\r
701   unsigned int version, flags0, flags1, transform;\r
702 \r
703   if (datalen >= APP14_DATA_LEN &&\r
704       GETJOCTET(data[0]) == 0x41 &&\r
705       GETJOCTET(data[1]) == 0x64 &&\r
706       GETJOCTET(data[2]) == 0x6F &&\r
707       GETJOCTET(data[3]) == 0x62 &&\r
708       GETJOCTET(data[4]) == 0x65) {\r
709     /* Found Adobe APP14 marker */\r
710     version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);\r
711     flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);\r
712     flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);\r
713     transform = GETJOCTET(data[11]);\r
714     TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);\r
715     cinfo->saw_Adobe_marker = TRUE;\r
716     cinfo->Adobe_transform = (UINT8) transform;\r
717   } else {\r
718     /* Start of APP14 does not match "Adobe", or too short */\r
719     TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));\r
720   }\r
721 }\r
722 \r
723 \r
724 METHODDEF(boolean)\r
725 get_interesting_appn (j_decompress_ptr cinfo)\r
726 /* Process an APP0 or APP14 marker without saving it */\r
727 {\r
728   INT32 length;\r
729   JOCTET b[APPN_DATA_LEN];\r
730   unsigned int i, numtoread;\r
731   INPUT_VARS(cinfo);\r
732 \r
733   INPUT_2BYTES(cinfo, length, return FALSE);\r
734   length -= 2;\r
735 \r
736   /* get the interesting part of the marker data */\r
737   if (length >= APPN_DATA_LEN)\r
738     numtoread = APPN_DATA_LEN;\r
739   else if (length > 0)\r
740     numtoread = (unsigned int) length;\r
741   else\r
742     numtoread = 0;\r
743   for (i = 0; i < numtoread; i++)\r
744     INPUT_BYTE(cinfo, b[i], return FALSE);\r
745   length -= numtoread;\r
746 \r
747   /* process it */\r
748   switch (cinfo->unread_marker) {\r
749   case M_APP0:\r
750     examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);\r
751     break;\r
752   case M_APP14:\r
753     examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);\r
754     break;\r
755   default:\r
756     /* can't get here unless jpeg_save_markers chooses wrong processor */\r
757     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);\r
758     break;\r
759   }\r
760 \r
761   /* skip any remaining data -- could be lots */\r
762   INPUT_SYNC(cinfo);\r
763   if (length > 0)\r
764     (*cinfo->src->skip_input_data) (cinfo, (long) length);\r
765 \r
766   return TRUE;\r
767 }\r
768 \r
769 \r
770 #ifdef SAVE_MARKERS_SUPPORTED\r
771 \r
772 METHODDEF(boolean)\r
773 save_marker (j_decompress_ptr cinfo)\r
774 /* Save an APPn or COM marker into the marker list */\r
775 {\r
776   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;\r
777   jpeg_saved_marker_ptr cur_marker = marker->cur_marker;\r
778   unsigned int bytes_read, data_length;\r
779   JOCTET FAR * data;\r
780   INT32 length = 0;\r
781   INPUT_VARS(cinfo);\r
782 \r
783   if (cur_marker == NULL) {\r
784     /* begin reading a marker */\r
785     INPUT_2BYTES(cinfo, length, return FALSE);\r
786     length -= 2;\r
787     if (length >= 0) {          /* watch out for bogus length word */\r
788       /* figure out how much we want to save */\r
789       unsigned int limit;\r
790       if (cinfo->unread_marker == (int) M_COM)\r
791         limit = marker->length_limit_COM;\r
792       else\r
793         limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];\r
794       if ((unsigned int) length < limit)\r
795         limit = (unsigned int) length;\r
796       /* allocate and initialize the marker item */\r
797       cur_marker = (jpeg_saved_marker_ptr)\r
798         (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
799                                     SIZEOF(struct jpeg_marker_struct) + limit);\r
800       cur_marker->next = NULL;\r
801       cur_marker->marker = (UINT8) cinfo->unread_marker;\r
802       cur_marker->original_length = (unsigned int) length;\r
803       cur_marker->data_length = limit;\r
804       /* data area is just beyond the jpeg_marker_struct */\r
805       data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);\r
806       marker->cur_marker = cur_marker;\r
807       marker->bytes_read = 0;\r
808       bytes_read = 0;\r
809       data_length = limit;\r
810     } else {\r
811       /* deal with bogus length word */\r
812       bytes_read = data_length = 0;\r
813       data = NULL;\r
814     }\r
815   } else {\r
816     /* resume reading a marker */\r
817     bytes_read = marker->bytes_read;\r
818     data_length = cur_marker->data_length;\r
819     data = cur_marker->data + bytes_read;\r
820   }\r
821 \r
822   while (bytes_read < data_length) {\r
823     INPUT_SYNC(cinfo);          /* move the restart point to here */\r
824     marker->bytes_read = bytes_read;\r
825     /* If there's not at least one byte in buffer, suspend */\r
826     MAKE_BYTE_AVAIL(cinfo, return FALSE);\r
827     /* Copy bytes with reasonable rapidity */\r
828     while (bytes_read < data_length && bytes_in_buffer > 0) {\r
829       *data++ = *next_input_byte++;\r
830       bytes_in_buffer--;\r
831       bytes_read++;\r
832     }\r
833   }\r
834 \r
835   /* Done reading what we want to read */\r
836   if (cur_marker != NULL) {     /* will be NULL if bogus length word */\r
837     /* Add new marker to end of list */\r
838     if (cinfo->marker_list == NULL) {\r
839       cinfo->marker_list = cur_marker;\r
840     } else {\r
841       jpeg_saved_marker_ptr prev = cinfo->marker_list;\r
842       while (prev->next != NULL)\r
843         prev = prev->next;\r
844       prev->next = cur_marker;\r
845     }\r
846     /* Reset pointer & calc remaining data length */\r
847     data = cur_marker->data;\r
848     length = cur_marker->original_length - data_length;\r
849   }\r
850   /* Reset to initial state for next marker */\r
851   marker->cur_marker = NULL;\r
852 \r
853   /* Process the marker if interesting; else just make a generic trace msg */\r
854   switch (cinfo->unread_marker) {\r
855   case M_APP0:\r
856     examine_app0(cinfo, data, data_length, length);\r
857     break;\r
858   case M_APP14:\r
859     examine_app14(cinfo, data, data_length, length);\r
860     break;\r
861   default:\r
862     TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,\r
863              (int) (data_length + length));\r
864     break;\r
865   }\r
866 \r
867   /* skip any remaining data -- could be lots */\r
868   INPUT_SYNC(cinfo);            /* do before skip_input_data */\r
869   if (length > 0)\r
870     (*cinfo->src->skip_input_data) (cinfo, (long) length);\r
871 \r
872   return TRUE;\r
873 }\r
874 \r
875 #endif /* SAVE_MARKERS_SUPPORTED */\r
876 \r
877 \r
878 METHODDEF(boolean)\r
879 skip_variable (j_decompress_ptr cinfo)\r
880 /* Skip over an unknown or uninteresting variable-length marker */\r
881 {\r
882   INT32 length;\r
883   INPUT_VARS(cinfo);\r
884 \r
885   INPUT_2BYTES(cinfo, length, return FALSE);\r
886   length -= 2;\r
887   \r
888   TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);\r
889 \r
890   INPUT_SYNC(cinfo);            /* do before skip_input_data */\r
891   if (length > 0)\r
892     (*cinfo->src->skip_input_data) (cinfo, (long) length);\r
893 \r
894   return TRUE;\r
895 }\r
896 \r
897 \r
898 /*\r
899  * Find the next JPEG marker, save it in cinfo->unread_marker.\r
900  * Returns FALSE if had to suspend before reaching a marker;\r
901  * in that case cinfo->unread_marker is unchanged.\r
902  *\r
903  * Note that the result might not be a valid marker code,\r
904  * but it will never be 0 or FF.\r
905  */\r
906 \r
907 LOCAL(boolean)\r
908 next_marker (j_decompress_ptr cinfo)\r
909 {\r
910   int c;\r
911   INPUT_VARS(cinfo);\r
912 \r
913   for (;;) {\r
914     INPUT_BYTE(cinfo, c, return FALSE);\r
915     /* Skip any non-FF bytes.\r
916      * This may look a bit inefficient, but it will not occur in a valid file.\r
917      * We sync after each discarded byte so that a suspending data source\r
918      * can discard the byte from its buffer.\r
919      */\r
920     while (c != 0xFF) {\r
921       cinfo->marker->discarded_bytes++;\r
922       INPUT_SYNC(cinfo);\r
923       INPUT_BYTE(cinfo, c, return FALSE);\r
924     }\r
925     /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as\r
926      * pad bytes, so don't count them in discarded_bytes.  We assume there\r
927      * will not be so many consecutive FF bytes as to overflow a suspending\r
928      * data source's input buffer.\r
929      */\r
930     do {\r
931       INPUT_BYTE(cinfo, c, return FALSE);\r
932     } while (c == 0xFF);\r
933     if (c != 0)\r
934       break;                    /* found a valid marker, exit loop */\r
935     /* Reach here if we found a stuffed-zero data sequence (FF/00).\r
936      * Discard it and loop back to try again.\r
937      */\r
938     cinfo->marker->discarded_bytes += 2;\r
939     INPUT_SYNC(cinfo);\r
940   }\r
941 \r
942   if (cinfo->marker->discarded_bytes != 0) {\r
943     WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);\r
944     cinfo->marker->discarded_bytes = 0;\r
945   }\r
946 \r
947   cinfo->unread_marker = c;\r
948 \r
949   INPUT_SYNC(cinfo);\r
950   return TRUE;\r
951 }\r
952 \r
953 \r
954 LOCAL(boolean)\r
955 first_marker (j_decompress_ptr cinfo)\r
956 /* Like next_marker, but used to obtain the initial SOI marker. */\r
957 /* For this marker, we do not allow preceding garbage or fill; otherwise,\r
958  * we might well scan an entire input file before realizing it ain't JPEG.\r
959  * If an application wants to process non-JFIF files, it must seek to the\r
960  * SOI before calling the JPEG library.\r
961  */\r
962 {\r
963   int c, c2;\r
964   INPUT_VARS(cinfo);\r
965 \r
966   INPUT_BYTE(cinfo, c, return FALSE);\r
967   INPUT_BYTE(cinfo, c2, return FALSE);\r
968   if (c != 0xFF || c2 != (int) M_SOI)\r
969     ERREXIT2(cinfo, JERR_NO_SOI, c, c2);\r
970 \r
971   cinfo->unread_marker = c2;\r
972 \r
973   INPUT_SYNC(cinfo);\r
974   return TRUE;\r
975 }\r
976 \r
977 \r
978 /*\r
979  * Read markers until SOS or EOI.\r
980  *\r
981  * Returns same codes as are defined for jpeg_consume_input:\r
982  * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.\r
983  */\r
984 \r
985 METHODDEF(int)\r
986 read_markers (j_decompress_ptr cinfo)\r
987 {\r
988   /* Outer loop repeats once for each marker. */\r
989   for (;;) {\r
990     /* Collect the marker proper, unless we already did. */\r
991     /* NB: first_marker() enforces the requirement that SOI appear first. */\r
992     if (cinfo->unread_marker == 0) {\r
993       if (! cinfo->marker->saw_SOI) {\r
994         if (! first_marker(cinfo))\r
995           return JPEG_SUSPENDED;\r
996       } else {\r
997         if (! next_marker(cinfo))\r
998           return JPEG_SUSPENDED;\r
999       }\r
1000     }\r
1001     /* At this point cinfo->unread_marker contains the marker code and the\r
1002      * input point is just past the marker proper, but before any parameters.\r
1003      * A suspension will cause us to return with this state still true.\r
1004      */\r
1005     switch (cinfo->unread_marker) {\r
1006     case M_SOI:\r
1007       if (! get_soi(cinfo))\r
1008         return JPEG_SUSPENDED;\r
1009       break;\r
1010 \r
1011     case M_SOF0:                /* Baseline */\r
1012     case M_SOF1:                /* Extended sequential, Huffman */\r
1013       if (! get_sof(cinfo, FALSE, FALSE))\r
1014         return JPEG_SUSPENDED;\r
1015       break;\r
1016 \r
1017     case M_SOF2:                /* Progressive, Huffman */\r
1018       if (! get_sof(cinfo, TRUE, FALSE))\r
1019         return JPEG_SUSPENDED;\r
1020       break;\r
1021 \r
1022     case M_SOF9:                /* Extended sequential, arithmetic */\r
1023       if (! get_sof(cinfo, FALSE, TRUE))\r
1024         return JPEG_SUSPENDED;\r
1025       break;\r
1026 \r
1027     case M_SOF10:               /* Progressive, arithmetic */\r
1028       if (! get_sof(cinfo, TRUE, TRUE))\r
1029         return JPEG_SUSPENDED;\r
1030       break;\r
1031 \r
1032     /* Currently unsupported SOFn types */\r
1033     case M_SOF3:                /* Lossless, Huffman */\r
1034     case M_SOF5:                /* Differential sequential, Huffman */\r
1035     case M_SOF6:                /* Differential progressive, Huffman */\r
1036     case M_SOF7:                /* Differential lossless, Huffman */\r
1037     case M_JPG:                 /* Reserved for JPEG extensions */\r
1038     case M_SOF11:               /* Lossless, arithmetic */\r
1039     case M_SOF13:               /* Differential sequential, arithmetic */\r
1040     case M_SOF14:               /* Differential progressive, arithmetic */\r
1041     case M_SOF15:               /* Differential lossless, arithmetic */\r
1042       ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);\r
1043       break;\r
1044 \r
1045     case M_SOS:\r
1046       if (! get_sos(cinfo))\r
1047         return JPEG_SUSPENDED;\r
1048       cinfo->unread_marker = 0; /* processed the marker */\r
1049       return JPEG_REACHED_SOS;\r
1050     \r
1051     case M_EOI:\r
1052       TRACEMS(cinfo, 1, JTRC_EOI);\r
1053       cinfo->unread_marker = 0; /* processed the marker */\r
1054       return JPEG_REACHED_EOI;\r
1055       \r
1056     case M_DAC:\r
1057       if (! get_dac(cinfo))\r
1058         return JPEG_SUSPENDED;\r
1059       break;\r
1060       \r
1061     case M_DHT:\r
1062       if (! get_dht(cinfo))\r
1063         return JPEG_SUSPENDED;\r
1064       break;\r
1065       \r
1066     case M_DQT:\r
1067       if (! get_dqt(cinfo))\r
1068         return JPEG_SUSPENDED;\r
1069       break;\r
1070       \r
1071     case M_DRI:\r
1072       if (! get_dri(cinfo))\r
1073         return JPEG_SUSPENDED;\r
1074       break;\r
1075       \r
1076     case M_APP0:\r
1077     case M_APP1:\r
1078     case M_APP2:\r
1079     case M_APP3:\r
1080     case M_APP4:\r
1081     case M_APP5:\r
1082     case M_APP6:\r
1083     case M_APP7:\r
1084     case M_APP8:\r
1085     case M_APP9:\r
1086     case M_APP10:\r
1087     case M_APP11:\r
1088     case M_APP12:\r
1089     case M_APP13:\r
1090     case M_APP14:\r
1091     case M_APP15:\r
1092       if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[\r
1093                 cinfo->unread_marker - (int) M_APP0]) (cinfo))\r
1094         return JPEG_SUSPENDED;\r
1095       break;\r
1096       \r
1097     case M_COM:\r
1098       if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))\r
1099         return JPEG_SUSPENDED;\r
1100       break;\r
1101 \r
1102     case M_RST0:                /* these are all parameterless */\r
1103     case M_RST1:\r
1104     case M_RST2:\r
1105     case M_RST3:\r
1106     case M_RST4:\r
1107     case M_RST5:\r
1108     case M_RST6:\r
1109     case M_RST7:\r
1110     case M_TEM:\r
1111       TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);\r
1112       break;\r
1113 \r
1114     case M_DNL:                 /* Ignore DNL ... perhaps the wrong thing */\r
1115       if (! skip_variable(cinfo))\r
1116         return JPEG_SUSPENDED;\r
1117       break;\r
1118 \r
1119     default:                    /* must be DHP, EXP, JPGn, or RESn */\r
1120       /* For now, we treat the reserved markers as fatal errors since they are\r
1121        * likely to be used to signal incompatible JPEG Part 3 extensions.\r
1122        * Once the JPEG 3 version-number marker is well defined, this code\r
1123        * ought to change!\r
1124        */\r
1125       ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);\r
1126       break;\r
1127     }\r
1128     /* Successfully processed marker, so reset state variable */\r
1129     cinfo->unread_marker = 0;\r
1130   } /* end loop */\r
1131 }\r
1132 \r
1133 \r
1134 /*\r
1135  * Read a restart marker, which is expected to appear next in the datastream;\r
1136  * if the marker is not there, take appropriate recovery action.\r
1137  * Returns FALSE if suspension is required.\r
1138  *\r
1139  * This is called by the entropy decoder after it has read an appropriate\r
1140  * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder\r
1141  * has already read a marker from the data source.  Under normal conditions\r
1142  * cinfo->unread_marker will be reset to 0 before returning; if not reset,\r
1143  * it holds a marker which the decoder will be unable to read past.\r
1144  */\r
1145 \r
1146 METHODDEF(boolean)\r
1147 read_restart_marker (j_decompress_ptr cinfo)\r
1148 {\r
1149   /* Obtain a marker unless we already did. */\r
1150   /* Note that next_marker will complain if it skips any data. */\r
1151   if (cinfo->unread_marker == 0) {\r
1152     if (! next_marker(cinfo))\r
1153       return FALSE;\r
1154   }\r
1155 \r
1156   if (cinfo->unread_marker ==\r
1157       ((int) M_RST0 + cinfo->marker->next_restart_num)) {\r
1158     /* Normal case --- swallow the marker and let entropy decoder continue */\r
1159     TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);\r
1160     cinfo->unread_marker = 0;\r
1161   } else {\r
1162     /* Uh-oh, the restart markers have been messed up. */\r
1163     /* Let the data source manager determine how to resync. */\r
1164     if (! (*cinfo->src->resync_to_restart) (cinfo,\r
1165                                             cinfo->marker->next_restart_num))\r
1166       return FALSE;\r
1167   }\r
1168 \r
1169   /* Update next-restart state */\r
1170   cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;\r
1171 \r
1172   return TRUE;\r
1173 }\r
1174 \r
1175 \r
1176 /*\r
1177  * This is the default resync_to_restart method for data source managers\r
1178  * to use if they don't have any better approach.  Some data source managers\r
1179  * may be able to back up, or may have additional knowledge about the data\r
1180  * which permits a more intelligent recovery strategy; such managers would\r
1181  * presumably supply their own resync method.\r
1182  *\r
1183  * read_restart_marker calls resync_to_restart if it finds a marker other than\r
1184  * the restart marker it was expecting.  (This code is *not* used unless\r
1185  * a nonzero restart interval has been declared.)  cinfo->unread_marker is\r
1186  * the marker code actually found (might be anything, except 0 or FF).\r
1187  * The desired restart marker number (0..7) is passed as a parameter.\r
1188  * This routine is supposed to apply whatever error recovery strategy seems\r
1189  * appropriate in order to position the input stream to the next data segment.\r
1190  * Note that cinfo->unread_marker is treated as a marker appearing before\r
1191  * the current data-source input point; usually it should be reset to zero\r
1192  * before returning.\r
1193  * Returns FALSE if suspension is required.\r
1194  *\r
1195  * This implementation is substantially constrained by wanting to treat the\r
1196  * input as a data stream; this means we can't back up.  Therefore, we have\r
1197  * only the following actions to work with:\r
1198  *   1. Simply discard the marker and let the entropy decoder resume at next\r
1199  *      byte of file.\r
1200  *   2. Read forward until we find another marker, discarding intervening\r
1201  *      data.  (In theory we could look ahead within the current bufferload,\r
1202  *      without having to discard data if we don't find the desired marker.\r
1203  *      This idea is not implemented here, in part because it makes behavior\r
1204  *      dependent on buffer size and chance buffer-boundary positions.)\r
1205  *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).\r
1206  *      This will cause the entropy decoder to process an empty data segment,\r
1207  *      inserting dummy zeroes, and then we will reprocess the marker.\r
1208  *\r
1209  * #2 is appropriate if we think the desired marker lies ahead, while #3 is\r
1210  * appropriate if the found marker is a future restart marker (indicating\r
1211  * that we have missed the desired restart marker, probably because it got\r
1212  * corrupted).\r
1213  * We apply #2 or #3 if the found marker is a restart marker no more than\r
1214  * two counts behind or ahead of the expected one.  We also apply #2 if the\r
1215  * found marker is not a legal JPEG marker code (it's certainly bogus data).\r
1216  * If the found marker is a restart marker more than 2 counts away, we do #1\r
1217  * (too much risk that the marker is erroneous; with luck we will be able to\r
1218  * resync at some future point).\r
1219  * For any valid non-restart JPEG marker, we apply #3.  This keeps us from\r
1220  * overrunning the end of a scan.  An implementation limited to single-scan\r
1221  * files might find it better to apply #2 for markers other than EOI, since\r
1222  * any other marker would have to be bogus data in that case.\r
1223  */\r
1224 \r
1225 GLOBAL(boolean)\r
1226 jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)\r
1227 {\r
1228   int marker = cinfo->unread_marker;\r
1229   int action = 1;\r
1230   \r
1231   /* Always put up a warning. */\r
1232   WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);\r
1233   \r
1234   /* Outer loop handles repeated decision after scanning forward. */\r
1235   for (;;) {\r
1236     if (marker < (int) M_SOF0)\r
1237       action = 2;               /* invalid marker */\r
1238     else if (marker < (int) M_RST0 || marker > (int) M_RST7)\r
1239       action = 3;               /* valid non-restart marker */\r
1240     else {\r
1241       if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||\r
1242           marker == ((int) M_RST0 + ((desired+2) & 7)))\r
1243         action = 3;             /* one of the next two expected restarts */\r
1244       else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||\r
1245                marker == ((int) M_RST0 + ((desired-2) & 7)))\r
1246         action = 2;             /* a prior restart, so advance */\r
1247       else\r
1248         action = 1;             /* desired restart or too far away */\r
1249     }\r
1250     TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);\r
1251     switch (action) {\r
1252     case 1:\r
1253       /* Discard marker and let entropy decoder resume processing. */\r
1254       cinfo->unread_marker = 0;\r
1255       return TRUE;\r
1256     case 2:\r
1257       /* Scan to the next marker, and repeat the decision loop. */\r
1258       if (! next_marker(cinfo))\r
1259         return FALSE;\r
1260       marker = cinfo->unread_marker;\r
1261       break;\r
1262     case 3:\r
1263       /* Return without advancing past this marker. */\r
1264       /* Entropy decoder will be forced to process an empty segment. */\r
1265       return TRUE;\r
1266     }\r
1267   } /* end loop */\r
1268 }\r
1269 \r
1270 \r
1271 /*\r
1272  * Reset marker processing state to begin a fresh datastream.\r
1273  */\r
1274 \r
1275 METHODDEF(void)\r
1276 reset_marker_reader (j_decompress_ptr cinfo)\r
1277 {\r
1278   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;\r
1279 \r
1280   cinfo->comp_info = NULL;              /* until allocated by get_sof */\r
1281   cinfo->input_scan_number = 0;         /* no SOS seen yet */\r
1282   cinfo->unread_marker = 0;             /* no pending marker */\r
1283   marker->pub.saw_SOI = FALSE;          /* set internal state too */\r
1284   marker->pub.saw_SOF = FALSE;\r
1285   marker->pub.discarded_bytes = 0;\r
1286   marker->cur_marker = NULL;\r
1287 }\r
1288 \r
1289 \r
1290 /*\r
1291  * Initialize the marker reader module.\r
1292  * This is called only once, when the decompression object is created.\r
1293  */\r
1294 \r
1295 GLOBAL(void)\r
1296 jinit_marker_reader (j_decompress_ptr cinfo)\r
1297 {\r
1298   my_marker_ptr marker;\r
1299   int i;\r
1300 \r
1301   /* Create subobject in permanent pool */\r
1302   marker = (my_marker_ptr)\r
1303     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,\r
1304                                 SIZEOF(my_marker_reader));\r
1305   cinfo->marker = (struct jpeg_marker_reader *) marker;\r
1306   /* Initialize public method pointers */\r
1307   marker->pub.reset_marker_reader = reset_marker_reader;\r
1308   marker->pub.read_markers = read_markers;\r
1309   marker->pub.read_restart_marker = read_restart_marker;\r
1310   /* Initialize COM/APPn processing.\r
1311    * By default, we examine and then discard APP0 and APP14,\r
1312    * but simply discard COM and all other APPn.\r
1313    */\r
1314   marker->process_COM = skip_variable;\r
1315   marker->length_limit_COM = 0;\r
1316   for (i = 0; i < 16; i++) {\r
1317     marker->process_APPn[i] = skip_variable;\r
1318     marker->length_limit_APPn[i] = 0;\r
1319   }\r
1320   marker->process_APPn[0] = get_interesting_appn;\r
1321   marker->process_APPn[14] = get_interesting_appn;\r
1322   /* Reset marker processing state */\r
1323   reset_marker_reader(cinfo);\r
1324 }\r
1325 \r
1326 \r
1327 /*\r
1328  * Control saving of COM and APPn markers into marker_list.\r
1329  */\r
1330 \r
1331 #ifdef SAVE_MARKERS_SUPPORTED\r
1332 \r
1333 GLOBAL(void)\r
1334 jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,\r
1335                    unsigned int length_limit)\r
1336 {\r
1337   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;\r
1338   long maxlength;\r
1339   jpeg_marker_parser_method processor;\r
1340 \r
1341   /* Length limit mustn't be larger than what we can allocate\r
1342    * (should only be a concern in a 16-bit environment).\r
1343    */\r
1344   maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);\r
1345   if (((long) length_limit) > maxlength)\r
1346     length_limit = (unsigned int) maxlength;\r
1347 \r
1348   /* Choose processor routine to use.\r
1349    * APP0/APP14 have special requirements.\r
1350    */\r
1351   if (length_limit) {\r
1352     processor = save_marker;\r
1353     /* If saving APP0/APP14, save at least enough for our internal use. */\r
1354     if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)\r
1355       length_limit = APP0_DATA_LEN;\r
1356     else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)\r
1357       length_limit = APP14_DATA_LEN;\r
1358   } else {\r
1359     processor = skip_variable;\r
1360     /* If discarding APP0/APP14, use our regular on-the-fly processor. */\r
1361     if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)\r
1362       processor = get_interesting_appn;\r
1363   }\r
1364 \r
1365   if (marker_code == (int) M_COM) {\r
1366     marker->process_COM = processor;\r
1367     marker->length_limit_COM = length_limit;\r
1368   } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {\r
1369     marker->process_APPn[marker_code - (int) M_APP0] = processor;\r
1370     marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;\r
1371   } else\r
1372     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);\r
1373 }\r
1374 \r
1375 #endif /* SAVE_MARKERS_SUPPORTED */\r
1376 \r
1377 \r
1378 /*\r
1379  * Install a special processing method for COM or APPn markers.\r
1380  */\r
1381 \r
1382 GLOBAL(void)\r
1383 jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,\r
1384                            jpeg_marker_parser_method routine)\r
1385 {\r
1386   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;\r
1387 \r
1388   if (marker_code == (int) M_COM)\r
1389     marker->process_COM = routine;\r
1390   else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)\r
1391     marker->process_APPn[marker_code - (int) M_APP0] = routine;\r
1392   else\r
1393     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);\r
1394 }\r
1395 \r
1396 #endif //_FX_JPEG_TURBO_\r