| 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 |