summaryrefslogtreecommitdiff
path: root/utils/pdftoppm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'utils/pdftoppm.cc')
-rw-r--r--utils/pdftoppm.cc130
1 files changed, 126 insertions, 4 deletions
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index cebb12a4..73f337c2 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -23,7 +23,8 @@
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2010 Jonathan Liu <net147@gmail.com>
// Copyright (C) 2010 William Bader <williambader@hotmail.com>
-// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2011-2013 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -49,6 +50,18 @@
#include "splash/Splash.h"
#include "SplashOutputDev.h"
+// Uncomment to build pdftoppm with pthreads
+// You may also have to change the buildsystem to
+// link pdftoppm to pthread library
+// This is here for developer testing not user ready
+// #define UTILS_USE_PTHREADS 1
+
+#ifdef UTILS_USE_PTHREADS
+#include <errno.h>
+#include <pthread.h>
+#include <deque>
+#endif // UTILS_USE_PTHREADS
+
static int firstPage = 1;
static int lastPage = 0;
static GBool printOnlyOdd = gFalse;
@@ -81,6 +94,9 @@ static char vectorAntialiasStr[16] = "";
static char ownerPassword[33] = "";
static char userPassword[33] = "";
static char TiffCompressionStr[16] = "";
+#ifdef UTILS_USE_PTHREADS
+static int numberOfJobs = 1;
+#endif // UTILS_USE_PTHREADS
static GBool quiet = gFalse;
static GBool printVersion = gFalse;
static GBool printHelp = gFalse;
@@ -164,6 +180,11 @@ static const ArgDesc argDesc[] = {
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+#ifdef UTILS_USE_PTHREADS
+ {"-j", argInt, &numberOfJobs, 0,
+ "number of jobs to run concurrently"},
+#endif // UTILS_USE_PTHREADS
+
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-v", argFlag, &printVersion, 0,
@@ -226,6 +247,54 @@ static void savePageSlice(PDFDoc *doc,
}
}
+#ifdef UTILS_USE_PTHREADS
+
+struct PageJob {
+ PDFDoc *doc;
+ int pg;
+
+ double pg_w, pg_h;
+ SplashColor* paperColor;
+
+ char *ppmFile;
+};
+
+static std::deque<PageJob> pageJobQueue;
+static pthread_mutex_t pageJobMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void processPageJobs() {
+ while(true) {
+ // pop the next job or exit if queue is empty
+ pthread_mutex_lock(&pageJobMutex);
+
+ if(pageJobQueue.empty()) {
+ pthread_mutex_unlock(&pageJobMutex);
+ return;
+ }
+
+ PageJob pageJob = pageJobQueue.front();
+ pageJobQueue.pop_front();
+
+ pthread_mutex_unlock(&pageJobMutex);
+
+ // process the job
+ SplashOutputDev *splashOut = new SplashOutputDev(mono ? splashModeMono1 :
+ gray ? splashModeMono8 :
+#if SPLASH_CMYK
+ (jpegcmyk || overprint) ? splashModeDeviceN8 :
+#endif
+ splashModeRGB8, 4, gFalse, *pageJob.paperColor);
+ splashOut->startDoc(pageJob.doc);
+
+ savePageSlice(pageJob.doc, splashOut, pageJob.pg, x, y, w, h, pageJob.pg_w, pageJob.pg_h, pageJob.ppmFile);
+
+ delete splashOut;
+ delete[] pageJob.ppmFile;
+ }
+}
+
+#endif // UTILS_USE_PTHREADS
+
static int numberOfCharacters(unsigned int n)
{
int charNum = 0;
@@ -245,7 +314,11 @@ int main(int argc, char *argv[]) {
char *ppmFile;
GooString *ownerPW, *userPW;
SplashColor paperColor;
+#ifndef UTILS_USE_PTHREADS
SplashOutputDev *splashOut;
+#else
+ pthread_t* jobs;
+#endif // UTILS_USE_PTHREADS
GBool ok;
int exitCode;
int pg, pg_num_len;
@@ -362,6 +435,9 @@ int main(int argc, char *argv[]) {
paperColor[1] = 255;
paperColor[2] = 255;
}
+
+#ifndef UTILS_USE_PTHREADS
+
splashOut = new SplashOutputDev(mono ? splashModeMono1 :
gray ? splashModeMono8 :
#if SPLASH_CMYK
@@ -370,6 +446,9 @@ int main(int argc, char *argv[]) {
splashModeRGB8, 4,
gFalse, paperColor);
splashOut->startDoc(doc);
+
+#endif // UTILS_USE_PTHREADS
+
if (sz != 0) w = h = sz;
pg_num_len = numberOfCharacters(doc->getNumPages());
for (pg = firstPage; pg <= lastPage; ++pg) {
@@ -414,13 +493,56 @@ int main(int argc, char *argv[]) {
ppmFile = new char[strlen(ppmRoot) + 1 + pg_num_len + 1 + strlen(ext) + 1];
sprintf(ppmFile, "%s-%0*d.%s", ppmRoot, pg_num_len, pg, ext);
}
- savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, ppmFile);
- delete[] ppmFile;
} else {
- savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, NULL);
+ ppmFile = NULL;
}
+#ifndef UTILS_USE_PTHREADS
+ // process job in main thread
+ savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, ppmFile);
+
+ delete[] ppmFile;
+#else
+
+ // queue job for worker threads
+ PageJob pageJob = {
+ .doc = doc,
+ .pg = pg,
+
+ .pg_w = pg_w, .pg_h = pg_h,
+
+ .paperColor = &paperColor,
+
+ .ppmFile = ppmFile
+ };
+
+ pageJobQueue.push_back(pageJob);
+
+#endif // UTILS_USE_PTHREADS
}
+#ifndef UTILS_USE_PTHREADS
delete splashOut;
+#else
+
+ // spawn worker threads and wait on them
+ jobs = (pthread_t*)malloc(numberOfJobs * sizeof(pthread_t));
+
+ for(int i=0; i < numberOfJobs; ++i) {
+ if(pthread_create(&jobs[i], NULL, (void* (*)(void*))processPageJobs, NULL) != 0) {
+ fprintf(stderr, "pthread_create() failed with errno: %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for(int i=0; i < numberOfJobs; ++i) {
+ if(pthread_join(jobs[i], NULL) != 0) {
+ fprintf(stderr, "pthread_join() failed with errno: %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ free(jobs);
+
+#endif // UTILS_USE_PTHREADS
exitCode = 0;