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);
}
/* *Routinestowritespecificmarkertypes.
*/
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 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++) { 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->_jpeg_height > 65535L || (long)cinfo->_jpeg_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);
/* We emit 0 for unused field(s); this is recommended by the P&M text *butdoesnotseemtobespecifiedinthestandard.
*/
/* 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;
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);
}
/* 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);
}
if (!cinfo->master->lossless) { /* Emit DQT for each quantization table. *Notethatemit_dqt()suppressesanyduplicatetables.
*/ 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. *NoteweassumethatHuffmantablenumberswon'tbechangedlater.
*/ if (cinfo->arith_code || cinfo->progressive_mode ||
cinfo->master->lossless || 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) { if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */ else
emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */
} else { if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ elseif (cinfo->master->lossless)
emit_sof(cinfo, M_SOF3); /* SOF code for lossless 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 */
}
}
if (cinfo->arith_code) { /* Emit arith conditioning info. We may have some duplication *ifthefilehasmultiplescans,butit'ssosmallit'shardly *worthworryingabout.
*/
emit_dac(cinfo);
} else { /* Emit Huffman tables. *Notethatemit_dht()suppressesanyduplicatetables.
*/ 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) || cinfo->master->lossless)
emit_dht(cinfo, compptr->dc_tbl_no, FALSE); /* AC needs no table when not present, and lossless mode uses only DC
tables. */ if (cinfo->Se && !cinfo->master->lossless)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
}
/* Emit DRI if required --- note that DRI value could change for each scan. *WeavoidwastingspacewithunnecessaryDRIs,however.
*/ if (cinfo->restart_interval != marker->last_restart_interval) {
emit_dri(cinfo);
marker->last_restart_interval = cinfo->restart_interval;
}
METHODDEF(void)
write_tables_only(j_compress_ptr cinfo)
{ int i;
emit_marker(cinfo, M_SOI);
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 und die Messung sind noch experimentell.