< prev index next >

modules/javafx.graphics/src/main/native-iio/libjpeg7/jdmarker.c

Print this page

        

*** 1,9 **** --- 1,10 ---- /* * jdmarker.c * * Copyright (C) 1991-1998, Thomas G. Lane. + * Modified 2009-2013 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains routines to decode JPEG datastream markers. * Most of the complexity arises from our desire to support input
*** 74,83 **** --- 75,85 ---- M_APP13 = 0xed, M_APP14 = 0xee, M_APP15 = 0xef, M_JPG0 = 0xf0, + M_JPG8 = 0xf8, M_JPG13 = 0xfd, M_COM = 0xfe, M_TEM = 0x01,
*** 214,223 **** --- 216,226 ---- cinfo->restart_interval = 0; /* Set initial assumptions for colorspace etc */ cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->color_transform = JCT_NONE; cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ cinfo->saw_JFIF_marker = FALSE; cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ cinfo->JFIF_minor_version = 1;
*** 232,249 **** return TRUE; } LOCAL(boolean) ! get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) /* Process a SOFn marker */ { INT32 length; ! int c, ci; jpeg_component_info * compptr; INPUT_VARS(cinfo); cinfo->progressive_mode = is_prog; cinfo->arith_code = is_arith; INPUT_2BYTES(cinfo, length, return FALSE); --- 235,254 ---- return TRUE; } LOCAL(boolean) ! get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog, ! boolean is_arith) /* Process a SOFn marker */ { INT32 length; ! int c, ci, i; jpeg_component_info * compptr; INPUT_VARS(cinfo); + cinfo->is_baseline = is_baseline; cinfo->progressive_mode = is_prog; cinfo->arith_code = is_arith; INPUT_2BYTES(cinfo, length, return FALSE);
*** 262,287 **** ERREXIT(cinfo, JERR_SOF_DUPLICATE); /* We don't support files in which the image height is initially specified */ /* as 0 and is later redefined by DNL. As long as we have to check that, */ /* might as well have a general sanity check. */ ! if (cinfo->image_height <= 0 || cinfo->image_width <= 0 ! || cinfo->num_components <= 0) ERREXIT(cinfo, JERR_EMPTY_IMAGE); if (length != (cinfo->num_components * 3)) ERREXIT(cinfo, JERR_BAD_LENGTH); if (cinfo->comp_info == NULL) /* do only once, even if suspend */ cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->num_components * SIZEOF(jpeg_component_info)); ! for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ! ci++, compptr++) { compptr->component_index = ci; - INPUT_BYTE(cinfo, compptr->component_id, return FALSE); INPUT_BYTE(cinfo, c, return FALSE); compptr->h_samp_factor = (c >> 4) & 15; compptr->v_samp_factor = (c ) & 15; INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); --- 267,308 ---- ERREXIT(cinfo, JERR_SOF_DUPLICATE); /* We don't support files in which the image height is initially specified */ /* as 0 and is later redefined by DNL. As long as we have to check that, */ /* might as well have a general sanity check. */ ! if (cinfo->image_height <= 0 || cinfo->image_width <= 0 || ! cinfo->num_components <= 0) ERREXIT(cinfo, JERR_EMPTY_IMAGE); if (length != (cinfo->num_components * 3)) ERREXIT(cinfo, JERR_BAD_LENGTH); if (cinfo->comp_info == NULL) /* do only once, even if suspend */ cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->num_components * SIZEOF(jpeg_component_info)); ! for (ci = 0; ci < cinfo->num_components; ci++) { ! INPUT_BYTE(cinfo, c, return FALSE); ! /* Check to see whether component id has already been seen */ ! /* (in violation of the spec, but unfortunately seen in some */ ! /* files). If so, create "fake" component id equal to the */ ! /* max id seen so far + 1. */ ! for (i = 0, compptr = cinfo->comp_info; i < ci; i++, compptr++) { ! if (c == compptr->component_id) { ! compptr = cinfo->comp_info; ! c = compptr->component_id; ! compptr++; ! for (i = 1; i < ci; i++, compptr++) { ! if (compptr->component_id > c) c = compptr->component_id; ! } ! c++; ! break; ! } ! } ! compptr->component_id = c; compptr->component_index = ci; INPUT_BYTE(cinfo, c, return FALSE); compptr->h_samp_factor = (c >> 4) & 15; compptr->v_samp_factor = (c ) & 15; INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
*** 300,348 **** LOCAL(boolean) get_sos (j_decompress_ptr cinfo) /* Process a SOS marker */ { INT32 length; ! int i, ci, n, c, cc; jpeg_component_info * compptr; INPUT_VARS(cinfo); if (! cinfo->marker->saw_SOF) ! ERREXIT(cinfo, JERR_SOS_NO_SOF); INPUT_2BYTES(cinfo, length, return FALSE); INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ TRACEMS1(cinfo, 1, JTRC_SOS, n); ! if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) ERREXIT(cinfo, JERR_BAD_LENGTH); cinfo->comps_in_scan = n; /* Collect the component-spec parameters */ for (i = 0; i < n; i++) { - INPUT_BYTE(cinfo, cc, return FALSE); INPUT_BYTE(cinfo, c, return FALSE); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { ! if (cc == compptr->component_id) goto id_found; } ! ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); id_found: cinfo->cur_comp_info[i] = compptr; compptr->dc_tbl_no = (c >> 4) & 15; compptr->ac_tbl_no = (c ) & 15; ! TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, compptr->dc_tbl_no, compptr->ac_tbl_no); } /* Collect the additional scan parameters Ss, Se, Ah/Al. */ INPUT_BYTE(cinfo, c, return FALSE); --- 321,388 ---- LOCAL(boolean) get_sos (j_decompress_ptr cinfo) /* Process a SOS marker */ { INT32 length; ! int c, ci, i, n; jpeg_component_info * compptr; INPUT_VARS(cinfo); if (! cinfo->marker->saw_SOF) ! ERREXITS(cinfo, JERR_SOF_BEFORE, "SOS"); INPUT_2BYTES(cinfo, length, return FALSE); INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ TRACEMS1(cinfo, 1, JTRC_SOS, n); ! if (length != (n * 2 + 6) || n > MAX_COMPS_IN_SCAN || ! (n == 0 && !cinfo->progressive_mode)) ! /* pseudo SOS marker only allowed in progressive mode */ ERREXIT(cinfo, JERR_BAD_LENGTH); cinfo->comps_in_scan = n; /* Collect the component-spec parameters */ for (i = 0; i < n; i++) { INPUT_BYTE(cinfo, c, return FALSE); + /* Detect the case where component id's are not unique, and, if so, */ + /* create a fake component id using the same logic as in get_sof. */ + /* Note: This also ensures that all of the SOF components are */ + /* referenced in the single scan case, which prevents access to */ + /* uninitialized memory in later decoding stages. */ + for (ci = 0; ci < i; ci++) { + if (c == cinfo->cur_comp_info[ci]->component_id) { + c = cinfo->cur_comp_info[0]->component_id; + for (ci = 1; ci < i; ci++) { + compptr = cinfo->cur_comp_info[ci]; + if (compptr->component_id > c) c = compptr->component_id; + } + c++; + break; + } + } + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { ! if (c == compptr->component_id) goto id_found; } ! ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, c); id_found: cinfo->cur_comp_info[i] = compptr; + INPUT_BYTE(cinfo, c, return FALSE); compptr->dc_tbl_no = (c >> 4) & 15; compptr->ac_tbl_no = (c ) & 15; ! TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, compptr->component_id, compptr->dc_tbl_no, compptr->ac_tbl_no); } /* Collect the additional scan parameters Ss, Se, Ah/Al. */ INPUT_BYTE(cinfo, c, return FALSE);
*** 357,368 **** cinfo->Ah, cinfo->Al); /* Prepare to scan data & restart markers */ cinfo->marker->next_restart_num = 0; ! /* Count another SOS marker */ ! cinfo->input_scan_number++; INPUT_SYNC(cinfo); return TRUE; } --- 397,408 ---- cinfo->Ah, cinfo->Al); /* Prepare to scan data & restart markers */ cinfo->marker->next_restart_num = 0; ! /* Count another (non-pseudo) SOS marker */ ! if (n) cinfo->input_scan_number++; INPUT_SYNC(cinfo); return TRUE; }
*** 454,463 **** --- 494,505 ---- * off the end of our table space. jdhuff.c will check more carefully. */ if (count > 256 || ((INT32) count) > length) ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */ + for (i = 0; i < count; i++) INPUT_BYTE(cinfo, huffval[i], return FALSE); length -= count;
*** 488,507 **** LOCAL(boolean) get_dqt (j_decompress_ptr cinfo) /* Process a DQT marker */ { ! INT32 length; ! int n, i, prec; unsigned int tmp; JQUANT_TBL *quant_ptr; INPUT_VARS(cinfo); INPUT_2BYTES(cinfo, length, return FALSE); length -= 2; while (length > 0) { INPUT_BYTE(cinfo, n, return FALSE); prec = n >> 4; n &= 0x0F; TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); --- 530,551 ---- LOCAL(boolean) get_dqt (j_decompress_ptr cinfo) /* Process a DQT marker */ { ! INT32 length, count, i; ! int n, prec; unsigned int tmp; JQUANT_TBL *quant_ptr; + const int *natural_order; INPUT_VARS(cinfo); INPUT_2BYTES(cinfo, length, return FALSE); length -= 2; while (length > 0) { + length--; INPUT_BYTE(cinfo, n, return FALSE); prec = n >> 4; n &= 0x0F; TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
*** 511,527 **** if (cinfo->quant_tbl_ptrs[n] == NULL) cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); quant_ptr = cinfo->quant_tbl_ptrs[n]; for (i = 0; i < DCTSIZE2; i++) { if (prec) INPUT_2BYTES(cinfo, tmp, return FALSE); else INPUT_BYTE(cinfo, tmp, return FALSE); /* We convert the zigzag-order table to natural array order. */ ! quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; } if (cinfo->err->trace_level >= 2) { for (i = 0; i < DCTSIZE2; i += 8) { TRACEMS8(cinfo, 2, JTRC_QUANTVALS, --- 555,601 ---- if (cinfo->quant_tbl_ptrs[n] == NULL) cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); quant_ptr = cinfo->quant_tbl_ptrs[n]; + if (prec) { + if (length < DCTSIZE2 * 2) { + /* Initialize full table for safety. */ + for (i = 0; i < DCTSIZE2; i++) { + quant_ptr->quantval[i] = 1; + } + count = length >> 1; + } else + count = DCTSIZE2; + } else { + if (length < DCTSIZE2) { + /* Initialize full table for safety. */ for (i = 0; i < DCTSIZE2; i++) { + quant_ptr->quantval[i] = 1; + } + count = length; + } else + count = DCTSIZE2; + } + + switch (count) { + case (2*2): natural_order = jpeg_natural_order2; break; + case (3*3): natural_order = jpeg_natural_order3; break; + case (4*4): natural_order = jpeg_natural_order4; break; + case (5*5): natural_order = jpeg_natural_order5; break; + case (6*6): natural_order = jpeg_natural_order6; break; + case (7*7): natural_order = jpeg_natural_order7; break; + default: natural_order = jpeg_natural_order; break; + } + + for (i = 0; i < count; i++) { if (prec) INPUT_2BYTES(cinfo, tmp, return FALSE); else INPUT_BYTE(cinfo, tmp, return FALSE); /* We convert the zigzag-order table to natural array order. */ ! quant_ptr->quantval[natural_order[i]] = (UINT16) tmp; } if (cinfo->err->trace_level >= 2) { for (i = 0; i < DCTSIZE2; i += 8) { TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
*** 530,541 **** quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); } } ! length -= DCTSIZE2+1; ! if (prec) length -= DCTSIZE2; } if (length != 0) ERREXIT(cinfo, JERR_BAD_LENGTH); --- 604,615 ---- quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); } } ! length -= count; ! if (prec) length -= count; } if (length != 0) ERREXIT(cinfo, JERR_BAD_LENGTH);
*** 566,575 **** --- 640,711 ---- INPUT_SYNC(cinfo); return TRUE; } + LOCAL(boolean) + get_lse (j_decompress_ptr cinfo) + /* Process an LSE marker */ + { + INT32 length; + unsigned int tmp; + int cid; + INPUT_VARS(cinfo); + + if (! cinfo->marker->saw_SOF) + ERREXITS(cinfo, JERR_SOF_BEFORE, "LSE"); + + if (cinfo->num_components < 3) goto bad; + + INPUT_2BYTES(cinfo, length, return FALSE); + + if (length != 24) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_BYTE(cinfo, tmp, return FALSE); + if (tmp != 0x0D) /* ID inverse transform specification */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != MAXJSAMPLE) goto bad; /* MAXTRANS */ + INPUT_BYTE(cinfo, tmp, return FALSE); + if (tmp != 3) goto bad; /* Nt=3 */ + INPUT_BYTE(cinfo, cid, return FALSE); + if (cid != cinfo->comp_info[1].component_id) goto bad; + INPUT_BYTE(cinfo, cid, return FALSE); + if (cid != cinfo->comp_info[0].component_id) goto bad; + INPUT_BYTE(cinfo, cid, return FALSE); + if (cid != cinfo->comp_info[2].component_id) goto bad; + INPUT_BYTE(cinfo, tmp, return FALSE); + if (tmp != 0x80) goto bad; /* F1: CENTER1=1, NORM1=0 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 0) goto bad; /* A(1,1)=0 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 0) goto bad; /* A(1,2)=0 */ + INPUT_BYTE(cinfo, tmp, return FALSE); + if (tmp != 0) goto bad; /* F2: CENTER2=0, NORM2=0 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 1) goto bad; /* A(2,1)=1 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 0) goto bad; /* A(2,2)=0 */ + INPUT_BYTE(cinfo, tmp, return FALSE); + if (tmp != 0) goto bad; /* F3: CENTER3=0, NORM3=0 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 1) goto bad; /* A(3,1)=1 */ + INPUT_2BYTES(cinfo, tmp, return FALSE); + if (tmp != 0) { /* A(3,2)=0 */ + bad: + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + } + + /* OK, valid transform that we can handle. */ + cinfo->color_transform = JCT_SUBTRACT_GREEN; + + INPUT_SYNC(cinfo); + return TRUE; + } + + /* * Routines for processing APPn and COM markers. * These are either saved in memory or discarded, per application request. * APP0 and APP14 are specially checked to see if they are * JFIF and Adobe markers, respectively.
*** 602,617 **** cinfo->JFIF_minor_version = GETJOCTET(data[6]); cinfo->density_unit = GETJOCTET(data[7]); cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); /* Check version. ! * Major version must be 1, anything else signals an incompatible change. * (We used to treat this as an error, but now it's a nonfatal warning, * because some bozo at Hijaak couldn't read the spec.) * Minor version should be 0..2, but process anyway if newer. */ ! if (cinfo->JFIF_major_version != 1) WARNMS2(cinfo, JWRN_JFIF_MAJOR, cinfo->JFIF_major_version, cinfo->JFIF_minor_version); /* Generate trace messages */ TRACEMS5(cinfo, 1, JTRC_JFIF, cinfo->JFIF_major_version, cinfo->JFIF_minor_version, --- 738,754 ---- cinfo->JFIF_minor_version = GETJOCTET(data[6]); cinfo->density_unit = GETJOCTET(data[7]); cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); /* Check version. ! * Major version must be 1 or 2, anything else signals an incompatible ! * change. * (We used to treat this as an error, but now it's a nonfatal warning, * because some bozo at Hijaak couldn't read the spec.) * Minor version should be 0..2, but process anyway if newer. */ ! if (cinfo->JFIF_major_version != 1 && cinfo->JFIF_major_version != 2) WARNMS2(cinfo, JWRN_JFIF_MAJOR, cinfo->JFIF_major_version, cinfo->JFIF_minor_version); /* Generate trace messages */ TRACEMS5(cinfo, 1, JTRC_JFIF, cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
*** 944,953 **** --- 1081,1095 ---- /* * Read markers until SOS or EOI. * * Returns same codes as are defined for jpeg_consume_input: * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * Note: This function may return a pseudo SOS marker (with zero + * component number) for treat by input controller's consume_input. + * consume_input itself should filter out (skip) the pseudo marker + * after processing for the caller. */ METHODDEF(int) read_markers (j_decompress_ptr cinfo) {
*** 973,999 **** if (! get_soi(cinfo)) return JPEG_SUSPENDED; break; case M_SOF0: /* Baseline */ case M_SOF1: /* Extended sequential, Huffman */ ! if (! get_sof(cinfo, FALSE, FALSE)) return JPEG_SUSPENDED; break; case M_SOF2: /* Progressive, Huffman */ ! if (! get_sof(cinfo, TRUE, FALSE)) return JPEG_SUSPENDED; break; case M_SOF9: /* Extended sequential, arithmetic */ ! if (! get_sof(cinfo, FALSE, TRUE)) return JPEG_SUSPENDED; break; case M_SOF10: /* Progressive, arithmetic */ ! if (! get_sof(cinfo, TRUE, TRUE)) return JPEG_SUSPENDED; break; /* Currently unsupported SOFn types */ case M_SOF3: /* Lossless, Huffman */ --- 1115,1145 ---- if (! get_soi(cinfo)) return JPEG_SUSPENDED; break; case M_SOF0: /* Baseline */ + if (! get_sof(cinfo, TRUE, FALSE, FALSE)) + return JPEG_SUSPENDED; + break; + case M_SOF1: /* Extended sequential, Huffman */ ! if (! get_sof(cinfo, FALSE, FALSE, FALSE)) return JPEG_SUSPENDED; break; case M_SOF2: /* Progressive, Huffman */ ! if (! get_sof(cinfo, FALSE, TRUE, FALSE)) return JPEG_SUSPENDED; break; case M_SOF9: /* Extended sequential, arithmetic */ ! if (! get_sof(cinfo, FALSE, FALSE, TRUE)) return JPEG_SUSPENDED; break; case M_SOF10: /* Progressive, arithmetic */ ! if (! get_sof(cinfo, FALSE, TRUE, TRUE)) return JPEG_SUSPENDED; break; /* Currently unsupported SOFn types */ case M_SOF3: /* Lossless, Huffman */
*** 1037,1046 **** --- 1183,1197 ---- case M_DRI: if (! get_dri(cinfo)) return JPEG_SUSPENDED; break; + case M_JPG8: + if (! get_lse(cinfo)) + return JPEG_SUSPENDED; + break; + case M_APP0: case M_APP1: case M_APP2: case M_APP3: case M_APP4:
*** 1266,1276 **** /* Create subobject in permanent pool */ marker = (my_marker_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_marker_reader)); ! cinfo->marker = (struct jpeg_marker_reader *) marker; /* Initialize public method pointers */ marker->pub.reset_marker_reader = reset_marker_reader; marker->pub.read_markers = read_markers; marker->pub.read_restart_marker = read_restart_marker; /* Initialize COM/APPn processing. --- 1417,1427 ---- /* Create subobject in permanent pool */ marker = (my_marker_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_marker_reader)); ! cinfo->marker = &marker->pub; /* Initialize public method pointers */ marker->pub.reset_marker_reader = reset_marker_reader; marker->pub.read_markers = read_markers; marker->pub.read_restart_marker = read_restart_marker; /* Initialize COM/APPn processing.
< prev index next >