Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/gs/src/genht.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 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: genht.c,v 1.5 2005/10/04 06:30:02 ray Exp $ */
18
/* Generate C code for compiling halftones into ROM. */
19
#include "malloc_.h"
20
#include "stdio_.h"
21
#include "string_.h"
22
#include "gscdefs.h"
23
#include "gsmemory.h"
24
#include "gxbitmap.h"
25
#include "gxhttile.h"
26
#include "gxtmap.h"
27
#include "gxdht.h"
28
#include "gxdhtres.h"
29
#include "strimpl.h"
30
#include "sstring.h"
31
 
32
/*
33
 * This program translates PostScript halftone resources into C data
34
 * structures that can then be compiled into executables and put in shared,
35
 * read-only memory.  The syntax of the resource file is a subset of
36
 * PostScript, tightly constrained so that it can be parsed easily.  Blank
37
 * lines and PostScript comments are ignored, but otherwise each halftone
38
 * in the file (there may be more than one) must follow this format,
39
 * where ... indicates arbitrary text:
40
    (optionally:)
41
	/halftone_name ...
42
	/HalftoneType 5
43
    (zero or more times:)
44
	/halftone_name ...
45
	/HalftoneType 3
46
	/Width xxx
47
	/Height xxx
48
	/Thresholds ...
49
	--hex data terminated by a >--
50
	(zero or more times:)
51
	    /halftone_name 1 index
52
    (finally)
53
    ... defineresource
54
 * Lines that don't follow the above syntax may appear anywhere in the file
55
 * except in the middle of the hex data.  Width and Height must precede
56
 * Thresholds, but otherwise the 4 parameters may appear in any order.
57
 * White space at the beginning or end of a line is ignored, and any
58
 * amount of white space may separate the parameter name from its value.
59
 *
60
 * We envision that this format will eventually be extended to cover
61
 * HalftoneType 16 halftones with a single rectangle, allowing 16-bit
62
 * threshold values.
63
 */
64
 
65
/* Read a source file into memory. */
66
private char *
67
read_file(FILE *in, char *cname)
68
{
69
    int len, nread;
70
    char *cont;
71
 
72
    fseek(in, 0L, 2 /*SEEK_END*/);
73
    len = ftell(in);
74
    cont = malloc(len + 1);
75
    if (cont == 0) {
76
	fprintf(stderr, "Can't allocate %d bytes to read %s.\n",
77
		len + 1, cname);
78
	return 0;
79
    }
80
    rewind(in);
81
    nread = fread(cont, 1, len, in);
82
    cont[nread] = 0;
83
    return cont;
84
}
85
 
86
/* Parse a Halftone resource file into memory. */
87
private bool
88
parse_line(char **pstr, char **pline)
89
{
90
    char *str = *pstr;
91
 
92
top:
93
    while (*str && strchr(" \t\r\n", *str)) /* trim leading space */
94
	++str;
95
    if (*str == 0) {
96
	*pline = 0;
97
	return false;
98
    }
99
    *pline = str;
100
    while (*str && !strchr("\r\n", *str)) /* find EOL */
101
	++str;
102
    while (str > *pline && strchr(" \t", str[-1])) /* trim trailing space */
103
	--str;
104
    *str = 0;
105
    *pstr = str + 1;
106
    return true;
107
}
108
private int
109
parse_halftone(gx_device_halftone_resource_t *phtr, byte **pThresholds,
110
	       char **pprefix, char **pcont)
