| 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 | 9 |
| 10 #include <list> | 10 #include <list> |
| 11 #include <sstream> | 11 #include <sstream> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> | 13 #include <utility> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "../fpdfsdk/include/fpdf_dataavail.h" | 16 #include "../fpdfsdk/include/fpdf_dataavail.h" |
| 17 #include "../fpdfsdk/include/fpdf_ext.h" | 17 #include "../fpdfsdk/include/fpdf_ext.h" |
| 18 #include "../fpdfsdk/include/fpdfformfill.h" | 18 #include "../fpdfsdk/include/fpdfformfill.h" |
| 19 #include "../fpdfsdk/include/fpdftext.h" | 19 #include "../fpdfsdk/include/fpdftext.h" |
| 20 #include "../fpdfsdk/include/fpdfview.h" | 20 #include "../fpdfsdk/include/fpdfview.h" |
| 21 #include "../core/include/fxcrt/fx_system.h" | 21 #include "../core/include/fxcrt/fx_system.h" |
| 22 #include "image_diff_png.h" |
| 22 #include "v8/include/v8.h" | 23 #include "v8/include/v8.h" |
| 23 #include "v8/include/libplatform/libplatform.h" | 24 #include "v8/include/libplatform/libplatform.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 = static_cast<int>(data_length); | 113 result_data->raw_size = static_cast<int>(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 (stride < 0 || width < 0 || height < 0) |
| 161 return; | 206 return; |
| 162 if (height > 0 && width > INT_MAX / height) | 207 if (height > 0 && width > INT_MAX / height) |
| 163 return; | 208 return; |
| 164 int out_len = stride * height; | 209 int out_len = stride * height; |
| 165 if (out_len > INT_MAX / 3) | 210 if (out_len > INT_MAX / 3) |
| 166 return; | 211 return; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 options->exe_path = args[0]; | 335 options->exe_path = args[0]; |
| 291 size_t cur_idx = 1; | 336 size_t cur_idx = 1; |
| 292 for (; cur_idx < args.size(); ++cur_idx) { | 337 for (; cur_idx < args.size(); ++cur_idx) { |
| 293 const std::string& cur_arg = args[cur_idx]; | 338 const std::string& cur_arg = args[cur_idx]; |
| 294 if (cur_arg == "--ppm") { | 339 if (cur_arg == "--ppm") { |
| 295 if (options->output_format != OUTPUT_NONE) { | 340 if (options->output_format != OUTPUT_NONE) { |
| 296 fprintf(stderr, "Duplicate or conflicting --ppm argument\n"); | 341 fprintf(stderr, "Duplicate or conflicting --ppm argument\n"); |
| 297 return false; | 342 return false; |
| 298 } | 343 } |
| 299 options->output_format = OUTPUT_PPM; | 344 options->output_format = OUTPUT_PPM; |
| 345 } else if (cur_arg == "--png") { |
| 346 if (options->output_format != OUTPUT_NONE) { |
| 347 fprintf(stderr, "Duplicate or conflicting --png argument\n"); |
| 348 return false; |
| 349 } |
| 350 options->output_format = OUTPUT_PNG; |
| 300 } | 351 } |
| 301 #ifdef _WIN32 | 352 #ifdef _WIN32 |
| 302 else if (cur_arg == "--emf") { | 353 else if (cur_arg == "--emf") { |
| 303 if (options->output_format != OUTPUT_NONE) { | 354 if (options->output_format != OUTPUT_NONE) { |
| 304 fprintf(stderr, "Duplicate or conflicting --emf argument\n"); | 355 fprintf(stderr, "Duplicate or conflicting --emf argument\n"); |
| 305 return false; | 356 return false; |
| 306 } | 357 } |
| 307 options->output_format = OUTPUT_EMF; | 358 options->output_format = OUTPUT_EMF; |
| 308 } | 359 } |
| 309 else if (cur_arg == "--bmp") { | 360 else if (cur_arg == "--bmp") { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 switch (options.output_format) { | 519 switch (options.output_format) { |
| 469 #ifdef _WIN32 | 520 #ifdef _WIN32 |
| 470 case OUTPUT_BMP: | 521 case OUTPUT_BMP: |
| 471 WriteBmp(name.c_str(), i, buffer, stride, width, height); | 522 WriteBmp(name.c_str(), i, buffer, stride, width, height); |
| 472 break; | 523 break; |
| 473 | 524 |
| 474 case OUTPUT_EMF: | 525 case OUTPUT_EMF: |
| 475 WriteEmf(page, name.c_str(), i); | 526 WriteEmf(page, name.c_str(), i); |
| 476 break; | 527 break; |
| 477 #endif | 528 #endif |
| 529 case OUTPUT_PNG: |
| 530 WritePng(name.c_str(), i, buffer, stride, width, height); |
| 531 break; |
| 532 |
| 478 case OUTPUT_PPM: | 533 case OUTPUT_PPM: |
| 479 WritePpm(name.c_str(), i, buffer, stride, width, height); | 534 WritePpm(name.c_str(), i, buffer, stride, width, height); |
| 480 break; | 535 break; |
| 536 |
| 481 default: | 537 default: |
| 482 break; | 538 break; |
| 483 } | 539 } |
| 484 | 540 |
| 485 FPDFBitmap_Destroy(bitmap); | 541 FPDFBitmap_Destroy(bitmap); |
| 486 | 542 |
| 487 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); | 543 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); |
| 488 FORM_OnBeforeClosePage(page, form); | 544 FORM_OnBeforeClosePage(page, form); |
| 489 FPDFText_ClosePage(text_page); | 545 FPDFText_ClosePage(text_page); |
| 490 FPDF_ClosePage(page); | 546 FPDF_ClosePage(page); |
| 491 } | 547 } |
| 492 | 548 |
| 493 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); | 549 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); |
| 494 FPDFDOC_ExitFormFillEnvironment(form); | 550 FPDFDOC_ExitFormFillEnvironment(form); |
| 495 FPDF_CloseDocument(doc); | 551 FPDF_CloseDocument(doc); |
| 496 FPDFAvail_Destroy(pdf_avail); | 552 FPDFAvail_Destroy(pdf_avail); |
| 497 | 553 |
| 498 fprintf(stderr, "Rendered %" PRIuS " pages.\n", rendered_pages); | 554 fprintf(stderr, "Rendered %" PRIuS " pages.\n", rendered_pages); |
| 499 fprintf(stderr, "Skipped %" PRIuS " bad pages.\n", bad_pages); | 555 fprintf(stderr, "Skipped %" PRIuS " bad pages.\n", bad_pages); |
| 500 } | 556 } |
| 501 | 557 |
| 502 static const char usage_string[] = | 558 static const char usage_string[] = |
| 503 "Usage: pdfium_test [OPTION] [FILE]...\n" | 559 "Usage: pdfium_test [OPTION] [FILE]...\n" |
| 504 " --bin-dir=<path> - override path to v8 external data\n" | 560 " --bin-dir=<path> - override path to v8 external data\n" |
| 505 " --scale=<number> - scale output size by number (e.g. 0.5)\n" | 561 " --scale=<number> - scale output size by number (e.g. 0.5)\n" |
| 506 #ifdef _WIN32 | 562 #ifdef _WIN32 |
| 507 " --bmp - write page images <pdf-name>.<page-number>.bmp\n" | 563 " --bmp - write page images <pdf-name>.<page-number>.bmp\n" |
| 508 " --emf - write page meta files <pdf-name>.<page-number>.emf\n" | 564 " --emf - write page meta files <pdf-name>.<page-number>.emf\n" |
| 509 #endif | 565 #endif |
| 566 " --png - write page images <pdf-name>.<page-number>.png\n" |
| 510 " --ppm - write page images <pdf-name>.<page-number>.ppm\n"; | 567 " --ppm - write page images <pdf-name>.<page-number>.ppm\n"; |
| 511 | 568 |
| 512 int main(int argc, const char* argv[]) { | 569 int main(int argc, const char* argv[]) { |
| 513 std::vector<std::string> args(argv, argv + argc); | 570 std::vector<std::string> args(argv, argv + argc); |
| 514 Options options; | 571 Options options; |
| 515 std::list<std::string> files; | 572 std::list<std::string> files; |
| 516 if (!ParseCommandLine(args, &options, &files)) { | 573 if (!ParseCommandLine(args, &options, &files)) { |
| 517 fprintf(stderr, "%s", usage_string); | 574 fprintf(stderr, "%s", usage_string); |
| 518 return 1; | 575 return 1; |
| 519 } | 576 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 RenderPdf(filename, file_contents, file_length, options); | 610 RenderPdf(filename, file_contents, file_length, options); |
| 554 free(file_contents); | 611 free(file_contents); |
| 555 } | 612 } |
| 556 | 613 |
| 557 FPDF_DestroyLibrary(); | 614 FPDF_DestroyLibrary(); |
| 558 v8::V8::ShutdownPlatform(); | 615 v8::V8::ShutdownPlatform(); |
| 559 delete platform; | 616 delete platform; |
| 560 | 617 |
| 561 return 0; | 618 return 0; |
| 562 } | 619 } |
| OLD | NEW |