"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.

    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 }