"Fossies" - the Fresh Open Source Software Archive

Member "xpdf-4.02/xpdf/pdftops.cc" (25 Sep 2019, 11065 Bytes) of package /linux/misc/xpdf-4.02.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 last Fossies "Diffs" side-by-side code changes report: 4.00_vs_4.01.

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