Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1994, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: scfdgen.c,v 1.5 2002/06/16 03:58:14 lpd Exp $ */
18
/* Generate the CCITTFaxDecode tables */
19
#include "stdio_.h"		/* includes std.h */
20
#include "scf.h"
21
#include "malloc_.h"
22
#include "memory_.h"
23
 
24
typedef void (*cfd_node_proc) (cfd_node *, cfd_node *, uint, int, int, int);
25
typedef void (*cfd_enum_proc) (cfd_node_proc, cfd_node *, cfd_node *, int);
26
private void cfd_build_tree(cfd_node *, cfd_enum_proc, int, FILE *);
27
private void cfd_enumerate_white(cfd_node_proc, cfd_node *, cfd_node *, int);
28
private void cfd_enumerate_black(cfd_node_proc, cfd_node *, cfd_node *, int);
29
private void cfd_enumerate_2d(cfd_node_proc, cfd_node *, cfd_node *, int);
30
private void cfd_enumerate_uncompressed(cfd_node_proc, cfd_node *, cfd_node *, int);
31
 
32
main()
33
{
34
    FILE *out = fopen("scfdtab.c", "w");
35
    cfd_node area[1 << max(cfd_white_initial_bits, cfd_black_initial_bits)];
36
 
37
    fputs("/* Copyright (C) 1992, 1993, 1998, 1999 Aladdin Enterprises.  All rights reserved. */\n\n", out);
38
    fputs("/* $Id: scfdgen.c,v 1.5 2002/06/16 03:58:14 lpd Exp $ */\n", out);
39
    fputs("/* Tables for CCITTFaxDecode filter. */\n\n", out);
40
    fputs("/* This file was generated automatically.  It is governed by the same terms */\n", out);
41
    fputs("/* as the files scfetab.c and scfdgen.c from which it was derived. */\n", out);
42
    fputs("/* Consult those files for the licensing terms and conditions. */\n\n", out);
43
    fputs("#include \"std.h\"\n", out);
44
    fputs("#include \"scommon.h\"\t\t/* for scf.h */\n", out);
45
    fputs("#include \"scf.h\"\n\n", out);
46
    fputs("/* White decoding table. */\n", out);
47
    fputs("const cfd_node cf_white_decode[] = {\n", out);
48
    cfd_build_tree(area, cfd_enumerate_white, cfd_white_initial_bits, out);
49
    fputs("\n};\n\n", out);
50
    fputs("/* Black decoding table. */\n", out);
51
    fputs("const cfd_node cf_black_decode[] = {\n", out);
52
    cfd_build_tree(area, cfd_enumerate_black, cfd_black_initial_bits, out);
53
    fputs("\n};\n\n", out);
54
    fputs("/* 2-D decoding table. */\n", out);
55
    fputs("const cfd_node cf_2d_decode[] = {\n", out);
56
    cfd_build_tree(area, cfd_enumerate_2d, cfd_2d_initial_bits, out);
57
    fputs("\n};\n\n", out);
58
    fputs("/* Uncompresssed decoding table. */\n", out);
59
    fputs("const cfd_node cf_uncompressed_decode[] = {\n", out);
60
    cfd_build_tree(area, cfd_enumerate_uncompressed, cfd_uncompressed_initial_bits, out);
61
    fputs("\n};\n\n", out);
62
    fputs("/* Dummy executable code to pacify compilers. */\n", out);
63
    fputs("void scfdtab_dummy(void);\n", out);
64
    fputs("void\nscfdtab_dummy(void)\n{\n}\n", out);
65
    fclose(out);
66
    return 0;
67
}
68
 
69
/* Initialize first-level leaves, count second-level nodes. */
70
private void
71
cfd_count_nodes(cfd_node * tree, cfd_node * ignore_extn,
72
		uint code, int code_length, int run_length, int initial_bits)
73
{
74
    if (code_length <= initial_bits) {
75
	/* Initialize one or more first-level leaves. */
76
	int sh = initial_bits - code_length;
77
	cfd_node *np = &tree[code << sh];
78
	int i;
79
 
80
	for (i = 1 << sh; i > 0; i--, np++)
81
	    np->run_length = run_length,
82
		np->code_length = code_length;
83
    } else {
84
	/* Note the need for a second level. */
85
	cfd_node *np = &tree[code >> (code_length - initial_bits)];
86
 
87
	np->code_length = max(np->code_length, code_length);
88
    }
89
}
90
 
91
/* Initialize second-level nodes. */
92
private void
93
cfd_init2_nodes(cfd_node * tree, cfd_node * extn,
94
		uint code, int code_length, int run_length, int initial_bits)
