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