"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. For more information about "pdftops.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.03_vs_4.04.

    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 }