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