xref: /plan9/sys/src/cmd/gs/jpeg/jcphuff.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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