diff options
author | Albert Astals Cid <aacid@kde.org> | 2007-08-22 21:29:32 +0000 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2007-08-22 21:29:32 +0000 |
commit | 3ba088d8caee3c40c2aba0cd85adcf9195ae88a3 (patch) | |
tree | 0256b768b673d3aa1c3459e2d39ef0ef4284a2ac /utils | |
parent | 567e82c13aace4f40c7a555a62a3a4d223a46d92 (diff) |
* splash/SplashBitmap.cc:
* splash/SplashBitmap.h:
* utils/pdftoppm.cc: Add the following features to pdftoppm
- if omitting input filename or using - for input filename
reads pdf from stdin
- if omitting output filename, prints output to stdout
- create image of a cropped rectangle of the pdf
- scale pdf to fit in a square of wanted size
Patch by Ilmari Heikkinen <ilmari.heikkinen@gmail.com>
Diffstat (limited to 'utils')
-rw-r--r-- | utils/pdftoppm.cc | 107 |
1 files changed, 91 insertions, 16 deletions
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 1ad16083..2369be50 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -9,6 +9,7 @@ #include "config.h" #include <poppler-config.h> #include <stdio.h> +#include <math.h> #include "parseargs.h" #include "goo/gmem.h" #include "goo/GooString.h" @@ -19,9 +20,17 @@ #include "splash/Splash.h" #include "SplashOutputDev.h" +#define PPM_FILE_SZ 512 + static int firstPage = 1; static int lastPage = 0; -static int resolution = 150; +static double resolution = 150.0; +static int scaleTo = 0; +static int x = 0; +static int y = 0; +static int w = 0; +static int h = 0; +static int sz = 0; static GBool mono = gFalse; static GBool gray = gFalse; static char enableFreeTypeStr[16] = ""; @@ -38,24 +47,43 @@ static ArgDesc argDesc[] = { "first page to print"}, {"-l", argInt, &lastPage, 0, "last page to print"}, - {"-r", argInt, &resolution, 0, + + {"-r", argFP, &resolution, 0, "resolution, in DPI (default is 150)"}, + {"-scale-to", argInt, &scaleTo, 0, + "scales each page to fit in scale-to*scale-to box"}, + + {"-x", argInt, &x, 0, + "x-coordinate of the crop area top left corner"}, + {"-y", argInt, &y, 0, + "y-coordinate of the crop area top left corner"}, + {"-W", argInt, &w, 0, + "width of crop area in pixels (default is 0)"}, + {"-H", argInt, &h, 0, + "height of crop area in pixels (default is 0)"}, + {"-sz", argInt, &sz, 0, + "size of crop square in pixels (sets W and H)"}, + {"-mono", argFlag, &mono, 0, "generate a monochrome PBM file"}, {"-gray", argFlag, &gray, 0, "generate a grayscale PGM file"}, + #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr), "enable FreeType font rasterizer: yes, no"}, #endif + {"-aa", argString, antialiasStr, sizeof(antialiasStr), "enable font anti-aliasing: yes, no"}, {"-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr), "enable vector anti-aliasing: yes, no"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)"}, {"-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)"}, + {"-q", argFlag, &quiet, 0, "don't print any messages or errors"}, {"-v", argFlag, &printVersion, 0, @@ -71,17 +99,40 @@ static ArgDesc argDesc[] = { {NULL} }; +void savePageSlice(PDFDoc *doc, + SplashOutputDev *splashOut, + int pg, int x, int y, int w, int h, + double pg_w, double pg_h, + char *ppmFile) { + if (w == 0) w = (int)ceil(pg_w); + if (h == 0) h = (int)ceil(pg_h); + w = (x+w > pg_w ? (int)ceil(pg_w-x) : w); + h = (y+h > pg_h ? (int)ceil(pg_h-y) : h); + doc->displayPageSlice(splashOut, + pg, resolution, resolution, + 0, + gTrue, gFalse, gFalse, + x, y, w, h + ); + if (ppmFile != NULL) { + splashOut->getBitmap()->writePNMFile(ppmFile); + } else { + splashOut->getBitmap()->writePNMFile(stdout); + } +} + int main(int argc, char *argv[]) { PDFDoc *doc; - GooString *fileName; - char *ppmRoot; - char ppmFile[512]; + GooString *fileName = NULL; + char *ppmRoot = NULL; + char ppmFile[PPM_FILE_SZ]; GooString *ownerPW, *userPW; SplashColor paperColor; SplashOutputDev *splashOut; GBool ok; int exitCode; - int pg; + int pg, pg_num_len, pg_x_len, pg_y_len; + double pg_w, pg_h, tmp; exitCode = 99; @@ -90,16 +141,16 @@ int main(int argc, char *argv[]) { if (mono && gray) { ok = gFalse; } - if (!ok || argc != 3 || printVersion || printHelp) { + if (!ok || argc > 3 || printVersion || printHelp) { fprintf(stderr, "pdftoppm version %s\n", xpdfVersion); fprintf(stderr, "%s\n", xpdfCopyright); if (!printVersion) { - printUsage("pdftoppm", "<PDF-file> <PPM-root>", argDesc); + printUsage("pdftoppm", "[PDF-file [PPM-file-prefix]]", argDesc); } goto err0; } - fileName = new GooString(argv[1]); - ppmRoot = argv[2]; + if (argc > 1) fileName = new GooString(argv[1]); + if (argc == 3) ppmRoot = argv[2]; // read config file globalParams = new GlobalParams(); @@ -133,7 +184,14 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if(fileName != NULL && fileName->cmp("-") != 0) { + doc = new PDFDoc(fileName, ownerPW, userPW); + } else { + Object obj; + + obj.initNull(); + doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + } if (userPW) { delete userPW; } @@ -160,12 +218,29 @@ int main(int argc, char *argv[]) { splashModeRGB8, 4, gFalse, paperColor); splashOut->startDoc(doc->getXRef()); + if (sz != 0) w = h = sz; + pg_num_len = (int)ceil(log(doc->getNumPages()) / log(10)); for (pg = firstPage; pg <= lastPage; ++pg) { - doc->displayPage(splashOut, pg, resolution, resolution, 0, gTrue, gFalse, gFalse); - sprintf(ppmFile, "%.*s-%06d.%s", - (int)sizeof(ppmFile) - 32, ppmRoot, pg, - mono ? "pbm" : gray ? "pgm" : "ppm"); - splashOut->getBitmap()->writePNMFile(ppmFile); + pg_w = doc->getPageMediaWidth(pg); + pg_h = doc->getPageMediaHeight(pg); + if (scaleTo != 0) { + resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h); + } + pg_w = pg_w * (resolution / 72.0); + pg_h = pg_h * (resolution / 72.0); + if (doc->getPageRotate(pg)) { + tmp = pg_w; + pg_w = pg_h; + pg_h = tmp; + } + if (ppmRoot != NULL) { + snprintf(ppmFile, PPM_FILE_SZ, "%.*s-%0*d.%s", + PPM_FILE_SZ - 32, ppmRoot, pg_num_len, pg, + mono ? "pbm" : gray ? "pgm" : "ppm"); + savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, ppmFile); + } else { + savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, NULL); + } } delete splashOut; |