111
{
112
    char *str;
113
    char *line;
114
    char *rname = 0;
115
    int HalftoneType = -1;
116
    int Width = -1, Height = -1;
117
    byte *Thresholds = 0;
118
    stream_AXD_state ss;
119
 
120
    /* Parse the file. */
121
    for (str = *pcont; parse_line(&str, &line);) {
122
	char *end;
123
	char *prefix;
124
	char terminator;
125
 
126
	if (line[0] == '%')
127
	    continue;
128
	if (strlen(line) >= 14 &&
129
	    !strcmp(line + strlen(line) - 14, "defineresource")
130
	    )
131
	    break;
132
	if (line[0] != '/')
133
	    continue;
134
	if (strlen(line) >= 8 &&
135
	    !strcmp(line + strlen(line) - 8, " 1 index")
136
	    )
137
	    continue;
138
	end = ++line;
139
	while (*end && !strchr(" \t<", *end)) /* find end of name */
140
	    ++end;
141
	terminator = *end;
142
	*end = 0;
143
	if (rname == 0) { /* first name is halftone name */
144
	    rname = malloc(strlen(line) + 1);
145
	    strcpy(rname, line);
146
	    continue;
147
	}
148
	if (terminator == 0)		/* name alone */
149
	    continue;
150
	++end;
151
	if (!strcmp(line, "HalftoneType")) {
152
	    if (sscanf(end, "%d", &HalftoneType) != 1) {
153
		fprintf(stderr, "Invalid HalftoneType syntax: %s\n", line - 1);
154
		return -1;
155
	    }
156
	    switch (HalftoneType) {
157
	    case 3:
158
		break;
159
	    case 5:
160
		if (*pprefix)
161
		    free(*pprefix);
162
		*pprefix = rname;
163
		rname = 0;
164
		break;
165
	    default:
166
		fprintf(stderr, "Invalid HalftoneType: %s\n", end);
167
		return -1;
168
	    }
169
	    continue;
170
	} else if (!strcmp(line, "Width")) {
171
	    if (sscanf(end, "%d", &Width) != 1 ||
172
		Width <= 0 || Width > 0x4000
173
		) {
174
		fprintf(stderr, "Invalid Width: %s\n", end);
175
		return -1;
176
	    }
177
	} else if (!strcmp(line, "Height")) {
178
	    if (sscanf(end, "%d", &Height) != 1 ||
179
		Height <= 0 || Height > 0x4000
180
		) {
181
		fprintf(stderr, "Invalid Height: %s\n", end);
182
		return -1;
183
	    }
184
	} else if (!strcmp(line, "Thresholds")) {
185
	    uint ignore;
186
	    uint num_levels = 256;
187
	    uint num_bits = Width * Height;
188
	    char *eol = end + strlen(end); /* skip rest of line */
189
	    stream_cursor_read r;
190
	    stream_cursor_write w;
191
 
192
	    if (Width < 0 || Height < 0) {
193
		fprintf(stderr, "Width and Height must precede Thresholds.\n");
194
		return -1;
195
	    }
196
	    phtr->num_levels = num_levels;
197
	    phtr->levels =
198
		malloc(num_levels * sizeof(*phtr->levels));
199
	    phtr->bit_data =
200
		malloc(num_bits * sizeof(ushort));
201
	    Thresholds = malloc(num_bits);
202
	    s_AXD_init_inline(&ss);
203
	    r.ptr = (const byte *)eol;
204
	    r.limit = (const byte *)eol + strlen(eol + 1);
205
	    w.ptr = Thresholds - 1;
206
	    w.limit = w.ptr + num_bits;
207
	    s_AXD_template.process((stream_state *)&ss, &r, &w, true);
208
	    str = (char *)r.ptr + 1;
209
	    break;
210
	}
211
    }
212
 
213
    /* Check for successful parsing. */
214
    if (rname == 0)
215
	return 1;		/* end of definitions */
216
    if (HalftoneType < 0)
217
	fprintf(stderr, "HalftoneType not found.\n");
218
    if (Width < 0)
219
	fprintf(stderr, "Width not found.\n");
220
    if (Height < 0)
221
	fprintf(stderr, "Height not found.\n");
222
    if (Thresholds == 0)
223
	fprintf(stderr, "Thresholds not found.\n");
224
    if (rname == 0 || Thresholds == 0)
225
	return -1;
226
    phtr->rname = rname;
227
    phtr->HalftoneType = HalftoneType;
228
    phtr->Width = Width;
229
    phtr->Height = Height;
230
    *pThresholds = Thresholds;
231
    *pcont = str;
232
    return 0;
233
}
234
 
235
/* Write a halftone as a C procedure. */
236
private int
237
write_halftone(FILE *out, gx_device_halftone_resource_t *phtr,
238
	       const char *prefix, int index)
239
{
240
    int num_bits = phtr->Width * phtr->Height;
241
    int i;
242
 
243
    /* Write the initial comment. */
244
    fputs("\n/* ", out);
245
    if (prefix)
246
	fprintf(out, "%s.", prefix);
247
    fprintf(out, "%s */\n", phtr->rname);
248
 
249
    /* Write the levels array. */
250
    fprintf(out, "static const unsigned int levels_%d[] = {", index);
251
    for (i = 0; i < phtr->num_levels; ++i) {
252
	if (i % 10 == 0)
253
	    fputs("\n", out);
254
	fprintf(out, "%5u,", phtr->levels[i]);
255
    }
256
    fputs("\n0};\n", out);
257
 
258
    /* Write the bit_data array. */
259
    fprintf(out, "static const unsigned short bit_data_%d[] = {", index);
260
    for (i = 0; i < num_bits; ++i) {
261
	if (i % 10 == 0)
262
	    fputs("\n", out);
263
	fprintf(out, "%5u,", ((const ushort *)phtr->bit_data)[i]);
264
    }
265
    fputs("\n0};\n", out);
266
 
267
    /* Write the top-level structure. */
268
    fprintf(out, "static const gx_device_halftone_resource_t res_%d = {\n    \"%s\", %d, %d, %d, %d, levels_%d, bit_data_%d, %u\n};\n",
269
	    index, phtr->rname, phtr->HalftoneType, phtr->Width, phtr->Height,
270
	    phtr->num_levels, index, index,
271
	    ht_order_procs_short.bit_data_elt_size);
272
 
273
    return 0;
274
}
275
 
