00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define JPEG_INTERNALS
00017 #include "jinclude.h"
00018 #include "jpeglib.h"
00019
00020
00021 typedef enum {
00022 M_SOF0 = 0xc0,
00023 M_SOF1 = 0xc1,
00024 M_SOF2 = 0xc2,
00025 M_SOF3 = 0xc3,
00026
00027 M_SOF5 = 0xc5,
00028 M_SOF6 = 0xc6,
00029 M_SOF7 = 0xc7,
00030
00031 M_JPG = 0xc8,
00032 M_SOF9 = 0xc9,
00033 M_SOF10 = 0xca,
00034 M_SOF11 = 0xcb,
00035
00036 M_SOF13 = 0xcd,
00037 M_SOF14 = 0xce,
00038 M_SOF15 = 0xcf,
00039
00040 M_DHT = 0xc4,
00041
00042 M_DAC = 0xcc,
00043
00044 M_RST0 = 0xd0,
00045 M_RST1 = 0xd1,
00046 M_RST2 = 0xd2,
00047 M_RST3 = 0xd3,
00048 M_RST4 = 0xd4,
00049 M_RST5 = 0xd5,
00050 M_RST6 = 0xd6,
00051 M_RST7 = 0xd7,
00052
00053 M_SOI = 0xd8,
00054 M_EOI = 0xd9,
00055 M_SOS = 0xda,
00056 M_DQT = 0xdb,
00057 M_DNL = 0xdc,
00058 M_DRI = 0xdd,
00059 M_DHP = 0xde,
00060 M_EXP = 0xdf,
00061
00062 M_APP0 = 0xe0,
00063 M_APP1 = 0xe1,
00064 M_APP2 = 0xe2,
00065 M_APP3 = 0xe3,
00066 M_APP4 = 0xe4,
00067 M_APP5 = 0xe5,
00068 M_APP6 = 0xe6,
00069 M_APP7 = 0xe7,
00070 M_APP8 = 0xe8,
00071 M_APP9 = 0xe9,
00072 M_APP10 = 0xea,
00073 M_APP11 = 0xeb,
00074 M_APP12 = 0xec,
00075 M_APP13 = 0xed,
00076 M_APP14 = 0xee,
00077 M_APP15 = 0xef,
00078
00079 M_JPG0 = 0xf0,
00080 M_JPG13 = 0xfd,
00081 M_COM = 0xfe,
00082
00083 M_TEM = 0x01,
00084
00085 M_ERROR = 0x100
00086 } JPEG_MARKER;
00087
00088
00089
00090
00091 typedef struct {
00092 struct jpeg_marker_reader pub;
00093
00094
00095 jpeg_marker_parser_method process_COM;
00096 jpeg_marker_parser_method process_APPn[16];
00097
00098
00099 unsigned int length_limit_COM;
00100 unsigned int length_limit_APPn[16];
00101
00102
00103 jpeg_saved_marker_ptr cur_marker;
00104 unsigned int bytes_read;
00105
00106 } my_marker_reader;
00107
00108 typedef my_marker_reader * my_marker_ptr;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #define INPUT_VARS(cinfo) \
00121 struct jpeg_source_mgr * datasrc = (cinfo)->src; \
00122 const JOCTET * next_input_byte = datasrc->next_input_byte; \
00123 size_t bytes_in_buffer = datasrc->bytes_in_buffer
00124
00125
00126 #define INPUT_SYNC(cinfo) \
00127 ( datasrc->next_input_byte = next_input_byte, \
00128 datasrc->bytes_in_buffer = bytes_in_buffer )
00129
00130
00131 #define INPUT_RELOAD(cinfo) \
00132 ( next_input_byte = datasrc->next_input_byte, \
00133 bytes_in_buffer = datasrc->bytes_in_buffer )
00134
00135
00136
00137
00138
00139 #define MAKE_BYTE_AVAIL(cinfo,action) \
00140 if (bytes_in_buffer == 0) { \
00141 if (! (*datasrc->fill_input_buffer) (cinfo)) \
00142 { action; } \
00143 INPUT_RELOAD(cinfo); \
00144 }
00145
00146
00147
00148
00149 #define INPUT_BYTE(cinfo,V,action) \
00150 MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
00151 bytes_in_buffer--; \
00152 V = GETJOCTET(*next_input_byte++); )
00153
00154
00155
00156
00157 #define INPUT_2BYTES(cinfo,V,action) \
00158 MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
00159 bytes_in_buffer--; \
00160 V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
00161 MAKE_BYTE_AVAIL(cinfo,action); \
00162 bytes_in_buffer--; \
00163 V += GETJOCTET(*next_input_byte++); )
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 LOCAL(boolean)
00198 get_soi (j_decompress_ptr cinfo)
00199
00200 {
00201 int i;
00202
00203 TRACEMS(cinfo, 1, JTRC_SOI);
00204
00205 if (cinfo->marker->saw_SOI)
00206 ERREXIT(cinfo, JERR_SOI_DUPLICATE);
00207
00208
00209
00210 for (i = 0; i < NUM_ARITH_TBLS; i++) {
00211 cinfo->arith_dc_L[i] = 0;
00212 cinfo->arith_dc_U[i] = 1;
00213 cinfo->arith_ac_K[i] = 5;
00214 }
00215 cinfo->restart_interval = 0;
00216
00217
00218
00219 cinfo->jpeg_color_space = JCS_UNKNOWN;
00220 cinfo->CCIR601_sampling = FALSE;
00221
00222 cinfo->saw_JFIF_marker = FALSE;
00223 cinfo->JFIF_major_version = 1;
00224 cinfo->JFIF_minor_version = 1;
00225 cinfo->density_unit = 0;
00226 cinfo->X_density = 1;
00227 cinfo->Y_density = 1;
00228 cinfo->saw_Adobe_marker = FALSE;
00229 cinfo->Adobe_transform = 0;
00230
00231 cinfo->marker->saw_SOI = TRUE;
00232
00233 return TRUE;
00234 }
00235
00236
00237 LOCAL(boolean)
00238 get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
00239 boolean is_arith)
00240
00241 {
00242 INT32 length;
00243 int c, ci;
00244 jpeg_component_info * compptr;
00245 INPUT_VARS(cinfo);
00246
00247 cinfo->is_baseline = is_baseline;
00248 cinfo->progressive_mode = is_prog;
00249 cinfo->arith_code = is_arith;
00250
00251 INPUT_2BYTES(cinfo, length, return FALSE);
00252
00253 INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
00254 INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
00255 INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
00256 INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
00257
00258 length -= 8;
00259
00260 TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
00261 (int) cinfo->image_width, (int) cinfo->image_height,
00262 cinfo->num_components);
00263
00264 if (cinfo->marker->saw_SOF)
00265 ERREXIT(cinfo, JERR_SOF_DUPLICATE);
00266
00267
00268
00269
00270 if (cinfo->image_height <= 0 || cinfo->image_width <= 0
00271 || cinfo->num_components <= 0)
00272 ERREXIT(cinfo, JERR_EMPTY_IMAGE);
00273
00274 if (length != (cinfo->num_components * 3))
00275 ERREXIT(cinfo, JERR_BAD_LENGTH);
00276
00277 if (cinfo->comp_info == NULL)
00278 cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
00279 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00280 cinfo->num_components * SIZEOF(jpeg_component_info));
00281
00282 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00283 ci++, compptr++) {
00284 compptr->component_index = ci;
00285 INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
00286 INPUT_BYTE(cinfo, c, return FALSE);
00287 compptr->h_samp_factor = (c >> 4) & 15;
00288 compptr->v_samp_factor = (c ) & 15;
00289 INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
00290
00291 TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
00292 compptr->component_id, compptr->h_samp_factor,
00293 compptr->v_samp_factor, compptr->quant_tbl_no);
00294 }
00295
00296 cinfo->marker->saw_SOF = TRUE;
00297
00298 INPUT_SYNC(cinfo);
00299 return TRUE;
00300 }
00301
00302
00303 LOCAL(boolean)
00304 get_sos (j_decompress_ptr cinfo)
00305
00306 {
00307 INT32 length;
00308 int i, ci, n, c, cc;
00309 jpeg_component_info * compptr;
00310 INPUT_VARS(cinfo);
00311
00312 if (! cinfo->marker->saw_SOF)
00313 ERREXIT(cinfo, JERR_SOS_NO_SOF);
00314
00315 INPUT_2BYTES(cinfo, length, return FALSE);
00316
00317 INPUT_BYTE(cinfo, n, return FALSE);
00318
00319 TRACEMS1(cinfo, 1, JTRC_SOS, n);
00320
00321 if (length != (n * 2 + 6) || n > MAX_COMPS_IN_SCAN ||
00322 (n == 0 && !cinfo->progressive_mode))
00323
00324 ERREXIT(cinfo, JERR_BAD_LENGTH);
00325
00326 cinfo->comps_in_scan = n;
00327
00328
00329
00330 for (i = 0; i < n; i++) {
00331 INPUT_BYTE(cinfo, cc, return FALSE);
00332 INPUT_BYTE(cinfo, c, return FALSE);
00333
00334 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00335 ci++, compptr++) {
00336 if (cc == compptr->component_id)
00337 goto id_found;
00338 }
00339
00340 ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
00341
00342 id_found:
00343
00344 cinfo->cur_comp_info[i] = compptr;
00345 compptr->dc_tbl_no = (c >> 4) & 15;
00346 compptr->ac_tbl_no = (c ) & 15;
00347
00348 TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
00349 compptr->dc_tbl_no, compptr->ac_tbl_no);
00350 }
00351
00352
00353 INPUT_BYTE(cinfo, c, return FALSE);
00354 cinfo->Ss = c;
00355 INPUT_BYTE(cinfo, c, return FALSE);
00356 cinfo->Se = c;
00357 INPUT_BYTE(cinfo, c, return FALSE);
00358 cinfo->Ah = (c >> 4) & 15;
00359 cinfo->Al = (c ) & 15;
00360
00361 TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
00362 cinfo->Ah, cinfo->Al);
00363
00364
00365 cinfo->marker->next_restart_num = 0;
00366
00367
00368 if (n) cinfo->input_scan_number++;
00369
00370 INPUT_SYNC(cinfo);
00371 return TRUE;
00372 }
00373
00374
00375 #ifdef D_ARITH_CODING_SUPPORTED
00376
00377 LOCAL(boolean)
00378 get_dac (j_decompress_ptr cinfo)
00379
00380 {
00381 INT32 length;
00382 int index, val;
00383 INPUT_VARS(cinfo);
00384
00385 INPUT_2BYTES(cinfo, length, return FALSE);
00386 length -= 2;
00387
00388 while (length > 0) {
00389 INPUT_BYTE(cinfo, index, return FALSE);
00390 INPUT_BYTE(cinfo, val, return FALSE);
00391
00392 length -= 2;
00393
00394 TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
00395
00396 if (index < 0 || index >= (2*NUM_ARITH_TBLS))
00397 ERREXIT1(cinfo, JERR_DAC_INDEX, index);
00398
00399 if (index >= NUM_ARITH_TBLS) {
00400 cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
00401 } else {
00402 cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
00403 cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
00404 if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
00405 ERREXIT1(cinfo, JERR_DAC_VALUE, val);
00406 }
00407 }
00408
00409 if (length != 0)
00410 ERREXIT(cinfo, JERR_BAD_LENGTH);
00411
00412 INPUT_SYNC(cinfo);
00413 return TRUE;
00414 }
00415
00416 #else
00417
00418 #define get_dac(cinfo) skip_variable(cinfo)
00419
00420 #endif
00421
00422
00423 LOCAL(boolean)
00424 get_dht (j_decompress_ptr cinfo)
00425
00426 {
00427 INT32 length;
00428 UINT8 bits[17];
00429 UINT8 huffval[256];
00430 int i, index, count;
00431 JHUFF_TBL **htblptr;
00432 INPUT_VARS(cinfo);
00433
00434 INPUT_2BYTES(cinfo, length, return FALSE);
00435 length -= 2;
00436
00437 while (length > 16) {
00438 INPUT_BYTE(cinfo, index, return FALSE);
00439
00440 TRACEMS1(cinfo, 1, JTRC_DHT, index);
00441
00442 bits[0] = 0;
00443 count = 0;
00444 for (i = 1; i <= 16; i++) {
00445 INPUT_BYTE(cinfo, bits[i], return FALSE);
00446 count += bits[i];
00447 }
00448
00449 length -= 1 + 16;
00450
00451 TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
00452 bits[1], bits[2], bits[3], bits[4],
00453 bits[5], bits[6], bits[7], bits[8]);
00454 TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
00455 bits[9], bits[10], bits[11], bits[12],
00456 bits[13], bits[14], bits[15], bits[16]);
00457
00458
00459
00460
00461 if (count > 256 || ((INT32) count) > length)
00462 ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
00463
00464 for (i = 0; i < count; i++)
00465 INPUT_BYTE(cinfo, huffval[i], return FALSE);
00466
00467 length -= count;
00468
00469 if (index & 0x10) {
00470 index -= 0x10;
00471 htblptr = &cinfo->ac_huff_tbl_ptrs[index];
00472 } else {
00473 htblptr = &cinfo->dc_huff_tbl_ptrs[index];
00474 }
00475
00476 if (index < 0 || index >= NUM_HUFF_TBLS)
00477 ERREXIT1(cinfo, JERR_DHT_INDEX, index);
00478
00479 if (*htblptr == NULL)
00480 *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
00481
00482 MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
00483 MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
00484 }
00485
00486 if (length != 0)
00487 ERREXIT(cinfo, JERR_BAD_LENGTH);
00488
00489 INPUT_SYNC(cinfo);
00490 return TRUE;
00491 }
00492
00493
00494 LOCAL(boolean)
00495 get_dqt (j_decompress_ptr cinfo)
00496
00497 {
00498 INT32 length, count, i;
00499 int n, prec;
00500 unsigned int tmp;
00501 JQUANT_TBL *quant_ptr;
00502 const int *natural_order;
00503 INPUT_VARS(cinfo);
00504
00505 INPUT_2BYTES(cinfo, length, return FALSE);
00506 length -= 2;
00507
00508 while (length > 0) {
00509 length--;
00510 INPUT_BYTE(cinfo, n, return FALSE);
00511 prec = n >> 4;
00512 n &= 0x0F;
00513
00514 TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
00515
00516 if (n >= NUM_QUANT_TBLS)
00517 ERREXIT1(cinfo, JERR_DQT_INDEX, n);
00518
00519 if (cinfo->quant_tbl_ptrs[n] == NULL)
00520 cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
00521 quant_ptr = cinfo->quant_tbl_ptrs[n];
00522
00523 if (prec) {
00524 if (length < DCTSIZE2 * 2) {
00525
00526 for (i = 0; i < DCTSIZE2; i++) {
00527 quant_ptr->quantval[i] = 1;
00528 }
00529 count = length >> 1;
00530 } else
00531 count = DCTSIZE2;
00532 } else {
00533 if (length < DCTSIZE2) {
00534
00535 for (i = 0; i < DCTSIZE2; i++) {
00536 quant_ptr->quantval[i] = 1;
00537 }
00538 count = length;
00539 } else
00540 count = DCTSIZE2;
00541 }
00542
00543 switch (count) {
00544 case (2*2): natural_order = jpeg_natural_order2; break;
00545 case (3*3): natural_order = jpeg_natural_order3; break;
00546 case (4*4): natural_order = jpeg_natural_order4; break;
00547 case (5*5): natural_order = jpeg_natural_order5; break;
00548 case (6*6): natural_order = jpeg_natural_order6; break;
00549 case (7*7): natural_order = jpeg_natural_order7; break;
00550 default: natural_order = jpeg_natural_order; break;
00551 }
00552
00553 for (i = 0; i < count; i++) {
00554 if (prec)
00555 INPUT_2BYTES(cinfo, tmp, return FALSE);
00556 else
00557 INPUT_BYTE(cinfo, tmp, return FALSE);
00558
00559 quant_ptr->quantval[natural_order[i]] = (UINT16) tmp;
00560 }
00561
00562 if (cinfo->err->trace_level >= 2) {
00563 for (i = 0; i < DCTSIZE2; i += 8) {
00564 TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
00565 quant_ptr->quantval[i], quant_ptr->quantval[i+1],
00566 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
00567 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
00568 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
00569 }
00570 }
00571
00572 length -= count;
00573 if (prec) length -= count;
00574 }
00575
00576 if (length != 0)
00577 ERREXIT(cinfo, JERR_BAD_LENGTH);
00578
00579 INPUT_SYNC(cinfo);
00580 return TRUE;
00581 }
00582
00583
00584 LOCAL(boolean)
00585 get_dri (j_decompress_ptr cinfo)
00586
00587 {
00588 INT32 length;
00589 unsigned int tmp;
00590 INPUT_VARS(cinfo);
00591
00592 INPUT_2BYTES(cinfo, length, return FALSE);
00593
00594 if (length != 4)
00595 ERREXIT(cinfo, JERR_BAD_LENGTH);
00596
00597 INPUT_2BYTES(cinfo, tmp, return FALSE);
00598
00599 TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
00600
00601 cinfo->restart_interval = tmp;
00602
00603 INPUT_SYNC(cinfo);
00604 return TRUE;
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 #define APP0_DATA_LEN 14
00616 #define APP14_DATA_LEN 12
00617 #define APPN_DATA_LEN 14
00618
00619
00620 LOCAL(void)
00621 examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
00622 unsigned int datalen, INT32 remaining)
00623
00624
00625
00626
00627 {
00628 INT32 totallen = (INT32) datalen + remaining;
00629
00630 if (datalen >= APP0_DATA_LEN &&
00631 GETJOCTET(data[0]) == 0x4A &&
00632 GETJOCTET(data[1]) == 0x46 &&
00633 GETJOCTET(data[2]) == 0x49 &&
00634 GETJOCTET(data[3]) == 0x46 &&
00635 GETJOCTET(data[4]) == 0) {
00636
00637 cinfo->saw_JFIF_marker = TRUE;
00638 cinfo->JFIF_major_version = GETJOCTET(data[5]);
00639 cinfo->JFIF_minor_version = GETJOCTET(data[6]);
00640 cinfo->density_unit = GETJOCTET(data[7]);
00641 cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
00642 cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
00643
00644
00645
00646
00647
00648
00649 if (cinfo->JFIF_major_version != 1)
00650 WARNMS2(cinfo, JWRN_JFIF_MAJOR,
00651 cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
00652
00653 TRACEMS5(cinfo, 1, JTRC_JFIF,
00654 cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
00655 cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
00656
00657 if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
00658 TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
00659 GETJOCTET(data[12]), GETJOCTET(data[13]));
00660 totallen -= APP0_DATA_LEN;
00661 if (totallen !=
00662 ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
00663 TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
00664 } else if (datalen >= 6 &&
00665 GETJOCTET(data[0]) == 0x4A &&
00666 GETJOCTET(data[1]) == 0x46 &&
00667 GETJOCTET(data[2]) == 0x58 &&
00668 GETJOCTET(data[3]) == 0x58 &&
00669 GETJOCTET(data[4]) == 0) {
00670
00671
00672
00673
00674 switch (GETJOCTET(data[5])) {
00675 case 0x10:
00676 TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
00677 break;
00678 case 0x11:
00679 TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
00680 break;
00681 case 0x13:
00682 TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
00683 break;
00684 default:
00685 TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
00686 GETJOCTET(data[5]), (int) totallen);
00687 break;
00688 }
00689 } else {
00690
00691 TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
00692 }
00693 }
00694
00695
00696 LOCAL(void)
00697 examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
00698 unsigned int datalen, INT32 remaining)
00699
00700
00701
00702
00703 {
00704 unsigned int version, flags0, flags1, transform;
00705
00706 if (datalen >= APP14_DATA_LEN &&
00707 GETJOCTET(data[0]) == 0x41 &&
00708 GETJOCTET(data[1]) == 0x64 &&
00709 GETJOCTET(data[2]) == 0x6F &&
00710 GETJOCTET(data[3]) == 0x62 &&
00711 GETJOCTET(data[4]) == 0x65) {
00712
00713 version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
00714 flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
00715 flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
00716 transform = GETJOCTET(data[11]);
00717 TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
00718 cinfo->saw_Adobe_marker = TRUE;
00719 cinfo->Adobe_transform = (UINT8) transform;
00720 } else {
00721
00722 TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
00723 }
00724 }
00725
00726
00727 METHODDEF(boolean)
00728 get_interesting_appn (j_decompress_ptr cinfo)
00729
00730 {
00731 INT32 length;
00732 JOCTET b[APPN_DATA_LEN];
00733 unsigned int i, numtoread;
00734 INPUT_VARS(cinfo);
00735
00736 INPUT_2BYTES(cinfo, length, return FALSE);
00737 length -= 2;
00738
00739
00740 if (length >= APPN_DATA_LEN)
00741 numtoread = APPN_DATA_LEN;
00742 else if (length > 0)
00743 numtoread = (unsigned int) length;
00744 else
00745 numtoread = 0;
00746 for (i = 0; i < numtoread; i++)
00747 INPUT_BYTE(cinfo, b[i], return FALSE);
00748 length -= numtoread;
00749
00750
00751 switch (cinfo->unread_marker) {
00752 case M_APP0:
00753 examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
00754 break;
00755 case M_APP14:
00756 examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
00757 break;
00758 default:
00759
00760 ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
00761 break;
00762 }
00763
00764
00765 INPUT_SYNC(cinfo);
00766 if (length > 0)
00767 (*cinfo->src->skip_input_data) (cinfo, (long) length);
00768
00769 return TRUE;
00770 }
00771
00772
00773 #ifdef SAVE_MARKERS_SUPPORTED
00774
00775 METHODDEF(boolean)
00776 save_marker (j_decompress_ptr cinfo)
00777
00778 {
00779 my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
00780 jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
00781 unsigned int bytes_read, data_length;
00782 JOCTET FAR * data;
00783 INT32 length = 0;
00784 INPUT_VARS(cinfo);
00785
00786 if (cur_marker == NULL) {
00787
00788 INPUT_2BYTES(cinfo, length, return FALSE);
00789 length -= 2;
00790 if (length >= 0) {
00791
00792 unsigned int limit;
00793 if (cinfo->unread_marker == (int) M_COM)
00794 limit = marker->length_limit_COM;
00795 else
00796 limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
00797 if ((unsigned int) length < limit)
00798 limit = (unsigned int) length;
00799
00800 cur_marker = (jpeg_saved_marker_ptr)
00801 (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00802 SIZEOF(struct jpeg_marker_struct) + limit);
00803 cur_marker->next = NULL;
00804 cur_marker->marker = (UINT8) cinfo->unread_marker;
00805 cur_marker->original_length = (unsigned int) length;
00806 cur_marker->data_length = limit;
00807
00808 data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
00809 marker->cur_marker = cur_marker;
00810 marker->bytes_read = 0;
00811 bytes_read = 0;
00812 data_length = limit;
00813 } else {
00814
00815 bytes_read = data_length = 0;
00816 data = NULL;
00817 }
00818 } else {
00819
00820 bytes_read = marker->bytes_read;
00821 data_length = cur_marker->data_length;
00822 data = cur_marker->data + bytes_read;
00823 }
00824
00825 while (bytes_read < data_length) {
00826 INPUT_SYNC(cinfo);
00827 marker->bytes_read = bytes_read;
00828
00829 MAKE_BYTE_AVAIL(cinfo, return FALSE);
00830
00831 while (bytes_read < data_length && bytes_in_buffer > 0) {
00832 *data++ = *next_input_byte++;
00833 bytes_in_buffer--;
00834 bytes_read++;
00835 }
00836 }
00837
00838
00839 if (cur_marker != NULL) {
00840
00841 if (cinfo->marker_list == NULL) {
00842 cinfo->marker_list = cur_marker;
00843 } else {
00844 jpeg_saved_marker_ptr prev = cinfo->marker_list;
00845 while (prev->next != NULL)
00846 prev = prev->next;
00847 prev->next = cur_marker;
00848 }
00849
00850 data = cur_marker->data;
00851 length = cur_marker->original_length - data_length;
00852 }
00853
00854 marker->cur_marker = NULL;
00855
00856
00857 switch (cinfo->unread_marker) {
00858 case M_APP0:
00859 examine_app0(cinfo, data, data_length, length);
00860 break;
00861 case M_APP14:
00862 examine_app14(cinfo, data, data_length, length);
00863 break;
00864 default:
00865 TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
00866 (int) (data_length + length));
00867 break;
00868 }
00869
00870
00871 INPUT_SYNC(cinfo);
00872 if (length > 0)
00873 (*cinfo->src->skip_input_data) (cinfo, (long) length);
00874
00875 return TRUE;
00876 }
00877
00878 #endif
00879
00880
00881 METHODDEF(boolean)
00882 skip_variable (j_decompress_ptr cinfo)
00883
00884 {
00885 INT32 length;
00886 INPUT_VARS(cinfo);
00887
00888 INPUT_2BYTES(cinfo, length, return FALSE);
00889 length -= 2;
00890
00891 TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
00892
00893 INPUT_SYNC(cinfo);
00894 if (length > 0)
00895 (*cinfo->src->skip_input_data) (cinfo, (long) length);
00896
00897 return TRUE;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 LOCAL(boolean)
00911 next_marker (j_decompress_ptr cinfo)
00912 {
00913 int c;
00914 INPUT_VARS(cinfo);
00915
00916 for (;;) {
00917 INPUT_BYTE(cinfo, c, return FALSE);
00918
00919
00920
00921
00922
00923 while (c != 0xFF) {
00924 cinfo->marker->discarded_bytes++;
00925 INPUT_SYNC(cinfo);
00926 INPUT_BYTE(cinfo, c, return FALSE);
00927 }
00928
00929
00930
00931
00932
00933 do {
00934 INPUT_BYTE(cinfo, c, return FALSE);
00935 } while (c == 0xFF);
00936 if (c != 0)
00937 break;
00938
00939
00940
00941 cinfo->marker->discarded_bytes += 2;
00942 INPUT_SYNC(cinfo);
00943 }
00944
00945 if (cinfo->marker->discarded_bytes != 0) {
00946 WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
00947 cinfo->marker->discarded_bytes = 0;
00948 }
00949
00950 cinfo->unread_marker = c;
00951
00952 INPUT_SYNC(cinfo);
00953 return TRUE;
00954 }
00955
00956
00957 LOCAL(boolean)
00958 first_marker (j_decompress_ptr cinfo)
00959
00960
00961
00962
00963
00964
00965 {
00966 int c, c2;
00967 INPUT_VARS(cinfo);
00968
00969 INPUT_BYTE(cinfo, c, return FALSE);
00970 INPUT_BYTE(cinfo, c2, return FALSE);
00971 if (c != 0xFF || c2 != (int) M_SOI)
00972 ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
00973
00974 cinfo->unread_marker = c2;
00975
00976 INPUT_SYNC(cinfo);
00977 return TRUE;
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 METHODDEF(int)
00994 read_markers (j_decompress_ptr cinfo)
00995 {
00996
00997 for (;;) {
00998
00999
01000 if (cinfo->unread_marker == 0) {
01001 if (! cinfo->marker->saw_SOI) {
01002 if (! first_marker(cinfo))
01003 return JPEG_SUSPENDED;
01004 } else {
01005 if (! next_marker(cinfo))
01006 return JPEG_SUSPENDED;
01007 }
01008 }
01009
01010
01011
01012
01013 switch (cinfo->unread_marker) {
01014 case M_SOI:
01015 if (! get_soi(cinfo))
01016 return JPEG_SUSPENDED;
01017 break;
01018
01019 case M_SOF0:
01020 if (! get_sof(cinfo, TRUE, FALSE, FALSE))
01021 return JPEG_SUSPENDED;
01022 break;
01023
01024 case M_SOF1:
01025 if (! get_sof(cinfo, FALSE, FALSE, FALSE))
01026 return JPEG_SUSPENDED;
01027 break;
01028
01029 case M_SOF2:
01030 if (! get_sof(cinfo, FALSE, TRUE, FALSE))
01031 return JPEG_SUSPENDED;
01032 break;
01033
01034 case M_SOF9:
01035 if (! get_sof(cinfo, FALSE, FALSE, TRUE))
01036 return JPEG_SUSPENDED;
01037 break;
01038
01039 case M_SOF10:
01040 if (! get_sof(cinfo, FALSE, TRUE, TRUE))
01041 return JPEG_SUSPENDED;
01042 break;
01043
01044
01045 case M_SOF3:
01046 case M_SOF5:
01047 case M_SOF6:
01048 case M_SOF7:
01049 case M_JPG:
01050 case M_SOF11:
01051 case M_SOF13:
01052 case M_SOF14:
01053 case M_SOF15:
01054 ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
01055 break;
01056
01057 case M_SOS:
01058 if (! get_sos(cinfo))
01059 return JPEG_SUSPENDED;
01060 cinfo->unread_marker = 0;
01061 return JPEG_REACHED_SOS;
01062
01063 case M_EOI:
01064 TRACEMS(cinfo, 1, JTRC_EOI);
01065 cinfo->unread_marker = 0;
01066 return JPEG_REACHED_EOI;
01067
01068 case M_DAC:
01069 if (! get_dac(cinfo))
01070 return JPEG_SUSPENDED;
01071 break;
01072
01073 case M_DHT:
01074 if (! get_dht(cinfo))
01075 return JPEG_SUSPENDED;
01076 break;
01077
01078 case M_DQT:
01079 if (! get_dqt(cinfo))
01080 return JPEG_SUSPENDED;
01081 break;
01082
01083 case M_DRI:
01084 if (! get_dri(cinfo))
01085 return JPEG_SUSPENDED;
01086 break;
01087
01088 case M_APP0:
01089 case M_APP1:
01090 case M_APP2:
01091 case M_APP3:
01092 case M_APP4:
01093 case M_APP5:
01094 case M_APP6:
01095 case M_APP7:
01096 case M_APP8:
01097 case M_APP9:
01098 case M_APP10:
01099 case M_APP11:
01100 case M_APP12:
01101 case M_APP13:
01102 case M_APP14:
01103 case M_APP15:
01104 if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
01105 cinfo->unread_marker - (int) M_APP0]) (cinfo))
01106 return JPEG_SUSPENDED;
01107 break;
01108
01109 case M_COM:
01110 if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
01111 return JPEG_SUSPENDED;
01112 break;
01113
01114 case M_RST0:
01115 case M_RST1:
01116 case M_RST2:
01117 case M_RST3:
01118 case M_RST4:
01119 case M_RST5:
01120 case M_RST6:
01121 case M_RST7:
01122 case M_TEM:
01123 TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
01124 break;
01125
01126 case M_DNL:
01127 if (! skip_variable(cinfo))
01128 return JPEG_SUSPENDED;
01129 break;
01130
01131 default:
01132
01133
01134
01135
01136
01137 ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
01138 break;
01139 }
01140
01141 cinfo->unread_marker = 0;
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 METHODDEF(boolean)
01159 read_restart_marker (j_decompress_ptr cinfo)
01160 {
01161
01162
01163 if (cinfo->unread_marker == 0) {
01164 if (! next_marker(cinfo))
01165 return FALSE;
01166 }
01167
01168 if (cinfo->unread_marker ==
01169 ((int) M_RST0 + cinfo->marker->next_restart_num)) {
01170
01171 TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
01172 cinfo->unread_marker = 0;
01173 } else {
01174
01175
01176 if (! (*cinfo->src->resync_to_restart) (cinfo,
01177 cinfo->marker->next_restart_num))
01178 return FALSE;
01179 }
01180
01181
01182 cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
01183
01184 return TRUE;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 GLOBAL(boolean)
01238 jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
01239 {
01240 int marker = cinfo->unread_marker;
01241 int action = 1;
01242
01243
01244 WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
01245
01246
01247 for (;;) {
01248 if (marker < (int) M_SOF0)
01249 action = 2;
01250 else if (marker < (int) M_RST0 || marker > (int) M_RST7)
01251 action = 3;
01252 else {
01253 if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
01254 marker == ((int) M_RST0 + ((desired+2) & 7)))
01255 action = 3;
01256 else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
01257 marker == ((int) M_RST0 + ((desired-2) & 7)))
01258 action = 2;
01259 else
01260 action = 1;
01261 }
01262 TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
01263 switch (action) {
01264 case 1:
01265
01266 cinfo->unread_marker = 0;
01267 return TRUE;
01268 case 2:
01269
01270 if (! next_marker(cinfo))
01271 return FALSE;
01272 marker = cinfo->unread_marker;
01273 break;
01274 case 3:
01275
01276
01277 return TRUE;
01278 }
01279 }
01280 }
01281
01282
01283
01284
01285
01286
01287 METHODDEF(void)
01288 reset_marker_reader (j_decompress_ptr cinfo)
01289 {
01290 my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01291
01292 cinfo->comp_info = NULL;
01293 cinfo->input_scan_number = 0;
01294 cinfo->unread_marker = 0;
01295 marker->pub.saw_SOI = FALSE;
01296 marker->pub.saw_SOF = FALSE;
01297 marker->pub.discarded_bytes = 0;
01298 marker->cur_marker = NULL;
01299 }
01300
01301
01302
01303
01304
01305
01306
01307 GLOBAL(void)
01308 jinit_marker_reader (j_decompress_ptr cinfo)
01309 {
01310 my_marker_ptr marker;
01311 int i;
01312
01313
01314 marker = (my_marker_ptr)
01315 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
01316 SIZEOF(my_marker_reader));
01317 cinfo->marker = (struct jpeg_marker_reader *) marker;
01318
01319 marker->pub.reset_marker_reader = reset_marker_reader;
01320 marker->pub.read_markers = read_markers;
01321 marker->pub.read_restart_marker = read_restart_marker;
01322
01323
01324
01325
01326 marker->process_COM = skip_variable;
01327 marker->length_limit_COM = 0;
01328 for (i = 0; i < 16; i++) {
01329 marker->process_APPn[i] = skip_variable;
01330 marker->length_limit_APPn[i] = 0;
01331 }
01332 marker->process_APPn[0] = get_interesting_appn;
01333 marker->process_APPn[14] = get_interesting_appn;
01334
01335 reset_marker_reader(cinfo);
01336 }
01337
01338
01339
01340
01341
01342
01343 #ifdef SAVE_MARKERS_SUPPORTED
01344
01345 GLOBAL(void)
01346 jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
01347 unsigned int length_limit)
01348 {
01349 my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01350 long maxlength;
01351 jpeg_marker_parser_method processor;
01352
01353
01354
01355
01356 maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
01357 if (((long) length_limit) > maxlength)
01358 length_limit = (unsigned int) maxlength;
01359
01360
01361
01362
01363 if (length_limit) {
01364 processor = save_marker;
01365
01366 if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
01367 length_limit = APP0_DATA_LEN;
01368 else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
01369 length_limit = APP14_DATA_LEN;
01370 } else {
01371 processor = skip_variable;
01372
01373 if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
01374 processor = get_interesting_appn;
01375 }
01376
01377 if (marker_code == (int) M_COM) {
01378 marker->process_COM = processor;
01379 marker->length_limit_COM = length_limit;
01380 } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
01381 marker->process_APPn[marker_code - (int) M_APP0] = processor;
01382 marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
01383 } else
01384 ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
01385 }
01386
01387 #endif
01388
01389
01390
01391
01392
01393
01394 GLOBAL(void)
01395 jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
01396 jpeg_marker_parser_method routine)
01397 {
01398 my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01399
01400 if (marker_code == (int) M_COM)
01401 marker->process_COM = routine;
01402 else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
01403 marker->process_APPn[marker_code - (int) M_APP0] = routine;
01404 else
01405 ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
01406 }