Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
#include "muxps.h"
3
 
4
#ifdef _MSC_VER
5
#include 
6
#else
7
#include 
8
#endif
9
 
10
char *output = NULL;
11
float resolution = 72;
12
 
13
int showxml = 0;
14
int showtext = 0;
15
int showtime = 0;
16
int showmd5 = 0;
17
int savealpha = 0;
18
int uselist = 1;
19
 
20
fz_colorspace *colorspace;
21
fz_glyph_cache *glyphcache;
22
char *filename;
23
 
24
struct {
25
	int count, total;
26
	int min, max;
27
	int minpage, maxpage;
28
} timing;
29
 
30
static void die(fz_error error)
31
{
32
	fz_catch(error, "aborting");
33
	exit(1);
34
}
35
 
36
static void usage(void)
37
{
38
	fprintf(stderr,
39
		"usage: xpsdraw [options] input.xps [pages]\n"
40
		"\t-o -\toutput filename (%%d for page number)\n"
41
		"\t\tsupported formats: pgm, ppm, pam, png\n"
42
		"\t-r -\tresolution in dpi (default: 72)\n"
43
		"\t-a\tsave alpha channel (only pam and png)\n"
44
		"\t-g\trender in grayscale\n"
45
		"\t-m\tshow timing information\n"
46
		"\t-t\tshow text (-tt for xml)\n"
47
		"\t-x\tshow display list\n"
48
		"\t-d\tdisable use of display list\n"
49
		"\t-5\tshow md5 checksums\n"
50
		"\tpages\tcomma separated list of ranges\n");
51
	exit(1);
52
}
53
 
54
static int gettime(void)
55
{
56
	static struct timeval first;
57
	static int once = 1;
58
	struct timeval now;
59
	if (once)
60
	{
61
		gettimeofday(&first, NULL);
62
		once = 0;
63
	}
64
	gettimeofday(&now, NULL);
65
	return (now.tv_sec - first.tv_sec) * 1000 + (now.tv_usec - first.tv_usec) / 1000;
66
}
67
 
68
static int isrange(char *s)
69
{
70
	while (*s)
71
	{
72
		if ((*s < '0' || *s > '9') && *s != '-' && *s != ',')
73
			return 0;
74
		s++;
75
	}
76
	return 1;
77
}
78
 
79
static void
80
xps_run_page(xps_context *ctx, xps_page *page, fz_device *dev, fz_matrix ctm)
81
{
82
	ctx->dev = dev;
83
	xps_parse_fixed_page(ctx, ctm, page);
84
	ctx->dev = NULL;
85
}
86
 
87
static void drawpage(xps_context *ctx, int pagenum)
88
{
89
	xps_page *page;
90
	fz_display_list *list;
91
	fz_device *dev;
92
	int start;
93
	int code;
94
 
95
	if (showtime)
96
	{
97
		start = gettime();
98
	}
99
 
100
	code = xps_load_page(&page, ctx, pagenum - 1);
101
	if (code)
102
		die(fz_rethrow(code, "cannot load page %d in file '%s'", pagenum, filename));
103
 
104
	list = NULL;
105
 
106
	if (uselist)
107
	{
108
		list = fz_new_display_list();
109
		dev = fz_new_list_device(list);
110
		xps_run_page(ctx, page, dev, fz_identity);
111
		fz_free_device(dev);
112
	}
113
 
114
	if (showxml)
115
	{
116
		dev = fz_new_trace_device();
117
		printf("\n", pagenum);
118
		if (list)
119
			fz_execute_display_list(list, dev, fz_identity, fz_infinite_bbox);
120
		else
121
			xps_run_page(ctx, page, dev, fz_identity);
122
		printf("\n");
123
		fz_free_device(dev);
124
	}
125
 
126
	if (showtext)
127
	{
128
		fz_text_span *text = fz_new_text_span();
129
		dev = fz_new_text_device(text);
130
		if (list)
131
			fz_execute_display_list(list, dev, fz_identity, fz_infinite_bbox);
132
		else
133
			xps_run_page(ctx, page, dev, fz_identity);
134
		fz_free_device(dev);
135
		printf("[Page %d]\n", pagenum);
136
		if (showtext > 1)
137
			fz_debug_text_span_xml(text);
138
		else
139
			fz_debug_text_span(text);
140
		printf("\n");
141
		fz_free_text_span(text);
142
	}
143
 
144
	if (showmd5 || showtime)
145
		printf("page %s %d", filename, pagenum);
146
 
147
	if (output || showmd5 || showtime)
148
	{
149
		float zoom;
150
		fz_matrix ctm;
151
		fz_rect rect;
152
		fz_bbox bbox;
153
		fz_pixmap *pix;
154
 
155
		rect.x0 = rect.y0 = 0;
156
		rect.x1 = page->width;
157
		rect.y1 = page->height;
158
 
159
		zoom = resolution / 96;
160
		ctm = fz_translate(0, -page->height);
161
		ctm = fz_concat(ctm, fz_scale(zoom, zoom));
162
		bbox = fz_round_rect(fz_transform_rect(ctm, rect));
163
 
164
		/* TODO: banded rendering and multi-page ppm */
165
 
166
		pix = fz_new_pixmap_with_rect(colorspace, bbox);
167
 
168
		if (savealpha)
169
			fz_clear_pixmap(pix);
170
		else
171
			fz_clear_pixmap_with_color(pix, 255);
172
 
173
		dev = fz_new_draw_device(glyphcache, pix);
174
		if (list)
175
			fz_execute_display_list(list, dev, ctm, bbox);
176
		else
177
			xps_run_page(ctx, page, dev, ctm);
178
		fz_free_device(dev);
179
 
180
		if (output)
181
		{
182
			char buf[512];
183
			sprintf(buf, output, pagenum);
184
			if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm"))
185
				fz_write_pnm(pix, buf);
186
			else if (strstr(output, ".pam"))
187
				fz_write_pam(pix, buf, savealpha);
188
			else if (strstr(output, ".png"))
189
				fz_write_png(pix, buf, savealpha);
190
		}
191
 
192
		if (showmd5)
193
		{
194
			fz_md5 md5;
195
			unsigned char digest[16];
196
			int i;
197
 
198
			fz_md5_init(&md5);
199
			fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n);
200
			fz_md5_final(&md5, digest);
201
 
202
			printf(" ");
203
			for (i = 0; i < 16; i++)
204
				printf("%02x", digest[i]);
205
		}
206
 
207
		fz_drop_pixmap(pix);
208
	}
