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
/*
2
 * pdfshow -- the ultimate pdf debugging tool
3
 */
4
 
5
#include "fitz.h"
6
#include "mupdf.h"
7
 
8
static pdf_xref *xref = NULL;
9
static int showbinary = 0;
10
static int showdecode = 1;
11
static int showcolumn;
12
 
13
void die(fz_error error)
14
{
15
	fz_catch(error, "aborting");
16
	if (xref)
17
		pdf_free_xref(xref);
18
	exit(1);
19
}
20
 
21
static void usage(void)
22
{
23
	fprintf(stderr, "usage: pdfshow [options] file.pdf [grepable] [xref] [trailer] [pagetree] [object numbers]\n");
24
	fprintf(stderr, "\t-b\tprint streams as binary data\n");
25
	fprintf(stderr, "\t-e\tprint encoded streams (don't decode)\n");
26
	fprintf(stderr, "\t-p\tpassword\n");
27
	exit(1);
28
}
29
 
30
static void showtrailer(void)
31
{
32
	if (!xref)
33
		die(fz_throw("no file specified"));
34
	printf("trailer\n");
35
	fz_debug_obj(xref->trailer);
36
	printf("\n");
37
}
38
 
39
static void showxref(void)
40
{
41
	if (!xref)
42
		die(fz_throw("no file specified"));
43
	pdf_debug_xref(xref);
44
	printf("\n");
45
}
46
 
47
static void showpagetree(void)
48
{
49
	fz_error error;
50
	fz_obj *ref;
51
	int count;
52
	int i;
53
 
54
	if (!xref)
55
		die(fz_throw("no file specified"));
56
 
57
	if (!xref->page_len)
58
	{
59
		error = pdf_load_page_tree(xref);
60
		if (error)
61
			die(fz_rethrow(error, "cannot load page tree"));
62
	}
63
 
64
	count = pdf_count_pages(xref);
65
	for (i = 0; i < count; i++)
66
	{
67
		ref = xref->page_refs[i];
68
		printf("page %d = %d %d R\n", i + 1, fz_to_num(ref), fz_to_gen(ref));
69
	}
70
	printf("\n");
71
}
72
 
73
static void showsafe(unsigned char *buf, int n)
74
{
75
	int i;
76
	for (i = 0; i < n; i++) {
77
		if (buf[i] == '\r' || buf[i] == '\n') {
78
			putchar('\n');
79
			showcolumn = 0;
80
		}
81
		else if (buf[i] < 32 || buf[i] > 126) {
82
			putchar('.');
83
			showcolumn ++;
84
		}
85
		else {
86
			putchar(buf[i]);
87
			showcolumn ++;
88
		}
89
		if (showcolumn == 79) {
90
			putchar('\n');
91
			showcolumn = 0;
92
		}
93
	}
94
}
95
 
96
static void showstream(int num, int gen)
97
{
98
	fz_error error;
99
	fz_stream *stm;
100
	unsigned char buf[2048];
101
	int n;
102
 
103
	showcolumn = 0;
104
 
105
	if (showdecode)
106
		error = pdf_open_stream(&stm, xref, num, gen);
107
	else
108
		error = pdf_open_raw_stream(&stm, xref, num, gen);
109
	if (error)
110
		die(error);
111
 
112
	while (1)
113
	{
114
		n = fz_read(stm, buf, sizeof buf);
115
		if (n < 0)
116
			die(n);
117
		if (n == 0)
118
			break;
119
		if (showbinary)
120
			fwrite(buf, 1, n, stdout);
121
		else
122
			showsafe(buf, n);
123
	}
124
 
125
	fz_close(stm);
126
}
127
 
128
static void showobject(int num, int gen)
129
{
130
	fz_error error;
131
	fz_obj *obj;
132
 
133
	if (!xref)
134
		die(fz_throw("no file specified"));
135
 
136
	error = pdf_load_object(&obj, xref, num, gen);
137
	if (error)
138
		die(error);
139
 
140
	if (pdf_is_stream(xref, num, gen))
141
	{
142
		if (showbinary)
143
		{
144
			showstream(num, gen);
145
		}
146
		else
147
		{
148
			printf("%d %d obj\n", num, gen);
149
			fz_debug_obj(obj);
150
			printf("stream\n");
151
			showstream(num, gen);
152
			printf("endstream\n");
153
			printf("endobj\n\n");
154
		}
155
	}
156
	else
157
	{
158
		printf("%d %d obj\n", num, gen);
159
		fz_debug_obj(obj);
160
		printf("endobj\n\n");
161
	}
162
 
163
	fz_drop_obj(obj);
164
}
165
 
166
static void showgrep(char *filename)
167
{
168
	fz_error error;
169
	fz_obj *obj;
170
	int i;
171
 
172
	for (i = 0; i < xref->len; i++)
173
	{
174
		if (xref->table[i].type == 'n' || xref->table[i].type == 'o')
175
		{
176
			error = pdf_load_object(&obj, xref, i, 0);
177
			if (error)
178
				die(error);
179
 
180
			fz_sort_dict(obj);
181
 
182
			printf("%s:%d: ", filename, i);
183
			fz_fprint_obj(stdout, obj, 1);
184
 
185
			fz_drop_obj(obj);
186
		}
187
	}
188
 
189
	printf("%s:trailer: ", filename);
190
	fz_fprint_obj(stdout, xref->trailer, 1);
191
}
192
 
193
int main(int argc, char **argv)
194
{
195
	char *password = NULL; /* don't throw errors if encrypted */
196
	char *filename;
197
	fz_error error;
198
	int c;
199
 
200
	while ((c = fz_getopt(argc, argv, "p:be")) != -1)
201
	{
202
		switch (c)
203
		{
204
		case 'p': password = fz_optarg; break;
205
		case 'b': showbinary = 1; break;
206
		case 'e': showdecode = 0; break;
207
		default: usage(); break;
208
		}
209
	}
210
 
211
	if (fz_optind == argc)
212
		usage();
213
 
214
	filename = argv[fz_optind++];
215
	error = pdf_open_xref(&xref, filename, password);
216
	if (error)
217
		die(fz_rethrow(error, "cannot open document: %s", filename));
218
 
219
	if (fz_optind == argc)
220
		showtrailer();
221
 
222
	while (fz_optind < argc)
223
	{
224
		switch (argv[fz_optind][0])
225
		{
226
		case 't': showtrailer(); break;
227
		case 'x': showxref(); break;
228
		case 'p': showpagetree(); break;
229
		case 'g': showgrep(filename); break;
230
		default: showobject(atoi(argv[fz_optind]), 0); break;
231
		}
232
		fz_optind++;
233
	}
234
 
235
	pdf_free_xref(xref);
236
 
237
	fz_flush_warnings();
238
 
239
	return 0;
240
}