xref: /plan9-contrib/sys/src/cmd/gs/src/shc.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1992, 1995, 1997, 1998 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: shc.h,v 1.5 2002/06/16 05:00:54 lpd Exp $ */
187dd7cddfSDavid du Colombier /* Common definitions for filters using Huffman coding */
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier #ifndef shc_INCLUDED
217dd7cddfSDavid du Colombier #  define shc_INCLUDED
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier #include "gsbittab.h"
247dd7cddfSDavid du Colombier #include "scommon.h"
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier /*
277dd7cddfSDavid du Colombier  * These definitions are valid for code lengths up to 16 bits
287dd7cddfSDavid du Colombier  * and non-negative decoded values up to 15 bits.
297dd7cddfSDavid du Colombier  *
307dd7cddfSDavid du Colombier  * We define 3 different representations of the code: encoding tables,
317dd7cddfSDavid du Colombier  * decoding tables, and a definition table which can be generated easily
327dd7cddfSDavid du Colombier  * from frequency information and which in turn can easily generate
337dd7cddfSDavid du Colombier  * the encoding and decoding tables.
347dd7cddfSDavid du Colombier  *
357dd7cddfSDavid du Colombier  * The definition table has two parts: a list of the number of i-bit
367dd7cddfSDavid du Colombier  * codes for each i >= 1, and the decoded values corresponding to
377dd7cddfSDavid du Colombier  * the code values in increasing lexicographic order (which will also
387dd7cddfSDavid du Colombier  * normally be decreasing code frequency).  Calling these two lists
397dd7cddfSDavid du Colombier  * L[1..M] and V[0..N-1] respectively, we have the following invariants:
407dd7cddfSDavid du Colombier  *      - 1 <= M <= max_hc_length, N >= 2.
417dd7cddfSDavid du Colombier  *      - L[0] = 0.
427dd7cddfSDavid du Colombier  *      - for i=1..M, L[i] >= 0.
437dd7cddfSDavid du Colombier  *      - sum(i=1..M: L[i]) = N.
447dd7cddfSDavid du Colombier  *      - sum(i=1..M: L[i] * 2^-i) = 1.
457dd7cddfSDavid du Colombier  *      - V[0..N-1] are a permutation of the integers 0..N-1.
467dd7cddfSDavid du Colombier  */
477dd7cddfSDavid du Colombier #define max_hc_length 16
487dd7cddfSDavid du Colombier typedef struct hc_definition_s {
497dd7cddfSDavid du Colombier     ushort *counts;		/* [0..M] */
507dd7cddfSDavid du Colombier     uint num_counts;		/* M */
517dd7cddfSDavid du Colombier     ushort *values;		/* [0..N-1] */
527dd7cddfSDavid du Colombier     uint num_values;		/* N */
537dd7cddfSDavid du Colombier } hc_definition;
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier /* ------ Common state ------ */
567dd7cddfSDavid du Colombier 
577dd7cddfSDavid du Colombier /*
587dd7cddfSDavid du Colombier  * Define the common stream state for Huffman-coded filters.
597dd7cddfSDavid du Colombier  * Invariants when writing:
607dd7cddfSDavid du Colombier  *      0 <= bits_left <= hc_bits_size;
617dd7cddfSDavid du Colombier  *      Only the leftmost (hc_bits_size - bits_left) bits of bits
627dd7cddfSDavid du Colombier  *        contain valid data.
637dd7cddfSDavid du Colombier  */
647dd7cddfSDavid du Colombier #define stream_hc_state_common\
657dd7cddfSDavid du Colombier 	stream_state_common;\
667dd7cddfSDavid du Colombier 		/* The client sets the following before initialization. */\
677dd7cddfSDavid du Colombier 	bool FirstBitLowOrder;\
687dd7cddfSDavid du Colombier 		/* The following are updated dynamically. */\
697dd7cddfSDavid du Colombier 	uint bits;		/* most recent bits of input or */\
707dd7cddfSDavid du Colombier 				/* current bits of output */\
717dd7cddfSDavid du Colombier 	int bits_left		/* # of valid low bits (input) or */\
727dd7cddfSDavid du Colombier 				/* unused low bits (output) in above, */\
737dd7cddfSDavid du Colombier 				/* 0 <= bits_left <= 7 */
747dd7cddfSDavid du Colombier typedef struct stream_hc_state_s {
757dd7cddfSDavid du Colombier     stream_hc_state_common;
767dd7cddfSDavid du Colombier } stream_hc_state;
777dd7cddfSDavid du Colombier 
787dd7cddfSDavid du Colombier #define hc_bits_size (arch_sizeof_int * 8)
797dd7cddfSDavid du Colombier #define s_hce_init_inline(ss)\
807dd7cddfSDavid du Colombier   ((ss)->bits = 0, (ss)->bits_left = hc_bits_size)
817dd7cddfSDavid du Colombier #define s_hcd_init_inline(ss)\
827dd7cddfSDavid du Colombier   ((ss)->bits = 0, (ss)->bits_left = 0)
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier /* ------ Encoding tables ------ */
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier /* Define the structure for the encoding tables. */
877dd7cddfSDavid du Colombier typedef struct hce_code_s {
887dd7cddfSDavid du Colombier     ushort code;
897dd7cddfSDavid du Colombier     ushort code_length;
907dd7cddfSDavid du Colombier } hce_code;
917dd7cddfSDavid du Colombier 
927dd7cddfSDavid du Colombier #define hce_entry(c, len) { c, len }
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier typedef struct hce_table_s {
957dd7cddfSDavid du Colombier     uint count;
967dd7cddfSDavid du Colombier     hce_code *codes;
977dd7cddfSDavid du Colombier } hce_table;
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier #define hce_bits_available(n)\
1007dd7cddfSDavid du Colombier   (ss->bits_left >= (n) || wlimit - q > ((n) - ss->bits_left - 1) >> 3)
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier /* ------ Encoding utilities ------ */
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier /*
1057dd7cddfSDavid du Colombier  * Put a code on the output.  The client is responsible for ensuring
1067dd7cddfSDavid du Colombier  * that q does not exceed pw->limit.
1077dd7cddfSDavid du Colombier  */
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier #ifdef DEBUG
1107dd7cddfSDavid du Colombier #  define hc_print_value(code, clen)\
1117dd7cddfSDavid du Colombier     (gs_debug_c('W') ?\
1127dd7cddfSDavid du Colombier      (dlprintf2("[W]0x%x,%d\n", code, clen), 0) : 0)
1137dd7cddfSDavid du Colombier #  define hc_print_value_then(code, clen) hc_print_value(code, clen),
1147dd7cddfSDavid du Colombier #else
1157dd7cddfSDavid du Colombier #  define hc_print_value(code, clen) 0
1167dd7cddfSDavid du Colombier #  define hc_print_value_then(code, clen)	/* */
1177dd7cddfSDavid du Colombier #endif
1187dd7cddfSDavid du Colombier #define hc_print_code(rp) hc_print_value((rp)->code, (rp)->code_length)
1197dd7cddfSDavid du Colombier 
1207dd7cddfSDavid du Colombier /* Declare variables that hold the encoder state. */
1217dd7cddfSDavid du Colombier #define hce_declare_state\
1227dd7cddfSDavid du Colombier 	register uint bits;\
1237dd7cddfSDavid du Colombier 	register int bits_left
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier /* Load the state from the stream. */
1267dd7cddfSDavid du Colombier /* Free variables: ss, bits, bits_left. */
1277dd7cddfSDavid du Colombier #define hce_load_state()\
1287dd7cddfSDavid du Colombier 	bits = ss->bits, bits_left = ss->bits_left
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier /* Store the state back in the stream. */
1317dd7cddfSDavid du Colombier /* Free variables: ss, bits, bits_left. */
1327dd7cddfSDavid du Colombier #define hce_store_state()\
1337dd7cddfSDavid du Colombier 	ss->bits = bits, ss->bits_left = bits_left
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier /* Put a code on the stream. */
136*593dc095SDavid du Colombier void hc_put_code_proc(bool, byte *, uint);
1377dd7cddfSDavid du Colombier 
1387dd7cddfSDavid du Colombier #define hc_put_value(ss, q, code, clen)\
1397dd7cddfSDavid du Colombier   (hc_print_value_then(code, clen)\
1407dd7cddfSDavid du Colombier    ((bits_left -= (clen)) >= 0 ?\
1417dd7cddfSDavid du Colombier     (bits += (code) << bits_left) :\
1427dd7cddfSDavid du Colombier     (hc_put_code_proc((ss)->FirstBitLowOrder,\
1437dd7cddfSDavid du Colombier 		      q += hc_bits_size >> 3,\
1447dd7cddfSDavid du Colombier 		      (bits + ((code) >> -bits_left))),\
1457dd7cddfSDavid du Colombier      bits = (code) << (bits_left += hc_bits_size))))
1467dd7cddfSDavid du Colombier #define hc_put_code(ss, q, cp)\
1477dd7cddfSDavid du Colombier   hc_put_value(ss, q, (cp)->code, (cp)->code_length)
1487dd7cddfSDavid du Colombier 
1497dd7cddfSDavid du Colombier /*
1507dd7cddfSDavid du Colombier  * Force out the final bits to the output.
1517dd7cddfSDavid du Colombier  * Note that this does a store_state, but not a load_state.
1527dd7cddfSDavid du Colombier  */
153*593dc095SDavid du Colombier byte *hc_put_last_bits_proc(stream_hc_state *, byte *, uint, int);
1547dd7cddfSDavid du Colombier 
1557dd7cddfSDavid du Colombier #define hc_put_last_bits(ss, q)\
1567dd7cddfSDavid du Colombier   hc_put_last_bits_proc(ss, q, bits, bits_left)
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier /* ------ Decoding tables ------ */
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier /*
1617dd7cddfSDavid du Colombier  * Define the structure for the decoding tables.
1627dd7cddfSDavid du Colombier  * First-level nodes are either leaves, which have
1637dd7cddfSDavid du Colombier  *      value = decoded value
1647dd7cddfSDavid du Colombier  *      code_length <= initial_bits
1657dd7cddfSDavid du Colombier  * or non-leaves, which have
1667dd7cddfSDavid du Colombier  *      value = the index of a sub-table
1677dd7cddfSDavid du Colombier  *      code_length = initial_bits + the number of additional dispatch bits
1687dd7cddfSDavid du Colombier  * Second-level nodes are always leaves, with
1697dd7cddfSDavid du Colombier  *      code_length = the actual number of bits in the code - initial_bits.
1707dd7cddfSDavid du Colombier  */
1717dd7cddfSDavid du Colombier 
1727dd7cddfSDavid du Colombier typedef struct hcd_code_s {
1737dd7cddfSDavid du Colombier     short value;
1747dd7cddfSDavid du Colombier     ushort code_length;
1757dd7cddfSDavid du Colombier } hcd_code;
1767dd7cddfSDavid du Colombier 
1777dd7cddfSDavid du Colombier typedef struct hcd_table_s {
1787dd7cddfSDavid du Colombier     uint count;
1797dd7cddfSDavid du Colombier     uint initial_bits;
1807dd7cddfSDavid du Colombier     hcd_code *codes;
1817dd7cddfSDavid du Colombier } hcd_table;
1827dd7cddfSDavid du Colombier 
1837dd7cddfSDavid du Colombier /* Declare variables that hold the decoder state. */
1847dd7cddfSDavid du Colombier #define hcd_declare_state\
1857dd7cddfSDavid du Colombier 	register const byte *p;\
1867dd7cddfSDavid du Colombier 	const byte *rlimit;\
1877dd7cddfSDavid du Colombier 	uint bits;\
1887dd7cddfSDavid du Colombier 	int bits_left
1897dd7cddfSDavid du Colombier 
1907dd7cddfSDavid du Colombier /* Load the state from the stream. */
1917dd7cddfSDavid du Colombier /* Free variables: pr, ss, p, rlimit, bits, bits_left. */
1927dd7cddfSDavid du Colombier #define hcd_load_state()\
1937dd7cddfSDavid du Colombier 	p = pr->ptr,\
1947dd7cddfSDavid du Colombier 	rlimit = pr->limit,\
1957dd7cddfSDavid du Colombier 	bits = ss->bits,\
1967dd7cddfSDavid du Colombier 	bits_left = ss->bits_left
1977dd7cddfSDavid du Colombier 
1987dd7cddfSDavid du Colombier /* Store the state back in the stream. */
1997dd7cddfSDavid du Colombier /* Put back any complete bytes into the input buffer. */
2007dd7cddfSDavid du Colombier /* Free variables: pr, ss, p, bits, bits_left. */
2017dd7cddfSDavid du Colombier #define hcd_store_state()\
2027dd7cddfSDavid du Colombier 	pr->ptr = p -= (bits_left >> 3),\
2037dd7cddfSDavid du Colombier 	ss->bits = bits >>= (bits_left & ~7),\
2047dd7cddfSDavid du Colombier 	ss->bits_left = bits_left &= 7
2057dd7cddfSDavid du Colombier 
2067dd7cddfSDavid du Colombier /* Macros to get blocks of bits from the input stream. */
2077dd7cddfSDavid du Colombier /* Invariants: 0 <= bits_left <= bits_size; */
2087dd7cddfSDavid du Colombier /* bits [bits_left-1..0] contain valid data. */
2097dd7cddfSDavid du Colombier 
2107dd7cddfSDavid du Colombier #define hcd_bits_available(n)\
2117dd7cddfSDavid du Colombier   (bits_left >= (n) || rlimit - p > ((n) - bits_left - 1) >> 3)
2127dd7cddfSDavid du Colombier /* For hcd_ensure_bits, n must not be greater than 8. */
2137dd7cddfSDavid du Colombier #define HCD_ENSURE_BITS_ELSE(n)\
2147dd7cddfSDavid du Colombier   if (bits_left >= n)\
2157dd7cddfSDavid du Colombier     DO_NOTHING;\
2167dd7cddfSDavid du Colombier   else HCD_MORE_BITS_ELSE
2177dd7cddfSDavid du Colombier #define hcd_ensure_bits(n, outl)\
2187dd7cddfSDavid du Colombier   BEGIN HCD_ENSURE_BITS_ELSE(n) goto outl; END
2197dd7cddfSDavid du Colombier 
2207dd7cddfSDavid du Colombier /* Load more bits into the buffer. */
2217dd7cddfSDavid du Colombier #define HCD_MORE_BITS_1_ELSE\
2227dd7cddfSDavid du Colombier   if (p < rlimit) {\
2237dd7cddfSDavid du Colombier     int c = *++p;\
2247dd7cddfSDavid du Colombier \
2257dd7cddfSDavid du Colombier     if (ss->FirstBitLowOrder)\
2267dd7cddfSDavid du Colombier       c = byte_reverse_bits[c];\
2277dd7cddfSDavid du Colombier     bits = (bits << 8) + c, bits_left += 8;\
2287dd7cddfSDavid du Colombier   } else
2297dd7cddfSDavid du Colombier #if hc_bits_size == 16
2307dd7cddfSDavid du Colombier #  define HCD_MORE_BITS_ELSE HCD_MORE_BITS_1_ELSE
2317dd7cddfSDavid du Colombier #else /* hc_bits_size >= 32 */
2327dd7cddfSDavid du Colombier #  define HCD_MORE_BITS_ELSE\
2337dd7cddfSDavid du Colombier   if (rlimit - p >= 3) {\
2347dd7cddfSDavid du Colombier     if (ss->FirstBitLowOrder)\
2357dd7cddfSDavid du Colombier       bits = (bits << 24) + ((uint)byte_reverse_bits[p[1]] << 16) + ((uint)byte_reverse_bits[p[2]] << 8) + byte_reverse_bits[p[3]];\
2367dd7cddfSDavid du Colombier     else\
2377dd7cddfSDavid du Colombier       bits = (bits << 24) + ((uint)p[1] << 16) + ((uint)p[2] << 8) + p[3];\
2387dd7cddfSDavid du Colombier     bits_left += 24, p += 3;\
2397dd7cddfSDavid du Colombier   } else HCD_MORE_BITS_1_ELSE
2407dd7cddfSDavid du Colombier #endif
2417dd7cddfSDavid du Colombier #define hcd_more_bits(outl)\
2427dd7cddfSDavid du Colombier   BEGIN HCD_MORE_BITS_ELSE goto outl; END
2437dd7cddfSDavid du Colombier 
2447dd7cddfSDavid du Colombier #define hcd_peek_bits(n) ((bits >> (bits_left - (n))) & ((1 << (n)) - 1))
2457dd7cddfSDavid du Colombier 
2467dd7cddfSDavid du Colombier /* hcd_peek_var_bits requires bits_left <= 8. */
2477dd7cddfSDavid du Colombier #define hcd_peek_var_bits(n)\
2487dd7cddfSDavid du Colombier   ((bits >> (bits_left - (n))) & byte_right_mask[n])
2497dd7cddfSDavid du Colombier 
2507dd7cddfSDavid du Colombier /* hcd_peek_bits_left requires bits_left <= 8. */
2517dd7cddfSDavid du Colombier #define hcd_peek_bits_left()\
2527dd7cddfSDavid du Colombier   (bits & byte_right_mask[bits_left])
2537dd7cddfSDavid du Colombier 
2547dd7cddfSDavid du Colombier #define hcd_skip_bits(n) (bits_left -= (n))
2557dd7cddfSDavid du Colombier 
2567dd7cddfSDavid du Colombier #endif /* shc_INCLUDED */
257