summaryrefslogtreecommitdiff
path: root/src/generic/evas/pdf/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/generic/evas/pdf/main.cpp')
-rw-r--r--src/generic/evas/pdf/main.cpp353
1 files changed, 353 insertions, 0 deletions
diff --git a/src/generic/evas/pdf/main.cpp b/src/generic/evas/pdf/main.cpp
new file mode 100644
index 0000000..6b1de13
--- /dev/null
+++ b/src/generic/evas/pdf/main.cpp
@@ -0,0 +1,353 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <sys/mman.h>
6#include <fcntl.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <libgen.h>
10
11#include <GlobalParams.h>
12#include <PDFDoc.h>
13#include <ErrorCodes.h>
14#include <Page.h>
15#include <SplashOutputDev.h>
16#include <splash/SplashBitmap.h>
17
18#include <Eina.h>
19
20#include "shmfile.h"
21#include "timeout.h"
22
23#define DATA32 unsigned int
24
25//#define PDF_DBG
26
27#ifdef PDF_DBG
28#define D(fmt, args...) fprintf(stderr, fmt, ## args)
29#else
30#define D(fmt, args...)
31#endif
32
33
34PDFDoc *pdfdoc;
35bool locked = false;
36
37::Page *page;
38int width = 0, height = 0;
39int crop_width = 0, crop_height = 0;
40void *data = NULL;
41double dpi = -1.0;
42
43#define DEF_DPI 72.0
44
45Eina_Bool poppler_init(const char *file, int page_nbr, int size_w, int size_h)
46{
47 Object obj;
48 double w, h, cw, ch;
49 int rot;
50
51 if (!file || !*file)
52 return EINA_FALSE;
53
54 if (page_nbr < 0)
55 return EINA_FALSE;
56
57 if (!(globalParams = new GlobalParams()))
58 return EINA_FALSE;
59
60 if (!eina_init())
61 goto del_global_param;
62
63#ifndef HAVE_POPPLER_031
64 if (globalParams->getAntialias())
65 globalParams->setAntialias((char *)"yes");
66 if (globalParams->getVectorAntialias())
67 globalParams->setVectorAntialias((char *)"yes");
68#endif
69
70 pdfdoc = new PDFDoc(new GooString(file), NULL);
71 if (!pdfdoc)
72 goto del_global_param;
73
74 if (!pdfdoc->isOk() || (pdfdoc->getErrorCode() == errEncrypted))
75 goto del_pdfdoc;
76
77 if (page_nbr >= pdfdoc->getNumPages())
78 goto del_pdfdoc;
79
80 /* load the page */
81
82 page = pdfdoc->getCatalog()->getPage(page_nbr + 1);
83 if (!page || !page->isOk())
84 goto del_pdfdoc;
85
86 w = page->getMediaWidth();
87 h = page->getMediaHeight();
88 cw = page->getCropWidth();
89 ch = page->getCropHeight();
90 rot = page->getRotate();
91 if (cw > w) cw = w;
92 if (ch > h) ch = h;
93 if ((rot == 90) || (rot == 270))
94 {
95 double t;
96 // swap width & height
97 t = w; w = h; h = t;
98 // swap crop width & height
99 t = cw; cw = ch; ch = t;
100 }
101
102 if ((size_w > 0) || (size_h > 0))
103 {
104 double w2 = cw, h2 = ch;
105
106 w2 = size_w;
107 h2 = (size_w * ch) / cw;
108 if (h2 > size_h)
109 {
110 h2 = size_h;
111 w2 = (size_h * cw) / ch;
112 }
113 D("XXXXXXXXXXXXXXXXXXXXx %3.3fx%3.3f\n", w2, h2);
114 if (w2 > h2) dpi = (w2 * DEF_DPI) / cw;
115 else dpi = (h2 * DEF_DPI) / ch;
116 }
117
118 if (dpi > 0.0)
119 {
120 cw = (cw * dpi) / DEF_DPI;
121 ch = (ch * dpi) / DEF_DPI;
122 w = (w * dpi) / DEF_DPI;
123 h = (h * dpi) / DEF_DPI;
124 }
125 width = w;
126 height = h;
127 crop_width = cw;
128 crop_height = ch;
129
130 return EINA_TRUE;
131
132 del_pdfdoc:
133 delete pdfdoc;
134 del_global_param:
135 delete globalParams;
136
137 return EINA_FALSE;
138}
139
140void poppler_shutdown()
141{
142 delete pdfdoc;
143 eina_shutdown();
144 delete globalParams;
145}
146
147void poppler_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED)
148{
149 SplashOutputDev *output_dev;
150 SplashColor white;
151 SplashColorPtr color_ptr;
152 DATA32 *src, *dst;
153 int y;
154
155 white[0] = 255;
156 white[1] = 255;
157 white[2] = 255;
158 white[3] = 255;
159
160 output_dev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, white);
161 if (!output_dev)
162 return;
163
164#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031)
165 output_dev->startDoc(pdfdoc);
166#else
167 output_dev->startDoc(pdfdoc->getXRef());
168#endif
169
170 if (dpi <= 0.0) dpi = DEF_DPI;
171
172#ifdef HAVE_POPPLER_031
173 output_dev->setFontAntialias(EINA_TRUE);
174 output_dev->setVectorAntialias(EINA_TRUE);
175#endif
176
177#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031)
178 page->displaySlice(output_dev, dpi, dpi,
179 0, false, false,
180 0, 0, width, height,
181 false, NULL, NULL);
182#else
183 page->displaySlice(output_dev, dpi, dpi,
184 0, false, false,
185 0, 0, width, height,
186 false, pdfdoc->getCatalog());
187#endif
188 color_ptr = output_dev->getBitmap()->getDataPtr();
189
190 shm_alloc(crop_width * crop_height * sizeof(DATA32));
191 if (!shm_addr) goto del_outpput_dev;
192 data = shm_addr;
193 src = (DATA32 *)color_ptr;
194 dst = (DATA32 *)data;
195 for (y = 0; y < crop_height; y++)
196 {
197 memcpy(dst, src, crop_width * sizeof(DATA32));
198 src += width;
199 dst += crop_width;
200 }
201
202 del_outpput_dev:
203 delete output_dev;
204}
205
206int
207main(int argc, char **argv)
208{
209 Eina_Tmpstr *tmpdir = NULL;
210 Eina_Tmpstr *generated = NULL;
211 char *extension;
212 char *dir;
213 char *file;
214 int i;
215 int size_w = 0, size_h = 0;
216 int head_only = 0;
217 int page_num = 0;
218
219 if (argc < 2) return -1;
220 // file is ALWAYS first arg, other options come after
221 file = argv[1];
222 for (i = 2; i < argc; i++)
223 {
224 if (!strcmp(argv[i], "-head"))
225 // asked to only load header, not body/data
226 head_only = 1;
227 else if (!strcmp(argv[i], "-key"))
228 {
229 i++;
230 page_num = atoi(argv[i]);
231 i++;
232 }
233 else if (!strcmp(argv[i], "-opt-scale-down-by"))
234 { // not used by pdf loader
235 i++;
236 // int scale_down = atoi(argv[i]);
237 }
238 else if (!strcmp(argv[i], "-opt-dpi"))
239 {
240 i++;
241 dpi = ((double)atoi(argv[i])) / 1000.0; // dpi is an int multiplied by 1000 (so 72dpi is 72000)
242 i++;
243 }
244 else if (!strcmp(argv[i], "-opt-size"))
245 { // not used by pdf loader
246 i++;
247 size_w = atoi(argv[i]);
248 i++;
249 size_h = atoi(argv[i]);
250 }
251 }
252
253 D("dpi....: %f\n", dpi);
254 D("page...: %d\n", page_num);
255
256 // This is a funny hack to call an external tool to generate a pdf that will then be processed by poppler
257 extension = strrchr(file, '.');
258 dir = dirname(argv[0]);
259 if (extension && dir && strcmp(extension, ".pdf"))
260 {
261 if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir))
262 {
263 Eina_Strbuf *tmp;
264 FILE *cmd;
265
266 tmp = eina_strbuf_new();
267 eina_strbuf_append_printf(tmp, "%s/evas_generic_pdf_loader.%s '%s' %s", dir, extension + 1, file, tmpdir);
268
269 cmd = popen(eina_strbuf_string_get(tmp), "r");
270 D("running preprocessing process '%s'...\n", eina_strbuf_string_get(tmp));
271 eina_strbuf_reset(tmp);
272
273 if (cmd)
274 {
275 struct stat st;
276 const char *filename;
277 char buf[1024];
278
279 while (fgets(buf, sizeof (buf), cmd))
280 ;
281 pclose(cmd);
282
283 filename = basename(file);
284 generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension));
285
286 eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated);
287
288 eina_tmpstr_del(generated);
289 generated = NULL;
290
291 if (stat(eina_strbuf_string_get(tmp), &st) == 0)
292 {
293 generated = eina_tmpstr_add_length(eina_strbuf_string_get(tmp),
294 eina_strbuf_length_get(tmp));
295 file = (char*) generated;
296 }
297 }
298
299 D("generated file: '%s'\n", generated);
300 eina_strbuf_free(tmp);
301 }
302 }
303
304 // Let's force a timeout if things go wrong
305 timeout_init(10);
306
307 // Now process the pdf (or the generated pdf)
308 D("poppler_file_init\n");
309 if (!poppler_init(file, page_num, size_w, size_h))
310 return -1;
311 D("poppler_file_init done\n");
312
313 D("dpi2...: %f\n", dpi);
314 if (!head_only)
315 {
316 poppler_load_image(size_w, size_h);
317 }
318
319 D("size...: %ix%i\n", width, height);
320 D("crop...: %ix%i\n", crop_width, crop_height);
321 D("alpha..: 1\n");
322
323 printf("size %i %i\n", crop_width, crop_height);
324 printf("alpha 0\n");
325
326 if (!head_only)
327 {
328 if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
329 else
330 {
331 // could also to "tmpfile %s\n" like shmfile but just
332 // a mmaped tmp file on the system
333 printf("data\n");
334 fwrite(data, crop_width * crop_height * sizeof(DATA32), 1, stdout);
335 }
336 shm_free();
337 }
338 else
339 printf("done\n");
340
341 poppler_shutdown();
342
343 if (tmpdir)
344 {
345 if (generated) unlink(generated);
346 rmdir(tmpdir);
347
348 eina_tmpstr_del(tmpdir);
349 eina_tmpstr_del(generated);
350 }
351 fflush(stdout);
352 return 0;
353}