"Fossies" - the Fresh Open Source Software Archive 
Member "xpdf-4.04/xpdf/pdftops.cc" (18 Apr 2022, 11515 Bytes) of package /linux/misc/xpdf-4.04.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 //========================================================================
2 //
3 // pdftops.cc
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stddef.h>
13 #include <string.h>
14 #ifdef DEBUG_FP_LINUX
15 # include <fenv.h>
16 # include <fpu_control.h>
17 #endif
18 #include "gmem.h"
19 #include "gmempp.h"
20 #include "parseargs.h"
21 #include "GString.h"
22 #include "GlobalParams.h"
23 #include "Object.h"
24 #include "Stream.h"
25 #include "Array.h"
26 #include "Dict.h"
27 #include "XRef.h"
28 #include "Catalog.h"
29 #include "Page.h"
30 #include "PDFDoc.h"
31 #include "PSOutputDev.h"
32 #include "Error.h"
33 #include "config.h"
34
35 static int firstPage = 1;
36 static int lastPage = 0;
37 static GBool level1 = gFalse;
38 static GBool level1Sep = gFalse;
39 static GBool level2 = gFalse;
40 static GBool level2Gray = gFalse;
41 static GBool level2Sep = gFalse;
42 static GBool level3 = gFalse;
43 static GBool level3Gray = gFalse;
44 static GBool level3Sep = gFalse;
45 static GBool doEPS = gFalse;
46 static GBool doForm = gFalse;
47 #if OPI_SUPPORT
48 static GBool doOPI = gFalse;
49 #endif
50 static GBool noEmbedT1Fonts = gFalse;
51 static GBool noEmbedTTFonts = gFalse;
52 static GBool noEmbedCIDPSFonts = gFalse;
53 static GBool noEmbedCIDTTFonts = gFalse;
54 static GBool preload = gFalse;
55 static char paperSize[15] = "";
56 static int paperWidth = 0;
57 static int paperHeight = 0;
58 static GBool noCrop = gFalse;
59 static GBool expand = gFalse;
60 static GBool noShrink = gFalse;
61 static GBool noCenter = gFalse;
62 static GBool pageCrop = gFalse;
63 static GBool userUnit = gFalse;
64 static GBool duplex = gFalse;
65 static char ownerPassword[33] = "\001";
66 static char userPassword[33] = "\001";
67 static GBool verbose = gFalse;
68 static GBool quiet = gFalse;
69 static char cfgFileName[256] = "";
70 static GBool printVersion = gFalse;
71 static GBool printHelp = gFalse;
72
73 static ArgDesc argDesc[] = {
74 {"-f", argInt, &firstPage, 0,
75 "first page to print"},
76 {"-l", argInt, &lastPage, 0,
77 "last page to print"},
78 {"-level1", argFlag, &level1, 0,
79 "generate Level 1 PostScript"},
80 {"-level1sep", argFlag, &level1Sep, 0,
81 "generate Level 1 separable PostScript"},
82 {"-level2", argFlag, &level2, 0,
83 "generate Level 2 PostScript"},
84 {"-level2gray", argFlag, &level2Gray, 0,
85 "generate Level 2 grayscale PostScript"},
86 {"-level2sep", argFlag, &level2Sep, 0,
87 "generate Level 2 separable PostScript"},
88 {"-level3", argFlag, &level3, 0,
89 "generate Level 3 PostScript"},
90 {"-level3gray", argFlag, &level3Gray, 0,
91 "generate Level 3 grayscale PostScript"},
92 {"-level3sep", argFlag, &level3Sep, 0,
93 "generate Level 3 separable PostScript"},
94 {"-eps", argFlag, &doEPS, 0,
95 "generate Encapsulated PostScript (EPS)"},
96 {"-form", argFlag, &doForm, 0,
97 "generate a PostScript form"},
98 #if OPI_SUPPORT
99 {"-opi", argFlag, &doOPI, 0,
100 "generate OPI comments"},
101 #endif
102 {"-noembt1", argFlag, &noEmbedT1Fonts, 0,
103 "don't embed Type 1 fonts"},
104 {"-noembtt", argFlag, &noEmbedTTFonts, 0,
105 "don't embed TrueType fonts"},
106 {"-noembcidps", argFlag, &noEmbedCIDPSFonts, 0,
107 "don't embed CID PostScript fonts"},
108 {"-noembcidtt", argFlag, &noEmbedCIDTTFonts, 0,
109 "don't embed CID TrueType fonts"},
110 {"-preload", argFlag, &preload, 0,
111 "preload images and forms"},
112 {"-paper", argString, paperSize, sizeof(paperSize),
113 "paper size (letter, legal, A4, A3, match)"},
114 {"-paperw", argInt, &paperWidth, 0,
115 "paper width, in points"},
116 {"-paperh", argInt, &paperHeight, 0,
117 "paper height, in points"},
118 {"-nocrop", argFlag, &noCrop, 0,
119 "don't crop pages to CropBox"},
120 {"-expand", argFlag, &expand, 0,
121 "expand pages smaller than the paper size"},
122 {"-noshrink", argFlag, &noShrink, 0,
123 "don't shrink pages larger than the paper size"},
124 {"-nocenter", argFlag, &noCenter, 0,
125 "don't center pages smaller than the paper size"},
126 {"-pagecrop", argFlag, &pageCrop, 0,
127 "treat the CropBox as the page size"},
128 {"-userunit", argFlag, &userUnit, 0,
129 "honor the UserUnit"},
130 {"-duplex", argFlag, &duplex, 0,
131 "enable duplex printing"},
132 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
133 "owner password (for encrypted files)"},
134 {"-upw", argString, userPassword, sizeof(userPassword),
135 "user password (for encrypted files)"},
136 {"-verbose", argFlag, &verbose, 0,
137 "print per-page status information"},
138 {"-q", argFlag, &quiet, 0,
139 "don't print any messages or errors"},
140 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
141 "configuration file to use in place of .xpdfrc"},
142 {"-v", argFlag, &printVersion, 0,
143 "print copyright and version info"},
144 {"-h", argFlag, &printHelp, 0,
145 "print usage information"},
146 {"-help", argFlag, &printHelp, 0,
147 "print usage information"},
148 {"--help", argFlag, &printHelp, 0,
149 "print usage information"},
150 {"-?", argFlag, &printHelp, 0,
151 "print usage information"},
152 {NULL}
153 };
154
155 int main(int argc, char *argv[]) {
156 PDFDoc *doc;
157 char *fileName;
158 GString *psFileName;
159 PSLevel level;
160 PSOutMode mode;
161 GString *ownerPW, *userPW;
162 PSOutputDev *psOut;
163 GBool ok;
164 char *p;
165 int exitCode;
166
167 #ifdef DEBUG_FP_LINUX
168 // enable exceptions on floating point div-by-zero
169 feenableexcept(FE_DIVBYZERO);
170 // force 64-bit rounding: this avoids changes in output when minor
171 // code changes result in spills of x87 registers; it also avoids
172 // differences in output with valgrind's 64-bit floating point
173 // emulation (yes, this is a kludge; but it's pretty much
174 // unavoidable given the x87 instruction set; see gcc bug 323 for
175 // more info)
176 fpu_control_t cw;
177 _FPU_GETCW(cw);
178 cw = (fpu_control_t)((cw & ~_FPU_EXTENDED) | _FPU_DOUBLE);
179 _FPU_SETCW(cw);
180 #endif
181
182 exitCode = 99;
183
184 // parse args
185 fixCommandLine(&argc, &argv);
186 ok = parseArgs(argDesc, &argc, argv);
187 if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
188 fprintf(stderr, "pdftops version %s [www.xpdfreader.com]\n", xpdfVersion);
189 fprintf(stderr, "%s\n", xpdfCopyright);
190 if (!printVersion) {
191 printUsage("pdftops", "<PDF-file> [<PS-file>]", argDesc);
192 }
193 exit(1);
194 }
195 if ((level1 ? 1 : 0) +
196 (level1Sep ? 1 : 0) +
197 (level2 ? 1 : 0) +
198 (level2Gray ? 1 : 0) +
199 (level2Sep ? 1 : 0) +
200 (level3 ? 1 : 0) +
201 (level3Gray ? 1 : 0) +
202 (level3Sep ? 1 : 0) > 1) {
203 fprintf(stderr, "Error: use only one of the 'level' options.\n");
204 exit(1);
205 }
206 if (doEPS && doForm) {
207 fprintf(stderr, "Error: use only one of -eps and -form\n");
208 exit(1);
209 }
210 if (level1) {
211 level = psLevel1;
212 } else if (level1Sep) {
213 level = psLevel1Sep;
214 } else if (level2Gray) {
215 level = psLevel2Gray;
216 } else if (level2Sep) {
217 level = psLevel2Sep;
218 } else if (level3) {
219 level = psLevel3;
220 } else if (level3Gray) {
221 level = psLevel3Gray;
222 } else if (level3Sep) {
223 level = psLevel3Sep;
224 } else {
225 level = psLevel2;
226 }
227 if (doForm && level < psLevel2) {
228 fprintf(stderr, "Error: forms are only available with Level 2 output.\n");
229 exit(1);
230 }
231 mode = doEPS ? psModeEPS
232 : doForm ? psModeForm
233 : psModePS;
234 fileName = argv[1];
235
236 // read config file
237 if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
238 error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
239 cfgFileName);
240 }
241 globalParams = new GlobalParams(cfgFileName);
242 #if HAVE_SPLASH
243 globalParams->setupBaseFonts(NULL);
244 #endif
245 if (paperSize[0]) {
246 if (!globalParams->setPSPaperSize(paperSize)) {
247 fprintf(stderr, "Invalid paper size\n");
248 goto err0;
249 }
250 } else {
251 if (paperWidth) {
252 globalParams->setPSPaperWidth(paperWidth);
253 }
254 if (paperHeight) {
255 globalParams->setPSPaperHeight(paperHeight);
256 }
257 }
258 if (noCrop) {
259 globalParams->setPSCrop(gFalse);
260 }
261 if (pageCrop) {
262 globalParams->setPSUseCropBoxAsPage(gTrue);
263 }
264 if (expand) {
265 globalParams->setPSExpandSmaller(gTrue);
266 }
267 if (noShrink) {
268 globalParams->setPSShrinkLarger(gFalse);
269 }
270 if (noCenter) {
271 globalParams->setPSCenter(gFalse);
272 }
273 if (duplex) {
274 globalParams->setPSDuplex(duplex);
275 }
276 if (level1 || level1Sep ||
277 level2 || level2Gray || level2Sep ||
278 level3 || level3Gray || level3Sep) {
279 globalParams->setPSLevel(level);
280 }
281 if (noEmbedT1Fonts) {
282 globalParams->setPSEmbedType1(!noEmbedT1Fonts);
283 }
284 if (noEmbedTTFonts) {
285 globalParams->setPSEmbedTrueType(!noEmbedTTFonts);
286 }
287 if (noEmbedCIDPSFonts) {
288 globalParams->setPSEmbedCIDPostScript(!noEmbedCIDPSFonts);
289 }
290 if (noEmbedCIDTTFonts) {
291 globalParams->setPSEmbedCIDTrueType(!noEmbedCIDTTFonts);
292 }
293 if (preload) {
294 globalParams->setPSPreload(preload);
295 }
296 #if OPI_SUPPORT
297 if (doOPI) {
298 globalParams->setPSOPI(doOPI);
299 }
300 #endif
301 if (verbose) {
302 globalParams->setPrintStatusInfo(verbose);
303 }
304 if (quiet) {
305 globalParams->setErrQuiet(quiet);
306 }
307
308 // open PDF file
309 if (ownerPassword[0] != '\001') {
310 ownerPW = new GString(ownerPassword);
311 } else {
312 ownerPW = NULL;
313 }
314 if (userPassword[0] != '\001') {
315 userPW = new GString(userPassword);
316 } else {
317 userPW = NULL;
318 }
319 doc = new PDFDoc(fileName, ownerPW, userPW);
320 if (userPW) {
321 delete userPW;
322 }
323 if (ownerPW) {
324 delete ownerPW;
325 }
326 if (!doc->isOk()) {
327 exitCode = 1;
328 goto err1;
329 }
330
331 // check for print permission
332 if (!doc->okToPrint()) {
333 error(errNotAllowed, -1, "Printing this document is not allowed.");
334 exitCode = 3;
335 goto err1;
336 }
337
338 // construct PostScript file name
339 if (argc == 3) {
340 psFileName = new GString(argv[2]);
341 } else {
342 p = fileName + strlen(fileName) - 4;
343 if (strlen(fileName) > 4 && (!strcmp(p, ".pdf") || !strcmp(p, ".PDF"))) {
344 psFileName = new GString(fileName, (int)strlen(fileName) - 4);
345 } else {
346 psFileName = new GString(fileName);
347 }
348 psFileName->append(doEPS ? ".eps" : ".ps");
349 }
350 if (psFileName->cmp("-") == 0) {
351 globalParams->setPrintStatusInfo(gFalse);
352 }
353
354 // get page range
355 if (firstPage < 1) {
356 firstPage = 1;
357 }
358 if (lastPage < 1 || lastPage > doc->getNumPages()) {
359 lastPage = doc->getNumPages();
360 }
361
362 // check for multi-page EPS or form
363 if ((doEPS || doForm) && firstPage != lastPage) {
364 error(errCommandLine, -1, "EPS and form files can only contain one page.");
365 goto err2;
366 }
367
368 // write PostScript file
369 psOut = new PSOutputDev(psFileName->getCString(), doc,
370 firstPage, lastPage, mode,
371 0, 0, 0, 0, gFalse, NULL, NULL, userUnit, gTrue);
372 if (!psOut->isOk()) {
373 delete psOut;
374 exitCode = 2;
375 goto err2;
376 }
377 doc->displayPages(psOut, firstPage, lastPage, 72, 72,
378 0, !globalParams->getPSUseCropBoxAsPage(),
379 globalParams->getPSCrop(), gTrue);
380 exitCode = 0;
381 if (!psOut->checkIO()) {
382 exitCode = 2;
383 }
384 delete psOut;
385
386 // clean up
387 err2:
388 delete psFileName;
389 err1:
390 delete doc;
391 err0:
392 delete globalParams;
393
394 // check for memory leaks
395 Object::memCheck(stderr);
396 gMemReport(stderr);
397
398 return exitCode;
399 }