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