95
{
96
    int xbits = code_length - initial_bits;
97
    int xrep;
98
    cfd_node *np1, *np2;
99
    int i;
100
 
101
    if (xbits <= 0)
102
	return;
103
    np1 = &tree[code >> xbits];
104
    np2 = &extn[np1->run_length - (1 << initial_bits)];
105
    xrep = np1->code_length - code_length;
106
    i = 1 << xrep;
107
    np2 += (code & ((1 << xbits) - 1)) * i;
108
    for (; i > 0; i--, np2++)
109
	np2->run_length = run_length,
110
	    np2->code_length = xbits;
111
}
112
 
113
/* Enumerate all the relevant white or black codes. */
114
private void
115
cfd_enumerate_codes(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
116
		  int initial_bits, const cfe_run * tt, const cfe_run * mut)
117
{
118
    int i;
119
    const cfe_run *ep;
120
 
121
    for (i = 0, ep = tt; i < 64; i++, ep++)
122
	(*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
123
    for (i = 1, ep = mut + 1; i < 41; i++, ep++)
124
	(*proc) (tree, extn, ep->code, ep->code_length, i << 6, initial_bits);
125
    (*proc) (tree, extn,
126
	     cf1_run_uncompressed.code, cf1_run_uncompressed.code_length,
127
	     run_uncompressed, initial_bits);
128
    (*proc) (tree, extn,
129
	     0, run_eol_code_length - 1,
130
	     run_zeros, initial_bits);
131
}
132
private void
133
cfd_enumerate_white(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
134
		    int initial_bits)
135
{
136
    cfd_enumerate_codes(proc, tree, extn, initial_bits,
137
			cf_white_runs.termination, cf_white_runs.make_up);
138
}
139
private void
140
cfd_enumerate_black(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
141
		    int initial_bits)
142
{
143
    cfd_enumerate_codes(proc, tree, extn, initial_bits,
144
			cf_black_runs.termination, cf_black_runs.make_up);
145
}
146
 
147
/* Enumerate the 2-D codes. */
148
private void
149
cfd_enumerate_2d(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
150
		 int initial_bits)
151
{
152
    int i;
153
    const cfe_run *ep;
154
 
155
    (*proc) (tree, extn, cf2_run_pass.code, cf2_run_pass.code_length,
156
	     run2_pass, initial_bits);
157
    (*proc) (tree, extn, cf2_run_horizontal.code, cf2_run_horizontal.code_length,
158
	     run2_horizontal, initial_bits);
159
    for (i = 0; i < countof(cf2_run_vertical); i++) {
160
	ep = &cf2_run_vertical[i];
161
	(*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
162
    }
163
    (*proc) (tree, extn, cf2_run_uncompressed.code, cf2_run_uncompressed.code_length,
164
	     run_uncompressed, initial_bits);
165
    (*proc) (tree, extn, 0, run_eol_code_length - 1, run_zeros, initial_bits);
166
}
167
 
168
/* Enumerate the uncompressed codes. */
169
private void
170
cfd_enumerate_uncompressed(cfd_node_proc proc, cfd_node * tree, cfd_node * extn,
171
			   int initial_bits)
172
{
173
    int i;
174
    const cfe_run *ep;
175
 
176
    for (i = 0; i < countof(cf_uncompressed); i++) {
177
	ep = &cf_uncompressed[i];
178
	(*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
179
    }
180
    for (i = 0; i < countof(cf_uncompressed_exit); i++) {
181
	ep = &cf_uncompressed_exit[i];
182
	(*proc) (tree, extn, ep->code, ep->code_length, i, initial_bits);
183
    }
184
}
185
 
186
/* Build and write out the table. */
187
private void
188
cfd_build_tree(cfd_node * tree, cfd_enum_proc enum_proc, int initial_bits,
189
	       FILE * f)
190
{
191
    cfd_node *np;
192
    const char *prev = "";
193
    int i, next;
194
    cfd_node *extn;
195
 
196
    memset(tree, 0, sizeof(cfd_node) << initial_bits);
197
    /* Construct and write the first level of the tree. */
198
    (*enum_proc) (cfd_count_nodes, tree, (cfd_node *) 0, initial_bits);
199
    next = 0;
200
    for (i = 0, np = tree; i < 1 << initial_bits; i++, np++) {
201
	if (np->code_length > initial_bits) {	/* second level needed */
202
	    np->run_length = next + (1 << initial_bits);
203
	    next += 1 << (np->code_length - initial_bits);
204
	}
205
	fprintf(f, "%s\t{ %d, %d }", prev, np->run_length, np->code_length);
206
	prev = ",\n";
207
    }
208
    /* Construct and write the second level. */
209
    extn = (cfd_node *) malloc(sizeof(cfd_node) * next);
210
    for (i = 0, np = extn; i < next; i++, np++)
211
	np->run_length = run_error,
212
	    np->code_length = 0;
213
    (*enum_proc) (cfd_init2_nodes, tree, extn, initial_bits);
214
    for (i = 0, np = extn; i < next; i++, np++)
215
	fprintf(f, ",\n\t{ %d, %d }", np->run_length, np->code_length);
216
    free((char *)extn);
217
}