1 /* Copyright (C) 1992, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved. 2 3 This file is part of AFPL Ghostscript. 4 5 AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6 distributor accepts any responsibility for the consequences of using it, or 7 for whether it serves any particular purpose or works at all, unless he or 8 she says so in writing. Refer to the Aladdin Free Public License (the 9 "License") for full details. 10 11 Every copy of AFPL Ghostscript must include a copy of the License, normally 12 in a plain ASCII text file named PUBLIC. The License grants you the right 13 to copy, modify and redistribute AFPL Ghostscript, but only under certain 14 conditions described in the License. Among other things, the License 15 requires that the copyright notice and this notice be preserved on all 16 copies. 17 */ 18 19 /*$Id: scfdgen.c,v 1.2 2000/09/19 19:00:48 lpd Exp $ */ 20 /* Generate the CCITTFaxDecode tables */ 21 #include "stdio_.h" /* includes std.h */ 22 #include "scf.h" 23 #include "malloc_.h" 24 #include "memory_.h" 25 26 typedef void (*cfd_node_proc) (P6(cfd_node *, cfd_node *, 27 uint, int, int, int)); 28 typedef void (*cfd_enum_proc) (P4(cfd_node_proc, 29 cfd_node *, cfd_node *, int)); 30 private void cfd_build_tree(P4(cfd_node *, cfd_enum_proc, int, FILE *)); 31 private void cfd_enumerate_white(P4(cfd_node_proc, 32 cfd_node *, cfd_node *, int)); 33 private void cfd_enumerate_black(P4(cfd_node_proc, 34 cfd_node *, cfd_node *, int)); 35 private void cfd_enumerate_2d(P4(cfd_node_proc, 36 cfd_node *, cfd_node *, int)); 37 private void cfd_enumerate_uncompressed(P4(cfd_node_proc, 38 cfd_node *, cfd_node *, int)); 39 40 main() 41 { 42 FILE *out = fopen("scfdtab.c", "w"); 43 cfd_node area[1 << max(cfd_white_initial_bits, cfd_black_initial_bits)]; 44 45 fputs("/* Copyright (C) 1992, 1993, 1998, 1999 Aladdin Enterprises. All rights reserved. */\n\n", out); 46 fputs("/* $Id: scfdgen.c,v 1.2 2000/09/19 19:00:48 lpd Exp $ */\n", out); 47 fputs("/* Tables for CCITTFaxDecode filter. */\n\n", out); 48 fputs("/* This file was generated automatically. It is governed by the same terms */\n", out); 49 fputs("/* as the files scfetab.c and scfdgen.c from which it was derived. */\n", out); 50 fputs("/* Consult those files for the licensing terms and conditions. */\n\n", out); 51 fputs("#include \"std.h\"\n", out); 52 fputs("#include \"scommon.h\"\t\t/* for scf.h */\n", out); 53 fputs("#include \"scf.h\"\n\n", out); 54 fputs("/* White decoding table. */\n", out); 55 fputs("const cfd_node cf_white_decode[] = {\n", out); 56 cfd_build_tree(area, cfd_enumerate_white, cfd_white_initial_bits, out); 57 fputs("\n};\n\n", out); 58 fputs("/* Black decoding table. */\n", out); 59 fputs("const cfd_node cf_black_decode[] = {\n", out); 60 cfd_build_tree(area, cfd_enumerate_black, cfd_black_initial_bits, out); 61 fputs("\n};\n\n", out); 62 fputs("/* 2-D decoding table. */\n", out); 63 fputs("const cfd_node cf_2d_decode[] = {\n", out); 64 cfd_build_tree(area, cfd_enumerate_2d, cfd_2d_initial_bits, out); 65 fputs("\n};\n\n", out); 66 fputs("/* Uncompresssed decoding table. */\n", out); 67 fputs("const cfd_node cf_uncompressed_decode[] = {\n", out); 68 cfd_build_tree(area, cfd_enumerate_uncompressed, cfd_uncompressed_initial_bits, out); 69 fputs("\n};\n\n", out); 70 fputs("/* Dummy executable code to pacify compilers. */\n", out); 71 fputs("void scfdtab_dummy(P0());\n", out); 72 fputs("void\nscfdtab_dummy()\n{\n}\n", out); 73 fclose(out); 74 return 0; 75 } 76 77 /* Initialize first-level leaves, count second-level nodes. */ 78 private void 79 cfd_count_nodes(cfd_node * tree, cfd_node * ignore_extn, 80 uint code, int code_length, int run_length, int initial_bits) 81 { 82 if (code_length <= initial_bits) { 83 /* Initialize one or more first-level leaves. */ 84 int sh = initial_bits - code_length; 85 cfd_node *np = &tree[code << sh]; 86 int i; 87 88 for (i = 1 << sh; i > 0; i--, np++) 89 np->run_length = run_length, 90 np->code_length = code_length; 91 } else { 92 /* Note the need for a second level. */ 93 cfd_node *np = &tree[code >> (code_length - initial_bits)]; 94 95 np->code_length = max(np->code_length, code_length); 96 } 97 } 98 99 /* Initialize second-level nodes. */ 100 private void 101 cfd_init2_nodes(cfd_node * tree, cfd_node * extn, 102 uint code, int code_length, int run_length, int initial_bits) 103 { 104 int xbits = code_length - initial_bits; 105 int xrep; 106 cfd_node *np1, *np2; 107 int i; 108 109 if (xbits <= 0) 110 return; 111 np1 = &tree[code >> xbits]; 112 np2 = &extn[np1->run_length - (1 << initial_bits)]; 113 xrep = np1->code_length - code_length; 114 i = 1 << xrep; 115 np2 += (code & ((1 << xbits) - 1)) * i; 116 for (; i > 0; i--, np2++) 117 np2->run_length = run_length, 118 np2->code_length = xbits; 119 } 120 121 /* Enumerate all the relevant white or black codes. */ 122 private void 123 cfd_enumerate_codes(cfd_node_proc proc, cfd_node * tree, cfd_node * extn, 124 int initial_bits, const cfe_run * tt, const cfe_run * mut) 125 { 126 int i; 127 const cfe_run *ep; 128 129 for (i = 0, ep = tt; i < 64; i++, ep++) 130 (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits); 131 for (i = 1, ep = mut + 1; i < 41; i++, ep++) 132 (*proc) (tree, extn, ep->code, ep->code_length, i << 6, initial_bits); 133 (*proc) (tree, extn, 134 cf1_run_uncompressed.code, cf1_run_uncompressed.code_length, 135 run_uncompressed, initial_bits); 136 (*proc) (tree, extn, 137 0, run_eol_code_length - 1, 138 run_zeros, initial_bits); 139 } 140 private void 141 cfd_enumerate_white(cfd_node_proc proc, cfd_node * tree, cfd_node * extn, 142 int initial_bits) 143 { 144 cfd_enumerate_codes(proc, tree, extn, initial_bits, 145 cf_white_runs.termination, cf_white_runs.make_up); 146 } 147 private void 148 cfd_enumerate_black(cfd_node_proc proc, cfd_node * tree, cfd_node * extn, 149 int initial_bits) 150 { 151 cfd_enumerate_codes(proc, tree, extn, initial_bits, 152 cf_black_runs.termination, cf_black_runs.make_up); 153 } 154 155 /* Enumerate the 2-D codes. */ 156 private void 157 cfd_enumerate_2d(cfd_node_proc proc, cfd_node * tree, cfd_node * extn, 158 int initial_bits) 159 { 160 int i; 161 const cfe_run *ep; 162 163 (*proc) (tree, extn, cf2_run_pass.code, cf2_run_pass.code_length, 164 run2_pass, initial_bits); 165 (*proc) (tree, extn, cf2_run_horizontal.code, cf2_run_horizontal.code_length, 166 run2_horizontal, initial_bits); 167 for (i = 0; i < countof(cf2_run_vertical); i++) { 168 ep = &cf2_run_vertical[i]; 169 (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits); 170 } 171 (*proc) (tree, extn, cf2_run_uncompressed.code, cf2_run_uncompressed.code_length, 172 run_uncompressed, initial_bits); 173 (*proc) (tree, extn, 0, run_eol_code_length - 1, run_zeros, initial_bits); 174 } 175 176 /* Enumerate the uncompressed codes. */ 177 private void 178 cfd_enumerate_uncompressed(cfd_node_proc proc, cfd_node * tree, cfd_node * extn, 179 int initial_bits) 180 { 181 int i; 182 const cfe_run *ep; 183 184 for (i = 0; i < countof(cf_uncompressed); i++) { 185 ep = &cf_uncompressed[i]; 186 (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits); 187 } 188 for (i = 0; i < countof(cf_uncompressed_exit); i++) { 189 ep = &cf_uncompressed_exit[i]; 190 (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits); 191 } 192 } 193 194 /* Build and write out the table. */ 195 private void 196 cfd_build_tree(cfd_node * tree, cfd_enum_proc enum_proc, int initial_bits, 197 FILE * f) 198 { 199 cfd_node *np; 200 const char *prev = ""; 201 int i, next; 202 cfd_node *extn; 203 204 memset(tree, 0, sizeof(cfd_node) << initial_bits); 205 /* Construct and write the first level of the tree. */ 206 (*enum_proc) (cfd_count_nodes, tree, (cfd_node *) 0, initial_bits); 207 next = 0; 208 for (i = 0, np = tree; i < 1 << initial_bits; i++, np++) { 209 if (np->code_length > initial_bits) { /* second level needed */ 210 np->run_length = next + (1 << initial_bits); 211 next += 1 << (np->code_length - initial_bits); 212 } 213 fprintf(f, "%s\t{ %d, %d }", prev, np->run_length, np->code_length); 214 prev = ",\n"; 215 } 216 /* Construct and write the second level. */ 217 extn = (cfd_node *) malloc(sizeof(cfd_node) * next); 218 for (i = 0, np = extn; i < next; i++, np++) 219 np->run_length = run_error, 220 np->code_length = 0; 221 (*enum_proc) (cfd_init2_nodes, tree, extn, initial_bits); 222 for (i = 0, np = extn; i < next; i++, np++) 223 fprintf(f, ",\n\t{ %d, %d }", np->run_length, np->code_length); 224 free((char *)extn); 225 } 226