< 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 >