summaryrefslogtreecommitdiff
path: root/graphics/sam2p/pts_fax.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/sam2p/pts_fax.c
Initial commit
Diffstat (limited to 'graphics/sam2p/pts_fax.c')
-rw-r--r--graphics/sam2p/pts_fax.c3222
1 files changed, 3222 insertions, 0 deletions
diff --git a/graphics/sam2p/pts_fax.c b/graphics/sam2p/pts_fax.c
new file mode 100644
index 0000000000..46f48e23fb
--- /dev/null
+++ b/graphics/sam2p/pts_fax.c
@@ -0,0 +1,3222 @@
+/*
+ * pts_fax.c -- a compact CCITTFax compressor and uncompressor) implementation
+ * compiled by pts@fazekas.hu at Sun Jul 7 19:51:42 CEST 2002
+ *
+ * algorithm ripped from GNU Ghostscript, implementation and (C):
+ *
+Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All
+rights reserved.
+
+GNU Ghostscript is free software; you can redistribute it and/or
+modify it under the terms of version 2 of the GNU General Public
+License as published by the Free Software Foundation.
+
+GNU Ghostscript is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program so you can know your rights and responsibilities.
+It should be in a file named doc/COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA
+02111-1307, USA.
+ */
+
+#include "pts_fax.h"
+#if 0 /* doesn't work in C++ */
+# define intern static
+# define impl static
+# define intern_const static const
+# define impl_const static const
+#else
+# define intern static
+# define impl static
+# define intern_const extern const
+# define impl_const const
+#endif
+/* #define cxxintern extern */
+
+#ifdef __GNUC__
+#ifndef __clang__
+#pragma implementation
+#endif
+#endif
+
+/* misc_types.h by pts@fazekas.hu at Sat Jul 6 19:20:17 CEST 2002 */
+#ifndef MISC_TYPES_H
+#define MISC_TYPES_H 1
+
+/* #include "config2.h" */
+
+#define BEGIN do {
+#define END } while (0)
+#ifndef DO_NOTHING
+# define DO_NOTHING BEGIN END
+#endif
+
+# define if_debug0(c,s) DO_NOTHING
+# define if_debug1(c,s,a1) DO_NOTHING
+# define if_debug2(c,s,a1,a2) DO_NOTHING
+# define if_debug3(c,s,a1,a2,a3) DO_NOTHING
+# define if_debug4(c,s,a1,a2,a3,a4) DO_NOTHING
+# define if_debug5(c,s,a1,a2,a3,a4,a5) DO_NOTHING
+# define if_debug6(c,s,a1,a2,a3,a4,a5,a6) DO_NOTHING
+# define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7) DO_NOTHING
+# define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8) DO_NOTHING
+# define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9) DO_NOTHING
+# define if_debug10(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) DO_NOTHING
+# define if_debug11(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) DO_NOTHING
+# define if_debug12(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) DO_NOTHING
+
+/* to the one that all the compilers seem to have.... */
+#ifndef min
+# define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+# define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+/* Define a standard way to round values to a (constant) modulus. */
+#define ROUND_DOWN(value, modulus)\
+ ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
+ (value) - (value) % (modulus) :\
+ (value) & -(modulus) )
+#define ROUND_UP(value, modulus)\
+ ( (modulus) & ((modulus) - 1) ? /* not a power of 2 */\
+ ((value) + ((modulus) - 1)) / (modulus) * (modulus) :\
+ ((value) + ((modulus) - 1)) & -(modulus) )
+
+#define countof(a) (sizeof(a) / sizeof((a)[0]))
+
+#define gs_alloc_bytes(a, n, c) ss->xalloc_(n)
+#define gs_free_object(a, ptr, c) ss->free_(ptr)
+
+#endif /* gstypes.h */
+/* end of former misc_types.h */
+
+/* gsbittab.h */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Interface to tables for bit operations */
+
+#ifndef gsbittab_INCLUDED
+# define gsbittab_INCLUDED
+
+/*
+ * Generate tables for transforming 2, 4, 6, or 8 bits.
+ */
+#define btab2_(v0,v2,v1)\
+ v0,v1+v0,v2+v0,v2+v1+v0
+#define bit_table_2(v0,v2,v1) btab2_(v0,v2,v1)
+#define btab4_(v0,v8,v4,v2,v1)\
+ btab2_(v0,v2,v1), btab2_(v4+v0,v2,v1),\
+ btab2_(v8+v0,v2,v1), btab2_(v8+v4+v0,v2,v1)
+#define bit_table_4(v0,v8,v4,v2,v1) btab4_(v0,v8,v4,v2,v1)
+#define btab6_(v0,v20,v10,v8,v4,v2,v1)\
+ btab4_(v0,v8,v4,v2,v1), btab4_(v10+v0,v8,v4,v2,v1),\
+ btab4_(v20+v0,v8,v4,v2,v1), btab4_(v20+v10+v0,v8,v4,v2,v1)
+#define bit_table_6(v0,v20,v10,v8,v4,v2,v1) btab6_(v0,v20,v10,v8,v4,v2,v1)
+#define bit_table_8(v0,v80,v40,v20,v10,v8,v4,v2,v1)\
+ btab6_(v0,v20,v10,v8,v4,v2,v1), btab6_(v40+v0,v20,v10,v8,v4,v2,v1),\
+ btab6_(v80+v0,v20,v10,v8,v4,v2,v1), btab6_(v80+v40+v0,v20,v10,v8,v4,v2,v1)
+
+/*
+ * byte_reverse_bits[B] = the unsigned char B with the order of bits reversed.
+ */
+intern_const unsigned char byte_reverse_bits[256];
+
+/*
+ * byte_right_mask[N] = a unsigned char with N trailing 1s, 0 <= N <= 8.
+ */
+intern_const unsigned char byte_right_mask[9];
+
+/*
+ * byte_count_bits[B] = the number of 1-bits in a unsigned char with value B.
+ */
+intern_const unsigned char byte_count_bits[256];
+
+/*
+ * byte_bit_run_length_N[B], for 0 <= N <= 7, gives the length of the
+ * run of 1-bits starting at bit N in a unsigned char with value B,
+ * numbering the bits in the unsigned char as 01234567. If the run includes
+ * the low-order bit (i.e., might be continued into a following unsigned char),
+ * the run length is increased by 8.
+ */
+intern_const unsigned char
+ byte_bit_run_length_0[256], byte_bit_run_length_1[256],
+ byte_bit_run_length_2[256], byte_bit_run_length_3[256],
+ byte_bit_run_length_4[256], byte_bit_run_length_5[256],
+ byte_bit_run_length_6[256], byte_bit_run_length_7[256];
+
+/*
+ * byte_bit_run_length[N] points to byte_bit_run_length_N.
+ * byte_bit_run_length_neg[N] = byte_bit_run_length[-N & 7].
+ */
+intern_const unsigned char *const byte_bit_run_length[8];
+intern_const unsigned char *const byte_bit_run_length_neg[8];
+
+/*
+ * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters
+ * denote the individual bits of the unsigned char.
+ */
+intern_const unsigned char byte_acegbdfh_to_abcdefgh[256];
+
+#endif /* gsbittab_INCLUDED */
+
+/* end of former gsbittab.h */
+
+/* shc.h */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Common definitions for filters using Huffman coding */
+
+#ifndef shc_INCLUDED
+# define shc_INCLUDED
+
+/* #include "gsbittab.h" */
+
+#define hc_bits_size (SIZEOF_INT * 8)
+#define s_hce_init_inline(ss)\
+ ((ss)->bits = 0, (ss)->bits_left = hc_bits_size)
+#define s_hcd_init_inline(ss)\
+ ((ss)->bits = 0, (ss)->bits_left = 0)
+
+/*
+ * These definitions are valid for code lengths up to 16 bits
+ * and non-negative decoded values up to 15 bits.
+ *
+ * We define 3 different representations of the code: encoding tables,
+ * decoding tables, and a definition table which can be generated easily
+ * from frequency information and which in turn can easily generate
+ * the encoding and decoding tables.
+ *
+ * The definition table has two parts: a list of the number of i-bit
+ * codes for each i >= 1, and the decoded values corresponding to
+ * the code values in increasing lexicographic order (which will also
+ * normally be decreasing code frequency). Calling these two lists
+ * L[1..M] and V[0..N-1] respectively, we have the following invariants:
+ * - 1 <= M <= max_hc_length, N >= 2.
+ * - L[0] = 0.
+ * - for i=1..M, L[i] >= 0.
+ * - sum(i=1..M: L[i]) = N.
+ * - sum(i=1..M: L[i] * 2^-i) = 1.
+ * - V[0..N-1] are a permutation of the integers 0..N-1.
+ */
+#define max_hc_length 16
+typedef struct hc_definition_s {
+ unsigned short *counts; /* [0..M] */
+ unsigned int num_counts; /* M */
+ unsigned short *values; /* [0..N-1] */
+ unsigned int num_values; /* N */
+} hc_definition;
+
+/**** pts ****/
+struct stream_hc_state_s;
+/* definition moved to pts_fax.h */
+
+/* ------ Encoding tables ------ */
+
+/* Define the structure for the encoding tables. */
+typedef struct hce_code_s {
+ unsigned short code;
+ unsigned short code_length;
+} hce_code;
+
+#define hce_entry(c, len) { c, len }
+
+typedef struct hce_table_s {
+ unsigned int count;
+ hce_code *codes;
+} hce_table;
+
+#define hce_bits_available(n)\
+ (ss->bits_left >= (n) || wlimit - q > ((n) - ss->bits_left - 1) >> 3)
+
+/* ------ Encoding utilities ------ */
+
+/*
+ * Put a code on the output. The client is responsible for ensuring
+ * that q does not exceed pw->limit.
+ */
+
+#ifdef DEBUG
+# define hc_print_value(code, clen)\
+ (gs_debug_c('W') ?\
+ (dlprintf2("[W]0x%x,%d\n", code, clen), 0) : 0)
+# define hc_print_value_then(code, clen) hc_print_value(code, clen),
+#else
+# define hc_print_value(code, clen) 0
+# define hc_print_value_then(code, clen) /* */
+#endif
+#define hc_print_code(rp) hc_print_value((rp)->code, (rp)->code_length)
+
+/* Declare variables that hold the encoder state. */
+#define hce_declare_state\
+ register unsigned int bits;\
+ register int bits_left
+
+/* Load the state from the stream. */
+/* Free variables: ss, bits, bits_left. */
+#define hce_load_state()\
+ bits = ss->bits, bits_left = ss->bits_left
+
+/* Store the state back in the stream. */
+/* Free variables: ss, bits, bits_left. */
+#define hce_store_state()\
+ ss->bits = bits, ss->bits_left = bits_left
+
+/* Put a code on the stream. */
+intern void hc_put_code_proc _((bool, unsigned char *, unsigned int));
+
+#define hc_put_value(ss, q, code, clen)\
+ (hc_print_value_then(code, clen)\
+ ((bits_left -= (clen)) >= 0 ?\
+ (bits += (code) << bits_left) :\
+ (hc_put_code_proc((ss)->FirstBitLowOrder,\
+ q += hc_bits_size >> 3,\
+ (bits + ((code) >> -bits_left))),\
+ bits = (code) << (bits_left += hc_bits_size))))
+#define hc_put_code(ss, q, cp)\
+ hc_put_value(ss, q, (cp)->code, (cp)->code_length)
+
+/*
+ * Force out the final bits to the output.
+ * Note that this does a store_state, but not a load_state.
+ */
+intern unsigned char *hc_put_last_bits_proc _((struct stream_hc_state_s *, unsigned char *, unsigned int, int));
+
+#define hc_put_last_bits(ss, q)\
+ hc_put_last_bits_proc(ss, q, bits, bits_left)
+
+/* ------ Decoding tables ------ */
+
+/*
+ * Define the structure for the decoding tables.
+ * First-level nodes are either leaves, which have
+ * value = decoded value
+ * code_length <= initial_bits
+ * or non-leaves, which have
+ * value = the index of a sub-table
+ * code_length = initial_bits + the number of additional dispatch bits
+ * Second-level nodes are always leaves, with
+ * code_length = the actual number of bits in the code - initial_bits.
+ */
+
+typedef struct hcd_code_s {
+ short value;
+ unsigned short code_length;
+} hcd_code;
+
+typedef struct hcd_table_s {
+ unsigned int count;
+ unsigned int initial_bits;
+ hcd_code *codes;
+} hcd_table;
+
+/* Declare variables that hold the decoder state. */
+#define hcd_declare_state\
+ register const unsigned char *p;\
+ const unsigned char *rlimit;\
+ unsigned int bits;\
+ int bits_left
+
+/* Load the state from the stream. */
+/* Free variables: pr, ss, p, rlimit, bits, bits_left. */
+#define hcd_load_state()\
+ p = pr->ptr,\
+ rlimit = pr->limit,\
+ bits = ss->bits,\
+ bits_left = ss->bits_left
+
+/* Store the state back in the stream. */
+/* Put back any complete bytes into the input buffer. */
+/* Free variables: pr, ss, p, bits, bits_left. */
+#define hcd_store_state()\
+ pr->ptr = p -= (bits_left >> 3),\
+ ss->bits = bits >>= (bits_left & ~7),\
+ ss->bits_left = bits_left &= 7
+
+/* Macros to get blocks of bits from the input stream. */
+/* Invariants: 0 <= bits_left <= bits_size; */
+/* bits [bits_left-1..0] contain valid data. */
+
+#define hcd_bits_available(n)\
+ (bits_left >= (n) || rlimit - p > ((n) - bits_left - 1) >> 3)
+/* For hcd_ensure_bits, n must not be greater than 8. */
+#define HCD_ENSURE_BITS_ELSE(n)\
+ if (bits_left >= n)\
+ DO_NOTHING;\
+ else HCD_MORE_BITS_ELSE
+#define hcd_ensure_bits(n, outl)\
+ BEGIN HCD_ENSURE_BITS_ELSE(n) goto outl; END
+
+/* Load more bits into the buffer. */
+#define HCD_MORE_BITS_1_ELSE\
+ if (p < rlimit) {\
+ int c = *++p;\
+\
+ if (ss->FirstBitLowOrder)\
+ c = byte_reverse_bits[c];\
+ bits = (bits << 8) + c, bits_left += 8;\
+ } else
+#if hc_bits_size == 16
+# define HCD_MORE_BITS_ELSE HCD_MORE_BITS_1_ELSE
+#else /* hc_bits_size >= 32 */
+# define HCD_MORE_BITS_ELSE\
+ if (rlimit - p >= 3) {\
+ if (ss->FirstBitLowOrder)\
+ bits = (bits << 24) + ((unsigned int)byte_reverse_bits[p[1]] << 16) + ((unsigned int)byte_reverse_bits[p[2]] << 8) + byte_reverse_bits[p[3]];\
+ else\
+ bits = (bits << 24) + ((unsigned int)p[1] << 16) + ((unsigned int)p[2] << 8) + p[3];\
+ bits_left += 24, p += 3;\
+ } else HCD_MORE_BITS_1_ELSE
+#endif
+#define hcd_more_bits(outl)\
+ BEGIN HCD_MORE_BITS_ELSE goto outl; END
+
+#define hcd_peek_bits(n) ((bits >> (bits_left - (n))) & ((1 << (n)) - 1))
+
+/* hcd_peek_var_bits requires bits_left <= 8. */
+#define hcd_peek_var_bits(n)\
+ ((bits >> (bits_left - (n))) & byte_right_mask[n])
+
+/* hcd_peek_bits_left requires bits_left <= 8. */
+#define hcd_peek_bits_left()\
+ (bits & byte_right_mask[bits_left])
+
+#define hcd_skip_bits(n) (bits_left -= (n))
+
+#endif /* shc_INCLUDED */
+
+/* end of former shc.h */
+
+/* scf.h */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Common definitions for CCITTFax encoding and decoding filters */
+
+#ifndef scf_INCLUDED
+# define scf_INCLUDED
+
+/* #include "shc.h" */
+
+/*
+ * The CCITT Group 3 (T.4) and Group 4 (T.6) fax specifications map
+ * run lengths to Huffman codes. White and black have different mappings.
+ * If the run length is 64 or greater, two or more codes are needed:
+ * - One or more 'make-up' codes for 2560 pixels;
+ * - A 'make-up' code that encodes the multiple of 64;
+ * - A 'termination' code for the remainder.
+ * For runs of 63 or less, only the 'termination' code is needed.
+ */
+
+/* ------ Encoding tables ------ */
+
+/*
+ * The maximum possible length of a scan line is determined by the
+ * requirement that 3 runs have to fit into the stream buffer.
+ * A run of length N requires approximately ceil(N / 2560) makeup codes,
+ * hence 1.5 * ceil(N / 2560) bytes. Taking the largest safe stream
+ * buffer size as 32K, we arrive at the following maximum width:
+ */
+#if SIZEOF_INT > 2
+# define cfe_max_width (2560 * 32000 * 2 / 3)
+#else
+# define cfe_max_width (max_int - 40) /* avoid overflows */
+#endif
+/* The +5 in cfe_max_code_bytes is a little conservative. */
+#define cfe_max_code_bytes(width) ((width) / 2560 * 3 / 2 + 5)
+
+typedef hce_code cfe_run;
+
+/* Codes common to 1-D and 2-D encoding. */
+/* The decoding algorithms know that EOL is 0....01. */
+#define run_eol_code_length 12
+#define run_eol_code_value 1
+intern_const cfe_run cf_run_eol;
+typedef struct cf_runs_s {
+ cfe_run termination[64];
+ cfe_run make_up[41];
+} cf_runs;
+intern_const cf_runs
+ cf_white_runs, cf_black_runs;
+intern_const cfe_run cf_uncompressed[6];
+intern_const cfe_run cf_uncompressed_exit[10]; /* indexed by 2 x length of */
+
+ /* white run + (1 if next run black, 0 if white) */
+/* 1-D encoding. */
+intern_const cfe_run cf1_run_uncompressed;
+
+/* 2-D encoding. */
+intern_const cfe_run cf2_run_pass;
+
+#define cf2_run_pass_length 4
+#define cf2_run_pass_value 0x1
+#define cf2_run_vertical_offset 3
+intern_const cfe_run cf2_run_vertical[7]; /* indexed by b1 - a1 + offset */
+intern_const cfe_run cf2_run_horizontal;
+
+#define cf2_run_horizontal_value 1
+#define cf2_run_horizontal_length 3
+intern_const cfe_run cf2_run_uncompressed;
+
+/* 2-D Group 3 encoding. */
+intern_const cfe_run cf2_run_eol_1d;
+intern_const cfe_run cf2_run_eol_2d;
+
+/* ------ Decoding tables ------ */
+
+typedef hcd_code cfd_node;
+
+#define run_length value
+
+/*
+ * The value in the decoding tables is either a white or black run length,
+ * or a (negative) exceptional value.
+ */
+#define run_error (-1)
+#define run_zeros (-2) /* EOL follows, possibly with more padding first */
+#define run_uncompressed (-3)
+/* 2-D codes */
+#define run2_pass (-4)
+#define run2_horizontal (-5)
+
+#define cfd_white_initial_bits 8
+#define cfd_white_min_bits 4 /* shortest white run */
+/* intern_const cfd_node cf_white_decode[]; */
+
+#define cfd_black_initial_bits 7
+#define cfd_black_min_bits 2 /* shortest black run */
+/* intern_const cfd_node cf_black_decode[]; */
+
+#define cfd_2d_initial_bits 7
+#define cfd_2d_min_bits 4 /* shortest non-H/V 2-D run */
+/* intern_const cfd_node cf_2d_decode[]; */
+
+#define cfd_uncompressed_initial_bits 6 /* must be 6 */
+/* intern_const cfd_node cf_uncompressed_decode[]; */
+
+/* ------ Run detection macros ------ */
+
+/*
+ * For the run detection macros:
+ * white_byte is 0 or 0xff for BlackIs1 or !BlackIs1 respectively;
+ * data holds p[-1], inverted if !BlackIs1;
+ * count is the number of valid bits remaining in the scan line.
+ */
+
+/* Aliases for bit processing tables. */
+#define cf_byte_run_length byte_bit_run_length_neg
+#define cf_byte_run_length_0 byte_bit_run_length_0
+
+/* Skip over white pixels to find the next black pixel in the input. */
+/* Store the run length in rlen, and update data, p, and count. */
+/* There are many more white pixels in typical input than black pixels, */
+/* and the runs of white pixels tend to be much longer, so we use */
+/* substantially different loops for the two cases. */
+
+#define skip_white_pixels(data, p, count, white_byte, rlen)\
+BEGIN\
+ rlen = cf_byte_run_length[count & 7][data ^ 0xff];\
+ if ( rlen >= 8 ) { /* run extends past unsigned char boundary */\
+ if ( white_byte == 0 ) {\
+ if ( p[0] ) { data = p[0]; p += 1; rlen -= 8; }\
+ else if ( p[1] ) { data = p[1]; p += 2; }\
+ else {\
+ while ( !(p[2] | p[3] | p[4] | p[5]) )\
+ p += 4, rlen += 32;\
+ if ( p[2] ) {\
+ data = p[2]; p += 3; rlen += 8;\
+ } else if ( p[3] ) {\
+ data = p[3]; p += 4; rlen += 16;\
+ } else if ( p[4] ) {\
+ data = p[4]; p += 5; rlen += 24;\
+ } else /* p[5] */ {\
+ data = p[5]; p += 6; rlen += 32;\
+ }\
+ }\
+ } else {\
+ if ( p[0] != 0xff ) { data = (unsigned char)~p[0]; p += 1; rlen -= 8; }\
+ else if ( p[1] != 0xff ) { data = (unsigned char)~p[1]; p += 2; }\
+ else {\
+ while ( (p[2] & p[3] & p[4] & p[5]) == 0xff )\
+ p += 4, rlen += 32;\
+ if ( p[2] != 0xff ) {\
+ data = (unsigned char)~p[2]; p += 3; rlen += 8;\
+ } else if ( p[3] != 0xff ) {\
+ data = (unsigned char)~p[3]; p += 4; rlen += 16;\
+ } else if ( p[4] != 0xff ) {\
+ data = (unsigned char)~p[4]; p += 5; rlen += 24;\
+ } else /* p[5] != 0xff */ {\
+ data = (unsigned char)~p[5]; p += 6; rlen += 32;\
+ }\
+ }\
+ }\
+ rlen += cf_byte_run_length_0[data ^ 0xff];\
+ }\
+ count -= rlen;\
+END
+
+/* Skip over black pixels to find the next white pixel in the input. */
+/* Store the run length in rlen, and update data, p, and count. */
+
+#define skip_black_pixels(data, p, count, white_byte, rlen)\
+BEGIN\
+ rlen = cf_byte_run_length[count & 7][data];\
+ if ( rlen >= 8 ) {\
+ if ( white_byte == 0 )\
+ for ( ; ; p += 4, rlen += 32 ) {\
+ if ( p[0] != 0xff ) { data = p[0]; p += 1; rlen -= 8; break; }\
+ if ( p[1] != 0xff ) { data = p[1]; p += 2; break; }\
+ if ( p[2] != 0xff ) { data = p[2]; p += 3; rlen += 8; break; }\
+ if ( p[3] != 0xff ) { data = p[3]; p += 4; rlen += 16; break; }\
+ }\
+ else\
+ for ( ; ; p += 4, rlen += 32 ) {\
+ if ( p[0] ) { data = (unsigned char)~p[0]; p += 1; rlen -= 8; break; }\
+ if ( p[1] ) { data = (unsigned char)~p[1]; p += 2; break; }\
+ if ( p[2] ) { data = (unsigned char)~p[2]; p += 3; rlen += 8; break; }\
+ if ( p[3] ) { data = (unsigned char)~p[3]; p += 4; rlen += 16; break; }\
+ }\
+ rlen += cf_byte_run_length_0[data];\
+ }\
+ count -= rlen;\
+END
+
+#endif /* scf_INCLUDED */
+
+/* end of former scf.h */
+
+#if USE_BUILTIN_FAXE
+#if OBJDEP
+# warning PROVIDES: pts_faxe
+#endif
+/* scfe.c */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* CCITTFax encoding filter */
+/* #include "config2.h" */
+/* #include "scf.h" */
+/* #include "scfx.h" */
+
+/* ------ Macros and support routines ------ */
+
+/* Statistics */
+
+#ifdef DEBUG
+
+typedef struct stats_runs_s {
+ unsigned long termination[64];
+ unsigned long make_up[41];
+} stats_runs_t;
+static stats_runs_t stats_white_runs, stats_black_runs;
+
+#define COUNT_RUN(tab, i) (tab)[i]++;
+
+static void
+print_run_stats(const stats_runs_t * stats)
+{
+ int i;
+ unsigned long total;
+
+ for (i = 0, total = 0; i < 41; i++)
+ dprintf1(" %lu", stats->make_up[i]),
+ total += stats->make_up[i];
+ dprintf1(" total=%lu\n\t", total);
+ for (i = 0, total = 0; i < 64; i++)
+ dprintf1(" %lu", stats->termination[i]),
+ total += stats->termination[i];
+ dprintf1(" total=%lu\n", total);
+}
+
+#else /* !DEBUG */
+
+#define COUNT_RUN(cnt, i) DO_NOTHING
+
+#endif /* DEBUG */
+
+/* Put a run onto the output stream. */
+/* Free variables: q, bits, bits_left. */
+
+#define CF_PUT_RUN(ss, lenv, rt, stats)\
+BEGIN\
+ cfe_run rr;\
+\
+ if ( lenv >= 64 ) {\
+ hce_store_state();\
+ q = cf_put_long_run(ss, q, lenv, &rt);\
+ hce_load_state();\
+ lenv &= 63;\
+ }\
+ rr = rt.termination[lenv];\
+ COUNT_RUN(stats.termination, lenv);\
+ hc_put_value(ss, q, rr.code, rr.code_length);\
+END
+
+static unsigned char *
+cf_put_long_run(stream_CFE_state * ss, unsigned char * q, int lenv, const cf_runs * prt)
+{
+ hce_declare_state;
+ cfe_run rr;
+
+#ifdef DEBUG
+ stats_runs_t *pstats =
+ (prt == &cf_white_runs ? &stats_white_runs : &stats_black_runs);
+
+#endif
+
+ hce_load_state();
+ while (lenv >= 2560 + 64) {
+ rr = prt->make_up[40];
+ COUNT_RUN(pstats->make_up, 40);
+ hc_put_value(ss, q, rr.code, rr.code_length);
+ lenv -= 2560;
+ }
+ rr = prt->make_up[lenv >> 6];
+ COUNT_RUN(pstats->make_up, lenv >> 6);
+ hc_put_value(ss, q, rr.code, rr.code_length);
+ hce_store_state();
+ return q;
+}
+
+#define CF_PUT_WHITE_RUN(ss, lenv)\
+ CF_PUT_RUN(ss, lenv, cf_white_runs, stats_white_runs)
+
+#define CF_PUT_BLACK_RUN(ss, lenv)\
+ CF_PUT_RUN(ss, lenv, cf_black_runs, stats_black_runs)
+
+/* ------ CCITTFaxEncode ------ */
+
+/* private_st_CFE_state(); */
+
+static void s_CFE_release _((stream_state *));
+
+/* Set default parameter values. */
+static void
+s_CFE_set_defaults(register stream_state * st)
+{
+ stream_CFE_state *const ss = (stream_CFE_state *) st;
+
+ s_CFE_set_defaults_inline(ss);
+}
+
+/* Initialize CCITTFaxEncode filter */
+static int
+s_CFE_init(register stream_state * st)
+{
+ stream_CFE_state *const ss = (stream_CFE_state *) st;
+ int columns = ss->Columns;
+
+ /*
+ * The worst case for encoding is alternating white and black pixels.
+ * For 1-D encoding, the worst case is 9 bits per 2 pixels; for 2-D
+ * (horizontal), 12 bits per 2 pixels. To fill out a scan line,
+ * we may add up to 6 12-bit EOL codes.
+ */
+ /**** pts: added UL ****/
+ int code_bytes =
+ ((columns * (ss->K == 0 ? 9UL : 12UL)) >> 4) + 20; /* add slop */
+ int raster = ss->raster =
+ ROUND_UP((columns + 7) >> 3, ss->DecodedByteAlign);
+
+ s_hce_init_inline(ss);
+ ss->lbuf = ss->lprev = ss->lcode = 0; /* in case we have to release */
+ if (columns > cfe_max_width)
+ return PTSFAX_ERRC;
+/****** WRONG ******/
+ /* Because skip_white_pixels can look as many as 4 bytes ahead, */
+ /* we need to allow 4 extra bytes at the end of the row buffers. */
+ ss->lbuf = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFE lbuf");
+ ss->lcode = (unsigned char*)gs_alloc_bytes(st->memory, code_bytes, "CFE lcode");
+ if (ss->lbuf == 0 || ss->lcode == 0) {
+ s_CFE_release(st);
+ return PTSFAX_ERRC;
+/****** WRONG ******/
+ }
+ if (ss->K != 0) {
+ ss->lprev = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFE lprev");
+ if (ss->lprev == 0) {
+ s_CFE_release(st);
+ return PTSFAX_ERRC;
+/****** WRONG ******/
+ }
+ /* Clear the initial reference line for 2-D encoding. */
+ /* Make sure it is terminated properly. */
+ ss->memset_(ss->lprev, (ss->BlackIs1 ? 0 : 0xff), raster);
+ if (columns & 7)
+ ss->lprev[raster - 1] ^= 0x80 >> (columns & 7);
+ else
+ ss->lprev[raster] = ~ss->lprev[0];
+ }
+ ss->read_count = raster;
+ ss->write_count = 0;
+ ss->k_left = (ss->K > 0 ? 1 : ss->K);
+ ss->max_code_bytes = code_bytes;
+ return 0;
+}
+
+/* Release the filter. */
+static void
+s_CFE_release(stream_state * st)
+{
+ stream_CFE_state *const ss = (stream_CFE_state *) st;
+
+ gs_free_object(st->memory, ss->lprev, "CFE lprev(close)");
+ gs_free_object(st->memory, ss->lcode, "CFE lcode(close)");
+ gs_free_object(st->memory, ss->lbuf, "CFE lbuf(close)");
+}
+
+/* Flush the buffer */
+static void cf_encode_1d _((stream_CFE_state *, const unsigned char *,
+ stream_cursor_write *));
+static void cf_encode_2d _((stream_CFE_state *, const unsigned char *,
+ stream_cursor_write *, const unsigned char *));
+static int
+s_CFE_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ stream_CFE_state *const ss = (stream_CFE_state *) st;
+ const unsigned char *rlimit = pr->limit;
+ unsigned char *wlimit = pw->limit;
+ int raster = ss->raster;
+ unsigned char end_mask = 1 << (-ss->Columns & 7);
+ int status = 0;
+
+ for (;;) {
+ stream_cursor_write w;
+
+ if_debug2('w', "[w]CFE: read_count = %d, write_count=%d,\n",
+ ss->read_count, ss->write_count);
+ if_debug6('w', " pr = 0x%lx(%d)0x%lx, pw = 0x%lx(%d)0x%lx\n",
+ (unsigned long) pr->ptr, (int)(rlimit - pr->ptr), (unsigned long) rlimit,
+ (unsigned long) pw->ptr, (int)(wlimit - pw->ptr), (unsigned long) wlimit);
+ if (ss->write_count) {
+ /* Copy more of an encoded line to the caller. */
+ int wcount = wlimit - pw->ptr;
+ int ccount = min(wcount, ss->write_count);
+
+ ss->memcpy_(pw->ptr + 1, ss->lcode + ss->code_bytes - ss->write_count,
+ ccount);
+ pw->ptr += ccount;
+ if ((ss->write_count -= ccount) > 0) {
+ status = 1;
+ break;
+ }
+ }
+ if (ss->read_count) {
+ /* Copy more of an unencoded line from the caller. */
+ int rcount = rlimit - pr->ptr;
+ int ccount = min(rcount, ss->read_count);
+
+ if (rcount == 0 && last)
+ break;
+ ss->memcpy_(ss->lbuf + raster - ss->read_count,
+ pr->ptr + 1, ccount);
+ pr->ptr += ccount;
+ if ((ss->read_count -= ccount) != 0)
+ break;
+ }
+ /*
+ * We have a full scan line in lbuf. Ensure that it ends with
+ * two polarity changes.
+ */
+ {
+ unsigned char *end = ss->lbuf + raster - 1;
+ unsigned char end_bit = *end & end_mask;
+ unsigned char not_bit = end_bit ^ end_mask;
+
+ *end &= -end_mask;
+ if (end_mask == 1)
+ end[1] = (end_bit ? 0x40 : 0x80);
+ else if (end_mask == 2)
+ *end |= not_bit >> 1, end[1] = end_bit << 7;
+ else
+ *end |= (not_bit >> 1) | (end_bit >> 2);
+ }
+ /*
+ * Write the output directly to the caller's buffer if it's large
+ * enough, otherwise to our own buffer.
+ */
+ if (wlimit - pw->ptr >= ss->max_code_bytes) {
+ w = *pw;
+ } else {
+ w.ptr = ss->lcode - 1;
+ w.limit = w.ptr + ss->max_code_bytes;
+ }
+#ifdef DEBUG
+ if (ss->K > 0) {
+ if_debug1('w', "[w]new row, k_left=%d\n",
+ ss->k_left);
+ } else {
+ if_debug0('w', "[w]new row\n");
+ }
+#endif
+ /*
+ * Write an EOL (actually a "beginning of line") if requested.
+ */
+ if (ss->EndOfLine) {
+ const cfe_run *rp =
+ (ss->K <= 0 ? &cf_run_eol :
+ ss->k_left > 1 ? &cf2_run_eol_2d :
+ &cf2_run_eol_1d);
+ cfe_run run;
+
+ hce_declare_state;
+
+ hce_load_state();
+ if (ss->EncodedByteAlign) {
+ run = *rp;
+ /* Pad the run on the left */
+ /* so it winds up unsigned char-aligned. */
+ run.code_length +=
+ (bits_left - run_eol_code_length) & 7;
+ if (run.code_length > 16) /* <= 23 */
+ bits_left -= run.code_length & 7,
+ run.code_length = 16;
+ rp = &run;
+ }
+ hc_put_code(ss, w.ptr, rp);
+ hce_store_state();
+ } else if (ss->EncodedByteAlign)
+ ss->bits_left &= ~7;
+ /* Encode the line. */
+ if (ss->K == 0)
+ cf_encode_1d(ss, ss->lbuf, &w); /* pure 1-D */
+ else if (ss->K < 0)
+ cf_encode_2d(ss, ss->lbuf, &w, ss->lprev); /* pure 2-D */
+ else if (--(ss->k_left)) /* mixed, use 2-D */
+ cf_encode_2d(ss, ss->lbuf, &w, ss->lprev);
+ else { /* mixed, use 1-D */
+ cf_encode_1d(ss, ss->lbuf, &w);
+ ss->k_left = ss->K;
+ }
+ /*
+ * If we didn't write directly to the client's buffer, schedule
+ * the output data to be written.
+ */
+ if (w.limit == wlimit)
+ pw->ptr = w.ptr;
+ else
+ ss->write_count = ss->code_bytes = w.ptr - (ss->lcode - 1);
+ if (ss->K != 0) {
+ /* In 2-D modes, swap the current and previous scan lines. */
+ unsigned char *temp = ss->lbuf;
+
+ ss->lbuf = ss->lprev;
+ ss->lprev = temp;
+ }
+ /* Note that the input buffer needs refilling. */
+ ss->read_count = raster;
+ }
+ /*
+ * When we exit from the loop, we know that write_count = 0, and
+ * there is no line waiting to be processed in the input buffer.
+ */
+ if (last && status == 0) {
+ const cfe_run *rp =
+ (ss->K > 0 ? &cf2_run_eol_1d : &cf_run_eol);
+ int i = (!ss->EndOfBlock ? 0 : ss->K < 0 ? 2 : 6);
+ unsigned int bits_to_write =
+ hc_bits_size - ss->bits_left + i * rp->code_length;
+ unsigned char *q = pw->ptr;
+
+ hce_declare_state;
+
+ if (0U+(wlimit - q) < (bits_to_write + 7) >> 3) { /* PTS_UNSIGNED */
+ status = 1;
+ goto out;
+ }
+ hce_load_state();
+ if (ss->EncodedByteAlign)
+ bits_left &= ~7;
+ while (--i >= 0)
+ hc_put_code(ss, q, rp);
+ /* Force out the last unsigned char or bytes. */
+ pw->ptr = hc_put_last_bits((stream_hc_state *) ss, q);
+ }
+ out:
+ if_debug9('w', "[w]CFE exit %d: read_count = %d, write_count = %d,\n pr = 0x%lx(%d)0x%lx; pw = 0x%lx(%d)0x%lx\n",
+ status, ss->read_count, ss->write_count,
+ (unsigned long) pr->ptr, (int)(rlimit - pr->ptr), (unsigned long) rlimit,
+ (unsigned long) pw->ptr, (int)(wlimit - pw->ptr), (unsigned long) wlimit);
+#ifdef DEBUG
+ if (pr->ptr > rlimit || pw->ptr > wlimit) {
+ lprintf("Pointer overrun!\n");
+ status = PTSFAX_ERRC;
+ }
+ if (gs_debug_c('w') && status == 1) {
+ dlputs("[w]white runs:");
+ print_run_stats(&stats_white_runs);
+ dlputs("[w]black runs:");
+ print_run_stats(&stats_black_runs);
+ }
+#endif
+ return status;
+}
+
+/* Encode a 1-D scan line. */
+static void
+cf_encode_1d(stream_CFE_state * ss, const unsigned char * lbuf, stream_cursor_write * pw)
+{
+ unsigned int count = ss->raster << 3;
+ unsigned char *q = pw->ptr;
+ int end_count = -ss->Columns & 7;
+ int rlen;
+
+ hce_declare_state;
+ const unsigned char *p = lbuf;
+ unsigned char invert = (ss->BlackIs1 ? 0 : 0xff);
+
+ /* Invariant: data = p[-1] ^ invert. */
+ unsigned int data = *p++ ^ invert;
+
+ hce_load_state();
+ while (count != 0U+end_count) { /* PTS_UNSIGNED */
+ /* Parse a white run. */
+ skip_white_pixels(data, p, count, invert, rlen);
+ CF_PUT_WHITE_RUN(ss, rlen);
+ if (count == 0U+end_count) /* PTS_UNSIGNED */
+ break;
+ /* Parse a black run. */
+ skip_black_pixels(data, p, count, invert, rlen);
+ CF_PUT_BLACK_RUN(ss, rlen);
+ }
+ hce_store_state();
+ pw->ptr = q;
+}
+
+/* Encode a 2-D scan line. */
+static void
+cf_encode_2d(stream_CFE_state * ss, const unsigned char * lbuf, stream_cursor_write * pw,
+ const unsigned char * lprev)
+{
+ unsigned char invert_white = (ss->BlackIs1 ? 0 : 0xff);
+ unsigned char invert = invert_white;
+ unsigned int count = ss->raster << 3;
+ int end_count = -ss->Columns & 7;
+ const unsigned char *p = lbuf;
+ unsigned char *q = pw->ptr;
+ unsigned int data = *p++ ^ invert;
+
+ hce_declare_state;
+ /*
+ * In order to handle the nominal 'changing white' at the beginning of
+ * each scan line, we need to suppress the test for an initial black bit
+ * in the reference line when we are at the very beginning of the scan
+ * line. To avoid an extra test, we use two different mask tables.
+ */
+ static const unsigned char initial_count_bit[8] =
+ {
+ 0, 1, 2, 4, 8, 0x10, 0x20, 0x40
+ };
+ static const unsigned char further_count_bit[8] =
+ {
+ 0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40
+ };
+ const unsigned char *count_bit = initial_count_bit;
+
+ hce_load_state();
+ while (count != 0U+end_count) { /* PTS_UNSIGNED */
+ /*
+ * If invert == invert_white, white and black have their
+ * correct meanings; if invert == ~invert_white,
+ * black and white are interchanged.
+ */
+ unsigned int a0 = count;
+ unsigned int a1;
+
+#define b1 (a1 - diff) /* only for printing */
+ int diff;
+ unsigned int prev_count = count;
+ const unsigned char *prev_p = p - lbuf + lprev;
+ unsigned char prev_data = prev_p[-1] ^ invert;
+ int rlen;
+
+ /* Find the a1 and b1 transitions. */
+ skip_white_pixels(data, p, count, invert, rlen);
+ a1 = count;
+ if ((prev_data & count_bit[prev_count & 7])) {
+ /* Look for changing white first. */
+ skip_black_pixels(prev_data, prev_p, prev_count, invert, rlen);
+ }
+ count_bit = further_count_bit; /* no longer at beginning */
+ pass:
+ if (prev_count != 0U+end_count) /* PTS_UNSIGNED */
+ skip_white_pixels(prev_data, prev_p, prev_count, invert, rlen);
+ diff = a1 - prev_count; /* i.e., logical b1 - a1 */
+ /* In all the comparisons below, remember that count */
+ /* runs downward, not upward, so the comparisons are */
+ /* reversed. */
+ if (diff <= -2) {
+ /* Could be a pass mode. Find b2. */
+ if (prev_count != 0U+ end_count) /* PTS_UNSIGNED */
+ skip_black_pixels(prev_data, prev_p,
+ prev_count, invert, rlen);
+ if (prev_count > a1) {
+ /* Use pass mode. */
+ if_debug4('W', "[W]pass: count = %d, a1 = %d, b1 = %d, new count = %d\n",
+ a0, a1, b1, prev_count);
+ hc_put_value(ss, q, cf2_run_pass_value, cf2_run_pass_length);
+ a0 = prev_count;
+ goto pass;
+ }
+ }
+ /* Check for vertical coding. */
+ if (diff <= 3 && diff >= -3) {
+ /* Use vertical coding. */
+ const cfe_run *cp = &cf2_run_vertical[diff + 3];
+
+ if_debug5('W', "[W]vertical %d: count = %d, a1 = %d, b1 = %d, new count = %d\n",
+ diff, a0, a1, b1, count);
+ hc_put_code(ss, q, cp);
+ invert = ~invert; /* a1 polarity changes */
+ data ^= 0xff;
+ continue;
+ }
+ /* No luck, use horizontal coding. */
+ if (count != 0U+end_count) /* PTS_UNSIGNED */
+ skip_black_pixels(data, p, count, invert, rlen); /* find a2 */
+ hc_put_value(ss, q, cf2_run_horizontal_value,
+ cf2_run_horizontal_length);
+ a0 -= a1;
+ a1 -= count;
+ if (invert == invert_white) {
+ if_debug3('W', "[W]horizontal: white = %d, black = %d, new count = %d\n",
+ a0, a1, count);
+ CF_PUT_WHITE_RUN(ss, a0);
+ CF_PUT_BLACK_RUN(ss, a1);
+ } else {
+ if_debug3('W', "[W]horizontal: black = %d, white = %d, new count = %d\n",
+ a0, a1, count);
+ CF_PUT_BLACK_RUN(ss, a0);
+ CF_PUT_WHITE_RUN(ss, a1);
+#undef b1
+ }
+ }
+ hce_store_state();
+ pw->ptr = q;
+}
+
+/* Stream template */
+const stream_template s_CFE_template = {
+ /*0, &st_CFE_state*/ s_CFE_init, s_CFE_process, 1, 1,
+ s_CFE_release, s_CFE_set_defaults, 0
+};
+/* end of former scfe.c */
+
+/* scfetab.c */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Tables for CCITTFaxEncode filter */
+/* #include "scommon.h" */ /* for scf.h */
+/* #include "scf.h" */
+
+/* We make this a separate file so that it can be used by */
+/* the program that generates the tables for the CCITTFaxDecode filter. */
+
+/* ------ Run encoding tables ------ */
+
+/* Abbreviate hce_entry to make the file smaller. */
+#define RUN(c,len) hce_entry(c,len)
+
+/* Define the end-of-line code. */
+/* Code in scfd.c and scfdgen.c knows that the run value is 1. */
+impl_const cfe_run cf_run_eol =
+RUN(run_eol_code_value, run_eol_code_length);
+
+/* Define the 1-D code that signals uncompressed data. */
+impl_const cfe_run cf1_run_uncompressed =
+RUN(0xf, 12);
+
+/* Define the 2-D run codes. */
+impl_const cfe_run cf2_run_pass =
+RUN(cf2_run_pass_value, cf2_run_pass_length);
+impl_const cfe_run cf2_run_vertical[7] =
+{
+ RUN(0x3, 7),
+ RUN(0x3, 6),
+ RUN(0x3, 3),
+ RUN(0x1, 1),
+ RUN(0x2, 3),
+ RUN(0x2, 6),
+ RUN(0x2, 7)
+};
+impl_const cfe_run cf2_run_horizontal =
+RUN(cf2_run_horizontal_value, cf2_run_horizontal_length);
+impl_const cfe_run cf2_run_uncompressed =
+RUN(0xf, 10);
+
+/* EOL codes for Group 3 2-D. */
+/* Code in scfd.c knows that these are 0...01x. */
+impl_const cfe_run cf2_run_eol_1d =
+RUN((run_eol_code_value << 1) + 1, run_eol_code_length + 1);
+impl_const cfe_run cf2_run_eol_2d =
+RUN((run_eol_code_value << 1) + 0, run_eol_code_length + 1);
+
+/* White run codes. */
+impl_const cf_runs cf_white_runs =
+{
+ { /* Termination codes */
+ RUN(0x35, 8), RUN(0x7, 6), RUN(0x7, 4), RUN(0x8, 4),
+ RUN(0xb, 4), RUN(0xc, 4), RUN(0xe, 4), RUN(0xf, 4),
+ RUN(0x13, 5), RUN(0x14, 5), RUN(0x7, 5), RUN(0x8, 5),
+ RUN(0x8, 6), RUN(0x3, 6), RUN(0x34, 6), RUN(0x35, 6),
+ RUN(0x2a, 6), RUN(0x2b, 6), RUN(0x27, 7), RUN(0xc, 7),
+ RUN(0x8, 7), RUN(0x17, 7), RUN(0x3, 7), RUN(0x4, 7),
+ RUN(0x28, 7), RUN(0x2b, 7), RUN(0x13, 7), RUN(0x24, 7),
+ RUN(0x18, 7), RUN(0x2, 8), RUN(0x3, 8), RUN(0x1a, 8),
+ RUN(0x1b, 8), RUN(0x12, 8), RUN(0x13, 8), RUN(0x14, 8),
+ RUN(0x15, 8), RUN(0x16, 8), RUN(0x17, 8), RUN(0x28, 8),
+ RUN(0x29, 8), RUN(0x2a, 8), RUN(0x2b, 8), RUN(0x2c, 8),
+ RUN(0x2d, 8), RUN(0x4, 8), RUN(0x5, 8), RUN(0xa, 8),
+ RUN(0xb, 8), RUN(0x52, 8), RUN(0x53, 8), RUN(0x54, 8),
+ RUN(0x55, 8), RUN(0x24, 8), RUN(0x25, 8), RUN(0x58, 8),
+ RUN(0x59, 8), RUN(0x5a, 8), RUN(0x5b, 8), RUN(0x4a, 8),
+ RUN(0x4b, 8), RUN(0x32, 8), RUN(0x33, 8), RUN(0x34, 8)
+ },
+ { /* Make-up codes */
+ RUN(0, 0) /* dummy */ , RUN(0x1b, 5), RUN(0x12, 5), RUN(0x17, 6),
+ RUN(0x37, 7), RUN(0x36, 8), RUN(0x37, 8), RUN(0x64, 8),
+ RUN(0x65, 8), RUN(0x68, 8), RUN(0x67, 8), RUN(0xcc, 9),
+ RUN(0xcd, 9), RUN(0xd2, 9), RUN(0xd3, 9), RUN(0xd4, 9),
+ RUN(0xd5, 9), RUN(0xd6, 9), RUN(0xd7, 9), RUN(0xd8, 9),
+ RUN(0xd9, 9), RUN(0xda, 9), RUN(0xdb, 9), RUN(0x98, 9),
+ RUN(0x99, 9), RUN(0x9a, 9), RUN(0x18, 6), RUN(0x9b, 9),
+ RUN(0x8, 11), RUN(0xc, 11), RUN(0xd, 11), RUN(0x12, 12),
+ RUN(0x13, 12), RUN(0x14, 12), RUN(0x15, 12), RUN(0x16, 12),
+ RUN(0x17, 12), RUN(0x1c, 12), RUN(0x1d, 12), RUN(0x1e, 12),
+ RUN(0x1f, 12)
+ }
+};
+
+/* Black run codes. */
+impl_const cf_runs cf_black_runs =
+{
+ { /* Termination codes */
+ RUN(0x37, 10), RUN(0x2, 3), RUN(0x3, 2), RUN(0x2, 2),
+ RUN(0x3, 3), RUN(0x3, 4), RUN(0x2, 4), RUN(0x3, 5),
+ RUN(0x5, 6), RUN(0x4, 6), RUN(0x4, 7), RUN(0x5, 7),
+ RUN(0x7, 7), RUN(0x4, 8), RUN(0x7, 8), RUN(0x18, 9),
+ RUN(0x17, 10), RUN(0x18, 10), RUN(0x8, 10), RUN(0x67, 11),
+ RUN(0x68, 11), RUN(0x6c, 11), RUN(0x37, 11), RUN(0x28, 11),
+ RUN(0x17, 11), RUN(0x18, 11), RUN(0xca, 12), RUN(0xcb, 12),
+ RUN(0xcc, 12), RUN(0xcd, 12), RUN(0x68, 12), RUN(0x69, 12),
+ RUN(0x6a, 12), RUN(0x6b, 12), RUN(0xd2, 12), RUN(0xd3, 12),
+ RUN(0xd4, 12), RUN(0xd5, 12), RUN(0xd6, 12), RUN(0xd7, 12),
+ RUN(0x6c, 12), RUN(0x6d, 12), RUN(0xda, 12), RUN(0xdb, 12),
+ RUN(0x54, 12), RUN(0x55, 12), RUN(0x56, 12), RUN(0x57, 12),
+ RUN(0x64, 12), RUN(0x65, 12), RUN(0x52, 12), RUN(0x53, 12),
+ RUN(0x24, 12), RUN(0x37, 12), RUN(0x38, 12), RUN(0x27, 12),
+ RUN(0x28, 12), RUN(0x58, 12), RUN(0x59, 12), RUN(0x2b, 12),
+ RUN(0x2c, 12), RUN(0x5a, 12), RUN(0x66, 12), RUN(0x67, 12)
+ },
+ { /* Make-up codes. */
+ RUN(0, 0) /* dummy */ , RUN(0xf, 10), RUN(0xc8, 12), RUN(0xc9, 12),
+ RUN(0x5b, 12), RUN(0x33, 12), RUN(0x34, 12), RUN(0x35, 12),
+ RUN(0x6c, 13), RUN(0x6d, 13), RUN(0x4a, 13), RUN(0x4b, 13),
+ RUN(0x4c, 13), RUN(0x4d, 13), RUN(0x72, 13), RUN(0x73, 13),
+ RUN(0x74, 13), RUN(0x75, 13), RUN(0x76, 13), RUN(0x77, 13),
+ RUN(0x52, 13), RUN(0x53, 13), RUN(0x54, 13), RUN(0x55, 13),
+ RUN(0x5a, 13), RUN(0x5b, 13), RUN(0x64, 13), RUN(0x65, 13),
+ RUN(0x8, 11), RUN(0xc, 11), RUN(0xd, 11), RUN(0x12, 12),
+ RUN(0x13, 12), RUN(0x14, 12), RUN(0x15, 12), RUN(0x16, 12),
+ RUN(0x17, 12), RUN(0x1c, 12), RUN(0x1d, 12), RUN(0x1e, 12),
+ RUN(0x1f, 12)
+ }
+};
+
+/* Uncompressed codes. */
+impl_const cfe_run cf_uncompressed[6] =
+{
+ RUN(1, 1),
+ RUN(1, 2),
+ RUN(1, 3),
+ RUN(1, 4),
+ RUN(1, 5),
+ RUN(1, 6)
+};
+
+/* Uncompressed exit codes. */
+impl_const cfe_run cf_uncompressed_exit[10] =
+{
+ RUN(2, 8), RUN(3, 8),
+ RUN(2, 9), RUN(3, 9),
+ RUN(2, 10), RUN(3, 10),
+ RUN(2, 11), RUN(3, 11),
+ RUN(2, 12), RUN(3, 12)
+};
+
+#if 0
+/* Some C compilers insist on having executable code in every file.... */
+void scfetab_dummy _((void)); /* for picky compilers */
+void
+scfetab_dummy(void)
+{
+}
+#endif
+
+/* end of former scfetab.c */
+
+#endif /* USE_BUILTIN_FAXE */
+
+#if USE_BUILTIN_FAXD
+#if OBJDEP
+# warning PROVIDES: pts_faxd
+#endif
+/* scfdtab.c; must be before scfd.c */
+/* #include "scommon.h" */ /* for scf.h */
+/* #include "scf.h" */
+
+/* White decoding table. */
+impl_const cfd_node cf_white_decode[] = {
+ { 256, 12 },
+ { 272, 12 },
+ { 29, 8 },
+ { 30, 8 },
+ { 45, 8 },
+ { 46, 8 },
+ { 22, 7 },
+ { 22, 7 },
+ { 23, 7 },
+ { 23, 7 },
+ { 47, 8 },
+ { 48, 8 },
+ { 13, 6 },
+ { 13, 6 },
+ { 13, 6 },
+ { 13, 6 },
+ { 20, 7 },
+ { 20, 7 },
+ { 33, 8 },
+ { 34, 8 },
+ { 35, 8 },
+ { 36, 8 },
+ { 37, 8 },
+ { 38, 8 },
+ { 19, 7 },
+ { 19, 7 },
+ { 31, 8 },
+ { 32, 8 },
+ { 1, 6 },
+ { 1, 6 },
+ { 1, 6 },
+ { 1, 6 },
+ { 12, 6 },
+ { 12, 6 },
+ { 12, 6 },
+ { 12, 6 },
+ { 53, 8 },
+ { 54, 8 },
+ { 26, 7 },
+ { 26, 7 },
+ { 39, 8 },
+ { 40, 8 },
+ { 41, 8 },
+ { 42, 8 },
+ { 43, 8 },
+ { 44, 8 },
+ { 21, 7 },
+ { 21, 7 },
+ { 28, 7 },
+ { 28, 7 },
+ { 61, 8 },
+ { 62, 8 },
+ { 63, 8 },
+ { 0, 8 },
+ { 320, 8 },
+ { 384, 8 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 10, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 11, 5 },
+ { 27, 7 },
+ { 27, 7 },
+ { 59, 8 },
+ { 60, 8 },
+ { 288, 9 },
+ { 290, 9 },
+ { 18, 7 },
+ { 18, 7 },
+ { 24, 7 },
+ { 24, 7 },
+ { 49, 8 },
+ { 50, 8 },
+ { 51, 8 },
+ { 52, 8 },
+ { 25, 7 },
+ { 25, 7 },
+ { 55, 8 },
+ { 56, 8 },
+ { 57, 8 },
+ { 58, 8 },
+ { 192, 6 },
+ { 192, 6 },
+ { 192, 6 },
+ { 192, 6 },
+ { 1664, 6 },
+ { 1664, 6 },
+ { 1664, 6 },
+ { 1664, 6 },
+ { 448, 8 },
+ { 512, 8 },
+ { 292, 9 },
+ { 640, 8 },
+ { 576, 8 },
+ { 294, 9 },
+ { 296, 9 },
+ { 298, 9 },
+ { 300, 9 },
+ { 302, 9 },
+ { 256, 7 },
+ { 256, 7 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 2, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 128, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 8, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 9, 5 },
+ { 16, 6 },
+ { 16, 6 },
+ { 16, 6 },
+ { 16, 6 },
+ { 17, 6 },
+ { 17, 6 },
+ { 17, 6 },
+ { 17, 6 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 14, 6 },
+ { 14, 6 },
+ { 14, 6 },
+ { 14, 6 },
+ { 15, 6 },
+ { 15, 6 },
+ { 15, 6 },
+ { 15, 6 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 64, 5 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { 7, 4 },
+ { -2, 3 },
+ { -2, 3 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -3, 4 },
+ { 1792, 3 },
+ { 1792, 3 },
+ { 1984, 4 },
+ { 2048, 4 },
+ { 2112, 4 },
+ { 2176, 4 },
+ { 2240, 4 },
+ { 2304, 4 },
+ { 1856, 3 },
+ { 1856, 3 },
+ { 1920, 3 },
+ { 1920, 3 },
+ { 2368, 4 },
+ { 2432, 4 },
+ { 2496, 4 },
+ { 2560, 4 },
+ { 1472, 1 },
+ { 1536, 1 },
+ { 1600, 1 },
+ { 1728, 1 },
+ { 704, 1 },
+ { 768, 1 },
+ { 832, 1 },
+ { 896, 1 },
+ { 960, 1 },
+ { 1024, 1 },
+ { 1088, 1 },
+ { 1152, 1 },
+ { 1216, 1 },
+ { 1280, 1 },
+ { 1344, 1 },
+ { 1408, 1 }
+};
+
+/* Black decoding table. */
+impl_const cfd_node cf_black_decode[] = {
+ { 128, 12 },
+ { 160, 13 },
+ { 224, 12 },
+ { 256, 12 },
+ { 10, 7 },
+ { 11, 7 },
+ { 288, 12 },
+ { 12, 7 },
+ { 9, 6 },
+ { 9, 6 },
+ { 8, 6 },
+ { 8, 6 },
+ { 7, 5 },
+ { 7, 5 },
+ { 7, 5 },
+ { 7, 5 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 6, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 1, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 3, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { 2, 2 },
+ { -2, 4 },
+ { -2, 4 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -3, 5 },
+ { 1792, 4 },
+ { 1792, 4 },
+ { 1984, 5 },
+ { 2048, 5 },
+ { 2112, 5 },
+ { 2176, 5 },
+ { 2240, 5 },
+ { 2304, 5 },
+ { 1856, 4 },
+ { 1856, 4 },
+ { 1920, 4 },
+ { 1920, 4 },
+ { 2368, 5 },
+ { 2432, 5 },
+ { 2496, 5 },
+ { 2560, 5 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 18, 3 },
+ { 52, 5 },
+ { 52, 5 },
+ { 640, 6 },
+ { 704, 6 },
+ { 768, 6 },
+ { 832, 6 },
+ { 55, 5 },
+ { 55, 5 },
+ { 56, 5 },
+ { 56, 5 },
+ { 1280, 6 },
+ { 1344, 6 },
+ { 1408, 6 },
+ { 1472, 6 },
+ { 59, 5 },
+ { 59, 5 },
+ { 60, 5 },
+ { 60, 5 },
+ { 1536, 6 },
+ { 1600, 6 },
+ { 24, 4 },
+ { 24, 4 },
+ { 24, 4 },
+ { 24, 4 },
+ { 25, 4 },
+ { 25, 4 },
+ { 25, 4 },
+ { 25, 4 },
+ { 1664, 6 },
+ { 1728, 6 },
+ { 320, 5 },
+ { 320, 5 },
+ { 384, 5 },
+ { 384, 5 },
+ { 448, 5 },
+ { 448, 5 },
+ { 512, 6 },
+ { 576, 6 },
+ { 53, 5 },
+ { 53, 5 },
+ { 54, 5 },
+ { 54, 5 },
+ { 896, 6 },
+ { 960, 6 },
+ { 1024, 6 },
+ { 1088, 6 },
+ { 1152, 6 },
+ { 1216, 6 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 64, 3 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 13, 1 },
+ { 23, 4 },
+ { 23, 4 },
+ { 50, 5 },
+ { 51, 5 },
+ { 44, 5 },
+ { 45, 5 },
+ { 46, 5 },
+ { 47, 5 },
+ { 57, 5 },
+ { 58, 5 },
+ { 61, 5 },
+ { 256, 5 },
+ { 16, 3 },
+ { 16, 3 },
+ { 16, 3 },
+ { 16, 3 },
+ { 17, 3 },
+ { 17, 3 },
+ { 17, 3 },
+ { 17, 3 },
+ { 48, 5 },
+ { 49, 5 },
+ { 62, 5 },
+ { 63, 5 },
+ { 30, 5 },
+ { 31, 5 },
+ { 32, 5 },
+ { 33, 5 },
+ { 40, 5 },
+ { 41, 5 },
+ { 22, 4 },
+ { 22, 4 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 14, 1 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 15, 2 },
+ { 128, 5 },
+ { 192, 5 },
+ { 26, 5 },
+ { 27, 5 },
+ { 28, 5 },
+ { 29, 5 },
+ { 19, 4 },
+ { 19, 4 },
+ { 20, 4 },
+ { 20, 4 },
+ { 34, 5 },
+ { 35, 5 },
+ { 36, 5 },
+ { 37, 5 },
+ { 38, 5 },
+ { 39, 5 },
+ { 21, 4 },
+ { 21, 4 },
+ { 42, 5 },
+ { 43, 5 },
+ { 0, 3 },
+ { 0, 3 },
+ { 0, 3 },
+ { 0, 3 }
+};
+
+/* 2-D decoding table. */
+impl_const cfd_node cf_2d_decode[] = {
+ { 128, 11 },
+ { 144, 10 },
+ { 6, 7 },
+ { 0, 7 },
+ { 5, 6 },
+ { 5, 6 },
+ { 1, 6 },
+ { 1, 6 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -4, 4 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { -5, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 4, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { 3, 1 },
+ { -2, 4 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -3, 3 }
+};
+
+/* Uncompresssed decoding table. */
+impl_const cfd_node cf_uncompressed_decode[] = {
+ { 64, 12 },
+ { 5, 6 },
+ { 4, 5 },
+ { 4, 5 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 3, 4 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { 0, 1 },
+ { -1, 0 },
+ { -1, 0 },
+ { 8, 6 },
+ { 9, 6 },
+ { 6, 5 },
+ { 6, 5 },
+ { 7, 5 },
+ { 7, 5 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 4, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 5, 4 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 2, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 3, 3 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 0, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 },
+ { 1, 2 }
+};
+
+#if 0
+/* Dummy executable code to pacify compilers. */
+void scfdtab_dummy _((void));
+void
+scfdtab_dummy()
+{
+}
+#endif
+/* end of former scfdtab.c */
+/* scfd.c */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* CCITTFax decoding filter */
+/* #include "gstypes.h" */
+/* #include "scf.h" */
+/* #include "scfx.h" */
+
+/* Utility procedures */
+int stream_move _((stream_cursor_read *, stream_cursor_write *)); /* in stream.c */
+
+/* ------ CCITTFaxDecode ------ */
+
+/* private_st_CFD_state(); */
+
+/* Set default parameter values. */
+static void
+s_CFD_set_defaults(register stream_state * st)
+{
+ stream_CFD_state *const ss = (stream_CFD_state *) st;
+
+ s_CFD_set_defaults_inline(ss);
+}
+
+/* Initialize CCITTFaxDecode filter */
+static int
+s_CFD_init(stream_state * st)
+{
+ stream_CFD_state *const ss = (stream_CFD_state *) st;
+ int raster = ss->raster =
+ ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign);
+ unsigned char white = (ss->BlackIs1 ? 0 : 0xff);
+
+ s_hcd_init_inline(ss);
+ /* Because skip_white_pixels can look as many as 4 bytes ahead, */
+ /* we need to allow 4 extra bytes at the end of the row buffers. */
+ ss->lbuf = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFD lbuf");
+ ss->lprev = 0;
+ if (ss->lbuf == 0)
+ return PTSFAX_ERRC;
+/****** WRONG ******/
+ if (ss->K != 0) {
+ ss->lprev = (unsigned char*)gs_alloc_bytes(st->memory, raster + 4, "CFD lprev");
+ if (ss->lprev == 0)
+ return PTSFAX_ERRC;
+/****** WRONG ******/
+ /* Clear the initial reference line for 2-D encoding. */
+ ss->memset_(ss->lbuf, white, raster);
+ /* Ensure that the scan of the reference line will stop. */
+ ss->lbuf[raster] = 0xa0;
+ }
+ ss->k_left = min(ss->K, 0);
+ ss->run_color = 0;
+ ss->damaged_rows = 0;
+ ss->skipping_damage = false;
+ ss->cbit = 0;
+ ss->uncomp_run = 0;
+ ss->rows_left = (ss->Rows <= 0 || ss->EndOfBlock ? -1 : ss->Rows + 1);
+ ss->rpos = ss->wpos = raster - 1;
+ ss->eol_count = 0;
+ ss->invert = white;
+ ss->min_left = 1;
+ return 0;
+}
+
+/* Release the filter. */
+static void
+s_CFD_release(stream_state * st)
+{
+ stream_CFD_state *const ss = (stream_CFD_state *) st;
+
+ gs_free_object(st->memory, ss->lprev, "CFD lprev(close)");
+ gs_free_object(st->memory, ss->lbuf, "CFD lbuf(close)");
+}
+
+/* Declare the variables that hold the state. */
+#define cfd_declare_state\
+ hcd_declare_state;\
+ register unsigned char *q;\
+ int qbit
+/* Load the state from the stream. */
+#define cfd_load_state()\
+ hcd_load_state(),\
+ q = ss->lbuf + ss->wpos, qbit = ss->cbit
+/* Store the state back in the stream. */
+#define cfd_store_state()\
+ hcd_store_state(),\
+ ss->wpos = q - ss->lbuf, ss->cbit = qbit
+
+/* Macros to get blocks of bits from the input stream. */
+/* Invariants: 0 <= bits_left <= bits_size; */
+/* bits [bits_left-1..0] contain valid data. */
+
+#define avail_bits(n) hcd_bits_available(n)
+#define ensure_bits(n, outl) hcd_ensure_bits(n, outl)
+#define peek_bits(n) hcd_peek_bits(n)
+#define peek_var_bits(n) hcd_peek_var_bits(n)
+#define skip_bits(n) hcd_skip_bits(n)
+
+/* Get a run from the stream. */
+#ifdef DEBUG
+# define IF_DEBUG(expr) expr
+#else
+# define IF_DEBUG(expr) DO_NOTHING
+#endif
+#define get_run(decode, initial_bits, min_bits, runlen, str, locl, outl)\
+ BEGIN\
+ const cfd_node *np;\
+ int clen;\
+\
+ HCD_ENSURE_BITS_ELSE(initial_bits) {\
+ /* We might still have enough bits for the specific code. */\
+ if (bits_left < min_bits) goto outl;\
+ np = &decode[hcd_peek_bits_left() << (initial_bits - bits_left)];\
+ if ((clen = np->code_length) > bits_left) goto outl;\
+ goto locl;\
+ }\
+ np = &decode[peek_bits(initial_bits)];\
+ if ((clen = np->code_length) > initial_bits) {\
+ IF_DEBUG(unsigned int init_bits = peek_bits(initial_bits));\
+ if (!avail_bits(clen)) goto outl;\
+ clen -= initial_bits;\
+ skip_bits(initial_bits);\
+ ensure_bits(clen, outl); /* can't goto outl */\
+ np = &decode[np->run_length + peek_var_bits(clen)];\
+ if_debug4('W', "%s xcode=0x%x,%d rlen=%d\n", str,\
+ (init_bits << np->code_length) +\
+ peek_var_bits(np->code_length),\
+ initial_bits + np->code_length,\
+ np->run_length);\
+ skip_bits(np->code_length);\
+ } else {\
+ locl: if_debug4('W', "%s code=0x%x,%d rlen=%d\n", str,\
+ peek_var_bits(clen), clen, np->run_length);\
+ skip_bits(clen);\
+ }\
+ runlen = np->run_length;\
+ END
+
+/* Skip data bits for a white run. */
+/* rlen is either less than 64, or a multiple of 64. */
+#define skip_data(rlen, makeup_label)\
+ if ( (qbit -= rlen) < 0 )\
+ { q -= qbit >> 3, qbit &= 7;\
+ if ( rlen >= 64 ) goto makeup_label;\
+ }
+
+/* Invert data bits for a black run. */
+/* If rlen >= 64, execute makeup_action: this is to handle */
+/* makeup codes efficiently, since these are always a multiple of 64. */
+#define invert_data(rlen, black_byte, makeup_action, d)\
+ if ( rlen > qbit )\
+ { *q++ ^= (1 << qbit) - 1;\
+ rlen -= qbit;\
+ switch ( rlen >> 3 )\
+ {\
+ case 7: /* original rlen possibly >= 64 */\
+ if ( rlen + qbit >= 64 ) goto d;\
+ *q++ = black_byte;\
+ case 6: *q++ = black_byte;\
+ case 5: *q++ = black_byte;\
+ case 4: *q++ = black_byte;\
+ case 3: *q++ = black_byte;\
+ case 2: *q++ = black_byte;\
+ case 1: *q = black_byte;\
+ rlen &= 7;\
+ if ( !rlen ) { qbit = 0; break; }\
+ q++;\
+ case 0: /* know rlen != 0 */\
+ qbit = 8 - rlen;\
+ *q ^= 0xff << qbit;\
+ break;\
+ default: /* original rlen >= 64 */\
+d: ss->memset_(q, black_byte, rlen >> 3);\
+ q += rlen >> 3;\
+ rlen &= 7;\
+ if ( !rlen ) qbit = 0, q--;\
+ else qbit = 8 - rlen, *q ^= 0xff << qbit;\
+ makeup_action;\
+ }\
+ }\
+ else\
+ qbit -= rlen,\
+ *q ^= ((1 << rlen) - 1) << qbit
+
+/* Buffer refill for CCITTFaxDecode filter */
+static int cf_decode_eol _((stream_CFD_state *, stream_cursor_read *));
+static int cf_decode_1d _((stream_CFD_state *, stream_cursor_read *));
+static int cf_decode_2d _((stream_CFD_state *, stream_cursor_read *));
+static int cf_decode_uncompressed _((stream_CFD_state *, stream_cursor_read *));
+static int
+s_CFD_process(stream_state * st, stream_cursor_read * pr,
+ stream_cursor_write * pw, bool last)
+{
+ stream_CFD_state *const ss = (stream_CFD_state *) st;
+ int wstop = ss->raster - 1;
+ int eol_count = ss->eol_count;
+ int k_left = ss->k_left;
+ int rows_left = ss->rows_left;
+ int status = 0;
+
+ (void)last; /**** pts ****/
+
+#ifdef DEBUG
+ const unsigned char *rstart = pr->ptr;
+ const unsigned char *wstart = pw->ptr;
+
+#endif
+
+ top:
+#ifdef DEBUG
+ {
+ hcd_declare_state;
+ hcd_load_state();
+ if_debug8('w', "\
+[w]CFD_process top: eol_count=%d, k_left=%d, rows_left=%d\n\
+ bits=0x%lx, bits_left=%d, read %u, wrote %u%s\n",
+ eol_count, k_left, rows_left,
+ (unsigned long) bits, bits_left,
+ (unsigned int) (p - rstart), (unsigned int) (pw->ptr - wstart),
+ (ss->skipping_damage ? ", skipping damage" : ""));
+ }
+#endif
+ if (ss->skipping_damage) { /* Skip until we reach an EOL. */
+ hcd_declare_state;
+ int skip;
+
+ status = 0;
+ do {
+ switch ((skip = cf_decode_eol(ss, pr))) {
+ default: /* not EOL */
+ hcd_load_state();
+ skip_bits(-skip);
+ hcd_store_state();
+ continue;
+ case 0: /* need more input */
+ goto out;
+ case 1: /* EOL */
+ { /* Back up over the EOL. */
+ hcd_load_state();
+ bits_left += run_eol_code_length;
+ hcd_store_state();
+ }
+ ss->skipping_damage = false;
+ }
+ }
+ while (ss->skipping_damage);
+ ss->damaged_rows++;
+ }
+ /*
+ * Check for a completed input scan line. This isn't quite as
+ * simple as it seems, because we could have run out of input data
+ * between a makeup code and a 0-length termination code, or in a
+ * 2-D line before a final horizontal code with a 0-length second
+ * run. There's probably a way to think about this situation that
+ * doesn't require a special check, but I haven't found it yet.
+ */
+ if (ss->wpos == wstop && ss->cbit <= (-ss->Columns & 7) &&
+ (k_left == 0 ? !(ss->run_color & ~1) : ss->run_color == 0)
+ ) { /* Check for completed data to be copied to the client. */
+ /* (We could avoid the extra copy step for 1-D, but */
+ /* it's simpler not to, and it doesn't cost much.) */
+ if (ss->rpos < ss->wpos) {
+ stream_cursor_read cr;
+
+ cr.ptr = ss->lbuf + ss->rpos;
+ cr.limit = ss->lbuf + ss->wpos;
+ status = stream_move(&cr, pw);
+ ss->rpos = cr.ptr - ss->lbuf;
+ if (status)
+ goto out;
+ }
+ if (rows_left > 0 && --rows_left == 0) {
+ status = EOFC;
+ goto out;
+ }
+ if (ss->K != 0) {
+ unsigned char *prev_bits = ss->lprev;
+
+ ss->lprev = ss->lbuf;
+ ss->lbuf = prev_bits;
+ if (ss->K > 0)
+ k_left = (k_left == 0 ? ss->K : k_left) - 1;
+ }
+ ss->rpos = ss->wpos = -1;
+ ss->eol_count = eol_count = 0;
+ ss->cbit = 0;
+ ss->invert = (ss->BlackIs1 ? 0 : 0xff);
+ ss->memset_(ss->lbuf, ss->invert, wstop + 1);
+ ss->run_color = 0;
+ /*
+ * If EndOfLine is true, we want to include the unsigned char padding
+ * in the string of initial zeros in the EOL. If EndOfLine
+ * is false, we aren't sure what we should do....
+ */
+ if (ss->EncodedByteAlign & !ss->EndOfLine)
+ ss->bits_left &= ~7;
+ }
+ /* If we're between scan lines, scan for EOLs. */
+ if (ss->wpos < 0) {
+ while ((status = cf_decode_eol(ss, pr)) > 0) {
+ if_debug0('w', "[w]EOL\n");
+ /* If we are in a Group 3 mixed regime, */
+ /* check the next bit for 1- vs. 2-D. */
+ if (ss->K > 0) {
+ hcd_declare_state;
+ hcd_load_state();
+ ensure_bits(1, out); /* can't fail */
+ k_left = (peek_bits(1) ? 0 : 1);
+ skip_bits(1);
+ hcd_store_state();
+ }
+ ++eol_count;
+ /*
+ * According to Adobe, the decoder should always check for
+ * the EOD sequence, regardless of EndOfBlock: the Red Book's
+ * documentation of EndOfBlock is wrong.
+ */
+ if (eol_count == (ss->K < 0 ? 2 : 6)) {
+ status = EOFC;
+ goto out;
+ }
+ }
+ if (status == 0) /* input empty while scanning EOLs */
+ goto out;
+ switch (eol_count) {
+ case 0:
+ if (ss->EndOfLine) { /* EOL is required, but none is present. */
+ status = PTSFAX_ERRC;
+ goto check;
+ }
+ case 1:
+ break;
+ default:
+ status = PTSFAX_ERRC;
+ goto check;
+ }
+ }
+ /* Now decode actual data. */
+ if (k_left < 0) {
+ if_debug0('w', "[w2]new row\n");
+ status = cf_decode_2d(ss, pr);
+ } else if (k_left == 0) {
+ if_debug0('w', "[w1]new row\n");
+ status = cf_decode_1d(ss, pr);
+ } else {
+ if_debug1('w', "[w1]new 2-D row, %d left\n", k_left);
+ status = cf_decode_2d(ss, pr);
+ }
+ if_debug3('w', "[w]CFD status = %d, wpos = %d, cbit = %d\n",
+ status, ss->wpos, ss->cbit);
+ check:switch (status) {
+ case 1: /* output full */
+ goto top;
+ case PTSFAX_ERRC:
+ /* Check for special handling of damaged rows. */
+ if (ss->damaged_rows >= ss->DamagedRowsBeforeError ||
+ !(ss->EndOfLine && ss->K >= 0)
+ )
+ break;
+ /* Substitute undamaged data if appropriate. */
+/****** NOT IMPLEMENTED YET ******/
+ {
+ ss->wpos = wstop;
+ ss->cbit = -ss->Columns & 7;
+ ss->run_color = 0;
+ }
+ ss->skipping_damage = true;
+ goto top;
+ default:
+ ss->damaged_rows = 0; /* finished a good row */
+ }
+ out:ss->k_left = k_left;
+ ss->rows_left = rows_left;
+ ss->eol_count = eol_count;
+ return status;
+}
+
+/*
+ * Decode a leading EOL, if any.
+ * If an EOL is present, skip over it and return 1;
+ * if no EOL is present, read no input and return -N, where N is the
+ * number of initial bits that can be skipped in the search for an EOL;
+ * if more input is needed, return 0.
+ * Note that if we detected an EOL, we know that we can back up over it;
+ * if we detected an N-bit non-EOL, we know that at least N bits of data
+ * are available in the buffer.
+ */
+static int
+cf_decode_eol(stream_CFD_state * ss, stream_cursor_read * pr)
+{
+ hcd_declare_state;
+ int zeros;
+ int look_ahead;
+
+ hcd_load_state();
+ for (zeros = 0; zeros < run_eol_code_length - 1; zeros++) {
+ ensure_bits(1, out);
+ if (peek_bits(1))
+ return -(zeros + 1);
+ skip_bits(1);
+ }
+ /* We definitely have an EOL. Skip further zero bits. */
+ look_ahead = (ss->K > 0 ? 2 : 1);
+ for (;;) {
+ ensure_bits(look_ahead, back);
+ if (peek_bits(1))
+ break;
+ skip_bits(1);
+ }
+ skip_bits(1);
+ hcd_store_state();
+ return 1;
+ back: /*
+ * We ran out of data while skipping zeros.
+ * We know we are at a unsigned char boundary, and have just skipped
+ * at least run_eol_code_length - 1 zeros. However,
+ * bits_left may be 1 if look_ahead == 2.
+ */
+ bits &= (1 << bits_left) - 1;
+ bits_left += run_eol_code_length - 1;
+ hcd_store_state();
+ out:return 0;
+}
+
+/* Decode a 1-D scan line. */
+static int
+cf_decode_1d(stream_CFD_state * ss, stream_cursor_read * pr)
+{
+ cfd_declare_state;
+ unsigned char black_byte = (ss->BlackIs1 ? 0xff : 0);
+ int end_bit = -ss->Columns & 7;
+ unsigned char *stop = ss->lbuf - 1 + ss->raster;
+ int run_color = ss->run_color;
+ int status;
+ int bcnt;
+
+ cfd_load_state();
+ if_debug1('w', "[w1]entry run_color = %d\n", ss->run_color);
+ if (ss->run_color > 0)
+ goto db;
+ else
+ goto dw;
+#define q_at_stop() (q >= stop && (qbit <= end_bit || q > stop))
+ top:run_color = 0;
+ if (q_at_stop())
+ goto done;
+ dw: /* Decode a white run. */
+ get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
+ bcnt, "[w1]white", dwl, out0);
+ if (bcnt < 0) { /* exceptional situation */
+ switch (bcnt) {
+ case run_uncompressed: /* Uncompressed data. */
+ cfd_store_state();
+ bcnt = cf_decode_uncompressed(ss, pr);
+ if (bcnt < 0)
+ return bcnt;
+ cfd_load_state();
+ if (bcnt)
+ goto db;
+ else
+ goto dw;
+ /*case run_error: */
+ /*case run_zeros: *//* Premature end-of-line. */
+ default:
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ }
+ skip_data(bcnt, dwx);
+ if (q_at_stop()) {
+ run_color = 0; /* not inside a run */
+ goto done;
+ }
+ run_color = 1;
+ db: /* Decode a black run. */
+ get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
+ bcnt, "[w1]black", dbl, out1);
+ if (bcnt < 0) { /* All exceptional codes are invalid here. */
+/****** WRONG, uncompressed IS ALLOWED ******/
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ /* Invert bits designated by black run. */
+ invert_data(bcnt, black_byte, goto dbx, idb);
+ goto top;
+ dwx: /* If we run out of data after a makeup code, */
+ /* note that we are still processing a white run. */
+ run_color = -1;
+ goto dw;
+ dbx: /* If we run out of data after a makeup code, */
+ /* note that we are still processing a black run. */
+ run_color = 2;
+ goto db;
+ done:if (q > stop || qbit < end_bit)
+ status = PTSFAX_ERRC;
+ else
+ status = 1;
+ out:cfd_store_state();
+ ss->run_color = run_color;
+ if_debug1('w', "[w1]exit run_color = %d\n", run_color);
+ return status;
+ out0: /* We already set run_color to 0 or -1. */
+ status = 0;
+ goto out;
+ out1: /* We already set run_color to 1 or 2. */
+ status = 0;
+ goto out;
+}
+
+/* Decode a 2-D scan line. */
+static int
+cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr)
+{
+ cfd_declare_state;
+ unsigned char invert_white = (ss->BlackIs1 ? 0 : 0xff);
+ unsigned char black_byte = ~invert_white;
+ unsigned char invert = ss->invert;
+ int end_count = -ss->Columns & 7;
+ unsigned int raster = ss->raster;
+ unsigned char *q0 = ss->lbuf;
+ unsigned char *prev_q01 = ss->lprev + 1;
+ unsigned char *endptr = q0 - 1 + raster;
+ int init_count = raster << 3;
+ register int count;
+ int rlen;
+ int status;
+
+ cfd_load_state();
+ count = ((endptr - q) << 3) + qbit;
+ endptr[1] = 0xa0; /* a unsigned char with some 0s and some 1s, */
+ /* to ensure run scan will stop */
+ if_debug1('W', "[w2]raster=%d\n", raster);
+ switch (ss->run_color) {
+ case -2:
+ ss->run_color = 0;
+ goto hww;
+ case -1:
+ ss->run_color = 0;
+ goto hbw;
+ case 1:
+ ss->run_color = 0;
+ goto hwb;
+ case 2:
+ ss->run_color = 0;
+ goto hbb;
+ /*case 0: */
+ }
+ top:if (count <= end_count) {
+ status = (count < end_count ? PTSFAX_ERRC : 1);
+ goto out;
+ }
+ /* If invert == invert_white, white and black have their */
+ /* correct meanings; if invert == ~invert_white, */
+ /* black and white are interchanged. */
+ if_debug1('W', "[w2]%4d:\n", count);
+#ifdef DEBUG
+ /* Check the invariant between q, qbit, and count. */
+ {
+ int pcount = (endptr - q) * 8 + qbit;
+
+ if (pcount != count)
+ dlprintf2("[w2]Error: count=%d pcount=%d\n",
+ count, pcount);
+ }
+#endif
+ /*
+ * We could just use get_run here, but we can do better. However,
+ * we must be careful to handle the case where the very last codes
+ * in the input stream are 1-bit "vertical 0" codes: we can't just
+ * use ensure_bits(3, ...) and go to get more data if it fails.
+ */
+ ensure_bits(3, out3);
+#define vertical_0 (countof(cf2_run_vertical) / 2)
+ switch (peek_bits(3)) {
+ default /*4..7*/ : /* vertical(0) */
+v0: skip_bits(1);
+ rlen = vertical_0;
+ break;
+ case 2: /* vertical(+1) */
+ skip_bits(3);
+ rlen = vertical_0 + 1;
+ break;
+ case 3: /* vertical(-1) */
+ skip_bits(3);
+ rlen = vertical_0 - 1;
+ break;
+ case 1: /* horizontal */
+ skip_bits(3);
+ if (invert == invert_white)
+ goto hww;
+ else
+ goto hbb;
+ case 0: /* everything else */
+ get_run(cf_2d_decode, cfd_2d_initial_bits, cfd_2d_min_bits,
+ rlen, "[w2]", d2l, out0);
+ /* rlen may be run2_pass, run_uncompressed, or */
+ /* 0..countof(cf2_run_vertical)-1. */
+ if (rlen < 0)
+ switch (rlen) {
+ case run2_pass:
+ break;
+ case run_uncompressed:
+ {
+ int which;
+
+ cfd_store_state();
+ which = cf_decode_uncompressed(ss, pr);
+ if (which < 0) {
+ status = which;
+ goto out;
+ }
+ cfd_load_state();
+/****** ADJUST count ******/
+ invert = (which ? ~invert_white : invert_white);
+ }
+ goto top;
+ default: /* run_error, run_zeros */
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ }
+ /* Interpreting the run requires scanning the */
+ /* previous ('reference') line. */
+ {
+ int prev_count = count;
+ unsigned char prev_data;
+ int dlen;
+ static const unsigned char count_bit[8] =
+ {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40};
+ unsigned char *prev_q = prev_q01 + (q - q0);
+ int plen;
+
+ if (!(count & 7))
+ prev_q++; /* because of skip macros */
+ prev_data = prev_q[-1] ^ invert;
+ /* Find the b1 transition. */
+ if ((prev_data & count_bit[prev_count & 7]) &&
+ (prev_count < init_count || invert != invert_white)
+ ) { /* Look for changing white first. */
+ if_debug1('W', " data=0x%x", prev_data);
+ skip_black_pixels(prev_data, prev_q,
+ prev_count, invert, plen);
+ if (prev_count < end_count) /* overshot */
+ prev_count = end_count;
+ if_debug1('W', " b1 other=%d", prev_count);
+ }
+ if (prev_count != end_count) {
+ if_debug1('W', " data=0x%x", prev_data);
+ skip_white_pixels(prev_data, prev_q,
+ prev_count, invert, plen);
+ if (prev_count < end_count) /* overshot */
+ prev_count = end_count;
+ if_debug1('W', " b1 same=%d", prev_count);
+ }
+ /* b1 = prev_count; */
+ if (rlen == run2_pass) { /* Pass mode. Find b2. */
+ if (prev_count != end_count) {
+ if_debug1('W', " data=0x%x", prev_data);
+ skip_black_pixels(prev_data, prev_q,
+ prev_count, invert, plen);
+ if (prev_count < end_count) /* overshot */
+ prev_count = end_count;
+ }
+ /* b2 = prev_count; */
+ if_debug2('W', " b2=%d, pass %d\n",
+ prev_count, count - prev_count);
+ } else { /* Vertical coding. */
+ /* Remember that count counts *down*. */
+ prev_count += rlen - vertical_0; /* a1 */
+ if_debug2('W', " vertical %d -> %d\n",
+ rlen - vertical_0, prev_count);
+ }
+ /* Now either invert or skip from count */
+ /* to prev_count, and reset count. */
+ if (invert == invert_white) { /* Skip data bits. */
+ q = endptr - (prev_count >> 3);
+ qbit = prev_count & 7;
+ } else { /* Invert data bits. */
+ dlen = count - prev_count;
+ invert_data(dlen, black_byte, DO_NOTHING, idd);
+ }
+ count = prev_count;
+ if (rlen >= 0) /* vertical mode */
+ invert = ~invert; /* polarity changes */
+ }
+ goto top;
+ out3:
+ if (bits_left > 0 && peek_bits(1)) {
+ /* This is a 1-bit "vertical 0" code, which we can still process. */
+ goto v0;
+ }
+ /* falls through */
+ out0:status = 0;
+ /* falls through */
+ out:cfd_store_state();
+ ss->invert = invert;
+ return status;
+ /*
+ * We handle horizontal decoding here, so that we can
+ * branch back into it if we run out of input data.
+ */
+ /* White, then black. */
+ hww:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
+ rlen, " white", wwl, outww);
+ if ((count -= rlen) < end_count) {
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ skip_data(rlen, hww);
+ /* Handle the second half of a white-black horizontal code. */
+ hwb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
+ rlen, " black", wbl, outwb);
+ if ((count -= rlen) < end_count) {
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ invert_data(rlen, black_byte, goto hwb, ihwb);
+ goto top;
+ outww:ss->run_color = -2;
+ goto out0;
+ outwb:ss->run_color = 1;
+ goto out0;
+ /* Black, then white. */
+ hbb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
+ rlen, " black", bbl, outbb);
+ if ((count -= rlen) < end_count) {
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ invert_data(rlen, black_byte, goto hbb, ihbb);
+ /* Handle the second half of a black-white horizontal code. */
+ hbw:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
+ rlen, " white", bwl, outbw);
+ if ((count -= rlen) < end_count) {
+ status = PTSFAX_ERRC;
+ goto out;
+ }
+ skip_data(rlen, hbw);
+ goto top;
+ outbb:ss->run_color = 2;
+ goto out0;
+ outbw:ss->run_color = -1;
+ goto out0;
+}
+
+#if 1 /*************** */
+static int
+cf_decode_uncompressed(stream_CFD_state * ss, stream_cursor_read * pr)
+{
+ (void)ss;
+ (void)pr;
+ /**** pts ****/
+ return PTSFAX_ERRC;
+}
+#else /*************** */
+
+/* Decode uncompressed data. */
+/* (Not tested: no sample data available!) */
+/****** DOESN'T CHECK FOR OVERFLOWING SCAN LINE ******/
+static int
+cf_decode_uncompressed(stream * s)
+{
+ cfd_declare_state;
+ const cfd_node *np;
+ int clen, rlen;
+
+ cfd_load_state();
+ while (1) {
+ ensure_bits(cfd_uncompressed_initial_bits, NOOUT);
+ np = &cf_uncompressed_decode[peek_bits(cfd_uncompressed_initial_bits)];
+ clen = np->code_length;
+ rlen = np->run_length;
+ if (clen > cfd_uncompressed_initial_bits) { /* Must be an exit code. */
+ break;
+ }
+ if (rlen == cfd_uncompressed_initial_bits) { /* Longest representable white run */
+ if_debug1('W', "[wu]%d\n", rlen);
+ if ((qbit -= cfd_uncompressed_initial_bits) < 0)
+ qbit += 8, q++;
+ } else {
+ if_debug1('W', "[wu]%d+1\n", rlen);
+ if (qbit -= rlen < 0)
+ qbit += 8, q++;
+ *q ^= 1 << qbit;
+ }
+ skip_bits(clen);
+ }
+ clen -= cfd_uncompressed_initial_bits;
+ skip_bits(cfd_uncompressed_initial_bits);
+ ensure_bits(clen, NOOUT);
+ np = &cf_uncompressed_decode[rlen + peek_var_bits(clen)];
+ rlen = np->run_length;
+ skip_bits(np->code_length);
+ if_debug1('w', "[wu]exit %d\n", rlen);
+ if (rlen >= 0) { /* Valid exit code, rlen = 2 * run length + next polarity */
+ if ((qbit -= rlen >> 1) < 0)
+ qbit += 8, q++;
+ rlen &= 1;
+ }
+ out:
+/******* WRONG ******/
+ cfd_store_state();
+ return rlen;
+}
+
+#endif /*************** */
+
+/* Move as much data as possible from one buffer to another. */
+/* Return 0 if the input became empty, 1 if the output became full. */
+int
+stream_move(stream_cursor_read * pr, stream_cursor_write * pw)
+{
+ unsigned int rcount = pr->limit - pr->ptr;
+ unsigned int wcount = pw->limit - pw->ptr;
+ unsigned int count;
+ int status;
+
+ if (rcount <= wcount)
+ count = rcount, status = 0;
+ else
+ count = wcount, status = 1;
+
+ /**** pts ****/ /* Dat: memcpy should be enough instead of memmove */
+ #if 0
+ memmove(pw->ptr + 1, pr->ptr + 1, count);
+ pr->ptr += count;
+ pw->ptr += count;
+ #else
+ while (count--!=0) *++pw->ptr=*++pr->ptr;
+ #endif
+ return status;
+}
+
+#if 1 /**** pts ****/
+/* Stream template */
+const stream_template s_CFD_template =
+{/*0, &st_CFD_state*/ s_CFD_init, s_CFD_process, 1, 1, s_CFD_release,
+ s_CFD_set_defaults, 0
+};
+#endif
+
+/* end of former scfd.c */
+
+
+#endif /* USE_BUILTIN_FAXD */
+
+#if USE_BUILTIN_FAXE || USE_BUILTIN_FAXD
+/* shc.c */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Support code for shc.h */
+/* #include "scommon.h" */
+/* #include "shc.h" */
+/* #include "scfx.h" */ /**** pts ****/ /* struct stream_hc_state_s */
+
+/* ------ Encoding ------ */
+
+/* Empty the 1-word buffer onto the output stream. */
+/* q has already been incremented. */
+static void
+hc_put_code_proc(bool reverse_bits, unsigned char * q, unsigned int cw)
+{
+#define cb(n) ((unsigned char)(cw >> (n * 8)))
+ if (reverse_bits) {
+#if hc_bits_size > 16
+ q[-3] = byte_reverse_bits[cb(3)];
+ q[-2] = byte_reverse_bits[cb(2)];
+#endif
+ q[-1] = byte_reverse_bits[cb(1)];
+ q[0] = byte_reverse_bits[cb(0)];
+ } else {
+#if hc_bits_size > 16
+ q[-3] = cb(3);
+ q[-2] = cb(2);
+#endif
+ q[-1] = cb(1);
+ q[0] = cb(0);
+ }
+#undef cb
+}
+
+/* Put out any final bytes. */
+/* Note that this does a store_state, but not a load_state. */
+static unsigned char *
+hc_put_last_bits_proc(stream_hc_state * ss, unsigned char * q, unsigned int bits, int bits_left)
+{
+ while (bits_left < hc_bits_size) {
+ unsigned char c = (unsigned char) (bits >> (hc_bits_size - 8));
+
+ if (ss->FirstBitLowOrder)
+ c = byte_reverse_bits[c];
+ *++q = c;
+ bits <<= 8;
+ bits_left += 8;
+ }
+ ss->bits = bits;
+ ss->bits_left = bits_left;
+ return q;
+}
+
+/* end of former shc.c */
+
+
+/* gsbittab.c */
+/*$Id: pts_fax.c,v 1.3 2005/02/21 13:09:56 pts Exp $ */
+/* Tables for bit operations */
+/* #include "gstypes.h" */
+/* #include "gsbittab.h" */
+
+/* ---------------- Byte processing tables ---------------- */
+
+/*
+ * byte_reverse_bits[B] = the unsigned char B with the order of bits reversed.
+ */
+impl_const unsigned char byte_reverse_bits[256] = {
+ bit_table_8(0, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80)
+};
+
+/*
+ * byte_right_mask[N] = a unsigned char with N trailing 1s, 0 <= N <= 8.
+ */
+impl_const unsigned char byte_right_mask[9] = {
+ 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
+};
+
+/*
+ * byte_count_bits[B] = the number of 1-bits in a unsigned char with value B.
+ */
+impl_const unsigned char byte_count_bits[256] = {
+ bit_table_8(0, 1, 1, 1, 1, 1, 1, 1, 1)
+};
+
+/* ---------------- Scanning tables ---------------- */
+
+/*
+ * byte_bit_run_length_N[B], for 0 <= N <= 7, gives the length of the
+ * run of 1-bits starting at bit N in a unsigned char with value B,
+ * numbering the bits in the unsigned char as 01234567. If the run includes
+ * the low-order bit (i.e., might be continued into a following unsigned char),
+ * the run length is increased by 8.
+ */
+
+#define t8(n) n,n,n,n,n+1,n+1,n+2,n+11
+#define r8(n) n,n,n,n,n,n,n,n
+#define r16(n) r8(n),r8(n)
+#define r32(n) r16(n),r16(n)
+#define r64(n) r32(n),r32(n)
+#define r128(n) r64(n),r64(n)
+impl_const unsigned char byte_bit_run_length_0[256] = {
+ r128(0), r64(1), r32(2), r16(3), r8(4), t8(5)
+};
+impl_const unsigned char byte_bit_run_length_1[256] = {
+ r64(0), r32(1), r16(2), r8(3), t8(4),
+ r64(0), r32(1), r16(2), r8(3), t8(4)
+};
+impl_const unsigned char byte_bit_run_length_2[256] = {
+ r32(0), r16(1), r8(2), t8(3),
+ r32(0), r16(1), r8(2), t8(3),
+ r32(0), r16(1), r8(2), t8(3),
+ r32(0), r16(1), r8(2), t8(3)
+};
+impl_const unsigned char byte_bit_run_length_3[256] = {
+ r16(0), r8(1), t8(2), r16(0), r8(1), t8(2),
+ r16(0), r8(1), t8(2), r16(0), r8(1), t8(2),
+ r16(0), r8(1), t8(2), r16(0), r8(1), t8(2),
+ r16(0), r8(1), t8(2), r16(0), r8(1), t8(2)
+};
+impl_const unsigned char byte_bit_run_length_4[256] = {
+ r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1),
+ r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1),
+ r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1),
+ r8(0), t8(1), r8(0), t8(1), r8(0), t8(1), r8(0), t8(1),
+};
+
+#define rr8(a,b,c,d,e,f,g,h)\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h,\
+ a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h, a,b,c,d,e,f,g,h
+impl_const unsigned char byte_bit_run_length_5[256] = {
+ rr8(0, 0, 0, 0, 1, 1, 2, 11)
+};
+impl_const unsigned char byte_bit_run_length_6[256] = {
+ rr8(0, 0, 1, 10, 0, 0, 1, 10)
+};
+impl_const unsigned char byte_bit_run_length_7[256] = {
+ rr8(0, 9, 0, 9, 0, 9, 0, 9)
+};
+
+/* Pointer tables indexed by bit number. */
+
+impl_const unsigned char *const byte_bit_run_length[8] = {
+ byte_bit_run_length_0, byte_bit_run_length_1,
+ byte_bit_run_length_2, byte_bit_run_length_3,
+ byte_bit_run_length_4, byte_bit_run_length_5,
+ byte_bit_run_length_6, byte_bit_run_length_7
+};
+impl_const unsigned char *const byte_bit_run_length_neg[8] = {
+ byte_bit_run_length_0, byte_bit_run_length_7,
+ byte_bit_run_length_6, byte_bit_run_length_5,
+ byte_bit_run_length_4, byte_bit_run_length_3,
+ byte_bit_run_length_2, byte_bit_run_length_1
+};
+
+/*
+ * byte_acegbdfh_to_abcdefgh[acegbdfh] = abcdefgh, where the letters
+ * denote the individual bits of the unsigned char.
+ */
+impl_const unsigned char byte_acegbdfh_to_abcdefgh[256] = {
+ bit_table_8(0, 0x80, 0x20, 0x08, 0x02, 0x40, 0x10, 0x04, 0x01)
+};
+
+#if 0
+/* Some C compilers insist on having executable code in every file.... */
+void gsbittab_dummy _((void)); /* for picky compilers */
+void
+gsbittab_dummy(void)
+{
+}
+#endif
+
+/* end of former gsbittab.c */
+#endif /* USE_BUILTIN_FAXE || USE_BUILTIN_FAXD */
+
+/* end of pts_fax.c */