1 #ifndef lint
2 static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/mkg3states.c,v 1.13 92/03/06 11:10:57 sam Exp $";
3 #endif
4 
5 /*
6  * Copyright (c) 1991, 1992 Sam Leffler
7  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
8  *
9  * Permission to use, copy, modify, distribute, and sell this software and
10  * its documentation for any purpose is hereby granted without fee, provided
11  * that (i) the above copyright notices and this permission notice appear in
12  * all copies of the software and related documentation, and (ii) the names of
13  * Sam Leffler and Silicon Graphics may not be used in any advertising or
14  * publicity relating to the software without the specific, prior written
15  * permission of Sam Leffler and Silicon Graphics.
16  *
17  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
19  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
22  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
23  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
25  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26  * OF THIS SOFTWARE.
27  */
28 
29 /*
30  * Program to construct Group 3 & Group 4 decoding tables.
31  *
32  * This code is derived from code by Michael P. Marking.  In
33  * particular, the algorithms to generate the null_mode and
34  * horiz_mode state tables are his.  See the comments below
35  * for more information.
36  *
37  * BEGIN (from the original source)
38  LEGAL
39  *	Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
40  *	Scottsdale, Arizona 85252-8039. All rights reserved.
41  *
42  *	License is granted by the copyright holder to distribute and use this
43  *	code without payment of royalties or the necessity of notification as
44  *	long as this notice (all the text under "LEGAL") is included.
45  *
46  *	Reference: $Id: mkg3states.c,v 1.13 92/03/06 11:10:57 sam Exp $
47  *
48  *	This program is offered without any warranty of any kind. It includes
49  *	no warranty of merchantability or fitness for any purpose. Testing and
50  *	suitability for any use are the sole responsibility of the user.
51  *
52  INFORMATION
53  *	Although there is no support offered with this program, the author will
54  *	endeavor to correct errors. Updates will also be made available from
55  *	time to time.
56  *
57  *	Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
58  *	85252-8039 USA. Replies are not guaranteed to be swift. Beginning
59  *	July 1990, e-mail may be sent to uunet!ipel!marking.
60  *
61  *	Also beginning in July 1990, this code will be archived at the
62  *	ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
63  *	for 300/1200/2400 is (602)274-0462. When logging in, specify user
64  *	"public", system "bbs", and password "public".
65  *
66  *	This code is also available from the C Users Group in volume 317.
67  *
68  * END (from the original source)
69  */
70 #include <stdio.h>
71 #include "prototypes.h"
72 
73 #ifndef TRUE
74 #define	TRUE	1
75 #define	FALSE	0
76 #endif
77 
78 #define WHITE	0
79 #define BLACK	1
80 
81 /*
82  * G3 2D and G4 decoding modes.  Note that
83  * the vertical modes are ordered so that
84  * (mode - MODE_VERT_V0) gives the vertical
85  * adjustment for the b1 parameter.
86  */
87 #define MODE_NULL	0
88 #define MODE_PASS	1
89 #define MODE_HORIZ	2
90 #define MODE_VERT_VL3	3
91 #define MODE_VERT_VL2	4
92 #define MODE_VERT_VL1	5
93 #define MODE_VERT_V0	6
94 #define MODE_VERT_VR1	7
95 #define MODE_VERT_VR2	8
96 #define MODE_VERT_VR3	9
97 #define MODE_UNCOMP	10
98 #define MODE_ERROR	11
99 #define MODE_ERROR_1	12
100 
101 unsigned long
DECLARE1(append_0,unsigned long,prefix)102 DECLARE1(append_0, unsigned long, prefix)
103 {
104     return (prefix + (1L<<16));
105 }
106 
107 unsigned long
DECLARE1(append_1,unsigned long,prefix)108 DECLARE1(append_1, unsigned long, prefix)
109 {
110     static unsigned short prefix_bit[16] = {
111 	0x8000, 0x4000, 0x2000, 0x1000,
112 	0x0800, 0x0400, 0x0200, 0x0100,
113 	0x0080, 0x0040, 0x0020, 0x0010,
114 	0x0008, 0x0004, 0x0002, 0x0001
115     };
116     unsigned char len = (prefix >> 16) & 0xf;
117     return (append_0(prefix) + prefix_bit[len]);
118 }
119 
120 #define	G3CODES
121 #include "t4.h"
122 
123 short
124 #if defined(__STDC__) || defined(__EXTENDED__) || USE_CONST
DECLARE3(search_table,unsigned long,prefix,tableentry const *,tab,int,n)125 DECLARE3(search_table, unsigned long, prefix, tableentry const*, tab, int, n)
126 #else
127 DECLARE3(search_table, unsigned long, prefix, tableentry*, tab, int, n)
128 #endif
129 {
130     unsigned short len = (prefix >> 16) & 0xf;
131     unsigned short code = (prefix & 0xffff) >> (16 - len);
132 
133     while (n-- > 0) {
134 	if (tab->length == len && tab->code == code)
135 	    return ((short) tab->runlen);
136 	tab++;
137     }
138     return (G3CODE_INCOMP);
139 }
140 
141 #define	NCODES(a)	(sizeof (a) / sizeof (a[0]))
142 short
DECLARE1(white_run_length,unsigned long,prefix)143 DECLARE1(white_run_length, unsigned long, prefix)
144 {
145     return (search_table(prefix, TIFFFaxWhiteCodes, NCODES(TIFFFaxWhiteCodes)));
146 }
147 
148 short
DECLARE1(black_run_length,unsigned long,prefix)149 DECLARE1(black_run_length, unsigned long, prefix)
150 {
151     return (search_table(prefix, TIFFFaxBlackCodes, NCODES(TIFFFaxBlackCodes)));
152 }
153 #undef NCODES
154 
155 #define MAX_NULLPREFIX	200	/* max # of null-mode prefixes */
156 typedef	unsigned char NullModeTable[MAX_NULLPREFIX][256];
157 #define MAX_HORIZPREFIX	250	/* max # of incomplete 1-D prefixes */
158 typedef	unsigned char HorizModeTable[MAX_HORIZPREFIX][256];
159 
160   /* the bit string corresponding to this row of the decoding table */
161 long	null_mode_prefix[MAX_NULLPREFIX];
162 NullModeTable null_mode;		/* MODE_*, indexed by bit and byte */
163 NullModeTable null_mode_next_state;	/* next row of decoding tables to use */
164   /* number of prefixes or rows in the G4 decoding tables */
165 short	null_mode_prefix_count = 0;
166 
167 /*
168  * 2D uncompressed mode codes.  Note
169  * that two groups of codes are arranged
170  * so that the decoder can caluclate the
171  * length of the run by subtracting the
172  * code from a known base value.
173  */
174 #define	UNCOMP_INCOMP	0
175 /* runs of [0]*1 */
176 #define	UNCOMP_RUN0	1
177 #define	UNCOMP_RUN1	2
178 #define	UNCOMP_RUN2	3
179 #define	UNCOMP_RUN3	4
180 #define	UNCOMP_RUN4	5
181 #define	UNCOMP_RUN5	6
182 #define	UNCOMP_RUN6	7
183 /* runs of [0]* w/ terminating color */
184 #define	UNCOMP_TRUN0	8
185 #define	UNCOMP_TRUN1	9
186 #define	UNCOMP_TRUN2	10
187 #define	UNCOMP_TRUN3	11
188 #define	UNCOMP_TRUN4	12
189 /* special code for unexpected EOF */
190 #define	UNCOMP_EOF	13
191 /* invalid code encountered */
192 #define	UNCOMP_INVALID	14
193 
194 long	uncomp_mode_prefix[MAX_NULLPREFIX];
195 NullModeTable uncomp_mode;
196 NullModeTable uncomp_mode_next_state;
197 short	uncomp_mode_prefix_count = 0;
198 
199 /*
200  * Decoding action values for horiz_mode.
201  */
202 #define ACT_INCOMP	0		/* incompletely decoded code */
203 #define ACT_INVALID	1		/* invalide code */
204 #define	ACT_WRUNT	2		/* terminating white run code */
205 #define	ACT_WRUN	65		/* non-terminating white run code */
206 #define	ACT_BRUNT	106		/* terminating black run code */
207 #define	ACT_BRUN	169		/* non-terminating black run code */
208 #define ACT_EOL		210		/* end-of-line code */
209 HorizModeTable horiz_mode;
210 
211 short
DECLARE1(horiz_mode_code_black,short,runlen)212 DECLARE1(horiz_mode_code_black, short, runlen)
213 {
214     return (runlen < 64 ? runlen + ACT_BRUNT : (runlen / 64) + ACT_BRUN);
215 }
216 
217 short
DECLARE1(horiz_mode_code_white,short,runlen)218 DECLARE1(horiz_mode_code_white, short, runlen)
219 {
220     return (runlen < 64 ? runlen + ACT_WRUNT : (runlen / 64) + ACT_WRUN);
221 }
222 
223 /*
224  * If the corresponding horiz_mode entry is ACT_INCOMP
225  * this entry is a row number for decoding the next byte;
226  * otherwise, it is the bit number with which to continue
227  * decoding the next codeword.
228  */
229 HorizModeTable horiz_mode_next_state;
230 		/* prefixes corresponding to the rows of the decoding table */
231 long	horiz_mode_prefix[MAX_HORIZPREFIX];
232 		/* color of next run, BLACK or WHITE */
233 char	horiz_mode_color[MAX_HORIZPREFIX];
234 short	horiz_mode_prefix_count = 0;
235 
236 static	unsigned char bit_mask[8] =
237     { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
238 
239 #if USE_PROTOTYPES
240 void	build_null_mode_tables(void);
241 short	find_horiz_mode_prefix(long, char);
242 short	find_null_mode_prefix(long);
243 short	null_mode_type(long);
244 void	build_horiz_mode_tables(void);
245 short	horiz_mode_code_black(short);
246 short	horiz_mode_code_white(short);
247 void	build_uncomp_mode_tables(void);
248 void	write_tables(FILE*);
249 #else
250 void	build_null_mode_tables();
251 short	find_horiz_mode_prefix();
252 short	find_null_mode_prefix();
253 short	null_mode_type();
254 void	build_horiz_mode_tables();
255 short	horiz_mode_code_black();
256 short	horiz_mode_code_white();
257 void	build_uncomp_mode_tables();
258 void	write_tables();
259 #endif
260 
261 int	verbose = FALSE;
262 char	*storage_class = "";
263 
264 void
DECLARE2(main,int,argc,char **,argv)265 DECLARE2(main, int, argc, char**, argv)
266 {
267     while (argc > 1 && argv[1][0] == '-') {
268 	if (strcmp(argv[1], "-v") == 0) {
269 	    verbose = TRUE;
270 	    argc--, argv++;
271 	} else if (strcmp(argv[1], "-c") == 0) {
272 	    storage_class = "const ";
273 	    argc--, argv++;
274 	}
275     }
276     build_null_mode_tables();		/* null mode decoding tables */
277     if (verbose) {
278 	fprintf(stderr, "%d null mode prefixes defined\n",
279 	    (int) null_mode_prefix_count);
280 	fprintf(stderr, "building uncompressed mode scripts...\n");
281     }
282     build_uncomp_mode_tables();		/* uncompressed mode decoding tables */
283     if (verbose) {
284 	fprintf(stderr, "%d uncompressed mode prefixes defined\n",
285 	    (int) uncomp_mode_prefix_count);
286 	fprintf(stderr, "building 1D scripts...\n");
287     }
288     build_horiz_mode_tables();		/* 1D decoding tables */
289     if (verbose)
290 	fprintf(stderr, "%d incomplete prefixes defined\n",
291 	    (int) horiz_mode_prefix_count);
292     write_tables(stdout);
293     exit(0);
294 }
295 
296 void
DECLARE3(write_null_mode_table,FILE *,fd,NullModeTable,table,char *,name)297 DECLARE3(write_null_mode_table, FILE*, fd, NullModeTable, table, char*, name)
298 {
299     int i, j;
300     char* outersep;
301     char* sep;
302 
303     fprintf(fd, "%su_char\t%s[%d][256] = {", storage_class,
304 	name, (int) null_mode_prefix_count);
305     outersep = "";
306     for (i = 0; i < null_mode_prefix_count; i++) {
307 	fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
308 	sep = "    ";
309 	for (j = 0; j < 256; j++) {
310 	    fprintf(fd, "%s%2d", sep, (int) table[i][j]);
311 	    if (((j+1) % 16) == 0) {
312 		fprintf(fd, ", /* %3d-%3d */\n", j-15, j);
313 		sep = "    ";
314 	    } else
315 		sep = ",";
316 	}
317 	fprintf(fd, "}");
318 	outersep = ",";
319     }
320     fprintf(fd, "\n};\n");
321 }
322 
323 void
DECLARE3(write_horiz_mode_table,FILE *,fd,HorizModeTable,table,char *,name)324 DECLARE3(write_horiz_mode_table, FILE*, fd, HorizModeTable, table, char*, name)
325 {
326     int i, j;
327     char* outersep;
328     char* sep;
329 
330     fprintf(fd, "%s u_char\t%s[%d][256] = {", storage_class,
331 	name, (int) horiz_mode_prefix_count);
332     outersep = "";
333     for (i = 0; i < horiz_mode_prefix_count; i++) {
334 	fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
335 	sep = "    ";
336 	for (j = 0; j < 256; j++) {
337 	    fprintf(fd, "%s%3d", sep, (int) table[i][j]);
338 	    if (((j+1) % 14) == 0) {
339 		fprintf(fd, ", /* %3d-%3d */\n", j-13, j);
340 		sep = "    ";
341 	    } else
342 		sep = ",";
343 	}
344 	fprintf(fd, "\n}");
345 	outersep = ",";
346     }
347     fprintf(fd, "\n};\n");
348 }
349 
350 void
write_define(fd,name,value,comment)351 write_define(fd, name, value, comment)
352     FILE *fd;
353     char *name;
354     int value;
355     char *comment;
356 {
357     fprintf(fd, "#define\t%s\t%d", name, value);
358     if (comment)
359 	fprintf(fd, "\t/* %s */", comment);
360     fprintf(fd, "\n");
361 }
362 
363 void
write_preamble(fd)364 write_preamble(fd)
365     FILE *fd;
366 {
367     fprintf(fd, "%s\n",
368 "/* DO NOT EDIT THIS FILE, IT WAS AUTOMATICALLY CREATED BY mkg3state */");
369     write_define(fd, "ACT_INCOMP", ACT_INCOMP, "incompletely decoded code");
370     write_define(fd, "ACT_INVALID", ACT_INVALID, "invalide code");
371     write_define(fd, "ACT_WRUNT", ACT_WRUNT, "terminating white run code");
372     write_define(fd, "ACT_WRUN", ACT_WRUN, "non-terminating white run code");
373     write_define(fd, "ACT_BRUNT", ACT_BRUNT, "terminating black run code");
374     write_define(fd, "ACT_BRUN", ACT_BRUN, "non-terminating black run code");
375     write_define(fd, "ACT_EOL", ACT_EOL, "end-of-line code");
376     fprintf(fd, "\n");
377     fprintf(fd, "/* modes that the decoder can be in */\n");
378     write_define(fd, "MODE_NULL", MODE_NULL, NULL);
379     write_define(fd, "MODE_PASS", MODE_PASS, NULL);
380     write_define(fd, "MODE_HORIZ", MODE_HORIZ, NULL);
381     write_define(fd, "MODE_VERT_V0", MODE_VERT_V0, NULL);
382     write_define(fd, "MODE_VERT_VR1", MODE_VERT_VR1, NULL);
383     write_define(fd, "MODE_VERT_VR2", MODE_VERT_VR2, NULL);
384     write_define(fd, "MODE_VERT_VR3", MODE_VERT_VR3, NULL);
385     write_define(fd, "MODE_VERT_VL1", MODE_VERT_VL1, NULL);
386     write_define(fd, "MODE_VERT_VL2", MODE_VERT_VL2, NULL);
387     write_define(fd, "MODE_VERT_VL3", MODE_VERT_VL3, NULL);
388     write_define(fd, "MODE_UNCOMP", MODE_UNCOMP, NULL);
389     write_define(fd, "MODE_ERROR", MODE_ERROR, NULL);
390     write_define(fd, "MODE_ERROR_1", MODE_ERROR_1, NULL);
391     fprintf(fd, "\n");
392     fprintf(fd, "#define\tRUNLENGTH(ix)	(TIFFFaxWhiteCodes[ix].runlen)\n");
393     fprintf(fd, "\n");
394     write_define(fd, "UNCOMP_INCOMP", UNCOMP_INCOMP, NULL);
395     fprintf(fd, "/* runs of [0]*1 */\n");
396     write_define(fd, "UNCOMP_RUN0", UNCOMP_RUN0, NULL);
397     write_define(fd, "UNCOMP_RUN1", UNCOMP_RUN1, NULL);
398     write_define(fd, "UNCOMP_RUN2", UNCOMP_RUN2, NULL);
399     write_define(fd, "UNCOMP_RUN3", UNCOMP_RUN3, NULL);
400     write_define(fd, "UNCOMP_RUN4", UNCOMP_RUN4, NULL);
401     write_define(fd, "UNCOMP_RUN5", UNCOMP_RUN5, NULL);
402     write_define(fd, "UNCOMP_RUN6", UNCOMP_RUN6, NULL);
403     fprintf(fd, "/* runs of [0]* w/ terminating color */\n");
404     write_define(fd, "UNCOMP_TRUN0", UNCOMP_TRUN0, NULL);
405     write_define(fd, "UNCOMP_TRUN1", UNCOMP_TRUN1, NULL);
406     write_define(fd, "UNCOMP_TRUN2", UNCOMP_TRUN2, NULL);
407     write_define(fd, "UNCOMP_TRUN3", UNCOMP_TRUN3, NULL);
408     write_define(fd, "UNCOMP_TRUN4", UNCOMP_TRUN4, NULL);
409     fprintf(fd, "/* special code for unexpected EOF */\n");
410     write_define(fd, "UNCOMP_EOF", UNCOMP_EOF, NULL);
411     fprintf(fd, "/* invalid code encountered */\n");
412     write_define(fd, "UNCOMP_INVALID", UNCOMP_INVALID, NULL);
413     fprintf(fd, "/* codes >= terminate uncompress mode */\n");
414     fprintf(fd, "#define\tUNCOMP_EXIT	UNCOMP_TRUN0\n");
415     fprintf(fd, "\n");
416 }
417 
418 void
extern_table(fd,name)419 extern_table(fd, name)
420     FILE* fd;
421     char* name;
422 {
423     fprintf(fd, "extern\t%su_char %s[][256];\n", storage_class, name);
424 }
425 
426 void
write_tables(fd)427 write_tables(fd)
428     FILE* fd;
429 {
430     write_preamble(fd);
431     fprintf(fd, "#ifdef G3STATES\n");
432     write_null_mode_table(fd, null_mode, "TIFFFax2DMode");
433     write_null_mode_table(fd, null_mode_next_state, "TIFFFax2DNextState");
434     write_null_mode_table(fd, uncomp_mode, "TIFFFaxUncompAction");
435     write_null_mode_table(fd, uncomp_mode_next_state, "TIFFFaxUncompNextState");
436     write_horiz_mode_table(fd, horiz_mode, "TIFFFax1DAction");
437     write_horiz_mode_table(fd, horiz_mode_next_state, "TIFFFax1DNextState");
438     fprintf(fd, "#else\n");
439     extern_table(fd, "TIFFFax2DMode");
440     extern_table(fd, "TIFFFax2DNextState");
441     extern_table(fd, "TIFFFaxUncompAction");
442     extern_table(fd, "TIFFFaxUncompNextState");
443     extern_table(fd, "TIFFFax1DAction");
444     extern_table(fd, "TIFFFax1DNextState");
445     fprintf(fd, "#endif\n");
446 }
447 
448 short
DECLARE1(find_null_mode_prefix,long,prefix)449 DECLARE1(find_null_mode_prefix, long, prefix)
450 {
451     short j1;
452 
453     if (prefix == 0L)
454 	return (0);
455     for (j1 = 8; j1 < null_mode_prefix_count; j1++)
456 	if (prefix == null_mode_prefix[j1])
457 		return (j1);
458     if (null_mode_prefix_count == MAX_NULLPREFIX) {
459 	fprintf(stderr, "ERROR: null mode prefix table overflow\n");
460 	exit(1);
461     }
462     if (verbose)
463 	fprintf(stderr, "adding null mode prefix[%d] 0x%lx\n",
464 	    (int) null_mode_prefix_count, prefix);
465     null_mode_prefix[null_mode_prefix_count++] = prefix;
466     return (null_mode_prefix_count-1);
467 }
468 
469 short
DECLARE2(find_horiz_mode_prefix,long,prefix,char,color)470 DECLARE2(find_horiz_mode_prefix, long, prefix, char, color)
471 {
472     short j1;
473 
474     for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
475 	if (prefix == horiz_mode_prefix[j1] && horiz_mode_color[j1] == color)
476 	    return (j1);
477     /*
478      * It wasn't found, so add it to the tables, but first, is there room?
479      */
480     if (horiz_mode_prefix_count == MAX_HORIZPREFIX) {
481 	fprintf(stderr, "ERROR: 1D prefix table overflow\n");
482 	exit(1);
483     }
484     /* OK, there's room... */
485     if (verbose)
486 	fprintf(stderr, "\nhoriz mode prefix %d, color %c = 0x%lx ",
487 	    (int) horiz_mode_prefix_count, "WB"[color], prefix);
488     horiz_mode_prefix[horiz_mode_prefix_count] = prefix;
489     horiz_mode_color[horiz_mode_prefix_count] = color;
490     horiz_mode_prefix_count++;
491     return (horiz_mode_prefix_count - 1);
492 }
493 
494 short
DECLARE1(find_uncomp_mode_prefix,long,prefix)495 DECLARE1(find_uncomp_mode_prefix, long, prefix)
496 {
497     short j1;
498 
499     if (prefix == 0L)
500 	return (0);
501     for (j1 = 8; j1 < uncomp_mode_prefix_count; j1++)
502 	if (prefix == uncomp_mode_prefix[j1])
503 		return (j1);
504     if (uncomp_mode_prefix_count == MAX_NULLPREFIX) {
505 	fprintf(stderr, "ERROR: uncomp mode prefix table overflow\n");
506 	exit(1);
507     }
508     if (verbose)
509 	fprintf(stderr, "adding uncomp mode prefix[%d] 0x%lx\n",
510 	    (int) uncomp_mode_prefix_count, prefix);
511     uncomp_mode_prefix[uncomp_mode_prefix_count++] = prefix;
512     return (uncomp_mode_prefix_count-1);
513 }
514 
515 short
DECLARE1(null_mode_type,long,prefix)516 DECLARE1(null_mode_type, long, prefix)
517 {
518     switch (prefix) {
519     case 0x18000L: return (MODE_VERT_V0);	/* 1 */
520     case 0x36000L: return (MODE_VERT_VR1);	/* 011 */
521     case 0x34000L: return (MODE_VERT_VL1);	/* 010 */
522     case 0x32000L: return (MODE_HORIZ);		/* 001 */
523     case 0x41000L: return (MODE_PASS);		/* 0001 */
524     case 0x60C00L: return (MODE_VERT_VR2);	/* 0000 11 */
525     case 0x60800L: return (MODE_VERT_VL2);	/* 0000 10 */
526     case 0x70600L: return (MODE_VERT_VR3);	/* 0000 011 */
527     case 0x70400L: return (MODE_VERT_VL3);	/* 0000 010 */
528     case 0x80200L: return (MODE_ERROR);		/* 0000 0010 */
529     case 0x90300L: return (MODE_ERROR);		/* 0000 0011 0 */
530     case 0xA0380L: return (MODE_ERROR);		/* 0000 0011 10 */
531     case 0xA03C0L: return (MODE_UNCOMP);	/* 0000 0011 11 */
532     /*
533      * Under the assumption that there are no
534      * errors in the file, then this bit string
535      * can only be the beginning of an EOL code.
536      */
537     case 0x70000L: return (MODE_ERROR_1);	/* 0000 000 */
538     }
539     return (-1);
540 }
541 
542 short
DECLARE1(uncomp_mode_type,long,prefix)543 DECLARE1(uncomp_mode_type, long, prefix)
544 {
545     short code;
546     short len;
547     switch (prefix) {
548     case 0x18000L: return (UNCOMP_RUN1);	/* 1 */
549     case 0x24000L: return (UNCOMP_RUN2);	/* 01 */
550     case 0x32000L: return (UNCOMP_RUN3);	/* 001 */
551     case 0x41000L: return (UNCOMP_RUN4);	/* 0001 */
552     case 0x50800L: return (UNCOMP_RUN5);	/* 0000 1 */
553     case 0x60400L: return (UNCOMP_RUN6);	/* 0000 01 */
554     case 0x70200L: return (UNCOMP_TRUN0);	/* 0000 001 */
555     case 0x80100L: return (UNCOMP_TRUN1);	/* 0000 0001 */
556     case 0x90080L: return (UNCOMP_TRUN2);	/* 0000 0000 1 */
557     case 0xA0040L: return (UNCOMP_TRUN3);	/* 0000 0000 01 */
558     case 0xB0020L: return (UNCOMP_TRUN4);	/* 0000 0000 001 */
559     }
560     code = prefix & 0xffffL;
561     len = (prefix >> 16) & 0xf;
562     return ((code || len > 10) ? UNCOMP_INVALID : -1);
563 }
564 
565 #define	BASESTATE(b)	((unsigned char) ((b) & 0x7))
566 
567 void
build_null_mode_tables()568 build_null_mode_tables()
569 {
570     short prefix;
571 
572     /*
573      * Note: the first eight entries correspond to
574      * a null prefix and starting bit numbers 0-7.
575      */
576     null_mode_prefix_count = 8;
577     for (prefix = 0; prefix < null_mode_prefix_count; prefix++) {
578 	short byte;
579 	for (byte = 0; byte < 256; byte++) {
580 	    short firstbit;
581 	    short bit;
582 	    long curprefix;
583 	    char found_code = FALSE;
584 
585 	    if (prefix < 8) {
586 		curprefix = 0L;
587 		firstbit = prefix;
588 	    } else {
589 		curprefix = null_mode_prefix[prefix];
590 		firstbit = 0;
591 	    }
592 	    for (bit = firstbit; bit < 8 && !found_code; bit++) {
593 		short mode;
594 
595 		if (bit_mask[bit] & byte)
596 		    curprefix = append_1(curprefix);
597 		else
598 		    curprefix = append_0(curprefix);
599 		switch (mode = null_mode_type(curprefix)) {
600 		case MODE_PASS:
601 		case MODE_HORIZ:
602 		case MODE_VERT_V0:
603 		case MODE_VERT_VR1:
604 		case MODE_VERT_VR2:
605 		case MODE_VERT_VR3:
606 		case MODE_VERT_VL1:
607 		case MODE_VERT_VL2:
608 		case MODE_VERT_VL3:
609 		case MODE_UNCOMP:
610 		case MODE_ERROR:
611 		case MODE_ERROR_1:
612 		    /*
613 		     * NOTE: if the bit number is 8, then the table
614 		     * entry will be zero, which indicates a new byte
615 		     * is to be fetched during the decoding process
616 		     */
617 		    found_code = TRUE;
618 		    null_mode[prefix][byte] = (unsigned char) mode;
619 		    null_mode_next_state[prefix][byte] = BASESTATE(bit+1);
620 		    break;
621 		}
622 	    }
623 	    if (!found_code) {
624 		null_mode_next_state[prefix][byte] = (unsigned char)
625 		    find_null_mode_prefix(curprefix);
626 		/*
627 		 * This indicates to the decoder that
628 		 * no valid code has yet been identified.
629 		 */
630 		null_mode[prefix][byte] = MODE_NULL;
631 	    }
632 	}
633     }
634 }
635 
636 void
build_horiz_mode_tables()637 build_horiz_mode_tables()
638 {
639     unsigned short byte;
640     short prefix;
641 
642     /*
643      * The first 8 are for white,
644      * the second 8 are for black,
645      * beginning with bits 0-7.
646      */
647     horiz_mode_prefix_count = 16;
648     for (prefix = 0; prefix < horiz_mode_prefix_count; prefix++)
649 	for (byte = 0; byte < 256; byte++) {
650 	    short bits_digested = 0;
651 	    short bit;
652 	    short firstbit;
653 	    char color;
654 	    unsigned long curprefix;
655 
656 	    if (prefix < 8) {
657 		color = WHITE;
658 		curprefix = 0L;
659 		firstbit = prefix;
660 	    } else if (prefix < 16) {
661 		color = BLACK;
662 		curprefix = 0L;
663 		firstbit = prefix - 8;
664 	    } else {
665 		color = horiz_mode_color[prefix];
666 		curprefix = horiz_mode_prefix[prefix];
667 		firstbit = 0;
668 	    }
669 	    for (bit = firstbit; bit < 8 && !bits_digested; bit++) {
670 		if (bit_mask[bit] & byte)
671 		    curprefix = append_1(curprefix);
672 		else
673 		    curprefix = append_0(curprefix);
674 		/*
675 		 * The following conversion allows for arbitrary strings of
676 		 * zeroes to precede the end-of-line code 0000 0000 0001.
677 		 * It assumes no errors in the data, and is based on
678 		 * the assumption that the code replaced (12 consecutive
679 		 * zeroes) can only be "legally" encountered before the
680 		 * end-of-line code.  This assumption is valid only for
681 		 * a Group 3 image; the combination will never occur
682 		 * in horizontal mode in a proper Group 4 image.
683 		 */
684 		if (curprefix == 0xC0000L)
685 		    curprefix = 0xB0000L;
686 		if (color == WHITE) {
687 		    short runlength = white_run_length(curprefix);
688 
689 		    if (runlength == G3CODE_INVALID) {
690 			horiz_mode[prefix][byte] = (unsigned char) ACT_INVALID;
691 			horiz_mode_next_state[prefix][byte] = (unsigned char) bit;
692 			bits_digested = bit + 1;
693 		    } else if (runlength == G3CODE_EOL) { /* Group 3 only */
694 			horiz_mode[prefix][byte] = (unsigned char) ACT_EOL;
695 			horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
696 			bits_digested = bit + 1;
697 		    } else if (runlength != G3CODE_INCOMP) {
698 			horiz_mode[prefix][byte] = (unsigned char)
699 			    horiz_mode_code_white(runlength);
700 			horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
701 			bits_digested = bit + 1;
702 		    }
703 		} else {		/* color == BLACK */
704 		    short runlength = black_run_length(curprefix);
705 
706 		    if (runlength == G3CODE_INVALID) {
707 			horiz_mode[prefix][byte] = (unsigned char) ACT_INVALID;
708 			horiz_mode_next_state[prefix][byte] = (unsigned char) (bit+8);
709 			bits_digested = bit + 1;
710 		    } else if (runlength == G3CODE_EOL) { /* Group 3 only */
711 			horiz_mode[prefix][byte] = (unsigned char) ACT_EOL;
712 			horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
713 			bits_digested = bit + 1;
714 		    } else if (runlength != G3CODE_INCOMP) {
715 			horiz_mode[prefix][byte] = (unsigned char)
716 			    horiz_mode_code_black(runlength);
717 			horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
718 			bits_digested = bit + 1;
719 		    }
720 		}
721 	    }
722 	    if (!bits_digested) {	/* no codewords after examining byte */
723 		horiz_mode[prefix][byte] = (unsigned char) ACT_INCOMP;
724 		horiz_mode_next_state[prefix][byte] = (unsigned char)
725 		    find_horiz_mode_prefix(curprefix, color);
726 	    }
727 	}
728 }
729 
730 void
build_uncomp_mode_tables()731 build_uncomp_mode_tables()
732 {
733     short prefix;
734 
735     /*
736      * Note: the first eight entries correspond to
737      * a null prefix and starting bit numbers 0-7.
738      */
739     uncomp_mode_prefix_count = 8;
740     for (prefix = 0; prefix < uncomp_mode_prefix_count; prefix++) {
741 	short byte;
742 	for (byte = 0; byte < 256; byte++) {
743 	    short firstbit;
744 	    short bit;
745 	    long curprefix;
746 	    char found_code = FALSE;
747 
748 	    if (prefix < 8) {
749 		curprefix = 0L;
750 		firstbit = prefix;
751 	    } else {
752 		curprefix = uncomp_mode_prefix[prefix];
753 		firstbit = 0;
754 	    }
755 	    for (bit = firstbit; bit < 8 && !found_code; bit++) {
756 		short mode;
757 
758 		if (bit_mask[bit] & byte)
759 		    curprefix = append_1(curprefix);
760 		else
761 		    curprefix = append_0(curprefix);
762 		mode = uncomp_mode_type(curprefix);
763 		if (mode != -1) {
764 		    /*
765 		     * NOTE: if the bit number is 8, then the table
766 		     * entry will be zero, which indicates a new byte
767 		     * is to be fetched during the decoding process
768 		     */
769 		    found_code = TRUE;
770 		    uncomp_mode[prefix][byte] = (unsigned char) mode;
771 		    uncomp_mode_next_state[prefix][byte] = BASESTATE(bit+1);
772 		    break;
773 		}
774 	    }
775 	    if (!found_code) {
776 		uncomp_mode_next_state[prefix][byte] = (unsigned char)
777 		    find_uncomp_mode_prefix(curprefix);
778 		/*
779 		 * This indicates to the decoder that
780 		 * no valid code has yet been identified.
781 		 */
782 		uncomp_mode[prefix][byte] = UNCOMP_INCOMP;
783 	    }
784 	}
785     }
786 }
787