17dd7cddfSDavid du Colombier /* Copyright (C) 1992, 1994, 1998, 1999 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: scfdgen.c,v 1.5 2002/06/16 03:58:14 lpd Exp $ */
187dd7cddfSDavid du Colombier /* Generate the CCITTFaxDecode tables */
197dd7cddfSDavid du Colombier #include "stdio_.h" /* includes std.h */
207dd7cddfSDavid du Colombier #include "scf.h"
217dd7cddfSDavid du Colombier #include "malloc_.h"
227dd7cddfSDavid du Colombier #include "memory_.h"
237dd7cddfSDavid du Colombier
24*593dc095SDavid du Colombier typedef void (*cfd_node_proc) (cfd_node *, cfd_node *, uint, int, int, int);
25*593dc095SDavid du Colombier typedef void (*cfd_enum_proc) (cfd_node_proc, cfd_node *, cfd_node *, int);
26*593dc095SDavid du Colombier private void cfd_build_tree(cfd_node *, cfd_enum_proc, int, FILE *);
27*593dc095SDavid du Colombier private void cfd_enumerate_white(cfd_node_proc, cfd_node *, cfd_node *, int);
28*593dc095SDavid du Colombier private void cfd_enumerate_black(cfd_node_proc, cfd_node *, cfd_node *, int);
29*593dc095SDavid du Colombier private void cfd_enumerate_2d(cfd_node_proc, cfd_node *, cfd_node *, int);
30*593dc095SDavid du Colombier private void cfd_enumerate_uncompressed(cfd_node_proc, cfd_node *, cfd_node *, int);
317dd7cddfSDavid du Colombier
main()327dd7cddfSDavid du Colombier main()
337dd7cddfSDavid du Colombier {
347dd7cddfSDavid du Colombier FILE *out = fopen("scfdtab.c", "w");
357dd7cddfSDavid du Colombier cfd_node area[1 << max(cfd_white_initial_bits, cfd_black_initial_bits)];
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier fputs("/* Copyright (C) 1992, 1993, 1998, 1999 Aladdin Enterprises. All rights reserved. */\n\n", out);
38*593dc095SDavid du Colombier fputs("/* $Id: scfdgen.c,v 1.5 2002/06/16 03:58:14 lpd Exp $ */\n", out);
397dd7cddfSDavid du Colombier fputs("/* Tables for CCITTFaxDecode filter. */\n\n", out);
407dd7cddfSDavid du Colombier fputs("/* This file was generated automatically. It is governed by the same terms */\n", out);
417dd7cddfSDavid du Colombier fputs("/* as the files scfetab.c and scfdgen.c from which it was derived. */\n", out);
427dd7cddfSDavid du Colombier fputs("/* Consult those files for the licensing terms and conditions. */\n\n", out);
437dd7cddfSDavid du Colombier fputs("#include \"std.h\"\n", out);
447dd7cddfSDavid du Colombier fputs("#include \"scommon.h\"\t\t/* for scf.h */\n", out);
457dd7cddfSDavid du Colombier fputs("#include \"scf.h\"\n\n", out);
467dd7cddfSDavid du Colombier fputs("/* White decoding table. */\n", out);
477dd7cddfSDavid du Colombier fputs("const cfd_node cf_white_decode[] = {\n", out);
487dd7cddfSDavid du Colombier cfd_build_tree(area, cfd_enumerate_white, cfd_white_initial_bits, out);
497dd7cddfSDavid du Colombier fputs("\n};\n\n", out);
507dd7cddfSDavid du Colombier fputs("/* Black decoding table. */\n", out);
517dd7cddfSDavid du Colombier fputs("const cfd_node cf_black_decode[] = {\n", out);
527dd7cddfSDavid du Colombier cfd_build_tree(area, cfd_enumerate_black, cfd_black_initial_bits, out);
537dd7cddfSDavid du Colombier fputs("\n};\n\n", out);
547dd7cddfSDavid du Colombier fputs("/* 2-D decoding table. */\n", out);
557dd7cddfSDavid du Colombier fputs("const cfd_node cf_2d_decode[] = {\n", out);
567dd7cddfSDavid du Colombier cfd_build_tree(area, cfd_enumerate_2d, cfd_2d_initial_bits, out);
577dd7cddfSDavid du Colombier fputs("\n};\n\n", out);
587dd7cddfSDavid du Colombier fputs("/* Uncompresssed decoding table. */\n", out);
597dd7cddfSDavid du Colombier fputs("const cfd_node cf_uncompressed_decode[] = {\n", out);
607dd7cddfSDavid du Colombier cfd_build_tree(area, cfd_enumerate_uncompressed, cfd_uncompressed_initial_bits, out);
617dd7cddfSDavid du Colombier fputs("\n};\n\n", out);
627dd7cddfSDavid du Colombier fputs("/* Dummy executable code to pacify compilers. */\n", out);
63*593dc095SDavid du Colombier fputs("void scfdtab_dummy(void);\n", out);
64*593dc095SDavid du Colombier fputs("void\nscfdtab_dummy(void)\n{\n}\n", out);
657dd7cddfSDavid du Colombier fclose(out);
667dd7cddfSDavid du Colombier return 0;
677dd7cddfSDavid du Colombier }
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier /* Initialize first-level leaves, count second-level nodes. */
707dd7cddfSDavid du Colombier private void
cfd_count_nodes(cfd_node * tree,cfd_node * ignore_extn,uint code,int code_length,int run_length,int initial_bits)717dd7cddfSDavid du Colombier cfd_count_nodes(cfd_node * tree, cfd_node * ignore_extn,
727dd7cddfSDavid du Colombier uint code, int code_length, int run_length, int initial_bits)
737dd7cddfSDavid du Colombier {
747dd7cddfSDavid du Colombier if (code_length <= initial_bits) {
757dd7cddfSDavid du Colombier /* Initialize one or more first-level leaves. */
767dd7cddfSDavid du Colombier int sh = initial_bits - code_length;
777dd7cddfSDavid du Colombier cfd_node *np = &tree[code << sh];
787dd7cddfSDavid du Colombier int i;
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier for (i = 1 << sh; i > 0; i--, np++)
817dd7cddfSDavid du Colombier np->run_length = run_length,
827dd7cddfSDavid du Colombier np->code_length = code_length;
837dd7cddfSDavid du Colombier } else {
847dd7cddfSDavid du Colombier /* Note the need for a second level. */
857dd7cddfSDavid du Colombier cfd_node *np = &tree[code >> (code_length - initial_bits)];
867dd7cddfSDavid du Colombier
877dd7cddfSDavid du Colombier np->code_length = max(np->code_length, code_length);
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier /* Initialize second-level nodes. */
927dd7cddfSDavid du Colombier private void
cfd_init2_nodes(cfd_node * tree,cfd_node * extn,uint code,int code_length,int run_length,int initial_bits)937dd7cddfSDavid du Colombier cfd_init2_nodes(cfd_node * tree, cfd_node * extn,
947dd7cddfSDavid du Colombier uint code, int code_length, int run_length, int initial_bits)
957dd7cddfSDavid du Colombier {
967dd7cddfSDavid du Colombier int xbits = code_length - initial_bits;
977dd7cddfSDavid du Colombier int xrep;
987dd7cddfSDavid du Colombier cfd_node *np1, *np2;
997dd7cddfSDavid du Colombier int i;
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier if (xbits <= 0)
1027dd7cddfSDavid du Colombier return;
1037dd7cddfSDavid du Colombier np1 = &tree[code >> xbits];
1047dd7cddfSDavid du Colombier np2 = &extn[np1->run_length - (1 << initial_bits)];
1057dd7cddfSDavid du Colombier xrep = np1->code_length - code_length;
1067dd7cddfSDavid du Colombier i = 1 << xrep;
1077dd7cddfSDavid du Colombier np2 += (code & ((1 << xbits) - 1)) * i;
1087dd7cddfSDavid du Colombier for (; i > 0; i--, np2++)
1097dd7cddfSDavid du Colombier np2->run_length = run_length,
1107dd7cddfSDavid du Colombier np2->code_length = xbits;
1117dd7cddfSDavid du Colombier }
1127dd7cddfSDavid du Colombier
1137dd7cddfSDavid du Colombier /* Enumerate all the relevant white or black codes. */
1147dd7cddfSDavid du Colombier private void
cfd_enumerate_codes(cfd_node_proc proc,cfd_node * tree,cfd_node * extn,int initial_bits,const cfe_run * tt,const cfe_run * mut)1157dd7cddfSDavid du Colombier cfd_enumerate_codes(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
1167dd7cddfSDavid du Colombier int initial_bits, const cfe_run * tt, const cfe_run * mut)
1177dd7cddfSDavid du Colombier {
1187dd7cddfSDavid du Colombier int i;
1197dd7cddfSDavid du Colombier const cfe_run *ep;
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier for (i = 0, ep = tt; i < 64; i++, ep++)
1227dd7cddfSDavid du Colombier (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
1237dd7cddfSDavid du Colombier for (i = 1, ep = mut + 1; i < 41; i++, ep++)
1247dd7cddfSDavid du Colombier (*proc) (tree, extn, ep->code, ep->code_length, i << 6, initial_bits);
1257dd7cddfSDavid du Colombier (*proc) (tree, extn,
1267dd7cddfSDavid du Colombier cf1_run_uncompressed.code, cf1_run_uncompressed.code_length,
1277dd7cddfSDavid du Colombier run_uncompressed, initial_bits);
1287dd7cddfSDavid du Colombier (*proc) (tree, extn,
1297dd7cddfSDavid du Colombier 0, run_eol_code_length - 1,
1307dd7cddfSDavid du Colombier run_zeros, initial_bits);
1317dd7cddfSDavid du Colombier }
1327dd7cddfSDavid du Colombier private void
cfd_enumerate_white(cfd_node_proc proc,cfd_node * tree,cfd_node * extn,int initial_bits)1337dd7cddfSDavid du Colombier cfd_enumerate_white(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
1347dd7cddfSDavid du Colombier int initial_bits)
1357dd7cddfSDavid du Colombier {
1367dd7cddfSDavid du Colombier cfd_enumerate_codes(proc, tree, extn, initial_bits,
1377dd7cddfSDavid du Colombier cf_white_runs.termination, cf_white_runs.make_up);
1387dd7cddfSDavid du Colombier }
1397dd7cddfSDavid du Colombier private void
cfd_enumerate_black(cfd_node_proc proc,cfd_node * tree,cfd_node * extn,int initial_bits)1407dd7cddfSDavid du Colombier cfd_enumerate_black(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
1417dd7cddfSDavid du Colombier int initial_bits)
1427dd7cddfSDavid du Colombier {
1437dd7cddfSDavid du Colombier cfd_enumerate_codes(proc, tree, extn, initial_bits,
1447dd7cddfSDavid du Colombier cf_black_runs.termination, cf_black_runs.make_up);
1457dd7cddfSDavid du Colombier }
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier /* Enumerate the 2-D codes. */
1487dd7cddfSDavid du Colombier private void
cfd_enumerate_2d(cfd_node_proc proc,cfd_node * tree,cfd_node * extn,int initial_bits)1497dd7cddfSDavid du Colombier cfd_enumerate_2d(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
1507dd7cddfSDavid du Colombier int initial_bits)
1517dd7cddfSDavid du Colombier {
1527dd7cddfSDavid du Colombier int i;
1537dd7cddfSDavid du Colombier const cfe_run *ep;
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier (*proc) (tree, extn, cf2_run_pass.code, cf2_run_pass.code_length,
1567dd7cddfSDavid du Colombier run2_pass, initial_bits);
1577dd7cddfSDavid du Colombier (*proc) (tree, extn, cf2_run_horizontal.code, cf2_run_horizontal.code_length,
1587dd7cddfSDavid du Colombier run2_horizontal, initial_bits);
1597dd7cddfSDavid du Colombier for (i = 0; i < countof(cf2_run_vertical); i++) {
1607dd7cddfSDavid du Colombier ep = &cf2_run_vertical[i];
1617dd7cddfSDavid du Colombier (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier (*proc) (tree, extn, cf2_run_uncompressed.code, cf2_run_uncompressed.code_length,
1647dd7cddfSDavid du Colombier run_uncompressed, initial_bits);
1657dd7cddfSDavid du Colombier (*proc) (tree, extn, 0, run_eol_code_length - 1, run_zeros, initial_bits);
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier /* Enumerate the uncompressed codes. */
1697dd7cddfSDavid du Colombier private void
cfd_enumerate_uncompressed(cfd_node_proc proc,cfd_node * tree,cfd_node * extn,int initial_bits)1707dd7cddfSDavid du Colombier cfd_enumerate_uncompressed(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
1717dd7cddfSDavid du Colombier int initial_bits)
1727dd7cddfSDavid du Colombier {
1737dd7cddfSDavid du Colombier int i;
1747dd7cddfSDavid du Colombier const cfe_run *ep;
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier for (i = 0; i < countof(cf_uncompressed); i++) {
1777dd7cddfSDavid du Colombier ep = &cf_uncompressed[i];
1787dd7cddfSDavid du Colombier (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
1797dd7cddfSDavid du Colombier }
1807dd7cddfSDavid du Colombier for (i = 0; i < countof(cf_uncompressed_exit); i++) {
1817dd7cddfSDavid du Colombier ep = &cf_uncompressed_exit[i];
1827dd7cddfSDavid du Colombier (*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
1837dd7cddfSDavid du Colombier }
1847dd7cddfSDavid du Colombier }
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier /* Build and write out the table. */
1877dd7cddfSDavid du Colombier private void
cfd_build_tree(cfd_node * tree,cfd_enum_proc enum_proc,int initial_bits,FILE * f)1887dd7cddfSDavid du Colombier cfd_build_tree(cfd_node * tree, cfd_enum_proc enum_proc, int initial_bits,
1897dd7cddfSDavid du Colombier FILE * f)
1907dd7cddfSDavid du Colombier {
1917dd7cddfSDavid du Colombier cfd_node *np;
1927dd7cddfSDavid du Colombier const char *prev = "";
1937dd7cddfSDavid du Colombier int i, next;
1947dd7cddfSDavid du Colombier cfd_node *extn;
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier memset(tree, 0, sizeof(cfd_node) << initial_bits);
1977dd7cddfSDavid du Colombier /* Construct and write the first level of the tree. */
1987dd7cddfSDavid du Colombier (*enum_proc) (cfd_count_nodes, tree, (cfd_node *) 0, initial_bits);
1997dd7cddfSDavid du Colombier next = 0;
2007dd7cddfSDavid du Colombier for (i = 0, np = tree; i < 1 << initial_bits; i++, np++) {
2017dd7cddfSDavid du Colombier if (np->code_length > initial_bits) { /* second level needed */
2027dd7cddfSDavid du Colombier np->run_length = next + (1 << initial_bits);
2037dd7cddfSDavid du Colombier next += 1 << (np->code_length - initial_bits);
2047dd7cddfSDavid du Colombier }
2057dd7cddfSDavid du Colombier fprintf(f, "%s\t{ %d, %d }", prev, np->run_length, np->code_length);
2067dd7cddfSDavid du Colombier prev = ",\n";
2077dd7cddfSDavid du Colombier }
2087dd7cddfSDavid du Colombier /* Construct and write the second level. */
2097dd7cddfSDavid du Colombier extn = (cfd_node *) malloc(sizeof(cfd_node) * next);
2107dd7cddfSDavid du Colombier for (i = 0, np = extn; i < next; i++, np++)
2117dd7cddfSDavid du Colombier np->run_length = run_error,
2127dd7cddfSDavid du Colombier np->code_length = 0;
2137dd7cddfSDavid du Colombier (*enum_proc) (cfd_init2_nodes, tree, extn, initial_bits);
2147dd7cddfSDavid du Colombier for (i = 0, np = extn; i < next; i++, np++)
2157dd7cddfSDavid du Colombier fprintf(f, ",\n\t{ %d, %d }", np->run_length, np->code_length);
2167dd7cddfSDavid du Colombier free((char *)extn);
2177dd7cddfSDavid du Colombier }
218