276
/* Main program */
277
int
278
main(int argc, char *argv[])
279
{
280
    char *iname;
281
    FILE *in;
282
    char *oname;
283
    FILE *out;
284
    int code;
285
    char *cont;
286
    char *line;
287
    gx_device_halftone_resource_t res;
288
    char *prefix = 0;
289
    byte *Thresholds;
290
    gx_ht_order order;
291
    int index, i;
292
 
293
    if (argc != 3) {
294
	fprintf(stderr, "Usage: genht ht_res.ps ht_data.c\n");
295
	exit(1);
296
    }
297
    iname = argv[1];
298
    oname = argv[2];
299
    in = fopen(iname, "rb");
300
    if (in == 0) {
301
	in = fopen(iname, "r");
302
	if (in == 0) {
303
	    fprintf(stderr, "Can't read %s.\n", iname);
304
	    exit(1);
305
	}
306
    }
307
    cont = read_file(in, iname);
308
    if (cont == 0)
309
	exit(1);
310
    fclose(in);
311
    out = fopen(oname, "w");
312
    if (out == 0) {
313
	fprintf(stderr, "Can't open %s for output.\n", oname);
314
	exit(1);
315
    }
316
    fprintf(out, "/*\n * This file %s was generated from %s by genht.\n * Do not edit this file.\n *\n", oname, iname);
317
    /* Copy initial comments from the input file. */
318
    while (parse_line(&cont, &line) && line[0] == '%')
319
	if (line[1] != '!')
320
	    fprintf(out, " * %s\n", line + 1);
321
    cont[-1] = '\n';
322
    cont = line;
323
    fputs(" */\n#include \"gxdhtres.h\"\n", out);
324
    for (index = 0;
325
	 (code = parse_halftone(&res, &Thresholds, &prefix, &cont)) == 0;
326
	 ++index) {
327
	order.width = res.Width;
328
	order.num_levels = res.num_levels;
329
	order.levels = (uint *)res.levels;
330
	order.num_bits = res.Width * res.Height;
331
	order.bit_data = (void *)res.bit_data;
332
	ht_order_procs_short.construct_order(&order, Thresholds);
333
	write_halftone(out, &res, prefix, index);
334
    }
335
    if (prefix == 0)
336
	prefix = res.rname;
337
    fputs("/* Check the prototype. */\n", out);
338
    fprintf(out, "DEVICE_HALFTONE_RESOURCE_PROC(gs_dht_%s);\n", prefix);
339
    fputs("\nconst gx_device_halftone_resource_t *const *\n", out);
340
    fprintf(out, "gs_dht_%s(void)\n{\n    static const gx_device_halftone_resource_t *const res[] = {\n\t",
341
	    prefix);
342
    for (i = 0; i < index; ++i)
343
	fprintf(out, "&res_%d, ", i);
344
    fputs("0\n    };\n    return res;\n}\n", out);
345
    fclose(out);
346
    if (code < 0)
347
	exit(1);
348
    return 0;
349
}
350
 
351
/* Stubs */
352
ENUM_PTRS_BEGIN_PROC(gs_no_struct_enum_ptrs)
353
{
354
    return 0;
355
    ENUM_PTRS_END_PROC
356
}
357
RELOC_PTRS_BEGIN(gs_no_struct_reloc_ptrs)
358
{
359
}
360
RELOC_PTRS_END
361
public_st_stream_state();
362
void
363
gx_ht_complete_threshold_order(gx_ht_order *porder)
364
{
365
}
366
 
367
/*
368
 * In order to avoid a linking step, we #include the required files here
369
 * rather than compiling them separately.
370
 */
371
#include "gxhtbit.c"
372
#include "scantab.c"
373
#include "sstring.c"
374
 
375
const gx_dht_proc gx_device_halftone_list[] = { 0 };