The Independent JPEG Group's JPEG software v6
diff --git a/jcmarker.c b/jcmarker.c
index 5454658..f4d290b 100644
--- a/jcmarker.c
+++ b/jcmarker.c
@@ -1,7 +1,7 @@
/*
* jcmarker.c
*
- * Copyright (C) 1991-1994, Thomas G. Lane.
+ * Copyright (C) 1991-1995, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -295,7 +295,7 @@
emit_sos (j_compress_ptr cinfo)
/* Emit a SOS marker */
{
- int i;
+ int i, td, ta;
jpeg_component_info *compptr;
emit_marker(cinfo, M_SOS);
@@ -307,12 +307,28 @@
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
emit_byte(cinfo, compptr->component_id);
- emit_byte(cinfo, (compptr->dc_tbl_no << 4) + compptr->ac_tbl_no);
+ 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
+ * 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 */
+ }
+ }
+ emit_byte(cinfo, (td << 4) + ta);
}
- emit_byte(cinfo, 0); /* Spectral selection start */
- emit_byte(cinfo, DCTSIZE2-1); /* Spectral selection end */
- emit_byte(cinfo, 0); /* Successive approximation */
+ emit_byte(cinfo, cinfo->Ss);
+ emit_byte(cinfo, cinfo->Se);
+ emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
}
@@ -434,7 +450,7 @@
* be used for any other JPEG colorspace. The Adobe marker is helpful
* to distinguish RGB, CMYK, and YCCK colorspaces.
* Note that an application can write additional header markers after
- * jpeg_start_decompress returns.
+ * jpeg_start_compress returns.
*/
METHODDEF void
@@ -477,27 +493,34 @@
/* Check for a non-baseline specification.
* Note we assume that Huffman table numbers won't be changed later.
*/
- is_baseline = TRUE;
- if (cinfo->arith_code || (cinfo->data_precision != 8))
+ if (cinfo->arith_code || cinfo->progressive_mode ||
+ cinfo->data_precision != 8) {
is_baseline = FALSE;
- for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
- ci++, compptr++) {
- if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
+ } else {
+ is_baseline = TRUE;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
+ is_baseline = FALSE;
+ }
+ if (prec && is_baseline) {
is_baseline = FALSE;
- }
- if (prec && is_baseline) {
- is_baseline = FALSE;
- /* If it's baseline except for quantizer size, warn the user */
- TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
+ /* If it's baseline except for quantizer size, warn the user */
+ TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
+ }
}
/* Emit the proper SOF marker */
- if (cinfo->arith_code)
+ if (cinfo->arith_code) {
emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
- 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 */
+ } else {
+ if (cinfo->progressive_mode)
+ emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
+ 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 */
+ }
}
@@ -525,8 +548,19 @@
*/
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
- emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
- emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+ 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 */
+ emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+ } else {
+ 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);
+ }
}
}