Spaces:
Running
Running
File size: 5,721 Bytes
5cee033 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
//========================================================================
//
// pdfseparate.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2011, 2012, 2015 Thomas Freitag <[email protected]>
// Copyright (C) 2012-2014, 2017, 2018, 2021, 2022 Albert Astals Cid <[email protected]>
// Copyright (C) 2013, 2016 Pino Toscano <[email protected]>
// Copyright (C) 2013 Daniel Kahn Gillmor <[email protected]>
// Copyright (C) 2013 Suzuki Toshiya <[email protected]>
// Copyright (C) 2017 Léonard Michelet <[email protected]>
// Copyright (C) 2017 Adrian Johnson <[email protected]>
// Copyright (C) 2018 Adam Reichold <[email protected]>
// Copyright (C) 2019 Oliver Sander <[email protected]>
//
//========================================================================
#include "config.h"
#include <poppler-config.h>
#include <cstdio>
#include <cstdlib>
#include <cstddef>
#include <cstring>
#include "parseargs.h"
#include "goo/GooString.h"
#include "PDFDoc.h"
#include "ErrorCodes.h"
#include "GlobalParams.h"
#include "Win32Console.h"
#include <cctype>
static int firstPage = 0;
static int lastPage = 0;
static bool printVersion = false;
static bool printHelp = false;
static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to extract" },
{ "-l", argInt, &lastPage, 0, "last page to extract" },
{ "-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" },
{} };
static bool extractPages(const char *srcFileName, const char *destFileName)
{
char pathName[4096];
PDFDoc *doc = new PDFDoc(std::make_unique<GooString>(srcFileName));
if (!doc->isOk()) {
error(errSyntaxError, -1, "Could not extract page(s) from damaged file ('{0:s}')", srcFileName);
delete doc;
return false;
}
// destFileName can have multiple %% and one %d
// We use auxDestFileName to replace all the valid % appearances
// by 'A' (random char that is not %), if at the end of replacing
// any of the valid appearances there is still any % around, the
// pattern is wrong
if (firstPage == 0 && lastPage == 0) {
firstPage = 1;
lastPage = doc->getNumPages();
}
if (lastPage == 0) {
lastPage = doc->getNumPages();
}
if (firstPage == 0) {
firstPage = 1;
}
if (lastPage < firstPage) {
error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
delete doc;
return false;
}
bool foundmatch = false;
char *auxDestFileName = strdup(destFileName);
char *p = strstr(auxDestFileName, "%d");
if (p != nullptr) {
foundmatch = true;
*p = 'A';
} else {
char pattern[6];
for (int i = 2; i < 10; i++) {
sprintf(pattern, "%%0%dd", i);
p = strstr(auxDestFileName, pattern);
if (p != nullptr) {
foundmatch = true;
*p = 'A';
break;
}
}
}
if (!foundmatch && firstPage != lastPage) {
error(errSyntaxError, -1, "'{0:s}' must contain '%d' (or any variant respecting printf format) if more than one page should be extracted, in order to print the page number", destFileName);
free(auxDestFileName);
delete doc;
return false;
}
// at this point auxDestFileName can only contain %%
p = strstr(auxDestFileName, "%%");
while (p != nullptr) {
*p = 'A';
*(p + 1) = 'A';
p = strstr(p, "%%");
}
// at this point any other % is wrong
p = strstr(auxDestFileName, "%");
if (p != nullptr) {
error(errSyntaxError, -1, "'{0:s}' can only contain one '%d' pattern", destFileName);
free(auxDestFileName);
delete doc;
return false;
}
free(auxDestFileName);
for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) {
snprintf(pathName, sizeof(pathName) - 1, destFileName, pageNo);
PDFDoc *pagedoc = new PDFDoc(std::make_unique<GooString>(srcFileName));
int errCode = pagedoc->savePageAs(GooString(pathName), pageNo);
if (errCode != errNone) {
delete doc;
delete pagedoc;
return false;
}
delete pagedoc;
}
delete doc;
return true;
}
static constexpr int kOtherError = 99;
int main(int argc, char *argv[])
{
// parse args
Win32Console win32console(&argc, &argv);
const bool parseOK = parseArgs(argDesc, &argc, argv);
if (!parseOK || argc != 3 || printVersion || printHelp) {
fprintf(stderr, "pdfseparate version %s\n", PACKAGE_VERSION);
fprintf(stderr, "%s\n", popplerCopyright);
fprintf(stderr, "%s\n", xpdfCopyright);
if (!printVersion) {
printUsage("pdfseparate", "<PDF-sourcefile> <PDF-pattern-destfile>", argDesc);
}
if (printVersion || printHelp) {
return 0;
} else {
return kOtherError;
}
}
globalParams = std::make_unique<GlobalParams>();
const bool extractOK = extractPages(argv[1], argv[2]);
return extractOK ? 0 : kOtherError;
}
|