/* * reserved comment block * DO NOT REMOVE OR ALTER!
*/ /* * jcmarker.c * * Copyright (C) 1991-1998, 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. * * This file contains routines to write JPEG datastream markers.
*/
typedefstruct { struct jpeg_marker_writer pub; /* public fields */
unsignedint last_restart_interval; /* last DRI value emitted; 0 after SOI */
} my_marker_writer;
typedef my_marker_writer * my_marker_ptr;
/* * Basic output routines. * * Note that we do not support suspension while writing a marker. * Therefore, an application using suspension must ensure that there is * enough buffer space for the initial markers (typ. 600-700 bytes) before * calling jpeg_start_compress, and enough space to write the trailing EOI * (a few bytes) before calling jpeg_finish_compress. Multipass compression * modes are not supported at all with suspension, so those two are the only * points where markers will be written.
*/
LOCAL(void)
emit_byte (j_compress_ptr cinfo, int val) /* Emit a byte */
{ struct jpeg_destination_mgr * dest = cinfo->dest;
*(dest->next_output_byte)++ = (JOCTET) val; if (--dest->free_in_buffer == 0) { if (! (*dest->empty_output_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
}
LOCAL(void)
emit_2bytes (j_compress_ptr cinfo, int value) /* Emit a 2-byte integer; these are always MSB first in JPEG files */
{
emit_byte(cinfo, (value >> 8) & 0xFF);
emit_byte(cinfo, value & 0xFF);
}
/* * Routines to write specific marker types.
*/
LOCAL(int)
emit_dqt (j_compress_ptr cinfo, int index) /* Emit a DQT marker */ /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
{
JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; int prec; int i;
if (qtbl == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
prec = 0; for (i = 0; i < DCTSIZE2; i++) { if (qtbl->quantval[i] > 255)
prec = 1;
}
if (! qtbl->sent_table) {
emit_marker(cinfo, M_DQT);
for (i = 0; i < DCTSIZE2; i++) { /* The table entries must be emitted in zigzag order. */ unsignedint qval = qtbl->quantval[jpeg_natural_order[i]]; if (prec)
emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF));
}
qtbl->sent_table = TRUE;
}
return prec;
}
LOCAL(void)
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) /* Emit a DHT marker */
{
JHUFF_TBL * htbl; int length, i;
if (is_ac) {
htbl = cinfo->ac_huff_tbl_ptrs[index];
index += 0x10; /* output index has AC bit set */
} else {
htbl = cinfo->dc_huff_tbl_ptrs[index];
}
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
if (! htbl->sent_table) {
emit_marker(cinfo, M_DHT);
length = 0; for (i = 1; i <= 16; i++)
length += htbl->bits[i];
for (i = 1; i <= 16; i++)
emit_byte(cinfo, htbl->bits[i]);
for (i = 0; i < length; i++)
emit_byte(cinfo, htbl->huffval[i]);
htbl->sent_table = TRUE;
}
}
LOCAL(void)
emit_dac (j_compress_ptr cinfo) /* Emit a DAC marker */ /* Since the useful info is so small, we want to emit all the tables in */ /* one DAC marker. Therefore this routine does its own scan of the table. */
{ #ifdef C_ARITH_CODING_SUPPORTED char dc_in_use[NUM_ARITH_TBLS]; char ac_in_use[NUM_ARITH_TBLS]; int length, i;
jpeg_component_info *compptr;
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_in_use[compptr->dc_tbl_no] = 1;
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];
emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2);
for (i = 0; i < NUM_ARITH_TBLS; i++) { if (dc_in_use[i]) {
emit_byte(cinfo, i);
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
} if (ac_in_use[i]) {
emit_byte(cinfo, i + 0x10);
emit_byte(cinfo, cinfo->arith_ac_K[i]);
}
} #endif/* C_ARITH_CODING_SUPPORTED */
}
/* Make sure image isn't bigger than SOF field can handle */ if ((long) cinfo->image_height > 65535L ||
(long) cinfo->image_width > 65535L)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsignedint) 65535);
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 * 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);
}
LOCAL(void)
emit_adobe_app14 (j_compress_ptr cinfo) /* Emit an Adobe APP14 marker */
{ /* * Length of APP14 block (2 bytes) * Block ID (5 bytes - ASCII "Adobe") * Version Number (2 bytes - currently 100) * Flags0 (2 bytes - currently 0) * Flags1 (2 bytes - currently 0) * Color transform (1 byte) * * Although Adobe TN 5116 mentions Version = 101, all the Adobe files * now in circulation seem to use Version = 100, so that's what we write. * * We write the color transform byte as 1 if the JPEG color space is * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with * whether the encoder performed a transformation, which is pretty useless.
*/
/* * These routines allow writing an arbitrary marker with parameters. * The only intended use is to emit COM or APPn markers after calling * write_file_header and before calling write_frame_header. * Other uses are not guaranteed to produce desirable results. * Counting the parameter bytes properly is the caller's responsibility.
*/
METHODDEF(void)
write_marker_header (j_compress_ptr cinfo, int marker, unsignedint datalen) /* Emit an arbitrary marker header */
{ if (datalen > (unsignedint) 65533) /* safety check */
ERREXIT(cinfo, JERR_BAD_LENGTH);
emit_marker(cinfo, (JPEG_MARKER) marker);
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
}
METHODDEF(void)
write_marker_byte (j_compress_ptr cinfo, int val) /* Emit one byte of marker parameters following write_marker_header */
{
emit_byte(cinfo, val);
}
/* * 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 * to distinguish RGB, CMYK, and YCCK colorspaces. * Note that an application can write additional header markers after * jpeg_start_compress returns.
*/
/* SOI is defined to reset restart interval to 0 */
marker->last_restart_interval = 0;
if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
emit_jfif_app0(cinfo); if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
emit_adobe_app14(cinfo);
}
/* * Write frame header. * This consists of DQT and SOFn markers. * 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.
*/
/* Emit DQT for each quantization table. * Note that emit_dqt() suppresses any duplicate tables.
*/
prec = 0; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
} /* now prec is nonzero iff there are any 16-bit quant tables. */
/* 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) {
is_baseline = FALSE;
} 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 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) {
emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
} else { if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ elseif (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 */
}
}
/* * Write scan header. * This consists of DHT or DAC markers, optional DRI, and SOS. * Compressed data will be written following the SOS.
*/
if (cinfo->arith_code) { /* Emit arith conditioning info. We may have some duplication * if the file has multiple scans, but it's so small it's hardly * worth worrying about.
*/
emit_dac(cinfo);
} else { /* 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 */
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);
}
}
}
/* Emit DRI if required --- note that DRI value could change for each scan. * We avoid wasting space with unnecessary DRIs, however.
*/ if (cinfo->restart_interval != marker->last_restart_interval) {
emit_dri(cinfo);
marker->last_restart_interval = cinfo->restart_interval;
}
/* * Write an abbreviated table-specification datastream. * This consists of SOI, DQT and DHT tables, and EOI. * Any table that is defined and not marked sent_table = TRUE will be * emitted. Note that all tables will be marked sent_table = TRUE at exit.
*/
METHODDEF(void)
write_tables_only (j_compress_ptr cinfo)
{ int i;
emit_marker(cinfo, M_SOI);
/* Emit DQT for each quantization table. * Only emit those tables that are actually associated with image components, * if there are any image components, which will usually not be the case. * Note that emit_dqt() suppresses any duplicate tables.
*/ if (cinfo->num_components > 0) { int ci;
jpeg_component_info *compptr; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
(void) emit_dqt(cinfo, compptr->quant_tbl_no);
}
} else { for (i = 0; i < NUM_QUANT_TBLS; i++) { if (cinfo->quant_tbl_ptrs[i] != NULL)
(void) emit_dqt(cinfo, i);
}
}
if (! cinfo->arith_code) { for (i = 0; i < NUM_HUFF_TBLS; i++) { if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
emit_dht(cinfo, i, FALSE); if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
emit_dht(cinfo, i, TRUE);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.