diff options
| author | Calvin Morrison <calvin@pobox.com> | 2023-04-05 14:13:39 -0400 | 
|---|---|---|
| committer | Calvin Morrison <calvin@pobox.com> | 2023-04-05 14:13:39 -0400 | 
| commit | 835e373b3eeaabcd0621ed6798ab500f37982fae (patch) | |
| tree | dfa16b0e2e1b4956b38f693220eac4e607802133 /xpdf/pdftoppm.cc | |
Diffstat (limited to 'xpdf/pdftoppm.cc')
| -rw-r--r-- | xpdf/pdftoppm.cc | 280 | 
1 files changed, 280 insertions, 0 deletions
| diff --git a/xpdf/pdftoppm.cc b/xpdf/pdftoppm.cc new file mode 100644 index 0000000..28861ef --- /dev/null +++ b/xpdf/pdftoppm.cc @@ -0,0 +1,280 @@ +//======================================================================== +// +// pdftoppm.cc +// +// Copyright 2003 Glyph & Cog, LLC +// +//======================================================================== + +#include <aconf.h> +#include <stdio.h> +#ifdef _WIN32 +#  include <io.h> +#  include <fcntl.h> +#endif +#ifdef DEBUG_FP_LINUX +#  include <fenv.h> +#  include <fpu_control.h> +#endif +#include "gmem.h" +#include "gmempp.h" +#include "parseargs.h" +#include "GString.h" +#include "GlobalParams.h" +#include "Object.h" +#include "PDFDoc.h" +#include "SplashBitmap.h" +#include "Splash.h" +#include "SplashOutputDev.h" +#include "Error.h" +#include "config.h" + +static int firstPage = 1; +static int lastPage = 0; +static double resolution = 150; +static GBool mono = gFalse; +static GBool gray = gFalse; +#if SPLASH_CMYK +static GBool cmyk = gFalse; +#endif +static int rotate = 0; +static char enableFreeTypeStr[16] = ""; +static char antialiasStr[16] = ""; +static char vectorAntialiasStr[16] = ""; +static char ownerPassword[33] = ""; +static char userPassword[33] = ""; +static GBool verbose = gFalse; +static GBool quiet = gFalse; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; +static GBool printHelp = gFalse; + +static ArgDesc argDesc[] = { +  {"-f",      argInt,      &firstPage,     0, +   "first page to print"}, +  {"-l",      argInt,      &lastPage,      0, +   "last page to print"}, +  {"-r",      argFP,       &resolution,    0, +   "resolution, in DPI (default is 150)"}, +  {"-mono",   argFlag,     &mono,          0, +   "generate a monochrome PBM file"}, +  {"-gray",   argFlag,     &gray,          0, +   "generate a grayscale PGM file"}, +#if SPLASH_CMYK +  {"-cmyk",   argFlag,     &cmyk,          0, +   "generate a CMYK PAM file"}, +#endif +  {"-rot",    argInt,      &rotate,        0, +   "set page rotation: 0, 90, 180, or 270"}, +#if 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)"}, +  {"-verbose", argFlag,    &verbose,       0, +   "print per-page status information"}, +  {"-q",      argFlag,     &quiet,         0, +   "don't print any messages or errors"}, +  {"-cfg",        argString,      cfgFileName,    sizeof(cfgFileName), +   "configuration file to use in place of .xpdfrc"}, +  {"-v",      argFlag,     &printVersion,  0, +   "print copyright and version info"}, +  {"-h",      argFlag,     &printHelp,     0, +   "print usage information"}, +  {"-help",   argFlag,     &printHelp,     0, +   "print usage information"}, +  {"--help",  argFlag,     &printHelp,     0, +   "print usage information"}, +  {"-?",      argFlag,     &printHelp,     0, +   "print usage information"}, +  {NULL} +}; + +int main(int argc, char *argv[]) { +  PDFDoc *doc; +  char *fileName; +  char *ppmRoot; +  GString *ppmFile; +  GString *ownerPW, *userPW; +  SplashColor paperColor; +  SplashOutputDev *splashOut; +  GBool ok, toStdout, printStatusInfo; +  int exitCode; +  int pg, n; +  const char *ext; + +#ifdef DEBUG_FP_LINUX +  // enable exceptions on floating point div-by-zero +  feenableexcept(FE_DIVBYZERO); +  // force 64-bit rounding: this avoids changes in output when minor +  // code changes result in spills of x87 registers; it also avoids +  // differences in output with valgrind's 64-bit floating point +  // emulation (yes, this is a kludge; but it's pretty much +  // unavoidable given the x87 instruction set; see gcc bug 323 for +  // more info) +  fpu_control_t cw; +  _FPU_GETCW(cw); +  cw = (fpu_control_t)((cw & ~_FPU_EXTENDED) | _FPU_DOUBLE); +  _FPU_SETCW(cw); +#endif + +  exitCode = 99; + +  // parse args +  fixCommandLine(&argc, &argv); +  ok = parseArgs(argDesc, &argc, argv); +  n = 0; +  n += mono ? 1 : 0; +  n += gray ? 1 : 0; +#if SPLASH_CMYK +  n += cmyk ? 1 : 0; +#endif +  if (n > 1) { +    ok = gFalse; +  } +  if (!ok || argc != 3 || printVersion || printHelp) { +    fprintf(stderr, "pdftoppm version %s [www.xpdfreader.com]\n", xpdfVersion); +    fprintf(stderr, "%s\n", xpdfCopyright); +    if (!printVersion) { +      printUsage("pdftoppm", "<PDF-file> <PPM-root>", argDesc); +    } +    goto err0; +  } +  fileName = argv[1]; +  ppmRoot = argv[2]; + +  // read config file +  if (cfgFileName[0] && !pathIsFile(cfgFileName)) { +    error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file", +	  cfgFileName); +  } +  globalParams = new GlobalParams(cfgFileName); +  globalParams->setupBaseFonts(NULL); +  if (enableFreeTypeStr[0]) { +    if (!globalParams->setEnableFreeType(enableFreeTypeStr)) { +      fprintf(stderr, "Bad '-freetype' value on command line\n"); +    } +  } +  if (antialiasStr[0]) { +    if (!globalParams->setAntialias(antialiasStr)) { +      fprintf(stderr, "Bad '-aa' value on command line\n"); +    } +  } +  if (vectorAntialiasStr[0]) { +    if (!globalParams->setVectorAntialias(vectorAntialiasStr)) { +      fprintf(stderr, "Bad '-aaVector' value on command line\n"); +    } +  } +  if (verbose) { +    globalParams->setPrintStatusInfo(verbose); +  } +  if (quiet) { +    globalParams->setErrQuiet(quiet); +  } + +  // open PDF file +  if (ownerPassword[0]) { +    ownerPW = new GString(ownerPassword); +  } else { +    ownerPW = NULL; +  } +  if (userPassword[0]) { +    userPW = new GString(userPassword); +  } else { +    userPW = NULL; +  } +  doc = new PDFDoc(fileName, ownerPW, userPW); +  if (userPW) { +    delete userPW; +  } +  if (ownerPW) { +    delete ownerPW; +  } +  if (!doc->isOk()) { +    exitCode = 1; +    goto err1; +  } + +  // get page range +  if (firstPage < 1) +    firstPage = 1; +  if (lastPage < 1 || lastPage > doc->getNumPages()) +    lastPage = doc->getNumPages(); + +  // file name extension +  if (mono) { +    ext = "pbm"; +  } else if (gray) { +    ext = "pgm"; +#if SPLASH_CMYK +  } else if (cmyk) { +    ext = "pam"; +#endif +  } else { +    ext = "ppm"; +  } + + +  // check for stdout; set up to print per-page status info +  toStdout = !strcmp(ppmRoot, "-"); +  printStatusInfo = !toStdout && globalParams->getPrintStatusInfo(); + +  // write PPM files +  if (mono) { +    paperColor[0] = 0xff; +    splashOut = new SplashOutputDev(splashModeMono1, 1, gFalse, paperColor); +  } else if (gray) { +    paperColor[0] = 0xff; +    splashOut = new SplashOutputDev(splashModeMono8, 1, gFalse, paperColor); +#if SPLASH_CMYK +  } else if (cmyk) { +    paperColor[0] = paperColor[1] = paperColor[2] = paperColor[3] = 0; +    splashOut = new SplashOutputDev(splashModeCMYK8, 1, gFalse, paperColor); +#endif // SPLASH_CMYK +  } else { +    paperColor[0] = paperColor[1] = paperColor[2] = 0xff; +    splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); +  } +  splashOut->startDoc(doc->getXRef()); +  for (pg = firstPage; pg <= lastPage; ++pg) { +    if (printStatusInfo) { +      fflush(stderr); +      printf("[processing page %d]\n", pg); +      fflush(stdout); +    } +    doc->displayPage(splashOut, pg, resolution, resolution, rotate, +		     gFalse, gTrue, gFalse); +    if (toStdout) { +#ifdef _WIN32 +      _setmode(_fileno(stdout), _O_BINARY); +#endif +      splashOut->getBitmap()->writePNMFile(stdout); +    } else { +      ppmFile = GString::format("{0:s}-{1:06d}.{2:s}", ppmRoot, pg, ext); +      splashOut->getBitmap()->writePNMFile(ppmFile->getCString()); +      delete ppmFile; +    } +  } +  delete splashOut; + +  exitCode = 0; + +  // clean up + err1: +  delete doc; +  delete globalParams; + err0: + +  // check for memory leaks +  Object::memCheck(stderr); +  gMemReport(stderr); + +  return exitCode; +} | 
