< prev index next >
modules/javafx.graphics/src/main/native-iio/libjpeg7/jcmarker.c
Print this page
@@ -1,9 +1,10 @@
/*
* jcmarker.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2003-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 write JPEG datastream markers.
*/
@@ -70,10 +71,11 @@
M_APP13 = 0xed,
M_APP14 = 0xee,
M_APP15 = 0xef,
M_JPG0 = 0xf0,
+ M_JPG8 = 0xf8,
M_JPG13 = 0xfd,
M_COM = 0xfe,
M_TEM = 0x01,
@@ -151,25 +153,26 @@
if (qtbl == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
prec = 0;
- for (i = 0; i < DCTSIZE2; i++) {
- if (qtbl->quantval[i] > 255)
+ for (i = 0; i <= cinfo->lim_Se; i++) {
+ if (qtbl->quantval[cinfo->natural_order[i]] > 255)
prec = 1;
}
if (! qtbl->sent_table) {
emit_marker(cinfo, M_DQT);
- emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+ emit_2bytes(cinfo,
+ prec ? cinfo->lim_Se * 2 + 2 + 1 + 2 : cinfo->lim_Se + 1 + 1 + 2);
emit_byte(cinfo, index + (prec<<4));
- for (i = 0; i < DCTSIZE2; i++) {
+ for (i = 0; i <= cinfo->lim_Se; i++) {
/* The table entries must be emitted in zigzag order. */
- unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
+ unsigned int qval = qtbl->quantval[cinfo->natural_order[i]];
if (prec)
emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF));
}
@@ -233,18 +236,23 @@
for (i = 0; i < NUM_ARITH_TBLS; i++)
dc_in_use[i] = ac_in_use[i] = 0;
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
+ /* DC needs no table for refinement scan */
+ if (cinfo->Ss == 0 && cinfo->Ah == 0)
dc_in_use[compptr->dc_tbl_no] = 1;
+ /* AC needs no table when not present */
+ if (cinfo->Se)
ac_in_use[compptr->ac_tbl_no] = 1;
}
length = 0;
for (i = 0; i < NUM_ARITH_TBLS; i++)
length += dc_in_use[i] + ac_in_use[i];
+ if (length) {
emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2);
for (i = 0; i < NUM_ARITH_TBLS; i++) {
@@ -255,10 +263,11 @@
if (ac_in_use[i]) {
emit_byte(cinfo, i + 0x10);
emit_byte(cinfo, cinfo->arith_ac_K[i]);
}
}
+ }
#endif /* C_ARITH_CODING_SUPPORTED */
}
LOCAL(void)
@@ -272,10 +281,41 @@
emit_2bytes(cinfo, (int) cinfo->restart_interval);
}
LOCAL(void)
+emit_lse_ict (j_compress_ptr cinfo)
+/* Emit an LSE inverse color transform specification marker */
+{
+ /* Support only 1 transform */
+ if (cinfo->color_transform != JCT_SUBTRACT_GREEN ||
+ cinfo->num_components < 3)
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+
+ emit_marker(cinfo, M_JPG8);
+
+ emit_2bytes(cinfo, 24); /* fixed length */
+
+ emit_byte(cinfo, 0x0D); /* ID inverse transform specification */
+ emit_2bytes(cinfo, MAXJSAMPLE); /* MAXTRANS */
+ emit_byte(cinfo, 3); /* Nt=3 */
+ emit_byte(cinfo, cinfo->comp_info[1].component_id);
+ emit_byte(cinfo, cinfo->comp_info[0].component_id);
+ emit_byte(cinfo, cinfo->comp_info[2].component_id);
+ emit_byte(cinfo, 0x80); /* F1: CENTER1=1, NORM1=0 */
+ emit_2bytes(cinfo, 0); /* A(1,1)=0 */
+ emit_2bytes(cinfo, 0); /* A(1,2)=0 */
+ emit_byte(cinfo, 0); /* F2: CENTER2=0, NORM2=0 */
+ emit_2bytes(cinfo, 1); /* A(2,1)=1 */
+ emit_2bytes(cinfo, 0); /* A(2,2)=0 */
+ emit_byte(cinfo, 0); /* F3: CENTER3=0, NORM3=0 */
+ emit_2bytes(cinfo, 1); /* A(3,1)=1 */
+ emit_2bytes(cinfo, 0); /* A(3,2)=0 */
+}
+
+
+LOCAL(void)
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
/* Emit a SOF marker */
{
int ci;
jpeg_component_info *compptr;
@@ -318,36 +358,46 @@
emit_byte(cinfo, cinfo->comps_in_scan);
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
emit_byte(cinfo, compptr->component_id);
- td = compptr->dc_tbl_no;
- ta = compptr->ac_tbl_no;
- if (cinfo->progressive_mode) {
- /* Progressive mode: only DC or only AC tables are used in one scan;
- * furthermore, Huffman coding of DC refinement uses no table at all.
- * We emit 0 for unused field(s); this is recommended by the P&M text
+
+ /* We emit 0 for unused field(s); this is recommended by the P&M text
* but does not seem to be specified in the standard.
*/
- if (cinfo->Ss == 0) {
- ta = 0; /* DC scan */
- if (cinfo->Ah != 0 && !cinfo->arith_code)
- td = 0; /* no DC table either */
- } else {
- td = 0; /* AC scan */
- }
- }
+
+ /* DC needs no table for refinement scan */
+ td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
+ /* AC needs no table when not present */
+ ta = cinfo->Se ? compptr->ac_tbl_no : 0;
+
emit_byte(cinfo, (td << 4) + ta);
}
emit_byte(cinfo, cinfo->Ss);
emit_byte(cinfo, cinfo->Se);
emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
}
LOCAL(void)
+emit_pseudo_sos (j_compress_ptr cinfo)
+/* Emit a pseudo SOS marker */
+{
+ emit_marker(cinfo, M_SOS);
+
+ emit_2bytes(cinfo, 2 + 1 + 3); /* length */
+
+ emit_byte(cinfo, 0); /* Ns */
+
+ emit_byte(cinfo, 0); /* Ss */
+ emit_byte(cinfo, cinfo->block_size * cinfo->block_size - 1); /* Se */
+ emit_byte(cinfo, 0); /* Ah/Al */
+}
+
+
+LOCAL(void)
emit_jfif_app0 (j_compress_ptr cinfo)
/* Emit a JFIF-compliant APP0 marker */
{
/*
* Length of APP0 block (2 bytes)
@@ -456,12 +506,12 @@
/*
* Write datastream header.
* This consists of an SOI and optional APPn markers.
* We recommend use of the JFIF marker, but not the Adobe marker,
- * when using YCbCr or grayscale data. The JFIF marker should NOT
- * be used for any other JPEG colorspace. The Adobe marker is helpful
+ * when using YCbCr or grayscale data. The JFIF marker is also used
+ * for other standard JPEG colorspaces. The Adobe marker is helpful
* to distinguish RGB, CMYK, and YCCK colorspaces.
* Note that an application can write additional header markers after
* jpeg_start_compress returns.
*/
@@ -482,11 +532,12 @@
}
/*
* Write frame header.
- * This consists of DQT and SOFn markers.
+ * This consists of DQT and SOFn markers,
+ * a conditional LSE marker and a conditional pseudo SOS marker.
* Note that we do not emit the SOF until we have emitted the DQT(s).
* This avoids compatibility problems with incorrect implementations that
* try to error-check the quant table numbers as soon as they see the SOF.
*/
@@ -509,11 +560,11 @@
/* Check for a non-baseline specification.
* Note we assume that Huffman table numbers won't be changed later.
*/
if (cinfo->arith_code || cinfo->progressive_mode ||
- cinfo->data_precision != 8) {
+ cinfo->data_precision != 8 || cinfo->block_size != DCTSIZE) {
is_baseline = FALSE;
} else {
is_baseline = TRUE;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
@@ -539,10 +590,18 @@
else if (is_baseline)
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
else
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
}
+
+ /* Check to emit LSE inverse color transform specification marker */
+ if (cinfo->color_transform)
+ emit_lse_ict(cinfo);
+
+ /* Check to emit pseudo SOS marker */
+ if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
+ emit_pseudo_sos(cinfo);
}
/*
* Write scan header.
@@ -567,24 +626,17 @@
/* Emit Huffman tables.
* Note that emit_dht() suppresses any duplicate tables.
*/
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
- if (cinfo->progressive_mode) {
- /* Progressive mode: only DC or only AC tables are used in one scan */
- if (cinfo->Ss == 0) {
- if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
+ /* DC needs no table for refinement scan */
+ if (cinfo->Ss == 0 && cinfo->Ah == 0)
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
- } else {
+ /* AC needs no table when not present */
+ if (cinfo->Se)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
- } else {
- /* Sequential mode: need both DC and AC tables */
- emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
- emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
- }
- }
}
/* Emit DRI if required --- note that DRI value could change for each scan.
* We avoid wasting space with unnecessary DRIs, however.
*/
@@ -651,11 +703,11 @@
/* Create the subobject */
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_marker_writer));
- cinfo->marker = (struct jpeg_marker_writer *) marker;
+ cinfo->marker = &marker->pub;
/* Initialize method pointers */
marker->pub.write_file_header = write_file_header;
marker->pub.write_frame_header = write_frame_header;
marker->pub.write_scan_header = write_scan_header;
marker->pub.write_file_trailer = write_file_trailer;
< prev index next >