1
//========================================================================
5
// Copyright 2003 Glyph & Cog, LLC
7
//========================================================================
9
//========================================================================
11
// Modified under the Poppler project - http://poppler.freedesktop.org
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
16
// Copyright (C) 2007 Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
17
// Copyright (C) 2008 Richard Airlie <richard.airlie@maglabs.net>
18
// Copyright (C) 2009 Michael K. Johnson <a1237@danlj.org>
19
// Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com>
20
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
21
// Copyright (C) 2009, 2010 Albert Astals Cid <aacid@kde.org>
22
// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
23
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
24
// Copyright (C) 2010 Jonathan Liu <net147@gmail.com>
26
// To see a description of the changes please see the Changelog file that
27
// came with your tarball or type make ChangeLog if you are building from git
29
//========================================================================
32
#include <poppler-config.h>
34
#include <fcntl.h> // for O_BINARY
35
#include <io.h> // for setmode
39
#include "parseargs.h"
41
#include "goo/GooString.h"
42
#include "GlobalParams.h"
45
#include "PDFDocFactory.h"
46
#include "splash/SplashBitmap.h"
47
#include "splash/Splash.h"
48
#include "SplashOutputDev.h"
50
#define PPM_FILE_SZ 512
52
static int firstPage = 1;
53
static int lastPage = 0;
54
static GBool printOnlyOdd = gFalse;
55
static GBool printOnlyEven = gFalse;
56
static double resolution = 0.0;
57
static double x_resolution = 150.0;
58
static double y_resolution = 150.0;
59
static int scaleTo = 0;
60
static int x_scaleTo = 0;
61
static int y_scaleTo = 0;
67
static GBool useCropBox = gFalse;
68
static GBool mono = gFalse;
69
static GBool gray = gFalse;
70
static GBool png = gFalse;
71
static GBool jpeg = gFalse;
72
static char enableFreeTypeStr[16] = "";
73
static char antialiasStr[16] = "";
74
static char vectorAntialiasStr[16] = "";
75
static char ownerPassword[33] = "";
76
static char userPassword[33] = "";
77
static GBool quiet = gFalse;
78
static GBool printVersion = gFalse;
79
static GBool printHelp = gFalse;
81
static const ArgDesc argDesc[] = {
82
{"-f", argInt, &firstPage, 0,
83
"first page to print"},
84
{"-l", argInt, &lastPage, 0,
85
"last page to print"},
86
{"-o", argFlag, &printOnlyOdd, 0,
87
"print only odd pages"},
88
{"-e", argFlag, &printOnlyEven, 0,
89
"print only even pages"},
91
{"-r", argFP, &resolution, 0,
92
"resolution, in DPI (default is 150)"},
93
{"-rx", argFP, &x_resolution, 0,
94
"X resolution, in DPI (default is 150)"},
95
{"-ry", argFP, &y_resolution, 0,
96
"Y resolution, in DPI (default is 150)"},
97
{"-scale-to", argInt, &scaleTo, 0,
98
"scales each page to fit within scale-to*scale-to pixel box"},
99
{"-scale-to-x", argInt, &x_scaleTo, 0,
100
"scales each page horizontally to fit in scale-to-x pixels"},
101
{"-scale-to-y", argInt, &y_scaleTo, 0,
102
"scales each page vertically to fit in scale-to-y pixels"},
104
{"-x", argInt, &x, 0,
105
"x-coordinate of the crop area top left corner"},
106
{"-y", argInt, &y, 0,
107
"y-coordinate of the crop area top left corner"},
108
{"-W", argInt, &w, 0,
109
"width of crop area in pixels (default is 0)"},
110
{"-H", argInt, &h, 0,
111
"height of crop area in pixels (default is 0)"},
112
{"-sz", argInt, &sz, 0,
113
"size of crop square in pixels (sets W and H)"},
114
{"-cropbox",argFlag, &useCropBox, 0,
115
"use the crop box rather than media box"},
117
{"-mono", argFlag, &mono, 0,
118
"generate a monochrome PBM file"},
119
{"-gray", argFlag, &gray, 0,
120
"generate a grayscale PGM file"},
122
{"-png", argFlag, &png, 0,
123
"generate a PNG file"},
126
{"-jpeg", argFlag, &jpeg, 0,
127
"generate a JPEG file"},
129
#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
130
{"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
131
"enable FreeType font rasterizer: yes, no"},
134
{"-aa", argString, antialiasStr, sizeof(antialiasStr),
135
"enable font anti-aliasing: yes, no"},
136
{"-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr),
137
"enable vector anti-aliasing: yes, no"},
139
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
140
"owner password (for encrypted files)"},
141
{"-upw", argString, userPassword, sizeof(userPassword),
142
"user password (for encrypted files)"},
144
{"-q", argFlag, &quiet, 0,
145
"don't print any messages or errors"},
146
{"-v", argFlag, &printVersion, 0,
147
"print copyright and version info"},
148
{"-h", argFlag, &printHelp, 0,
149
"print usage information"},
150
{"-help", argFlag, &printHelp, 0,
151
"print usage information"},
152
{"--help", argFlag, &printHelp, 0,
153
"print usage information"},
154
{"-?", argFlag, &printHelp, 0,
155
"print usage information"},
159
static void savePageSlice(PDFDoc *doc,
160
SplashOutputDev *splashOut,
161
int pg, int x, int y, int w, int h,
162
double pg_w, double pg_h,
164
if (w == 0) w = (int)ceil(pg_w);
165
if (h == 0) h = (int)ceil(pg_h);
166
w = (x+w > pg_w ? (int)ceil(pg_w-x) : w);
167
h = (y+h > pg_h ? (int)ceil(pg_h-y) : h);
168
doc->displayPageSlice(splashOut,
169
pg, x_resolution, y_resolution,
171
!useCropBox, gFalse, gFalse,
175
SplashBitmap *bitmap = splashOut->getBitmap();
177
if (ppmFile != NULL) {
179
bitmap->writeImgFile(splashFormatPng, ppmFile, x_resolution, y_resolution);
181
bitmap->writeImgFile(splashFormatJpeg, ppmFile, x_resolution, y_resolution);
183
bitmap->writePNMFile(ppmFile);
187
setmode(fileno(stdout), O_BINARY);
191
bitmap->writeImgFile(splashFormatPng, stdout, x_resolution, y_resolution);
193
bitmap->writeImgFile(splashFormatJpeg, stdout, x_resolution, y_resolution);
195
bitmap->writePNMFile(stdout);
200
static int numberOfCharacters(unsigned int n)
212
int main(int argc, char *argv[]) {
214
GooString *fileName = NULL;
215
char *ppmRoot = NULL;
216
char ppmFile[PPM_FILE_SZ];
217
GooString *ownerPW, *userPW;
218
SplashColor paperColor;
219
SplashOutputDev *splashOut;
223
double pg_w, pg_h, tmp;
228
ok = parseArgs(argDesc, &argc, argv);
232
if ( resolution != 0.0 &&
233
(x_resolution == 150.0 ||
234
y_resolution == 150.0)) {
235
x_resolution = resolution;
236
y_resolution = resolution;
238
if (!ok || argc > 3 || printVersion || printHelp) {
239
fprintf(stderr, "pdftoppm version %s\n", PACKAGE_VERSION);
240
fprintf(stderr, "%s\n", popplerCopyright);
241
fprintf(stderr, "%s\n", xpdfCopyright);
243
printUsage("pdftoppm", "[PDF-file [PPM-file-prefix]]", argDesc);
245
if (printVersion || printHelp)
249
if (argc > 1) fileName = new GooString(argv[1]);
250
if (argc == 3) ppmRoot = argv[2];
253
globalParams = new GlobalParams();
254
if (enableFreeTypeStr[0]) {
255
if (!globalParams->setEnableFreeType(enableFreeTypeStr)) {
256
fprintf(stderr, "Bad '-freetype' value on command line\n");
259
if (antialiasStr[0]) {
260
if (!globalParams->setAntialias(antialiasStr)) {
261
fprintf(stderr, "Bad '-aa' value on command line\n");
264
if (vectorAntialiasStr[0]) {
265
if (!globalParams->setVectorAntialias(vectorAntialiasStr)) {
266
fprintf(stderr, "Bad '-aaVector' value on command line\n");
270
globalParams->setErrQuiet(quiet);
274
if (ownerPassword[0]) {
275
ownerPW = new GooString(ownerPassword);
279
if (userPassword[0]) {
280
userPW = new GooString(userPassword);
285
if (fileName == NULL) {
286
fileName = new GooString("fd://0");
288
if (fileName->cmp("-") == 0) {
290
fileName = new GooString("fd://0");
292
doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
309
if (lastPage < 1 || lastPage > doc->getNumPages())
310
lastPage = doc->getNumPages();
316
splashOut = new SplashOutputDev(mono ? splashModeMono1 :
317
gray ? splashModeMono8 :
320
splashOut->startDoc(doc->getXRef());
321
if (sz != 0) w = h = sz;
322
pg_num_len = numberOfCharacters(doc->getNumPages());
323
for (pg = firstPage; pg <= lastPage; ++pg) {
324
if (printOnlyEven && pg % 2 == 0) continue;
325
if (printOnlyOdd && pg % 2 == 1) continue;
327
pg_w = doc->getPageCropWidth(pg);
328
pg_h = doc->getPageCropHeight(pg);
330
pg_w = doc->getPageMediaWidth(pg);
331
pg_h = doc->getPageMediaHeight(pg);
335
resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h);
336
x_resolution = y_resolution = resolution;
338
if (x_scaleTo != 0) {
339
x_resolution = (72.0 * x_scaleTo) / pg_w;
341
if (y_scaleTo != 0) {
342
y_resolution = (72.0 * y_scaleTo) / pg_h;
345
pg_w = pg_w * (x_resolution / 72.0);
346
pg_h = pg_h * (y_resolution / 72.0);
347
if ((doc->getPageRotate(pg) == 90) || (doc->getPageRotate(pg) == 270)) {
352
if (ppmRoot != NULL) {
353
snprintf(ppmFile, PPM_FILE_SZ, "%.*s-%0*d.%s",
354
PPM_FILE_SZ - 32, ppmRoot, pg_num_len, pg,
355
png ? "png" : jpeg ? "jpg" : mono ? "pbm" : gray ? "pgm" : "ppm");
356
savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, ppmFile);
358
savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, NULL);
371
// check for memory leaks
372
Object::memCheck(stderr);