From ef1e85caf492e1b9bf9803647d3c5db1abea77c7 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 23 Feb 2015 15:59:57 -0800 Subject: Backport PNG output format to origin/master branch. The pdfium library itself does not support the format, but the test utility can convert to this output format. GN build can't be tested standalone, so push this out to the next CL. R=jam@chromium.org Review URL: https://codereview.chromium.org/950113002 --- samples/pdfium_test.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-) (limited to 'samples/pdfium_test.cc') diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index 8f9c832fb2..e3ad47ac15 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -19,6 +19,7 @@ #include "../fpdfsdk/include/fpdftext.h" #include "../fpdfsdk/include/fpdfview.h" #include "../core/include/fxcrt/fx_system.h" +#include "image_diff_png.h" #include "v8/include/v8.h" #include "v8/include/libplatform/libplatform.h" @@ -32,6 +33,7 @@ enum OutputFormat { OUTPUT_NONE, OUTPUT_PPM, + OUTPUT_PNG, #ifdef _WIN32 OUTPUT_BMP, OUTPUT_EMF, @@ -113,14 +115,21 @@ static bool GetExternalData(const Options& options, } #endif // V8_USE_EXTERNAL_STARTUP_DATA +static bool CheckDimensions(int stride, int width, int height) { + if (stride < 0 || width < 0 || height < 0) + return false; + if (height > 0 && width > INT_MAX / height) + return false; + return true; +} + static void WritePpm(const char* pdf_name, int num, const void* buffer_void, int stride, int width, int height) { const char* buffer = reinterpret_cast(buffer_void); - if (stride < 0 || width < 0 || height < 0) - return; - if (height > 0 && width > INT_MAX / height) + if (!CheckDimensions(stride, width, height)) return; + int out_len = width * height; if (out_len > INT_MAX / 3) return; @@ -154,6 +163,42 @@ static void WritePpm(const char* pdf_name, int num, const void* buffer_void, fclose(fp); } +static void WritePng(const char* pdf_name, int num, const void* buffer_void, + int stride, int width, int height) { + if (!CheckDimensions(stride, width, height)) + return; + + std::vector png_encoding; + const unsigned char* buffer = static_cast(buffer_void); + if (!image_diff_png::EncodeBGRAPNG( + buffer, width, height, stride, false, &png_encoding)) { + fprintf(stderr, "Failed to convert bitmap to PNG\n"); + return; + } + + char filename[256]; + int chars_formatted = snprintf( + filename, sizeof(filename), "%s.%d.png", pdf_name, num); + if (chars_formatted < 0 || + static_cast(chars_formatted) >= sizeof(filename)) { + fprintf(stderr, "Filname %s is too long\n", filename); + return; + } + + FILE* fp = fopen(filename, "wb"); + if (!fp) { + fprintf(stderr, "Failed to open %s for output\n", filename); + return; + } + + size_t bytes_written = fwrite( + &png_encoding.front(), 1, png_encoding.size(), fp); + if (bytes_written != png_encoding.size()) + fprintf(stderr, "Failed to write to %s\n", filename); + + (void) fclose(fp); +} + #ifdef _WIN32 static void WriteBmp(const char* pdf_name, int num, const void* buffer, int stride, int width, int height) { @@ -297,6 +342,12 @@ bool ParseCommandLine(const std::vector& args, return false; } options->output_format = OUTPUT_PPM; + } else if (cur_arg == "--png") { + if (options->output_format != OUTPUT_NONE) { + fprintf(stderr, "Duplicate or conflicting --png argument\n"); + return false; + } + options->output_format = OUTPUT_PNG; } #ifdef _WIN32 else if (cur_arg == "--emf") { @@ -475,9 +526,14 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, WriteEmf(page, name.c_str(), i); break; #endif + case OUTPUT_PNG: + WritePng(name.c_str(), i, buffer, stride, width, height); + break; + case OUTPUT_PPM: WritePpm(name.c_str(), i, buffer, stride, width, height); break; + default: break; } @@ -507,6 +563,7 @@ static const char usage_string[] = " --bmp - write page images ..bmp\n" " --emf - write page meta files ..emf\n" #endif + " --png - write page images ..png\n" " --ppm - write page images ..ppm\n"; int main(int argc, const char* argv[]) { -- cgit v1.2.3