Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
/*
2
* Information tool.
3
* Print information about pages of a pdf.
4
*/
5
6
#include "mupdf/pdf.h"
7
8
static void
9
infousage(void)
10
{
11
fprintf(stderr,
12
"usage: mutool pages [options] file.pdf [pages]\n"
13
"\t-p -\tpassword for decryption\n"
14
"\tpages\tcomma separated list of page numbers and ranges\n"
15
);
16
exit(1);
17
}
18
19
static int
20
showbox(fz_context *ctx, fz_output *out, pdf_obj *page, char *text, pdf_obj *name)
21
{
22
fz_rect bbox;
23
pdf_obj *obj;
24
int failed = 0;
25
26
fz_try(ctx)
27
{
28
obj = pdf_dict_get(ctx, page, name);
29
if (!pdf_is_array(ctx, obj))
30
break;
31
32
pdf_to_rect(ctx, obj, &bbox);
33
34
fz_printf(ctx, out, "<%s l=\"%g\" b=\"%g\" r=\"%g\" t=\"%g\" />\n", text, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
35
}
36
fz_catch(ctx)
37
{
38
failed = 1;
39
}
40
41
return failed;
42
}
43
44
static int
45
shownum(fz_context *ctx, fz_output *out, pdf_obj *page, char *text, pdf_obj *name)
46
{
47
pdf_obj *obj;
48
int failed = 0;
49
50
fz_try(ctx)
51
{
52
obj = pdf_dict_get(ctx, page, name);
53
if (!pdf_is_number(ctx, obj))
54
break;
55
56
fz_printf(ctx, out, "<%s v=\"%g\" />\n", text, pdf_to_real(ctx, obj));
57
}
58
fz_catch(ctx)
59
{
60
failed = 1;
61
}
62
63
return failed;
64
}
65
66
static int
67
showpage(fz_context *ctx, pdf_document *doc, fz_output *out, int page)
68
{
69
pdf_obj *pageobj;
70
pdf_obj *pageref;
71
int failed = 0;
72
73
fz_printf(ctx, out, "<page pagenum=\"%d\">\n", page);
74
fz_try(ctx)
75
{
76
pageref = pdf_lookup_page_obj(ctx, doc, page-1);
77
pageobj = pdf_resolve_indirect(ctx, pageref);
78
79
if (!pageobj)
80
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot retrieve info from page %d", page);
81
}
82
fz_catch(ctx)
83
{
84
fz_printf(ctx, out, "Failed to gather information for page %d\n", page);
85
failed = 1;
86
}
87
88
if (!failed)
89
{
90
failed |= showbox(ctx, out, pageobj, "MediaBox", PDF_NAME_MediaBox);
91
failed |= showbox(ctx, out, pageobj, "CropBox", PDF_NAME_CropBox);
92
failed |= showbox(ctx, out, pageobj, "ArtBox", PDF_NAME_ArtBox);
93
failed |= showbox(ctx, out, pageobj, "BleedBox", PDF_NAME_BleedBox);
94
failed |= showbox(ctx, out, pageobj, "TrimBox", PDF_NAME_TrimBox);
95
failed |= shownum(ctx, out, pageobj, "Rotate", PDF_NAME_Rotate);
96
failed |= shownum(ctx, out, pageobj, "UserUnit", PDF_NAME_UserUnit);
97
}
98
99
fz_printf(ctx, out, "</page>\n");
100
101
return failed;
102
}
103
104
static int
105
showpages(fz_context *ctx, pdf_document *doc, fz_output *out, char *pagelist)
106
{
107
int page, spage, epage;
108
char *spec, *dash;
109
int pagecount;
110
int ret = 0;
111
112
if (!doc)
113
infousage();
114
115
pagecount = pdf_count_pages(ctx, doc);
116
spec = fz_strsep(&pagelist, ",");
117
while (spec && pagecount)
118
{
119
dash = strchr(spec, '-');
120
121
if (dash == spec)
122
spage = epage = pagecount;
123
else
124
spage = epage = atoi(spec);
125
126
if (dash)
127
{
128
if (strlen(dash) > 1)
129
epage = atoi(dash + 1);
130
else
131
epage = pagecount;
132
}
133
134
if (spage > epage)
135
page = spage, spage = epage, epage = page;
136
137
spage = fz_clampi(spage, 1, pagecount);
138
epage = fz_clampi(epage, 1, pagecount);
139
140
for (page = spage; page <= epage; page++)
141
{
142
ret |= showpage(ctx, doc, out, page);
143
}
144
145
spec = fz_strsep(&pagelist, ",");
146
}
147
148
return ret;
149
}
150
151
static int arg_is_page_range(const char *arg)
152
{
153
int c;
154
155
while ((c = *arg++) != 0)
156
{
157
if ((c < '0' || c > '9') && (c != '-') && (c != ','))
158
return 0;
159
}
160
return 1;
161
}
162
163
static int
164
pdfpages_pages(fz_context *ctx, fz_output *out, char *filename, char *password, char *argv[], int argc)
165
{
166
enum { NO_FILE_OPENED, NO_INFO_GATHERED, INFO_SHOWN } state;
167
int argidx = 0;
168
pdf_document *doc = NULL;
169
int ret = 0;
170
171
state = NO_FILE_OPENED;
172
while (argidx < argc)
173
{
174
if (state == NO_FILE_OPENED || !arg_is_page_range(argv[argidx]))
175
{
176
if (state == NO_INFO_GATHERED)
177
{
178
showpages(ctx, doc, out, "1-");
179
}
180
181
pdf_close_document(ctx, doc);
182
183
filename = argv[argidx];
184
fz_printf(ctx, out, "%s:\n", filename);
185
doc = pdf_open_document(ctx, filename);
186
if (pdf_needs_password(ctx, doc))
187
if (!pdf_authenticate_password(ctx, doc, password))
188
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename);
189
190
state = NO_INFO_GATHERED;
191
}
192
else
193
{
194
ret |= showpages(ctx, doc, out, argv[argidx]);
195
state = INFO_SHOWN;
196
}
197
198
argidx++;
199
}
200
201
if (state == NO_INFO_GATHERED)
202
showpages(ctx, doc, out, "1-");
203
204
pdf_close_document(ctx, doc);
205
206
return ret;
207
}
208
209
int pdfpages_main(int argc, char **argv)
210
{
211
char *filename = "";
212
char *password = "";
213
int c;
214
fz_output *out = NULL;
215
int ret;
216
fz_context *ctx;
217
218
while ((c = fz_getopt(argc, argv, "p:")) != -1)
219
{
220
switch (c)
221
{
222
case 'p': password = fz_optarg; break;
223
default:
224
infousage();
225
break;
226
}
227
}
228
229
if (fz_optind == argc)
230
infousage();
231
232
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
233
if (!ctx)
234
{
235
fprintf(stderr, "cannot initialise context\n");
236
exit(1);
237
}
238
239
fz_var(out);
240
241
ret = 0;
242
fz_try(ctx)
243
{
244
out = fz_new_output_with_file(ctx, stdout, 0);
245
ret = pdfpages_pages(ctx, out, filename, password, &argv[fz_optind], argc-fz_optind);
246
}
247
fz_catch(ctx)
248
{
249
ret = 1;
250
}
251
fz_drop_output(ctx, out);
252
fz_drop_context(ctx);
253
return ret;
254
}
255
256