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