source: trunk/third/firefox/jpeg/jdmarker.c @ 21695

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