OLD | NEW |
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 #include <wchar.h> | 9 #include <wchar.h> |
10 | 10 |
11 #include <list> | 11 #include <list> |
12 #include <sstream> | 12 #include <sstream> |
13 #include <string> | 13 #include <string> |
14 #include <utility> | 14 #include <utility> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "../fpdfsdk/include/fpdf_dataavail.h" | 17 #include "../fpdfsdk/include/fpdf_dataavail.h" |
18 #include "../fpdfsdk/include/fpdf_ext.h" | 18 #include "../fpdfsdk/include/fpdf_ext.h" |
19 #include "../fpdfsdk/include/fpdfformfill.h" | 19 #include "../fpdfsdk/include/fpdfformfill.h" |
20 #include "../fpdfsdk/include/fpdftext.h" | 20 #include "../fpdfsdk/include/fpdftext.h" |
21 #include "../fpdfsdk/include/fpdfview.h" | 21 #include "../fpdfsdk/include/fpdfview.h" |
22 #include "../core/include/fxcrt/fx_system.h" | 22 #include "../core/include/fxcrt/fx_system.h" |
23 #include "v8/include/v8.h" | 23 #include "v8/include/v8.h" |
| 24 #include "image_diff_png.h" |
24 | 25 |
25 #ifdef _WIN32 | 26 #ifdef _WIN32 |
26 #define snprintf _snprintf | 27 #define snprintf _snprintf |
27 #define PATH_SEPARATOR '\\' | 28 #define PATH_SEPARATOR '\\' |
28 #else | 29 #else |
29 #define PATH_SEPARATOR '/' | 30 #define PATH_SEPARATOR '/' |
30 #endif | 31 #endif |
31 | 32 |
32 enum OutputFormat { | 33 enum OutputFormat { |
33 OUTPUT_NONE, | 34 OUTPUT_NONE, |
34 OUTPUT_PPM, | 35 OUTPUT_PPM, |
| 36 OUTPUT_PNG, |
35 #ifdef _WIN32 | 37 #ifdef _WIN32 |
36 OUTPUT_BMP, | 38 OUTPUT_BMP, |
37 OUTPUT_EMF, | 39 OUTPUT_EMF, |
38 #endif | 40 #endif |
39 }; | 41 }; |
40 | 42 |
41 struct Options { | 43 struct Options { |
42 Options() : output_format(OUTPUT_NONE) { } | 44 Options() : output_format(OUTPUT_NONE) { } |
43 | 45 |
44 OutputFormat output_format; | 46 OutputFormat output_format; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 char* data_buffer = GetFileContents(full_path.c_str(), &data_length); | 108 char* data_buffer = GetFileContents(full_path.c_str(), &data_length); |
107 if (!data_buffer) { | 109 if (!data_buffer) { |
108 return false; | 110 return false; |
109 } | 111 } |
110 result_data->data = const_cast<const char*>(data_buffer); | 112 result_data->data = const_cast<const char*>(data_buffer); |
111 result_data->raw_size = data_length; | 113 result_data->raw_size = data_length; |
112 return true; | 114 return true; |
113 } | 115 } |
114 #endif // V8_USE_EXTERNAL_STARTUP_DATA | 116 #endif // V8_USE_EXTERNAL_STARTUP_DATA |
115 | 117 |
| 118 static bool CheckDimensions(int stride, int width, int height) { |
| 119 if (stride < 0 || width < 0 || height < 0) |
| 120 return false; |
| 121 if (height > 0 && width > INT_MAX / height) |
| 122 return false; |
| 123 return true; |
| 124 } |
| 125 |
116 static void WritePpm(const char* pdf_name, int num, const void* buffer_void, | 126 static void WritePpm(const char* pdf_name, int num, const void* buffer_void, |
117 int stride, int width, int height) { | 127 int stride, int width, int height) { |
118 const char* buffer = reinterpret_cast<const char*>(buffer_void); | 128 const char* buffer = reinterpret_cast<const char*>(buffer_void); |
119 | 129 |
120 if (stride < 0 || width < 0 || height < 0) | 130 if (!CheckDimensions(stride, width, height)) |
121 return; | 131 return; |
122 if (height > 0 && width > INT_MAX / height) | 132 |
123 return; | |
124 int out_len = width * height; | 133 int out_len = width * height; |
125 if (out_len > INT_MAX / 3) | 134 if (out_len > INT_MAX / 3) |
126 return; | 135 return; |
127 out_len *= 3; | 136 out_len *= 3; |
128 | 137 |
129 char filename[256]; | 138 char filename[256]; |
130 snprintf(filename, sizeof(filename), "%s.%d.ppm", pdf_name, num); | 139 snprintf(filename, sizeof(filename), "%s.%d.ppm", pdf_name, num); |
131 FILE* fp = fopen(filename, "wb"); | 140 FILE* fp = fopen(filename, "wb"); |
132 if (!fp) | 141 if (!fp) |
133 return; | 142 return; |
(...skipping 13 matching lines...) Expand all Loading... |
147 // B | 156 // B |
148 dest_line[(w * 3) + 2] = src_line[w * 4]; | 157 dest_line[(w * 3) + 2] = src_line[w * 4]; |
149 } | 158 } |
150 } | 159 } |
151 fwrite(result, out_len, 1, fp); | 160 fwrite(result, out_len, 1, fp); |
152 delete [] result; | 161 delete [] result; |
153 } | 162 } |
154 fclose(fp); | 163 fclose(fp); |
155 } | 164 } |
156 | 165 |
| 166 static void WritePng(const char* pdf_name, int num, const void* buffer_void, |
| 167 int stride, int width, int height) { |
| 168 if (!CheckDimensions(stride, width, height)) |
| 169 return; |
| 170 |
| 171 std::vector<unsigned char> png_encoding; |
| 172 const unsigned char* buffer = static_cast<const unsigned char*>(buffer_void); |
| 173 if (!image_diff_png::EncodeBGRAPNG( |
| 174 buffer, width, height, stride, false, &png_encoding)) { |
| 175 fprintf(stderr, "Failed to convert bitmap to PNG\n"); |
| 176 return; |
| 177 } |
| 178 |
| 179 char filename[256]; |
| 180 int chars_formatted = snprintf( |
| 181 filename, sizeof(filename), "%s.%d.png", pdf_name, num); |
| 182 if (chars_formatted < 0 || |
| 183 static_cast<size_t>(chars_formatted) >= sizeof(filename)) { |
| 184 fprintf(stderr, "Filname %s is too long\n", filename); |
| 185 return; |
| 186 } |
| 187 |
| 188 FILE* fp = fopen(filename, "wb"); |
| 189 if (!fp) { |
| 190 fprintf(stderr, "Failed to open %s for output\n", filename); |
| 191 return; |
| 192 } |
| 193 |
| 194 size_t bytes_written = fwrite( |
| 195 &png_encoding.front(), 1, png_encoding.size(), fp); |
| 196 if (bytes_written != png_encoding.size()) |
| 197 fprintf(stderr, "Failed to write to %s\n", filename); |
| 198 |
| 199 (void) fclose(fp); |
| 200 } |
| 201 |
157 #ifdef _WIN32 | 202 #ifdef _WIN32 |
158 static void WriteBmp(const char* pdf_name, int num, const void* buffer, | 203 static void WriteBmp(const char* pdf_name, int num, const void* buffer, |
159 int stride, int width, int height) { | 204 int stride, int width, int height) { |
160 if (stride < 0 || width < 0 || height < 0) | 205 if (!CheckDimensions(stride, width, height)) |
161 return; | 206 return; |
162 if (height > 0 && width > INT_MAX / height) | 207 |
163 return; | |
164 int out_len = stride * height; | 208 int out_len = stride * height; |
165 if (out_len > INT_MAX / 3) | 209 if (out_len > INT_MAX / 3) |
166 return; | 210 return; |
167 | 211 |
168 char filename[256]; | 212 char filename[256]; |
169 snprintf(filename, sizeof(filename), "%s.%d.bmp", pdf_name, num); | 213 snprintf(filename, sizeof(filename), "%s.%d.bmp", pdf_name, num); |
170 FILE* fp = fopen(filename, "wb"); | 214 FILE* fp = fopen(filename, "wb"); |
171 if (!fp) | 215 if (!fp) |
172 return; | 216 return; |
173 | 217 |
(...skipping 18 matching lines...) Expand all Loading... |
192 } | 236 } |
193 | 237 |
194 void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) { | 238 void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) { |
195 int width = static_cast<int>(FPDF_GetPageWidth(page)); | 239 int width = static_cast<int>(FPDF_GetPageWidth(page)); |
196 int height = static_cast<int>(FPDF_GetPageHeight(page)); | 240 int height = static_cast<int>(FPDF_GetPageHeight(page)); |
197 | 241 |
198 char filename[256]; | 242 char filename[256]; |
199 snprintf(filename, sizeof(filename), "%s.%d.emf", pdf_name, num); | 243 snprintf(filename, sizeof(filename), "%s.%d.emf", pdf_name, num); |
200 | 244 |
201 HDC dc = CreateEnhMetaFileA(NULL, filename, NULL, NULL); | 245 HDC dc = CreateEnhMetaFileA(NULL, filename, NULL, NULL); |
202 | 246 |
203 HRGN rgn = CreateRectRgn(0, 0, width, height); | 247 HRGN rgn = CreateRectRgn(0, 0, width, height); |
204 SelectClipRgn(dc, rgn); | 248 SelectClipRgn(dc, rgn); |
205 DeleteObject(rgn); | 249 DeleteObject(rgn); |
206 | 250 |
207 SelectObject(dc, GetStockObject(NULL_PEN)); | 251 SelectObject(dc, GetStockObject(NULL_PEN)); |
208 SelectObject(dc, GetStockObject(WHITE_BRUSH)); | 252 SelectObject(dc, GetStockObject(WHITE_BRUSH)); |
209 // If a PS_NULL pen is used, the dimensions of the rectangle are 1 pixel less. | 253 // If a PS_NULL pen is used, the dimensions of the rectangle are 1 pixel less. |
210 Rectangle(dc, 0, 0, width + 1, height + 1); | 254 Rectangle(dc, 0, 0, width + 1, height + 1); |
211 | 255 |
212 FPDF_RenderPage(dc, page, 0, 0, width, height, 0, | 256 FPDF_RenderPage(dc, page, 0, 0, width, height, 0, |
213 FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH); | 257 FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH); |
214 | 258 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 options->exe_path = args[0]; | 330 options->exe_path = args[0]; |
287 size_t cur_idx = 1; | 331 size_t cur_idx = 1; |
288 for (; cur_idx < args.size(); ++cur_idx) { | 332 for (; cur_idx < args.size(); ++cur_idx) { |
289 const std::string& cur_arg = args[cur_idx]; | 333 const std::string& cur_arg = args[cur_idx]; |
290 if (cur_arg == "--ppm") { | 334 if (cur_arg == "--ppm") { |
291 if (options->output_format != OUTPUT_NONE) { | 335 if (options->output_format != OUTPUT_NONE) { |
292 fprintf(stderr, "Duplicate or conflicting --ppm argument\n"); | 336 fprintf(stderr, "Duplicate or conflicting --ppm argument\n"); |
293 return false; | 337 return false; |
294 } | 338 } |
295 options->output_format = OUTPUT_PPM; | 339 options->output_format = OUTPUT_PPM; |
| 340 } else if (cur_arg == "--png") { |
| 341 if (options->output_format != OUTPUT_NONE) { |
| 342 fprintf(stderr, "Duplicate or conflicting --png argument\n"); |
| 343 return false; |
| 344 } |
| 345 options->output_format = OUTPUT_PNG; |
296 } | 346 } |
297 #ifdef _WIN32 | 347 #ifdef _WIN32 |
298 else if (cur_arg == "--emf") { | 348 else if (cur_arg == "--emf") { |
299 if (options->output_format != OUTPUT_NONE) { | 349 if (options->output_format != OUTPUT_NONE) { |
300 fprintf(stderr, "Duplicate or conflicting --emf argument\n"); | 350 fprintf(stderr, "Duplicate or conflicting --emf argument\n"); |
301 return false; | 351 return false; |
302 } | 352 } |
303 options->output_format = OUTPUT_EMF; | 353 options->output_format = OUTPUT_EMF; |
304 } | 354 } |
305 else if (cur_arg == "--bmp") { | 355 else if (cur_arg == "--bmp") { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 WriteBmp(name.c_str(), i, buffer, stride, width, height); | 519 WriteBmp(name.c_str(), i, buffer, stride, width, height); |
470 break; | 520 break; |
471 | 521 |
472 case OUTPUT_EMF: | 522 case OUTPUT_EMF: |
473 WriteEmf(page, name.c_str(), i); | 523 WriteEmf(page, name.c_str(), i); |
474 break; | 524 break; |
475 #endif | 525 #endif |
476 case OUTPUT_PPM: | 526 case OUTPUT_PPM: |
477 WritePpm(name.c_str(), i, buffer, stride, width, height); | 527 WritePpm(name.c_str(), i, buffer, stride, width, height); |
478 break; | 528 break; |
| 529 |
| 530 case OUTPUT_PNG: |
| 531 WritePng(name.c_str(), i, buffer, stride, width, height); |
| 532 break; |
| 533 |
479 default: | 534 default: |
480 break; | 535 break; |
481 } | 536 } |
482 | 537 |
483 FPDFBitmap_Destroy(bitmap); | 538 FPDFBitmap_Destroy(bitmap); |
484 | 539 |
485 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); | 540 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); |
486 FORM_OnBeforeClosePage(page, form); | 541 FORM_OnBeforeClosePage(page, form); |
487 FPDFText_ClosePage(text_page); | 542 FPDFText_ClosePage(text_page); |
488 FPDF_ClosePage(page); | 543 FPDF_ClosePage(page); |
489 } | 544 } |
490 | 545 |
491 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); | 546 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); |
492 FPDF_CloseDocument(doc); | 547 FPDF_CloseDocument(doc); |
493 FPDFDOC_ExitFormFillEnvironment(form); | 548 FPDFDOC_ExitFormFillEnvironment(form); |
494 FPDFAvail_Destroy(pdf_avail); | 549 FPDFAvail_Destroy(pdf_avail); |
495 | 550 |
496 printf("Loaded, parsed and rendered %" PRIuS " pages.\n", rendered_pages); | 551 printf("Loaded, parsed and rendered %" PRIuS " pages.\n", rendered_pages); |
497 printf("Skipped %" PRIuS " bad pages.\n", bad_pages); | 552 printf("Skipped %" PRIuS " bad pages.\n", bad_pages); |
498 } | 553 } |
499 | 554 |
500 int main(int argc, const char* argv[]) { | 555 int main(int argc, const char* argv[]) { |
501 std::vector<std::string> args(argv, argv + argc); | 556 std::vector<std::string> args(argv, argv + argc); |
502 Options options; | 557 Options options; |
503 std::list<std::string> files; | 558 std::list<std::string> files; |
504 if (!ParseCommandLine(args, &options, &files)) { | 559 if (!ParseCommandLine(args, &options, &files)) { |
505 printf("Usage: pdfium_test [OPTION] [FILE]...\n"); | 560 printf("Usage: pdfium_test [OPTION] [FILE]...\n"); |
506 printf("--bin-dir=<path> - override path to v8 external data\n"); | 561 printf("--bin-dir=<path> - override path to v8 external data\n"); |
507 printf("--scale=<number> - scale output size by number (e.g. 0.5)\n"); | 562 printf("--scale=<number> - scale output size by number (e.g. 0.5)\n"); |
| 563 printf("--png - write page images <pdf-name>.<page-number>.png\n"); |
508 printf("--ppm - write page images <pdf-name>.<page-number>.ppm\n"); | 564 printf("--ppm - write page images <pdf-name>.<page-number>.ppm\n"); |
509 #ifdef _WIN32 | 565 #ifdef _WIN32 |
510 printf("--bmp - write page images <pdf-name>.<page-number>.bmp\n"); | 566 printf("--bmp - write page images <pdf-name>.<page-number>.bmp\n"); |
511 printf("--emf - write page meta files <pdf-name>.<page-number>.emf\n"); | 567 printf("--emf - write page meta files <pdf-name>.<page-number>.emf\n"); |
512 #endif | 568 #endif |
513 return 1; | 569 return 1; |
514 } | 570 } |
515 | 571 |
516 v8::V8::InitializeICU(); | 572 v8::V8::InitializeICU(); |
517 | 573 |
(...skipping 25 matching lines...) Expand all Loading... |
543 if (!file_contents) | 599 if (!file_contents) |
544 continue; | 600 continue; |
545 RenderPdf(filename, file_contents, file_length, options); | 601 RenderPdf(filename, file_contents, file_length, options); |
546 free(file_contents); | 602 free(file_contents); |
547 } | 603 } |
548 | 604 |
549 FPDF_DestroyLibrary(); | 605 FPDF_DestroyLibrary(); |
550 | 606 |
551 return 0; | 607 return 0; |
552 } | 608 } |
OLD | NEW |