Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: samples/pdfium_test.cc

Issue 408403002: Added options to save pages into BMP and EMF on Windows. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Tue 07/22/2014 15:21:41.80 Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits.h> 5 #include <limits.h>
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include <list> 10 #include <list>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 13
14 #include "../fpdfsdk/include/fpdf_dataavail.h" 14 #include "../fpdfsdk/include/fpdf_dataavail.h"
15 #include "../fpdfsdk/include/fpdf_ext.h" 15 #include "../fpdfsdk/include/fpdf_ext.h"
16 #include "../fpdfsdk/include/fpdfformfill.h" 16 #include "../fpdfsdk/include/fpdfformfill.h"
17 #include "../fpdfsdk/include/fpdftext.h" 17 #include "../fpdfsdk/include/fpdftext.h"
18 #include "../fpdfsdk/include/fpdfview.h" 18 #include "../fpdfsdk/include/fpdfview.h"
19 #include "v8/include/v8.h" 19 #include "v8/include/v8.h"
20 20
21 #ifdef _WIN32 21 #ifdef _WIN32
22 #define snprintf _snprintf 22 #define snprintf _snprintf
23 #endif 23 #endif
24 24
25 static void WritePpm(const char* pdf_name, int num, 25 enum OutputFormat {
26 const char* buffer, int stride, int width, int height) { 26 OUTPUT_NONE,
27 OUTPUT_PPM,
28 #ifdef _WIN32
29 OUTPUT_BMP,
30 OUTPUT_EMF,
31 #endif
32 };
33
34 static void WritePpm(const char* pdf_name, int num, const void* buffer_void,
35 int stride, int width, int height) {
36 const char* buffer = reinterpret_cast<const char*>(buffer_void);
37
27 if (stride < 0 || width < 0 || height < 0) 38 if (stride < 0 || width < 0 || height < 0)
28 return; 39 return;
29 if (height > 0 && width > INT_MAX / height) 40 if (height > 0 && width > INT_MAX / height)
30 return; 41 return;
31 int out_len = width * height; 42 int out_len = width * height;
32 if (out_len > INT_MAX / 3) 43 if (out_len > INT_MAX / 3)
33 return; 44 return;
34 out_len *= 3; 45 out_len *= 3;
35 46
36 char filename[256]; 47 char filename[256];
(...skipping 17 matching lines...) Expand all
54 // B 65 // B
55 dest_line[(w * 3) + 2] = src_line[w * 4]; 66 dest_line[(w * 3) + 2] = src_line[w * 4];
56 } 67 }
57 } 68 }
58 fwrite(result, out_len, 1, fp); 69 fwrite(result, out_len, 1, fp);
59 delete [] result; 70 delete [] result;
60 } 71 }
61 fclose(fp); 72 fclose(fp);
62 } 73 }
63 74
75 #ifdef _WIN32
76 static void WriteBmp(const char* pdf_name, int num, const void* buffer,
77 int stride, int width, int height) {
78 if (stride < 0 || width < 0 || height < 0)
79 return;
80 if (height > 0 && width > INT_MAX / height)
81 return;
82 int out_len = stride * height;
83 if (out_len > INT_MAX / 3)
84 return;
85
86 char filename[256];
87 snprintf(filename, sizeof(filename), "%s.%d.bmp", pdf_name, num);
88 FILE* fp = fopen(filename, "wb");
89 if (!fp)
90 return;
91
92 BITMAPINFO bmi = {0};
93 bmi.bmiHeader.biSize = sizeof(bmi) - sizeof(RGBQUAD);
94 bmi.bmiHeader.biWidth = width;
95 bmi.bmiHeader.biHeight = -height; // top-down image
96 bmi.bmiHeader.biPlanes = 1;
97 bmi.bmiHeader.biBitCount = 32;
98 bmi.bmiHeader.biCompression = BI_RGB;
99 bmi.bmiHeader.biSizeImage = 0;
100
101 BITMAPFILEHEADER file_header = {0};
102 file_header.bfType = 0x4d42;
103 file_header.bfSize = sizeof(file_header) + bmi.bmiHeader.biSize + out_len;
104 file_header.bfOffBits = file_header.bfSize - out_len;
105
106 fwrite(&file_header, sizeof(file_header), 1, fp);
107 fwrite(&bmi, bmi.bmiHeader.biSize, 1, fp);
108 fwrite(buffer, out_len, 1, fp);
109 fclose(fp);
110 }
111
112 HDC CreatePageMetafile(const char* pdf_name, int num, int width, int height) {
113 char filename[256];
114 snprintf(filename, sizeof(filename), "%s.%d_%dx%d.emf", pdf_name, num, width,
115 height);
116 return CreateEnhMetaFileA(NULL, filename, NULL, NULL);
117 }
118 #endif
119
64 int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) { 120 int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) {
65 printf("Form_Alert called.\n"); 121 printf("Form_Alert called.\n");
66 return 0; 122 return 0;
67 } 123 }
68 124
69 void Unsupported_Handler(UNSUPPORT_INFO*, int type) { 125 void Unsupported_Handler(UNSUPPORT_INFO*, int type) {
70 std::string feature = "Unknown"; 126 std::string feature = "Unknown";
71 switch (type) { 127 switch (type) {
72 case FPDF_UNSP_DOC_XFAFORM: 128 case FPDF_UNSP_DOC_XFAFORM:
73 feature = "XFA"; 129 feature = "XFA";
(...skipping 29 matching lines...) Expand all
103 case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA: 159 case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA:
104 feature = "Screen"; 160 feature = "Screen";
105 break; 161 break;
106 case FPDF_UNSP_ANNOT_SIG: 162 case FPDF_UNSP_ANNOT_SIG:
107 feature = "Digital_Signature"; 163 feature = "Digital_Signature";
108 break; 164 break;
109 } 165 }
110 printf("Unsupported feature: %s.\n", feature.c_str()); 166 printf("Unsupported feature: %s.\n", feature.c_str());
111 } 167 }
112 168
113 bool ParseCommandLine(int argc, const char* argv[], bool* write_images, 169 bool ParseCommandLine(int argc, const char* argv[], OutputFormat* output_format,
114 std::list<const char*>* files) { 170 std::list<const char*>* files) {
115 *write_images = false; 171 *output_format = OUTPUT_NONE;
116 files->clear(); 172 files->clear();
117 173
118 int cur_arg = 1; 174 int cur_arg = 1;
119 if (cur_arg < argc && 175 if (cur_arg < argc) {
120 strcmp(argv[cur_arg], "--write_images") == 0) { 176 if (strcmp(argv[cur_arg], "--ppm") == 0)
121 *write_images = true; 177 *output_format = OUTPUT_PPM;
178 #ifdef _WIN32
179 if (strcmp(argv[cur_arg], "--emf") == 0)
180 *output_format = OUTPUT_EMF;
181 if (strcmp(argv[cur_arg], "--bmp") == 0)
182 *output_format = OUTPUT_BMP;
183 #endif
122 cur_arg++; 184 cur_arg++;
123 } 185 }
124 186
125 if (cur_arg >= argc) 187 if (cur_arg >= argc)
126 return false; 188 return false;
127 189
128 for (int i = cur_arg; i < argc; i++) 190 for (int i = cur_arg; i < argc; i++)
129 files->push_back(argv[i]); 191 files->push_back(argv[i]);
130 192
131 return true; 193 return true;
(...skipping 20 matching lines...) Expand all
152 } 214 }
153 215
154 bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { 216 bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {
155 return true; 217 return true;
156 } 218 }
157 219
158 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { 220 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {
159 } 221 }
160 222
161 void RenderPdf(const char* name, const char* pBuf, size_t len, 223 void RenderPdf(const char* name, const char* pBuf, size_t len,
162 bool write_images) { 224 OutputFormat format) {
163 printf("Rendering PDF file %s.\n", name); 225 printf("Rendering PDF file %s.\n", name);
164 226
165 IPDF_JSPLATFORM platform_callbacks; 227 IPDF_JSPLATFORM platform_callbacks;
166 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); 228 memset(&platform_callbacks, '\0', sizeof(platform_callbacks));
167 platform_callbacks.version = 1; 229 platform_callbacks.version = 1;
168 platform_callbacks.app_alert = Form_Alert; 230 platform_callbacks.app_alert = Form_Alert;
169 231
170 FPDF_FORMFILLINFO form_callbacks; 232 FPDF_FORMFILLINFO form_callbacks;
171 memset(&form_callbacks, '\0', sizeof(form_callbacks)); 233 memset(&form_callbacks, '\0', sizeof(form_callbacks));
172 form_callbacks.version = 1; 234 form_callbacks.version = 1;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 FORM_OnAfterLoadPage(page, form); 289 FORM_OnAfterLoadPage(page, form);
228 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); 290 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN);
229 291
230 int width = static_cast<int>(FPDF_GetPageWidth(page)); 292 int width = static_cast<int>(FPDF_GetPageWidth(page));
231 int height = static_cast<int>(FPDF_GetPageHeight(page)); 293 int height = static_cast<int>(FPDF_GetPageHeight(page));
232 FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); 294 FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);
233 FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); 295 FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
234 296
235 FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); 297 FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
236 FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); 298 FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0);
237 if (write_images) { 299 int stride = FPDFBitmap_GetStride(bitmap);
238 const char* buffer = reinterpret_cast<const char*>( 300 const char* buffer =
239 FPDFBitmap_GetBuffer(bitmap)); 301 reinterpret_cast<const char*>(FPDFBitmap_GetBuffer(bitmap));
240 int stride = FPDFBitmap_GetStride(bitmap); 302
241 WritePpm(name, i, buffer, stride, width, height); 303 switch(format) {
304 #ifdef _WIN32
305 case OUTPUT_BMP:
306 WriteBmp(name, i, buffer, stride, width, height);
307 break;
308 #endif
309 case OUTPUT_PPM:
310 WritePpm(name, i, buffer, stride, width, height);
311 break;
312 default:
313 break;
242 } 314 }
243 315
244 FPDFBitmap_Destroy(bitmap); 316 FPDFBitmap_Destroy(bitmap);
245 317
318 #ifdef _WIN32
319 HDC dc = (format == OUTPUT_EMF) ?
320 CreatePageMetafile(name, i, width, height) :
321 CreateEnhMetaFile(NULL, NULL, NULL, NULL);
322 FPDF_RenderPage(dc, page, 0, 0, width, height,
323 0, FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
324 DeleteEnhMetaFile(CloseEnhMetaFile(dc));
Bo Xu 2014/07/22 23:13:48 It seems we won't do anything when (format == OUTP
Vitaly Buka (NO REVIEWS) 2014/07/22 23:24:46 Actually idea was to call that code just like it d
325 #endif
326
246 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); 327 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE);
247 FORM_OnBeforeClosePage(page, form); 328 FORM_OnBeforeClosePage(page, form);
248 FPDFText_ClosePage(text_page); 329 FPDFText_ClosePage(text_page);
249 FPDF_ClosePage(page); 330 FPDF_ClosePage(page);
250 } 331 }
251 332
252 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); 333 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC);
253 FPDFDOC_ExitFormFillEnviroument(form); 334 FPDFDOC_ExitFormFillEnviroument(form);
254 FPDF_CloseDocument(doc); 335 FPDF_CloseDocument(doc);
255 FPDFAvail_Destroy(pdf_avail); 336 FPDFAvail_Destroy(pdf_avail);
256 337
257 printf("Loaded, parsed and rendered %d pages.\n", page_count); 338 printf("Loaded, parsed and rendered %d pages.\n", page_count);
258 } 339 }
259 340
260 int main(int argc, const char* argv[]) { 341 int main(int argc, const char* argv[]) {
261 v8::V8::InitializeICU(); 342 v8::V8::InitializeICU();
262 bool write_images = false; 343 OutputFormat format = OUTPUT_NONE;
263 std::list<const char*> files; 344 std::list<const char*> files;
264 if (!ParseCommandLine(argc, argv, &write_images, &files)) { 345 if (!ParseCommandLine(argc, argv, &format, &files)) {
265 printf("Usage is: test [--write_images] /path/to/pdf\n"); 346 printf("Usage: pdfium_test [OPTIONS] [FILE]\n");
266 printf("--write_images - to write page images <pdf-name>.<page-number>.ppm\n "); 347 printf("--ppm write page images <pdf-name>.<page-number>.ppm\n");
348 #ifdef _WIN32
349 printf("--bmp write page images <pdf-name>.<page-number>.bmp\n");
350 printf("--emf write page meta files <pdf-name>.<page-number>.emf\n");
351 #endif
267 return 1; 352 return 1;
268 } 353 }
269 354
270 FPDF_InitLibrary(NULL); 355 FPDF_InitLibrary(NULL);
271 356
272 UNSUPPORT_INFO unsuppored_info; 357 UNSUPPORT_INFO unsuppored_info;
273 memset(&unsuppored_info, '\0', sizeof(unsuppored_info)); 358 memset(&unsuppored_info, '\0', sizeof(unsuppored_info));
274 unsuppored_info.version = 1; 359 unsuppored_info.version = 1;
275 unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler; 360 unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler;
276 361
277 FSDK_SetUnSpObjProcessHandler(&unsuppored_info); 362 FSDK_SetUnSpObjProcessHandler(&unsuppored_info);
278 363
279 while (!files.empty()) { 364 while (!files.empty()) {
280 const char* filename = files.front(); 365 const char* filename = files.front();
281 files.pop_front(); 366 files.pop_front();
282 FILE* file = fopen(filename, "rb"); 367 FILE* file = fopen(filename, "rb");
283 if (!file) { 368 if (!file) {
284 fprintf(stderr, "Failed to open: %s\n", filename); 369 fprintf(stderr, "Failed to open: %s\n", filename);
285 continue; 370 continue;
286 } 371 }
287 (void) fseek(file, 0, SEEK_END); 372 (void) fseek(file, 0, SEEK_END);
288 size_t len = ftell(file); 373 size_t len = ftell(file);
289 (void) fseek(file, 0, SEEK_SET); 374 (void) fseek(file, 0, SEEK_SET);
290 char* pBuf = (char*) malloc(len); 375 char* pBuf = (char*) malloc(len);
291 size_t ret = fread(pBuf, 1, len, file); 376 size_t ret = fread(pBuf, 1, len, file);
292 (void) fclose(file); 377 (void) fclose(file);
293 if (ret != len) { 378 if (ret != len) {
294 fprintf(stderr, "Failed to read: %s\n", filename); 379 fprintf(stderr, "Failed to read: %s\n", filename);
295 } else { 380 } else {
296 RenderPdf(filename, pBuf, len, write_images); 381 RenderPdf(filename, pBuf, len, format);
297 } 382 }
298 free(pBuf); 383 free(pBuf);
299 } 384 }
300 385
301 FPDF_DestroyLibrary(); 386 FPDF_DestroyLibrary();
302 387
303 return 0; 388 return 0;
304 } 389 }
305
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698