17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier * jcphuff.c
37dd7cddfSDavid du Colombier *
4*593dc095SDavid du Colombier * Copyright (C) 1995-1997, Thomas G. Lane.
57dd7cddfSDavid du Colombier * This file is part of the Independent JPEG Group's software.
67dd7cddfSDavid du Colombier * For conditions of distribution and use, see the accompanying README file.
77dd7cddfSDavid du Colombier *
87dd7cddfSDavid du Colombier * This file contains Huffman entropy encoding routines for progressive JPEG.
97dd7cddfSDavid du Colombier *
107dd7cddfSDavid du Colombier * We do not support output suspension in this module, since the library
117dd7cddfSDavid du Colombier * currently does not allow multiple-scan files to be written with output
127dd7cddfSDavid du Colombier * suspension.
137dd7cddfSDavid du Colombier */
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier #define JPEG_INTERNALS
167dd7cddfSDavid du Colombier #include "jinclude.h"
177dd7cddfSDavid du Colombier #include "jpeglib.h"
187dd7cddfSDavid du Colombier #include "jchuff.h" /* Declarations shared with jchuff.c */
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier #ifdef C_PROGRESSIVE_SUPPORTED
217dd7cddfSDavid du Colombier
227dd7cddfSDavid du Colombier /* Expanded entropy encoder object for progressive Huffman encoding. */
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier typedef struct {
257dd7cddfSDavid du Colombier struct jpeg_entropy_encoder pub; /* public fields */
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier /* Mode flag: TRUE for optimization, FALSE for actual data output */
287dd7cddfSDavid du Colombier boolean gather_statistics;
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier /* Bit-level coding status.
317dd7cddfSDavid du Colombier * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
327dd7cddfSDavid du Colombier */
337dd7cddfSDavid du Colombier JOCTET * next_output_byte; /* => next byte to write in buffer */
347dd7cddfSDavid du Colombier size_t free_in_buffer; /* # of byte spaces remaining in buffer */
357dd7cddfSDavid du Colombier INT32 put_buffer; /* current bit-accumulation buffer */
367dd7cddfSDavid du Colombier int put_bits; /* # of bits now in it */
377dd7cddfSDavid du Colombier j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier /* Coding status for DC components */
407dd7cddfSDavid du Colombier int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier /* Coding status for AC components */
437dd7cddfSDavid du Colombier int ac_tbl_no; /* the table number of the single component */
447dd7cddfSDavid du Colombier unsigned int EOBRUN; /* run length of EOBs */
457dd7cddfSDavid du Colombier unsigned int BE; /* # of buffered correction bits before MCU */
467dd7cddfSDavid du Colombier char * bit_buffer; /* buffer for correction bits (1 per char) */
477dd7cddfSDavid du Colombier /* packing correction bits tightly would save some space but cost time... */
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier unsigned int restarts_to_go; /* MCUs left in this restart interval */
507dd7cddfSDavid du Colombier int next_restart_num; /* next restart number to write (0-7) */
517dd7cddfSDavid du Colombier
527dd7cddfSDavid du Colombier /* Pointers to derived tables (these workspaces have image lifespan).
537dd7cddfSDavid du Colombier * Since any one scan codes only DC or only AC, we only need one set
547dd7cddfSDavid du Colombier * of tables, not one for DC and one for AC.
557dd7cddfSDavid du Colombier */
567dd7cddfSDavid du Colombier c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
577dd7cddfSDavid du Colombier
587dd7cddfSDavid du Colombier /* Statistics tables for optimization; again, one set is enough */
597dd7cddfSDavid du Colombier long * count_ptrs[NUM_HUFF_TBLS];
607dd7cddfSDavid du Colombier } phuff_entropy_encoder;
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier typedef phuff_entropy_encoder * phuff_entropy_ptr;
637dd7cddfSDavid du Colombier
647dd7cddfSDavid du Colombier /* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
657dd7cddfSDavid du Colombier * buffer can hold. Larger sizes may slightly improve compression, but
667dd7cddfSDavid du Colombier * 1000 is already well into the realm of overkill.
677dd7cddfSDavid du Colombier * The minimum safe size is 64 bits.
687dd7cddfSDavid du Colombier */
697dd7cddfSDavid du Colombier
707dd7cddfSDavid du Colombier #define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier /* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
737dd7cddfSDavid du Colombier * We assume that int right shift is unsigned if INT32 right shift is,
747dd7cddfSDavid du Colombier * which should be safe.
757dd7cddfSDavid du Colombier */
767dd7cddfSDavid du Colombier
777dd7cddfSDavid du Colombier #ifdef RIGHT_SHIFT_IS_UNSIGNED
787dd7cddfSDavid du Colombier #define ISHIFT_TEMPS int ishift_temp;
797dd7cddfSDavid du Colombier #define IRIGHT_SHIFT(x,shft) \
807dd7cddfSDavid du Colombier ((ishift_temp = (x)) < 0 ? \
817dd7cddfSDavid du Colombier (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
827dd7cddfSDavid du Colombier (ishift_temp >> (shft)))
837dd7cddfSDavid du Colombier #else
847dd7cddfSDavid du Colombier #define ISHIFT_TEMPS
857dd7cddfSDavid du Colombier #define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
867dd7cddfSDavid du Colombier #endif
877dd7cddfSDavid du Colombier
887dd7cddfSDavid du Colombier /* Forward declarations */
897dd7cddfSDavid du Colombier METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
907dd7cddfSDavid du Colombier JBLOCKROW *MCU_data));
917dd7cddfSDavid du Colombier METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
927dd7cddfSDavid du Colombier JBLOCKROW *MCU_data));
937dd7cddfSDavid du Colombier METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
947dd7cddfSDavid du Colombier JBLOCKROW *MCU_data));
957dd7cddfSDavid du Colombier METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
967dd7cddfSDavid du Colombier JBLOCKROW *MCU_data));
977dd7cddfSDavid du Colombier METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
987dd7cddfSDavid du Colombier METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier /*
1027dd7cddfSDavid du Colombier * Initialize for a Huffman-compressed scan using progressive JPEG.
1037dd7cddfSDavid du Colombier */
1047dd7cddfSDavid du Colombier
1057dd7cddfSDavid du Colombier METHODDEF(void)
start_pass_phuff(j_compress_ptr cinfo,boolean gather_statistics)1067dd7cddfSDavid du Colombier start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
1077dd7cddfSDavid du Colombier {
1087dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
1097dd7cddfSDavid du Colombier boolean is_DC_band;
1107dd7cddfSDavid du Colombier int ci, tbl;
1117dd7cddfSDavid du Colombier jpeg_component_info * compptr;
1127dd7cddfSDavid du Colombier
1137dd7cddfSDavid du Colombier entropy->cinfo = cinfo;
1147dd7cddfSDavid du Colombier entropy->gather_statistics = gather_statistics;
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier is_DC_band = (cinfo->Ss == 0);
1177dd7cddfSDavid du Colombier
1187dd7cddfSDavid du Colombier /* We assume jcmaster.c already validated the scan parameters. */
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier /* Select execution routines */
1217dd7cddfSDavid du Colombier if (cinfo->Ah == 0) {
1227dd7cddfSDavid du Colombier if (is_DC_band)
1237dd7cddfSDavid du Colombier entropy->pub.encode_mcu = encode_mcu_DC_first;
1247dd7cddfSDavid du Colombier else
1257dd7cddfSDavid du Colombier entropy->pub.encode_mcu = encode_mcu_AC_first;
1267dd7cddfSDavid du Colombier } else {
1277dd7cddfSDavid du Colombier if (is_DC_band)
1287dd7cddfSDavid du Colombier entropy->pub.encode_mcu = encode_mcu_DC_refine;
1297dd7cddfSDavid du Colombier else {
1307dd7cddfSDavid du Colombier entropy->pub.encode_mcu = encode_mcu_AC_refine;
1317dd7cddfSDavid du Colombier /* AC refinement needs a correction bit buffer */
1327dd7cddfSDavid du Colombier if (entropy->bit_buffer == NULL)
1337dd7cddfSDavid du Colombier entropy->bit_buffer = (char *)
1347dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
1357dd7cddfSDavid du Colombier MAX_CORR_BITS * SIZEOF(char));
1367dd7cddfSDavid du Colombier }
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier if (gather_statistics)
1397dd7cddfSDavid du Colombier entropy->pub.finish_pass = finish_pass_gather_phuff;
1407dd7cddfSDavid du Colombier else
1417dd7cddfSDavid du Colombier entropy->pub.finish_pass = finish_pass_phuff;
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
1447dd7cddfSDavid du Colombier * for AC coefficients.
1457dd7cddfSDavid du Colombier */
1467dd7cddfSDavid du Colombier for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
1477dd7cddfSDavid du Colombier compptr = cinfo->cur_comp_info[ci];
1487dd7cddfSDavid du Colombier /* Initialize DC predictions to 0 */
1497dd7cddfSDavid du Colombier entropy->last_dc_val[ci] = 0;
150*593dc095SDavid du Colombier /* Get table index */
1517dd7cddfSDavid du Colombier if (is_DC_band) {
1527dd7cddfSDavid du Colombier if (cinfo->Ah != 0) /* DC refinement needs no table */
1537dd7cddfSDavid du Colombier continue;
1547dd7cddfSDavid du Colombier tbl = compptr->dc_tbl_no;
1557dd7cddfSDavid du Colombier } else {
1567dd7cddfSDavid du Colombier entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
1577dd7cddfSDavid du Colombier }
1587dd7cddfSDavid du Colombier if (gather_statistics) {
159*593dc095SDavid du Colombier /* Check for invalid table index */
160*593dc095SDavid du Colombier /* (make_c_derived_tbl does this in the other path) */
161*593dc095SDavid du Colombier if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
162*593dc095SDavid du Colombier ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
1637dd7cddfSDavid du Colombier /* Allocate and zero the statistics tables */
1647dd7cddfSDavid du Colombier /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
1657dd7cddfSDavid du Colombier if (entropy->count_ptrs[tbl] == NULL)
1667dd7cddfSDavid du Colombier entropy->count_ptrs[tbl] = (long *)
1677dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
1687dd7cddfSDavid du Colombier 257 * SIZEOF(long));
1697dd7cddfSDavid du Colombier MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
1707dd7cddfSDavid du Colombier } else {
171*593dc095SDavid du Colombier /* Compute derived values for Huffman table */
1727dd7cddfSDavid du Colombier /* We may do this more than once for a table, but it's not expensive */
173*593dc095SDavid du Colombier jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
1747dd7cddfSDavid du Colombier & entropy->derived_tbls[tbl]);
1757dd7cddfSDavid du Colombier }
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier /* Initialize AC stuff */
1797dd7cddfSDavid du Colombier entropy->EOBRUN = 0;
1807dd7cddfSDavid du Colombier entropy->BE = 0;
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier /* Initialize bit buffer to empty */
1837dd7cddfSDavid du Colombier entropy->put_buffer = 0;
1847dd7cddfSDavid du Colombier entropy->put_bits = 0;
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier /* Initialize restart stuff */
1877dd7cddfSDavid du Colombier entropy->restarts_to_go = cinfo->restart_interval;
1887dd7cddfSDavid du Colombier entropy->next_restart_num = 0;
1897dd7cddfSDavid du Colombier }
1907dd7cddfSDavid du Colombier
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier /* Outputting bytes to the file.
1937dd7cddfSDavid du Colombier * NB: these must be called only when actually outputting,
1947dd7cddfSDavid du Colombier * that is, entropy->gather_statistics == FALSE.
1957dd7cddfSDavid du Colombier */
1967dd7cddfSDavid du Colombier
1977dd7cddfSDavid du Colombier /* Emit a byte */
1987dd7cddfSDavid du Colombier #define emit_byte(entropy,val) \
1997dd7cddfSDavid du Colombier { *(entropy)->next_output_byte++ = (JOCTET) (val); \
2007dd7cddfSDavid du Colombier if (--(entropy)->free_in_buffer == 0) \
2017dd7cddfSDavid du Colombier dump_buffer(entropy); }
2027dd7cddfSDavid du Colombier
2037dd7cddfSDavid du Colombier
2047dd7cddfSDavid du Colombier LOCAL(void)
dump_buffer(phuff_entropy_ptr entropy)2057dd7cddfSDavid du Colombier dump_buffer (phuff_entropy_ptr entropy)
2067dd7cddfSDavid du Colombier /* Empty the output buffer; we do not support suspension in this module. */
2077dd7cddfSDavid du Colombier {
2087dd7cddfSDavid du Colombier struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
2097dd7cddfSDavid du Colombier
2107dd7cddfSDavid du Colombier if (! (*dest->empty_output_buffer) (entropy->cinfo))
2117dd7cddfSDavid du Colombier ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
2127dd7cddfSDavid du Colombier /* After a successful buffer dump, must reset buffer pointers */
2137dd7cddfSDavid du Colombier entropy->next_output_byte = dest->next_output_byte;
2147dd7cddfSDavid du Colombier entropy->free_in_buffer = dest->free_in_buffer;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier
2177dd7cddfSDavid du Colombier
2187dd7cddfSDavid du Colombier /* Outputting bits to the file */
2197dd7cddfSDavid du Colombier
2207dd7cddfSDavid du Colombier /* Only the right 24 bits of put_buffer are used; the valid bits are
2217dd7cddfSDavid du Colombier * left-justified in this part. At most 16 bits can be passed to emit_bits
2227dd7cddfSDavid du Colombier * in one call, and we never retain more than 7 bits in put_buffer
2237dd7cddfSDavid du Colombier * between calls, so 24 bits are sufficient.
2247dd7cddfSDavid du Colombier */
2257dd7cddfSDavid du Colombier
2267dd7cddfSDavid du Colombier INLINE
LOCAL(void)2277dd7cddfSDavid du Colombier LOCAL(void)
2287dd7cddfSDavid du Colombier emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
2297dd7cddfSDavid du Colombier /* Emit some bits, unless we are in gather mode */
2307dd7cddfSDavid du Colombier {
2317dd7cddfSDavid du Colombier /* This routine is heavily used, so it's worth coding tightly. */
2327dd7cddfSDavid du Colombier register INT32 put_buffer = (INT32) code;
2337dd7cddfSDavid du Colombier register int put_bits = entropy->put_bits;
2347dd7cddfSDavid du Colombier
2357dd7cddfSDavid du Colombier /* if size is 0, caller used an invalid Huffman table entry */
2367dd7cddfSDavid du Colombier if (size == 0)
2377dd7cddfSDavid du Colombier ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
2387dd7cddfSDavid du Colombier
2397dd7cddfSDavid du Colombier if (entropy->gather_statistics)
2407dd7cddfSDavid du Colombier return; /* do nothing if we're only getting stats */
2417dd7cddfSDavid du Colombier
2427dd7cddfSDavid du Colombier put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
2437dd7cddfSDavid du Colombier
2447dd7cddfSDavid du Colombier put_bits += size; /* new number of bits in buffer */
2457dd7cddfSDavid du Colombier
2467dd7cddfSDavid du Colombier put_buffer <<= 24 - put_bits; /* align incoming bits */
2477dd7cddfSDavid du Colombier
2487dd7cddfSDavid du Colombier put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier while (put_bits >= 8) {
2517dd7cddfSDavid du Colombier int c = (int) ((put_buffer >> 16) & 0xFF);
2527dd7cddfSDavid du Colombier
2537dd7cddfSDavid du Colombier emit_byte(entropy, c);
2547dd7cddfSDavid du Colombier if (c == 0xFF) { /* need to stuff a zero byte? */
2557dd7cddfSDavid du Colombier emit_byte(entropy, 0);
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier put_buffer <<= 8;
2587dd7cddfSDavid du Colombier put_bits -= 8;
2597dd7cddfSDavid du Colombier }
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier entropy->put_buffer = put_buffer; /* update variables */
2627dd7cddfSDavid du Colombier entropy->put_bits = put_bits;
2637dd7cddfSDavid du Colombier }
2647dd7cddfSDavid du Colombier
2657dd7cddfSDavid du Colombier
2667dd7cddfSDavid du Colombier LOCAL(void)
flush_bits(phuff_entropy_ptr entropy)2677dd7cddfSDavid du Colombier flush_bits (phuff_entropy_ptr entropy)
2687dd7cddfSDavid du Colombier {
2697dd7cddfSDavid du Colombier emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
2707dd7cddfSDavid du Colombier entropy->put_buffer = 0; /* and reset bit-buffer to empty */
2717dd7cddfSDavid du Colombier entropy->put_bits = 0;
2727dd7cddfSDavid du Colombier }
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier /*
2767dd7cddfSDavid du Colombier * Emit (or just count) a Huffman symbol.
2777dd7cddfSDavid du Colombier */
2787dd7cddfSDavid du Colombier
2797dd7cddfSDavid du Colombier INLINE
LOCAL(void)2807dd7cddfSDavid du Colombier LOCAL(void)
2817dd7cddfSDavid du Colombier emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
2827dd7cddfSDavid du Colombier {
2837dd7cddfSDavid du Colombier if (entropy->gather_statistics)
2847dd7cddfSDavid du Colombier entropy->count_ptrs[tbl_no][symbol]++;
2857dd7cddfSDavid du Colombier else {
2867dd7cddfSDavid du Colombier c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
2877dd7cddfSDavid du Colombier emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
2887dd7cddfSDavid du Colombier }
2897dd7cddfSDavid du Colombier }
2907dd7cddfSDavid du Colombier
2917dd7cddfSDavid du Colombier
2927dd7cddfSDavid du Colombier /*
2937dd7cddfSDavid du Colombier * Emit bits from a correction bit buffer.
2947dd7cddfSDavid du Colombier */
2957dd7cddfSDavid du Colombier
2967dd7cddfSDavid du Colombier LOCAL(void)
emit_buffered_bits(phuff_entropy_ptr entropy,char * bufstart,unsigned int nbits)2977dd7cddfSDavid du Colombier emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
2987dd7cddfSDavid du Colombier unsigned int nbits)
2997dd7cddfSDavid du Colombier {
3007dd7cddfSDavid du Colombier if (entropy->gather_statistics)
3017dd7cddfSDavid du Colombier return; /* no real work */
3027dd7cddfSDavid du Colombier
3037dd7cddfSDavid du Colombier while (nbits > 0) {
3047dd7cddfSDavid du Colombier emit_bits(entropy, (unsigned int) (*bufstart), 1);
3057dd7cddfSDavid du Colombier bufstart++;
3067dd7cddfSDavid du Colombier nbits--;
3077dd7cddfSDavid du Colombier }
3087dd7cddfSDavid du Colombier }
3097dd7cddfSDavid du Colombier
3107dd7cddfSDavid du Colombier
3117dd7cddfSDavid du Colombier /*
3127dd7cddfSDavid du Colombier * Emit any pending EOBRUN symbol.
3137dd7cddfSDavid du Colombier */
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier LOCAL(void)
emit_eobrun(phuff_entropy_ptr entropy)3167dd7cddfSDavid du Colombier emit_eobrun (phuff_entropy_ptr entropy)
3177dd7cddfSDavid du Colombier {
3187dd7cddfSDavid du Colombier register int temp, nbits;
3197dd7cddfSDavid du Colombier
3207dd7cddfSDavid du Colombier if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
3217dd7cddfSDavid du Colombier temp = entropy->EOBRUN;
3227dd7cddfSDavid du Colombier nbits = 0;
3237dd7cddfSDavid du Colombier while ((temp >>= 1))
3247dd7cddfSDavid du Colombier nbits++;
325*593dc095SDavid du Colombier /* safety check: shouldn't happen given limited correction-bit buffer */
326*593dc095SDavid du Colombier if (nbits > 14)
327*593dc095SDavid du Colombier ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
3287dd7cddfSDavid du Colombier
3297dd7cddfSDavid du Colombier emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
3307dd7cddfSDavid du Colombier if (nbits)
3317dd7cddfSDavid du Colombier emit_bits(entropy, entropy->EOBRUN, nbits);
3327dd7cddfSDavid du Colombier
3337dd7cddfSDavid du Colombier entropy->EOBRUN = 0;
3347dd7cddfSDavid du Colombier
3357dd7cddfSDavid du Colombier /* Emit any buffered correction bits */
3367dd7cddfSDavid du Colombier emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
3377dd7cddfSDavid du Colombier entropy->BE = 0;
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier }
3407dd7cddfSDavid du Colombier
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier /*
3437dd7cddfSDavid du Colombier * Emit a restart marker & resynchronize predictions.
3447dd7cddfSDavid du Colombier */
3457dd7cddfSDavid du Colombier
3467dd7cddfSDavid du Colombier LOCAL(void)
emit_restart(phuff_entropy_ptr entropy,int restart_num)3477dd7cddfSDavid du Colombier emit_restart (phuff_entropy_ptr entropy, int restart_num)
3487dd7cddfSDavid du Colombier {
3497dd7cddfSDavid du Colombier int ci;
3507dd7cddfSDavid du Colombier
3517dd7cddfSDavid du Colombier emit_eobrun(entropy);
3527dd7cddfSDavid du Colombier
3537dd7cddfSDavid du Colombier if (! entropy->gather_statistics) {
3547dd7cddfSDavid du Colombier flush_bits(entropy);
3557dd7cddfSDavid du Colombier emit_byte(entropy, 0xFF);
3567dd7cddfSDavid du Colombier emit_byte(entropy, JPEG_RST0 + restart_num);
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier
3597dd7cddfSDavid du Colombier if (entropy->cinfo->Ss == 0) {
3607dd7cddfSDavid du Colombier /* Re-initialize DC predictions to 0 */
3617dd7cddfSDavid du Colombier for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
3627dd7cddfSDavid du Colombier entropy->last_dc_val[ci] = 0;
3637dd7cddfSDavid du Colombier } else {
3647dd7cddfSDavid du Colombier /* Re-initialize all AC-related fields to 0 */
3657dd7cddfSDavid du Colombier entropy->EOBRUN = 0;
3667dd7cddfSDavid du Colombier entropy->BE = 0;
3677dd7cddfSDavid du Colombier }
3687dd7cddfSDavid du Colombier }
3697dd7cddfSDavid du Colombier
3707dd7cddfSDavid du Colombier
3717dd7cddfSDavid du Colombier /*
3727dd7cddfSDavid du Colombier * MCU encoding for DC initial scan (either spectral selection,
3737dd7cddfSDavid du Colombier * or first pass of successive approximation).
3747dd7cddfSDavid du Colombier */
3757dd7cddfSDavid du Colombier
3767dd7cddfSDavid du Colombier METHODDEF(boolean)
encode_mcu_DC_first(j_compress_ptr cinfo,JBLOCKROW * MCU_data)3777dd7cddfSDavid du Colombier encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
3787dd7cddfSDavid du Colombier {
3797dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
3807dd7cddfSDavid du Colombier register int temp, temp2;
3817dd7cddfSDavid du Colombier register int nbits;
3827dd7cddfSDavid du Colombier int blkn, ci;
3837dd7cddfSDavid du Colombier int Al = cinfo->Al;
3847dd7cddfSDavid du Colombier JBLOCKROW block;
3857dd7cddfSDavid du Colombier jpeg_component_info * compptr;
3867dd7cddfSDavid du Colombier ISHIFT_TEMPS
3877dd7cddfSDavid du Colombier
3887dd7cddfSDavid du Colombier entropy->next_output_byte = cinfo->dest->next_output_byte;
3897dd7cddfSDavid du Colombier entropy->free_in_buffer = cinfo->dest->free_in_buffer;
3907dd7cddfSDavid du Colombier
3917dd7cddfSDavid du Colombier /* Emit restart marker if needed */
3927dd7cddfSDavid du Colombier if (cinfo->restart_interval)
3937dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0)
3947dd7cddfSDavid du Colombier emit_restart(entropy, entropy->next_restart_num);
3957dd7cddfSDavid du Colombier
3967dd7cddfSDavid du Colombier /* Encode the MCU data blocks */
3977dd7cddfSDavid du Colombier for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
3987dd7cddfSDavid du Colombier block = MCU_data[blkn];
3997dd7cddfSDavid du Colombier ci = cinfo->MCU_membership[blkn];
4007dd7cddfSDavid du Colombier compptr = cinfo->cur_comp_info[ci];
4017dd7cddfSDavid du Colombier
4027dd7cddfSDavid du Colombier /* Compute the DC value after the required point transform by Al.
4037dd7cddfSDavid du Colombier * This is simply an arithmetic right shift.
4047dd7cddfSDavid du Colombier */
4057dd7cddfSDavid du Colombier temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
4067dd7cddfSDavid du Colombier
4077dd7cddfSDavid du Colombier /* DC differences are figured on the point-transformed values. */
4087dd7cddfSDavid du Colombier temp = temp2 - entropy->last_dc_val[ci];
4097dd7cddfSDavid du Colombier entropy->last_dc_val[ci] = temp2;
4107dd7cddfSDavid du Colombier
4117dd7cddfSDavid du Colombier /* Encode the DC coefficient difference per section G.1.2.1 */
4127dd7cddfSDavid du Colombier temp2 = temp;
4137dd7cddfSDavid du Colombier if (temp < 0) {
4147dd7cddfSDavid du Colombier temp = -temp; /* temp is abs value of input */
4157dd7cddfSDavid du Colombier /* For a negative input, want temp2 = bitwise complement of abs(input) */
4167dd7cddfSDavid du Colombier /* This code assumes we are on a two's complement machine */
4177dd7cddfSDavid du Colombier temp2--;
4187dd7cddfSDavid du Colombier }
4197dd7cddfSDavid du Colombier
4207dd7cddfSDavid du Colombier /* Find the number of bits needed for the magnitude of the coefficient */
4217dd7cddfSDavid du Colombier nbits = 0;
4227dd7cddfSDavid du Colombier while (temp) {
4237dd7cddfSDavid du Colombier nbits++;
4247dd7cddfSDavid du Colombier temp >>= 1;
4257dd7cddfSDavid du Colombier }
426*593dc095SDavid du Colombier /* Check for out-of-range coefficient values.
427*593dc095SDavid du Colombier * Since we're encoding a difference, the range limit is twice as much.
428*593dc095SDavid du Colombier */
429*593dc095SDavid du Colombier if (nbits > MAX_COEF_BITS+1)
430*593dc095SDavid du Colombier ERREXIT(cinfo, JERR_BAD_DCT_COEF);
4317dd7cddfSDavid du Colombier
4327dd7cddfSDavid du Colombier /* Count/emit the Huffman-coded symbol for the number of bits */
4337dd7cddfSDavid du Colombier emit_symbol(entropy, compptr->dc_tbl_no, nbits);
4347dd7cddfSDavid du Colombier
4357dd7cddfSDavid du Colombier /* Emit that number of bits of the value, if positive, */
4367dd7cddfSDavid du Colombier /* or the complement of its magnitude, if negative. */
4377dd7cddfSDavid du Colombier if (nbits) /* emit_bits rejects calls with size 0 */
4387dd7cddfSDavid du Colombier emit_bits(entropy, (unsigned int) temp2, nbits);
4397dd7cddfSDavid du Colombier }
4407dd7cddfSDavid du Colombier
4417dd7cddfSDavid du Colombier cinfo->dest->next_output_byte = entropy->next_output_byte;
4427dd7cddfSDavid du Colombier cinfo->dest->free_in_buffer = entropy->free_in_buffer;
4437dd7cddfSDavid du Colombier
4447dd7cddfSDavid du Colombier /* Update restart-interval state too */
4457dd7cddfSDavid du Colombier if (cinfo->restart_interval) {
4467dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0) {
4477dd7cddfSDavid du Colombier entropy->restarts_to_go = cinfo->restart_interval;
4487dd7cddfSDavid du Colombier entropy->next_restart_num++;
4497dd7cddfSDavid du Colombier entropy->next_restart_num &= 7;
4507dd7cddfSDavid du Colombier }
4517dd7cddfSDavid du Colombier entropy->restarts_to_go--;
4527dd7cddfSDavid du Colombier }
4537dd7cddfSDavid du Colombier
4547dd7cddfSDavid du Colombier return TRUE;
4557dd7cddfSDavid du Colombier }
4567dd7cddfSDavid du Colombier
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier /*
4597dd7cddfSDavid du Colombier * MCU encoding for AC initial scan (either spectral selection,
4607dd7cddfSDavid du Colombier * or first pass of successive approximation).
4617dd7cddfSDavid du Colombier */
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier METHODDEF(boolean)
encode_mcu_AC_first(j_compress_ptr cinfo,JBLOCKROW * MCU_data)4647dd7cddfSDavid du Colombier encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
4657dd7cddfSDavid du Colombier {
4667dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
4677dd7cddfSDavid du Colombier register int temp, temp2;
4687dd7cddfSDavid du Colombier register int nbits;
4697dd7cddfSDavid du Colombier register int r, k;
4707dd7cddfSDavid du Colombier int Se = cinfo->Se;
4717dd7cddfSDavid du Colombier int Al = cinfo->Al;
4727dd7cddfSDavid du Colombier JBLOCKROW block;
4737dd7cddfSDavid du Colombier
4747dd7cddfSDavid du Colombier entropy->next_output_byte = cinfo->dest->next_output_byte;
4757dd7cddfSDavid du Colombier entropy->free_in_buffer = cinfo->dest->free_in_buffer;
4767dd7cddfSDavid du Colombier
4777dd7cddfSDavid du Colombier /* Emit restart marker if needed */
4787dd7cddfSDavid du Colombier if (cinfo->restart_interval)
4797dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0)
4807dd7cddfSDavid du Colombier emit_restart(entropy, entropy->next_restart_num);
4817dd7cddfSDavid du Colombier
4827dd7cddfSDavid du Colombier /* Encode the MCU data block */
4837dd7cddfSDavid du Colombier block = MCU_data[0];
4847dd7cddfSDavid du Colombier
4857dd7cddfSDavid du Colombier /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
4867dd7cddfSDavid du Colombier
4877dd7cddfSDavid du Colombier r = 0; /* r = run length of zeros */
4887dd7cddfSDavid du Colombier
4897dd7cddfSDavid du Colombier for (k = cinfo->Ss; k <= Se; k++) {
4907dd7cddfSDavid du Colombier if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
4917dd7cddfSDavid du Colombier r++;
4927dd7cddfSDavid du Colombier continue;
4937dd7cddfSDavid du Colombier }
4947dd7cddfSDavid du Colombier /* We must apply the point transform by Al. For AC coefficients this
4957dd7cddfSDavid du Colombier * is an integer division with rounding towards 0. To do this portably
4967dd7cddfSDavid du Colombier * in C, we shift after obtaining the absolute value; so the code is
4977dd7cddfSDavid du Colombier * interwoven with finding the abs value (temp) and output bits (temp2).
4987dd7cddfSDavid du Colombier */
4997dd7cddfSDavid du Colombier if (temp < 0) {
5007dd7cddfSDavid du Colombier temp = -temp; /* temp is abs value of input */
5017dd7cddfSDavid du Colombier temp >>= Al; /* apply the point transform */
5027dd7cddfSDavid du Colombier /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
5037dd7cddfSDavid du Colombier temp2 = ~temp;
5047dd7cddfSDavid du Colombier } else {
5057dd7cddfSDavid du Colombier temp >>= Al; /* apply the point transform */
5067dd7cddfSDavid du Colombier temp2 = temp;
5077dd7cddfSDavid du Colombier }
5087dd7cddfSDavid du Colombier /* Watch out for case that nonzero coef is zero after point transform */
5097dd7cddfSDavid du Colombier if (temp == 0) {
5107dd7cddfSDavid du Colombier r++;
5117dd7cddfSDavid du Colombier continue;
5127dd7cddfSDavid du Colombier }
5137dd7cddfSDavid du Colombier
5147dd7cddfSDavid du Colombier /* Emit any pending EOBRUN */
5157dd7cddfSDavid du Colombier if (entropy->EOBRUN > 0)
5167dd7cddfSDavid du Colombier emit_eobrun(entropy);
5177dd7cddfSDavid du Colombier /* if run length > 15, must emit special run-length-16 codes (0xF0) */
5187dd7cddfSDavid du Colombier while (r > 15) {
5197dd7cddfSDavid du Colombier emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
5207dd7cddfSDavid du Colombier r -= 16;
5217dd7cddfSDavid du Colombier }
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier /* Find the number of bits needed for the magnitude of the coefficient */
5247dd7cddfSDavid du Colombier nbits = 1; /* there must be at least one 1 bit */
5257dd7cddfSDavid du Colombier while ((temp >>= 1))
5267dd7cddfSDavid du Colombier nbits++;
527*593dc095SDavid du Colombier /* Check for out-of-range coefficient values */
528*593dc095SDavid du Colombier if (nbits > MAX_COEF_BITS)
529*593dc095SDavid du Colombier ERREXIT(cinfo, JERR_BAD_DCT_COEF);
5307dd7cddfSDavid du Colombier
5317dd7cddfSDavid du Colombier /* Count/emit Huffman symbol for run length / number of bits */
5327dd7cddfSDavid du Colombier emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
5337dd7cddfSDavid du Colombier
5347dd7cddfSDavid du Colombier /* Emit that number of bits of the value, if positive, */
5357dd7cddfSDavid du Colombier /* or the complement of its magnitude, if negative. */
5367dd7cddfSDavid du Colombier emit_bits(entropy, (unsigned int) temp2, nbits);
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier r = 0; /* reset zero run length */
5397dd7cddfSDavid du Colombier }
5407dd7cddfSDavid du Colombier
5417dd7cddfSDavid du Colombier if (r > 0) { /* If there are trailing zeroes, */
5427dd7cddfSDavid du Colombier entropy->EOBRUN++; /* count an EOB */
5437dd7cddfSDavid du Colombier if (entropy->EOBRUN == 0x7FFF)
5447dd7cddfSDavid du Colombier emit_eobrun(entropy); /* force it out to avoid overflow */
5457dd7cddfSDavid du Colombier }
5467dd7cddfSDavid du Colombier
5477dd7cddfSDavid du Colombier cinfo->dest->next_output_byte = entropy->next_output_byte;
5487dd7cddfSDavid du Colombier cinfo->dest->free_in_buffer = entropy->free_in_buffer;
5497dd7cddfSDavid du Colombier
5507dd7cddfSDavid du Colombier /* Update restart-interval state too */
5517dd7cddfSDavid du Colombier if (cinfo->restart_interval) {
5527dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0) {
5537dd7cddfSDavid du Colombier entropy->restarts_to_go = cinfo->restart_interval;
5547dd7cddfSDavid du Colombier entropy->next_restart_num++;
5557dd7cddfSDavid du Colombier entropy->next_restart_num &= 7;
5567dd7cddfSDavid du Colombier }
5577dd7cddfSDavid du Colombier entropy->restarts_to_go--;
5587dd7cddfSDavid du Colombier }
5597dd7cddfSDavid du Colombier
5607dd7cddfSDavid du Colombier return TRUE;
5617dd7cddfSDavid du Colombier }
5627dd7cddfSDavid du Colombier
5637dd7cddfSDavid du Colombier
5647dd7cddfSDavid du Colombier /*
5657dd7cddfSDavid du Colombier * MCU encoding for DC successive approximation refinement scan.
5667dd7cddfSDavid du Colombier * Note: we assume such scans can be multi-component, although the spec
5677dd7cddfSDavid du Colombier * is not very clear on the point.
5687dd7cddfSDavid du Colombier */
5697dd7cddfSDavid du Colombier
5707dd7cddfSDavid du Colombier METHODDEF(boolean)
encode_mcu_DC_refine(j_compress_ptr cinfo,JBLOCKROW * MCU_data)5717dd7cddfSDavid du Colombier encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
5727dd7cddfSDavid du Colombier {
5737dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
5747dd7cddfSDavid du Colombier register int temp;
5757dd7cddfSDavid du Colombier int blkn;
5767dd7cddfSDavid du Colombier int Al = cinfo->Al;
5777dd7cddfSDavid du Colombier JBLOCKROW block;
5787dd7cddfSDavid du Colombier
5797dd7cddfSDavid du Colombier entropy->next_output_byte = cinfo->dest->next_output_byte;
5807dd7cddfSDavid du Colombier entropy->free_in_buffer = cinfo->dest->free_in_buffer;
5817dd7cddfSDavid du Colombier
5827dd7cddfSDavid du Colombier /* Emit restart marker if needed */
5837dd7cddfSDavid du Colombier if (cinfo->restart_interval)
5847dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0)
5857dd7cddfSDavid du Colombier emit_restart(entropy, entropy->next_restart_num);
5867dd7cddfSDavid du Colombier
5877dd7cddfSDavid du Colombier /* Encode the MCU data blocks */
5887dd7cddfSDavid du Colombier for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
5897dd7cddfSDavid du Colombier block = MCU_data[blkn];
5907dd7cddfSDavid du Colombier
5917dd7cddfSDavid du Colombier /* We simply emit the Al'th bit of the DC coefficient value. */
5927dd7cddfSDavid du Colombier temp = (*block)[0];
5937dd7cddfSDavid du Colombier emit_bits(entropy, (unsigned int) (temp >> Al), 1);
5947dd7cddfSDavid du Colombier }
5957dd7cddfSDavid du Colombier
5967dd7cddfSDavid du Colombier cinfo->dest->next_output_byte = entropy->next_output_byte;
5977dd7cddfSDavid du Colombier cinfo->dest->free_in_buffer = entropy->free_in_buffer;
5987dd7cddfSDavid du Colombier
5997dd7cddfSDavid du Colombier /* Update restart-interval state too */
6007dd7cddfSDavid du Colombier if (cinfo->restart_interval) {
6017dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0) {
6027dd7cddfSDavid du Colombier entropy->restarts_to_go = cinfo->restart_interval;
6037dd7cddfSDavid du Colombier entropy->next_restart_num++;
6047dd7cddfSDavid du Colombier entropy->next_restart_num &= 7;
6057dd7cddfSDavid du Colombier }
6067dd7cddfSDavid du Colombier entropy->restarts_to_go--;
6077dd7cddfSDavid du Colombier }
6087dd7cddfSDavid du Colombier
6097dd7cddfSDavid du Colombier return TRUE;
6107dd7cddfSDavid du Colombier }
6117dd7cddfSDavid du Colombier
6127dd7cddfSDavid du Colombier
6137dd7cddfSDavid du Colombier /*
6147dd7cddfSDavid du Colombier * MCU encoding for AC successive approximation refinement scan.
6157dd7cddfSDavid du Colombier */
6167dd7cddfSDavid du Colombier
6177dd7cddfSDavid du Colombier METHODDEF(boolean)
encode_mcu_AC_refine(j_compress_ptr cinfo,JBLOCKROW * MCU_data)6187dd7cddfSDavid du Colombier encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
6197dd7cddfSDavid du Colombier {
6207dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
6217dd7cddfSDavid du Colombier register int temp;
6227dd7cddfSDavid du Colombier register int r, k;
6237dd7cddfSDavid du Colombier int EOB;
6247dd7cddfSDavid du Colombier char *BR_buffer;
6257dd7cddfSDavid du Colombier unsigned int BR;
6267dd7cddfSDavid du Colombier int Se = cinfo->Se;
6277dd7cddfSDavid du Colombier int Al = cinfo->Al;
6287dd7cddfSDavid du Colombier JBLOCKROW block;
6297dd7cddfSDavid du Colombier int absvalues[DCTSIZE2];
6307dd7cddfSDavid du Colombier
6317dd7cddfSDavid du Colombier entropy->next_output_byte = cinfo->dest->next_output_byte;
6327dd7cddfSDavid du Colombier entropy->free_in_buffer = cinfo->dest->free_in_buffer;
6337dd7cddfSDavid du Colombier
6347dd7cddfSDavid du Colombier /* Emit restart marker if needed */
6357dd7cddfSDavid du Colombier if (cinfo->restart_interval)
6367dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0)
6377dd7cddfSDavid du Colombier emit_restart(entropy, entropy->next_restart_num);
6387dd7cddfSDavid du Colombier
6397dd7cddfSDavid du Colombier /* Encode the MCU data block */
6407dd7cddfSDavid du Colombier block = MCU_data[0];
6417dd7cddfSDavid du Colombier
6427dd7cddfSDavid du Colombier /* It is convenient to make a pre-pass to determine the transformed
6437dd7cddfSDavid du Colombier * coefficients' absolute values and the EOB position.
6447dd7cddfSDavid du Colombier */
6457dd7cddfSDavid du Colombier EOB = 0;
6467dd7cddfSDavid du Colombier for (k = cinfo->Ss; k <= Se; k++) {
6477dd7cddfSDavid du Colombier temp = (*block)[jpeg_natural_order[k]];
6487dd7cddfSDavid du Colombier /* We must apply the point transform by Al. For AC coefficients this
6497dd7cddfSDavid du Colombier * is an integer division with rounding towards 0. To do this portably
6507dd7cddfSDavid du Colombier * in C, we shift after obtaining the absolute value.
6517dd7cddfSDavid du Colombier */
6527dd7cddfSDavid du Colombier if (temp < 0)
6537dd7cddfSDavid du Colombier temp = -temp; /* temp is abs value of input */
6547dd7cddfSDavid du Colombier temp >>= Al; /* apply the point transform */
6557dd7cddfSDavid du Colombier absvalues[k] = temp; /* save abs value for main pass */
6567dd7cddfSDavid du Colombier if (temp == 1)
6577dd7cddfSDavid du Colombier EOB = k; /* EOB = index of last newly-nonzero coef */
6587dd7cddfSDavid du Colombier }
6597dd7cddfSDavid du Colombier
6607dd7cddfSDavid du Colombier /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
6617dd7cddfSDavid du Colombier
6627dd7cddfSDavid du Colombier r = 0; /* r = run length of zeros */
6637dd7cddfSDavid du Colombier BR = 0; /* BR = count of buffered bits added now */
6647dd7cddfSDavid du Colombier BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
6657dd7cddfSDavid du Colombier
6667dd7cddfSDavid du Colombier for (k = cinfo->Ss; k <= Se; k++) {
6677dd7cddfSDavid du Colombier if ((temp = absvalues[k]) == 0) {
6687dd7cddfSDavid du Colombier r++;
6697dd7cddfSDavid du Colombier continue;
6707dd7cddfSDavid du Colombier }
6717dd7cddfSDavid du Colombier
6727dd7cddfSDavid du Colombier /* Emit any required ZRLs, but not if they can be folded into EOB */
6737dd7cddfSDavid du Colombier while (r > 15 && k <= EOB) {
6747dd7cddfSDavid du Colombier /* emit any pending EOBRUN and the BE correction bits */
6757dd7cddfSDavid du Colombier emit_eobrun(entropy);
6767dd7cddfSDavid du Colombier /* Emit ZRL */
6777dd7cddfSDavid du Colombier emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
6787dd7cddfSDavid du Colombier r -= 16;
6797dd7cddfSDavid du Colombier /* Emit buffered correction bits that must be associated with ZRL */
6807dd7cddfSDavid du Colombier emit_buffered_bits(entropy, BR_buffer, BR);
6817dd7cddfSDavid du Colombier BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
6827dd7cddfSDavid du Colombier BR = 0;
6837dd7cddfSDavid du Colombier }
6847dd7cddfSDavid du Colombier
6857dd7cddfSDavid du Colombier /* If the coef was previously nonzero, it only needs a correction bit.
6867dd7cddfSDavid du Colombier * NOTE: a straight translation of the spec's figure G.7 would suggest
6877dd7cddfSDavid du Colombier * that we also need to test r > 15. But if r > 15, we can only get here
6887dd7cddfSDavid du Colombier * if k > EOB, which implies that this coefficient is not 1.
6897dd7cddfSDavid du Colombier */
6907dd7cddfSDavid du Colombier if (temp > 1) {
6917dd7cddfSDavid du Colombier /* The correction bit is the next bit of the absolute value. */
6927dd7cddfSDavid du Colombier BR_buffer[BR++] = (char) (temp & 1);
6937dd7cddfSDavid du Colombier continue;
6947dd7cddfSDavid du Colombier }
6957dd7cddfSDavid du Colombier
6967dd7cddfSDavid du Colombier /* Emit any pending EOBRUN and the BE correction bits */
6977dd7cddfSDavid du Colombier emit_eobrun(entropy);
6987dd7cddfSDavid du Colombier
6997dd7cddfSDavid du Colombier /* Count/emit Huffman symbol for run length / number of bits */
7007dd7cddfSDavid du Colombier emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
7017dd7cddfSDavid du Colombier
7027dd7cddfSDavid du Colombier /* Emit output bit for newly-nonzero coef */
7037dd7cddfSDavid du Colombier temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
7047dd7cddfSDavid du Colombier emit_bits(entropy, (unsigned int) temp, 1);
7057dd7cddfSDavid du Colombier
7067dd7cddfSDavid du Colombier /* Emit buffered correction bits that must be associated with this code */
7077dd7cddfSDavid du Colombier emit_buffered_bits(entropy, BR_buffer, BR);
7087dd7cddfSDavid du Colombier BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
7097dd7cddfSDavid du Colombier BR = 0;
7107dd7cddfSDavid du Colombier r = 0; /* reset zero run length */
7117dd7cddfSDavid du Colombier }
7127dd7cddfSDavid du Colombier
7137dd7cddfSDavid du Colombier if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
7147dd7cddfSDavid du Colombier entropy->EOBRUN++; /* count an EOB */
7157dd7cddfSDavid du Colombier entropy->BE += BR; /* concat my correction bits to older ones */
7167dd7cddfSDavid du Colombier /* We force out the EOB if we risk either:
7177dd7cddfSDavid du Colombier * 1. overflow of the EOB counter;
7187dd7cddfSDavid du Colombier * 2. overflow of the correction bit buffer during the next MCU.
7197dd7cddfSDavid du Colombier */
7207dd7cddfSDavid du Colombier if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
7217dd7cddfSDavid du Colombier emit_eobrun(entropy);
7227dd7cddfSDavid du Colombier }
7237dd7cddfSDavid du Colombier
7247dd7cddfSDavid du Colombier cinfo->dest->next_output_byte = entropy->next_output_byte;
7257dd7cddfSDavid du Colombier cinfo->dest->free_in_buffer = entropy->free_in_buffer;
7267dd7cddfSDavid du Colombier
7277dd7cddfSDavid du Colombier /* Update restart-interval state too */
7287dd7cddfSDavid du Colombier if (cinfo->restart_interval) {
7297dd7cddfSDavid du Colombier if (entropy->restarts_to_go == 0) {
7307dd7cddfSDavid du Colombier entropy->restarts_to_go = cinfo->restart_interval;
7317dd7cddfSDavid du Colombier entropy->next_restart_num++;
7327dd7cddfSDavid du Colombier entropy->next_restart_num &= 7;
7337dd7cddfSDavid du Colombier }
7347dd7cddfSDavid du Colombier entropy->restarts_to_go--;
7357dd7cddfSDavid du Colombier }
7367dd7cddfSDavid du Colombier
7377dd7cddfSDavid du Colombier return TRUE;
7387dd7cddfSDavid du Colombier }
7397dd7cddfSDavid du Colombier
7407dd7cddfSDavid du Colombier
7417dd7cddfSDavid du Colombier /*
7427dd7cddfSDavid du Colombier * Finish up at the end of a Huffman-compressed progressive scan.
7437dd7cddfSDavid du Colombier */
7447dd7cddfSDavid du Colombier
7457dd7cddfSDavid du Colombier METHODDEF(void)
finish_pass_phuff(j_compress_ptr cinfo)7467dd7cddfSDavid du Colombier finish_pass_phuff (j_compress_ptr cinfo)
7477dd7cddfSDavid du Colombier {
7487dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
7497dd7cddfSDavid du Colombier
7507dd7cddfSDavid du Colombier entropy->next_output_byte = cinfo->dest->next_output_byte;
7517dd7cddfSDavid du Colombier entropy->free_in_buffer = cinfo->dest->free_in_buffer;
7527dd7cddfSDavid du Colombier
7537dd7cddfSDavid du Colombier /* Flush out any buffered data */
7547dd7cddfSDavid du Colombier emit_eobrun(entropy);
7557dd7cddfSDavid du Colombier flush_bits(entropy);
7567dd7cddfSDavid du Colombier
7577dd7cddfSDavid du Colombier cinfo->dest->next_output_byte = entropy->next_output_byte;
7587dd7cddfSDavid du Colombier cinfo->dest->free_in_buffer = entropy->free_in_buffer;
7597dd7cddfSDavid du Colombier }
7607dd7cddfSDavid du Colombier
7617dd7cddfSDavid du Colombier
7627dd7cddfSDavid du Colombier /*
7637dd7cddfSDavid du Colombier * Finish up a statistics-gathering pass and create the new Huffman tables.
7647dd7cddfSDavid du Colombier */
7657dd7cddfSDavid du Colombier
7667dd7cddfSDavid du Colombier METHODDEF(void)
finish_pass_gather_phuff(j_compress_ptr cinfo)7677dd7cddfSDavid du Colombier finish_pass_gather_phuff (j_compress_ptr cinfo)
7687dd7cddfSDavid du Colombier {
7697dd7cddfSDavid du Colombier phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
7707dd7cddfSDavid du Colombier boolean is_DC_band;
7717dd7cddfSDavid du Colombier int ci, tbl;
7727dd7cddfSDavid du Colombier jpeg_component_info * compptr;
7737dd7cddfSDavid du Colombier JHUFF_TBL **htblptr;
7747dd7cddfSDavid du Colombier boolean did[NUM_HUFF_TBLS];
7757dd7cddfSDavid du Colombier
7767dd7cddfSDavid du Colombier /* Flush out buffered data (all we care about is counting the EOB symbol) */
7777dd7cddfSDavid du Colombier emit_eobrun(entropy);
7787dd7cddfSDavid du Colombier
7797dd7cddfSDavid du Colombier is_DC_band = (cinfo->Ss == 0);
7807dd7cddfSDavid du Colombier
7817dd7cddfSDavid du Colombier /* It's important not to apply jpeg_gen_optimal_table more than once
7827dd7cddfSDavid du Colombier * per table, because it clobbers the input frequency counts!
7837dd7cddfSDavid du Colombier */
7847dd7cddfSDavid du Colombier MEMZERO(did, SIZEOF(did));
7857dd7cddfSDavid du Colombier
7867dd7cddfSDavid du Colombier for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
7877dd7cddfSDavid du Colombier compptr = cinfo->cur_comp_info[ci];
7887dd7cddfSDavid du Colombier if (is_DC_band) {
7897dd7cddfSDavid du Colombier if (cinfo->Ah != 0) /* DC refinement needs no table */
7907dd7cddfSDavid du Colombier continue;
7917dd7cddfSDavid du Colombier tbl = compptr->dc_tbl_no;
7927dd7cddfSDavid du Colombier } else {
7937dd7cddfSDavid du Colombier tbl = compptr->ac_tbl_no;
7947dd7cddfSDavid du Colombier }
7957dd7cddfSDavid du Colombier if (! did[tbl]) {
7967dd7cddfSDavid du Colombier if (is_DC_band)
7977dd7cddfSDavid du Colombier htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
7987dd7cddfSDavid du Colombier else
7997dd7cddfSDavid du Colombier htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
8007dd7cddfSDavid du Colombier if (*htblptr == NULL)
8017dd7cddfSDavid du Colombier *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
8027dd7cddfSDavid du Colombier jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
8037dd7cddfSDavid du Colombier did[tbl] = TRUE;
8047dd7cddfSDavid du Colombier }
8057dd7cddfSDavid du Colombier }
8067dd7cddfSDavid du Colombier }
8077dd7cddfSDavid du Colombier
8087dd7cddfSDavid du Colombier
8097dd7cddfSDavid du Colombier /*
8107dd7cddfSDavid du Colombier * Module initialization routine for progressive Huffman entropy encoding.
8117dd7cddfSDavid du Colombier */
8127dd7cddfSDavid du Colombier
8137dd7cddfSDavid du Colombier GLOBAL(void)
jinit_phuff_encoder(j_compress_ptr cinfo)8147dd7cddfSDavid du Colombier jinit_phuff_encoder (j_compress_ptr cinfo)
8157dd7cddfSDavid du Colombier {
8167dd7cddfSDavid du Colombier phuff_entropy_ptr entropy;
8177dd7cddfSDavid du Colombier int i;
8187dd7cddfSDavid du Colombier
8197dd7cddfSDavid du Colombier entropy = (phuff_entropy_ptr)
8207dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
8217dd7cddfSDavid du Colombier SIZEOF(phuff_entropy_encoder));
8227dd7cddfSDavid du Colombier cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
8237dd7cddfSDavid du Colombier entropy->pub.start_pass = start_pass_phuff;
8247dd7cddfSDavid du Colombier
8257dd7cddfSDavid du Colombier /* Mark tables unallocated */
8267dd7cddfSDavid du Colombier for (i = 0; i < NUM_HUFF_TBLS; i++) {
8277dd7cddfSDavid du Colombier entropy->derived_tbls[i] = NULL;
8287dd7cddfSDavid du Colombier entropy->count_ptrs[i] = NULL;
8297dd7cddfSDavid du Colombier }
8307dd7cddfSDavid du Colombier entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
8317dd7cddfSDavid du Colombier }
8327dd7cddfSDavid du Colombier
8337dd7cddfSDavid du Colombier #endif /* C_PROGRESSIVE_SUPPORTED */
834