xref: /plan9/sys/src/cmd/gs/src/scf.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1992, 1995, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: scf.h,v 1.4 2002/02/21 22:24:53 giles Exp $ */
18 /* Common definitions for CCITTFax encoding and decoding filters */
19 
20 #ifndef scf_INCLUDED
21 #  define scf_INCLUDED
22 
23 #include "shc.h"
24 
25 /*
26  * The CCITT Group 3 (T.4) and Group 4 (T.6) fax specifications map
27  * run lengths to Huffman codes.  White and black have different mappings.
28  * If the run length is 64 or greater, two or more codes are needed:
29  *      - One or more 'make-up' codes for 2560 pixels;
30  *      - A 'make-up' code that encodes the multiple of 64;
31  *      - A 'termination' code for the remainder.
32  * For runs of 63 or less, only the 'termination' code is needed.
33  */
34 
35 /* ------ Encoding tables ------ */
36 
37 /*
38  * The maximum possible length of a scan line is determined by the
39  * requirement that 3 runs have to fit into the stream buffer.
40  * A run of length N requires approximately ceil(N / 2560) makeup codes,
41  * hence 1.5 * ceil(N / 2560) bytes.  Taking the largest safe stream
42  * buffer size as 32K, we arrive at the following maximum width:
43  */
44 #if arch_sizeof_int > 2
45 #  define cfe_max_width (2560 * 32000 * 2 / 3)
46 #else
47 #  define cfe_max_width (max_int - 40)	/* avoid overflows */
48 #endif
49 /* The +5 in cfe_max_code_bytes is a little conservative. */
50 #define cfe_max_code_bytes(width) ((width) / 2560 * 3 / 2 + 5)
51 
52 typedef hce_code cfe_run;
53 
54 /* Codes common to 1-D and 2-D encoding. */
55 /* The decoding algorithms know that EOL is 0....01. */
56 #define run_eol_code_length 12
57 #define run_eol_code_value 1
58 extern const cfe_run cf_run_eol;
59 typedef struct cf_runs_s {
60     cfe_run termination[64];
61     cfe_run make_up[41];
62 } cf_runs;
63 extern const cf_runs
64       cf_white_runs, cf_black_runs;
65 extern const cfe_run cf_uncompressed[6];
66 extern const cfe_run cf_uncompressed_exit[10];	/* indexed by 2 x length of */
67 
68 			/* white run + (1 if next run black, 0 if white) */
69 /* 1-D encoding. */
70 extern const cfe_run cf1_run_uncompressed;
71 
72 /* 2-D encoding. */
73 extern const cfe_run cf2_run_pass;
74 
75 #define cf2_run_pass_length 4
76 #define cf2_run_pass_value 0x1
77 #define cf2_run_vertical_offset 3
78 extern const cfe_run cf2_run_vertical[7];	/* indexed by b1 - a1 + offset */
79 extern const cfe_run cf2_run_horizontal;
80 
81 #define cf2_run_horizontal_value 1
82 #define cf2_run_horizontal_length 3
83 extern const cfe_run cf2_run_uncompressed;
84 
85 /* 2-D Group 3 encoding. */
86 extern const cfe_run cf2_run_eol_1d;
87 extern const cfe_run cf2_run_eol_2d;
88 
89 /* ------ Decoding tables ------ */
90 
91 typedef hcd_code cfd_node;
92 
93 #define run_length value
94 
95 /*
96  * The value in the decoding tables is either a white or black run length,
97  * or a (negative) exceptional value.
98  */
99 #define run_error (-1)
100 #define run_zeros (-2)	/* EOL follows, possibly with more padding first */
101 #define run_uncompressed (-3)
102 /* 2-D codes */
103 #define run2_pass (-4)
104 #define run2_horizontal (-5)
105 
106 #define cfd_white_initial_bits 8
107 #define cfd_white_min_bits 4	/* shortest white run */
108 extern const cfd_node cf_white_decode[];
109 
110 #define cfd_black_initial_bits 7
111 #define cfd_black_min_bits 2	/* shortest black run */
112 extern const cfd_node cf_black_decode[];
113 
114 #define cfd_2d_initial_bits 7
115 #define cfd_2d_min_bits 4	/* shortest non-H/V 2-D run */
116 extern const cfd_node cf_2d_decode[];
117 
118 #define cfd_uncompressed_initial_bits 6		/* must be 6 */
119 extern const cfd_node cf_uncompressed_decode[];
120 
121 /* ------ Run detection macros ------ */
122 
123 /*
124  * For the run detection macros:
125  *   white_byte is 0 or 0xff for BlackIs1 or !BlackIs1 respectively;
126  *   data holds p[-1], inverted if !BlackIs1;
127  *   count is the number of valid bits remaining in the scan line.
128  */
129 
130 /* Aliases for bit processing tables. */
131 #define cf_byte_run_length byte_bit_run_length_neg
132 #define cf_byte_run_length_0 byte_bit_run_length_0
133 
134 /* Skip over white pixels to find the next black pixel in the input. */
135 /* Store the run length in rlen, and update data, p, and count. */
136 /* There are many more white pixels in typical input than black pixels, */
137 /* and the runs of white pixels tend to be much longer, so we use */
138 /* substantially different loops for the two cases. */
139 
140 #define skip_white_pixels(data, p, count, white_byte, rlen)\
141 BEGIN\
142     rlen = cf_byte_run_length[count & 7][data ^ 0xff];\
143     if ( rlen >= 8 ) {		/* run extends past byte boundary */\
144 	if ( white_byte == 0 ) {\
145 	    if ( p[0] ) { data = p[0]; p += 1; rlen -= 8; }\
146 	    else if ( p[1] ) { data = p[1]; p += 2; }\
147 	    else {\
148 		while ( !(p[2] | p[3] | p[4] | p[5]) )\
149 		    p += 4, rlen += 32;\
150 		if ( p[2] ) {\
151 		    data = p[2]; p += 3; rlen += 8;\
152 		} else if ( p[3] ) {\
153 		    data = p[3]; p += 4; rlen += 16;\
154 		} else if ( p[4] ) {\
155 		    data = p[4]; p += 5; rlen += 24;\
156 		} else /* p[5] */ {\
157 		    data = p[5]; p += 6; rlen += 32;\
158 		}\
159 	    }\
160 	} else {\
161 	    if ( p[0] != 0xff ) { data = (byte)~p[0]; p += 1; rlen -= 8; }\
162 	    else if ( p[1] != 0xff ) { data = (byte)~p[1]; p += 2; }\
163 	    else {\
164 		while ( (p[2] & p[3] & p[4] & p[5]) == 0xff )\
165 		    p += 4, rlen += 32;\
166 		if ( p[2] != 0xff ) {\
167 		    data = (byte)~p[2]; p += 3; rlen += 8;\
168 		} else if ( p[3] != 0xff ) {\
169 		    data = (byte)~p[3]; p += 4; rlen += 16;\
170 		} else if ( p[4] != 0xff ) {\
171 		    data = (byte)~p[4]; p += 5; rlen += 24;\
172 		} else /* p[5] != 0xff */ {\
173 		    data = (byte)~p[5]; p += 6; rlen += 32;\
174 		}\
175 	    }\
176 	}\
177 	rlen += cf_byte_run_length_0[data ^ 0xff];\
178     }\
179     count -= rlen;\
180 END
181 
182 /* Skip over black pixels to find the next white pixel in the input. */
183 /* Store the run length in rlen, and update data, p, and count. */
184 
185 #define skip_black_pixels(data, p, count, white_byte, rlen)\
186 BEGIN\
187     rlen = cf_byte_run_length[count & 7][data];\
188     if ( rlen >= 8 ) {\
189 	if ( white_byte == 0 )\
190 	    for ( ; ; p += 4, rlen += 32 ) {\
191 		if ( p[0] != 0xff ) { data = p[0]; p += 1; rlen -= 8; break; }\
192 		if ( p[1] != 0xff ) { data = p[1]; p += 2; break; }\
193 		if ( p[2] != 0xff ) { data = p[2]; p += 3; rlen += 8; break; }\
194 		if ( p[3] != 0xff ) { data = p[3]; p += 4; rlen += 16; break; }\
195 	    }\
196 	else\
197 	    for ( ; ; p += 4, rlen += 32 ) {\
198 		if ( p[0] ) { data = (byte)~p[0]; p += 1; rlen -= 8; break; }\
199 		if ( p[1] ) { data = (byte)~p[1]; p += 2; break; }\
200 		if ( p[2] ) { data = (byte)~p[2]; p += 3; rlen += 8; break; }\
201 		if ( p[3] ) { data = (byte)~p[3]; p += 4; rlen += 16; break; }\
202 	    }\
203 	rlen += cf_byte_run_length_0[data];\
204     }\
205     count -= rlen;\
206 END
207 
208 #endif /* scf_INCLUDED */
209