209
 
210
	if (list)
211
		fz_free_display_list(list);
212
 
213
	if (showtime)
214
	{
215
		int end = gettime();
216
		int diff = end - start;
217
 
218
		if (diff < timing.min)
219
		{
220
			timing.min = diff;
221
			timing.minpage = pagenum;
222
		}
223
		if (diff > timing.max)
224
		{
225
			timing.max = diff;
226
			timing.maxpage = pagenum;
227
		}
228
		timing.total += diff;
229
		timing.count ++;
230
 
231
		printf(" %dms", diff);
232
	}
233
 
234
	if (showmd5 || showtime)
235
		printf("\n");
236
}
237
 
238
static void drawrange(xps_context *ctx, char *range)
239
{
240
	int page, spage, epage;
241
	char *spec, *dash;
242
 
243
	spec = fz_strsep(&range, ",");
244
	while (spec)
245
	{
246
		dash = strchr(spec, '-');
247
 
248
		if (dash == spec)
249
			spage = epage = xps_count_pages(ctx);
250
		else
251
			spage = epage = atoi(spec);
252
 
253
		if (dash)
254
		{
255
			if (strlen(dash) > 1)
256
				epage = atoi(dash + 1);
257
			else
258
				epage = xps_count_pages(ctx);
259
		}
260
 
261
		spage = CLAMP(spage, 1, xps_count_pages(ctx));
262
		epage = CLAMP(epage, 1, xps_count_pages(ctx));
263
 
264
		if (spage < epage)
265
			for (page = spage; page <= epage; page++)
266
				drawpage(ctx, page);
267
		else
268
			for (page = spage; page >= epage; page--)
269
				drawpage(ctx, page);
270
 
271
		spec = fz_strsep(&range, ",");
272
	}
273
}
274
 
275
int main(int argc, char **argv)
276
{
277
	int grayscale = 0;
278
	int accelerate = 1;
279
	xps_context *ctx;
280
	int code;
281
	int c;
282
 
283
	while ((c = fz_getopt(argc, argv, "o:p:r:Aadgmtx5")) != -1)
284
	{
285
		switch (c)
286
		{
287
		case 'o': output = fz_optarg; break;
288
		case 'r': resolution = atof(fz_optarg); break;
289
		case 'A': accelerate = 0; break;
290
		case 'a': savealpha = 1; break;
291
		case 'm': showtime++; break;
292
		case 't': showtext++; break;
293
		case 'x': showxml++; break;
294
		case '5': showmd5++; break;
295
		case 'g': grayscale++; break;
296
		case 'd': uselist = 0; break;
297
		default: usage(); break;
298
		}
299
	}
300
 
301
	if (fz_optind == argc)
302
		usage();
303
 
304
	if (!showtext && !showxml && !showtime && !showmd5 && !output)
305
	{
306
		printf("nothing to do\n");
307
		exit(0);
308
	}
309
 
310
	if (accelerate)
311
		fz_accelerate();
312
 
313
	glyphcache = fz_new_glyph_cache();
314
 
315
	colorspace = fz_device_rgb;
316
	if (grayscale)
317
		colorspace = fz_device_gray;
318
	if (output && strstr(output, ".pgm"))
319
		colorspace = fz_device_gray;
320
	if (output && strstr(output, ".ppm"))
321
		colorspace = fz_device_rgb;
322
 
323
	timing.count = 0;
324
	timing.total = 0;
325
	timing.min = 1 << 30;
326
	timing.max = 0;
327
	timing.minpage = 0;
328
	timing.maxpage = 0;
329
 
330
	if (showxml)
331
		printf("\n");
332
 
333
	while (fz_optind < argc)
334
	{
335
		filename = argv[fz_optind++];
336
 
337
		code = xps_open_file(&ctx, filename);
338
		if (code)
339
			die(fz_rethrow(code, "cannot open document: %s", filename));
340
 
341
		if (showxml)
342
			printf("\n", filename);
343
 
344
		if (fz_optind == argc || !isrange(argv[fz_optind]))
345
			drawrange(ctx, "1-");
346
		if (fz_optind < argc && isrange(argv[fz_optind]))
347
			drawrange(ctx, argv[fz_optind++]);
348
 
349
		if (showxml)
350
			printf("\n");
351
 
352
		xps_free_context(ctx);
353
	}
354
 
355
	if (showtime)
356
	{
357
		printf("total %dms / %d pages for an average of %dms\n",
358
			timing.total, timing.count, timing.total / timing.count);
359
		printf("fastest page %d: %dms\n", timing.minpage, timing.min);
360
		printf("slowest page %d: %dms\n", timing.maxpage, timing.max);
361
	}
362
 
363
	fz_free_glyph_cache(glyphcache);
364
 
365
	return 0;
366
}