Move image_diff code into testing/image_diff/

It is not actually a sample program to demonstrate how to use PDFium
APIs. It is more of a test utility program.

Remove header include dependency from samples/ to core/, to set a good
example.

Change-Id: Idd5d567c82314bcf0e4a7bec8a3210e7d57226ee
Reviewed-on: https://pdfium-review.googlesource.com/6871
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 2c038b2..f577986 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -260,6 +260,18 @@
   configs += [ ":pdfium_core_config" ]
 }
 
+static_library("image_diff") {
+  testonly = true
+  sources = [
+    "testing/image_diff/image_diff_png.cpp",
+    "testing/image_diff/image_diff_png.h",
+  ]
+  deps = []
+  if (!pdf_enable_xfa) {
+    deps += [ "third_party:fx_lpng" ]
+  }
+}
+
 # Targets below this are only visible within this file (and to the
 # top-level gn_visibility target used to help gn_all build everything).
 visibility = [
@@ -2045,6 +2057,22 @@
       "//samples",
     ]
   }
+
+  executable("pdfium_diff") {
+    testonly = true
+    sources = [
+      "testing/image_diff/image_diff.cpp",
+    ]
+    deps = [
+      ":image_diff",
+      ":pdfium",
+      "//build/config:exe_and_shlib_deps",
+      "//build/win:default_exe_manifest",
+    ]
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+
   group("fuzzers") {
     testonly = true
     deps = [
@@ -2062,6 +2090,7 @@
   if (pdf_is_standalone) {
     deps += [
       ":fuzzers",
+      ":pdfium_diff",
       ":samples",
     ]
   }
diff --git a/samples/BUILD.gn b/samples/BUILD.gn
index 779d4f3..59ab4b4 100644
--- a/samples/BUILD.gn
+++ b/samples/BUILD.gn
@@ -8,7 +8,6 @@
 group("samples") {
   testonly = true
   deps = [
-    ":pdfium_diff",
     ":pdfium_test",
   ]
 }
@@ -46,19 +45,15 @@
 executable("pdfium_test") {
   testonly = true
   sources = [
-    "image_diff_png.cc",
-    "image_diff_png.h",
     "pdfium_test.cc",
   ]
   deps = [
+    "../:image_diff",
     "../:pdfium",
     "../:test_support",
     "//build/config:exe_and_shlib_deps",
     "//build/win:default_exe_manifest",
   ]
-  if (!pdf_enable_xfa) {
-    deps += [ "../third_party:fx_lpng" ]
-  }
   if (pdf_enable_v8) {
     deps += [ "//v8:v8_libplatform" ]
     include_dirs = [
@@ -72,25 +67,3 @@
   }
   configs += [ ":pdfium_samples_config" ]
 }
-
-executable("pdfium_diff") {
-  testonly = true
-  sources = [
-    "image_diff.cc",
-    "image_diff_png.cc",
-    "image_diff_png.h",
-  ]
-  deps = [
-    "../:pdfium",
-    "//build/config:exe_and_shlib_deps",
-    "//build/win:default_exe_manifest",
-  ]
-  if (!pdf_enable_xfa) {
-    deps += [ "../third_party:fx_lpng" ]
-  }
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [
-    ":pdfium_samples_config",
-    "//build/config/compiler:no_chromium_code",
-  ]
-}
diff --git a/samples/DEPS b/samples/DEPS
index 0a426d6..26f9ee2 100644
--- a/samples/DEPS
+++ b/samples/DEPS
@@ -1,9 +1,5 @@
 include_rules = [
   '+public',
-  '+third_party/libpng16',
   '+third_party/skia/include',
-  '+third_party/zlib',
   '+v8',
-  '+core/fdrm/crypto/fx_crypt.h',
-  '+core/fxcrt/fx_memory.h',
 ]
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index a53edb7..ccd57a7 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -18,7 +18,6 @@
 #define _SKIA_SUPPORT_
 #endif
 
-#include "core/fdrm/crypto/fx_crypt.h"
 #include "public/cpp/fpdf_deleters.h"
 #include "public/fpdf_annot.h"
 #include "public/fpdf_dataavail.h"
@@ -28,7 +27,7 @@
 #include "public/fpdf_structtree.h"
 #include "public/fpdf_text.h"
 #include "public/fpdfview.h"
-#include "samples/image_diff_png.h"
+#include "testing/image_diff/image_diff_png.h"
 #include "testing/test_support.h"
 #include "third_party/base/logging.h"
 
@@ -121,12 +120,9 @@
 
 static void OutputMD5Hash(const char* file_name, const char* buffer, int len) {
   // Get the MD5 hash and write it to stdout.
-  uint8_t digest[16];
-  CRYPT_MD5Generate(reinterpret_cast<const uint8_t*>(buffer), len, digest);
-  printf("MD5:%s:", file_name);
-  for (int i = 0; i < 16; i++)
-    printf("%02x", digest[i]);
-  printf("\n");
+  std::string hash =
+      GenerateMD5Base16(reinterpret_cast<const uint8_t*>(buffer), len);
+  printf("MD5:%s:%s\n", file_name, hash.c_str());
 }
 
 static std::string WritePpm(const char* pdf_name,
diff --git a/testing/image_diff/DEPS b/testing/image_diff/DEPS
new file mode 100644
index 0000000..4bd2335
--- /dev/null
+++ b/testing/image_diff/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+  '+third_party/libpng16',
+  '+third_party/zlib',
+]
+
diff --git a/samples/image_diff.cc b/testing/image_diff/image_diff.cpp
similarity index 89%
rename from samples/image_diff.cc
rename to testing/image_diff/image_diff.cpp
index 21460f5..806e0c8 100644
--- a/samples/image_diff.cc
+++ b/testing/image_diff/image_diff.cpp
@@ -20,7 +20,7 @@
 #include <vector>
 
 #include "core/fxcrt/fx_memory.h"
-#include "samples/image_diff_png.h"
+#include "testing/image_diff/image_diff_png.h"
 #include "third_party/base/logging.h"
 #include "third_party/base/numerics/safe_conversions.h"
 
@@ -39,30 +39,13 @@
 
 class Image {
  public:
-  Image() : w_(0), h_(0) {
-  }
+  Image() : w_(0), h_(0) {}
+  Image(const Image& image) : w_(image.w_), h_(image.h_), data_(image.data_) {}
 
-  Image(const Image& image)
-      : w_(image.w_),
-        h_(image.h_),
-        data_(image.data_) {
-  }
-
-  bool has_image() const {
-    return w_ > 0 && h_ > 0;
-  }
-
-  int w() const {
-    return w_;
-  }
-
-  int h() const {
-    return h_;
-  }
-
-  const unsigned char* data() const {
-    return &data_.front();
-  }
+  bool has_image() const { return w_ > 0 && h_ > 0; }
+  int w() const { return w_; }
+  int h() const { return h_; }
+  const unsigned char* data() const { return &data_.front(); }
 
   // Creates the image from the given filename on disk, and returns true on
   // success.
@@ -202,15 +185,16 @@
 }
 
 void PrintHelp() {
-  fprintf(stderr,
-    "Usage:\n"
-    "  image_diff [--histogram] <compare file> <reference file>\n"
-    "    Compares two files on disk, returning 0 when they are the same;\n"
-    "    passing \"--histogram\" additionally calculates a diff of the\n"
-    "    RGBA value histograms (which is resistant to shifts in layout)\n"
-    "  image_diff --diff <compare file> <reference file> <output file>\n"
-    "    Compares two files on disk, outputs an image that visualizes the\n"
-    "    difference to <output file>\n");
+  fprintf(
+      stderr,
+      "Usage:\n"
+      "  image_diff [--histogram] <compare file> <reference file>\n"
+      "    Compares two files on disk, returning 0 when they are the same;\n"
+      "    passing \"--histogram\" additionally calculates a diff of the\n"
+      "    RGBA value histograms (which is resistant to shifts in layout)\n"
+      "  image_diff --diff <compare file> <reference file> <output file>\n"
+      "    Compares two files on disk, outputs an image that visualizes the\n"
+      "    difference to <output file>\n");
 }
 
 int CompareImages(const std::string& file1,
@@ -296,9 +280,9 @@
     return kStatusSame;
 
   std::vector<unsigned char> png_encoding;
-  image_diff_png::EncodeRGBAPNG(
-      diff_image.data(), diff_image.w(), diff_image.h(),
-      diff_image.w() * 4, &png_encoding);
+  image_diff_png::EncodeRGBAPNG(diff_image.data(), diff_image.w(),
+                                diff_image.h(), diff_image.w() * 4,
+                                &png_encoding);
 
   FILE* f = fopen(out_file.c_str(), "wb");
   if (!f)
diff --git a/samples/image_diff_png.cc b/testing/image_diff/image_diff_png.cpp
similarity index 78%
rename from samples/image_diff_png.cc
rename to testing/image_diff/image_diff_png.cpp
index 3d12b7e..a5e8cdb 100644
--- a/samples/image_diff_png.cc
+++ b/testing/image_diff/image_diff_png.cpp
@@ -9,7 +9,7 @@
 // This is a duplicate of ui/gfx/codec/png_codec.cc, after removing code related
 // to Skia, that we can use when running layout tests with minimal dependencies.
 
-#include "samples/image_diff_png.h"
+#include "testing/image_diff/image_diff_png.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -44,8 +44,10 @@
 };
 
 // Converts BGRA->RGBA and RGBA->BGRA.
-void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
-                               unsigned char* output, bool* is_opaque) {
+void ConvertBetweenBGRAandRGBA(const unsigned char* input,
+                               int pixel_width,
+                               unsigned char* output,
+                               bool* is_opaque) {
   for (int x = 0; x < pixel_width; x++) {
     const unsigned char* pixel_in = &input[x * 4];
     unsigned char* pixel_out = &output[x * 4];
@@ -56,8 +58,10 @@
   }
 }
 
-void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
-                      unsigned char* rgb, bool* is_opaque) {
+void ConvertRGBAtoRGB(const unsigned char* rgba,
+                      int pixel_width,
+                      unsigned char* rgb,
+                      bool* is_opaque) {
   for (int x = 0; x < pixel_width; x++) {
     const unsigned char* pixel_in = &rgba[x * 4];
     unsigned char* pixel_out = &rgb[x * 3];
@@ -92,8 +96,7 @@
         row_converter(NULL),
         width(0),
         height(0),
-        done(false) {
-  }
+        done(false) {}
 
   ColorFormat output_format;
   int output_channels;
@@ -107,7 +110,9 @@
 
   // Called to convert a row from the library to the correct output format.
   // When NULL, no conversion is necessary.
-  void (*row_converter)(const unsigned char* in, int w, unsigned char* out,
+  void (*row_converter)(const unsigned char* in,
+                        int w,
+                        unsigned char* out,
                         bool* is_opaque);
 
   // Size of the image, set in the info callback.
@@ -118,8 +123,10 @@
   bool done;
 };
 
-void ConvertRGBtoRGBA(const unsigned char* rgb, int pixel_width,
-                      unsigned char* rgba, bool* is_opaque) {
+void ConvertRGBtoRGBA(const unsigned char* rgb,
+                      int pixel_width,
+                      unsigned char* rgba,
+                      bool* is_opaque) {
   for (int x = 0; x < pixel_width; x++) {
     const unsigned char* pixel_in = &rgb[x * 3];
     unsigned char* pixel_out = &rgba[x * 4];
@@ -130,8 +137,10 @@
   }
 }
 
-void ConvertRGBtoBGRA(const unsigned char* rgb, int pixel_width,
-                      unsigned char* bgra, bool* is_opaque) {
+void ConvertRGBtoBGRA(const unsigned char* rgb,
+                      int pixel_width,
+                      unsigned char* bgra,
+                      bool* is_opaque) {
   for (int x = 0; x < pixel_width; x++) {
     const unsigned char* pixel_in = &rgb[x * 3];
     unsigned char* pixel_out = &bgra[x * 4];
@@ -145,8 +154,8 @@
 // Called when the png header has been read. This code is based on the WebKit
 // PNGImageDecoder
 void DecodeInfoCallback(png_struct* png_ptr, png_info* info_ptr) {
-  PngDecoderState* state = static_cast<PngDecoderState*>(
-      png_get_progressive_ptr(png_ptr));
+  PngDecoderState* state =
+      static_cast<PngDecoderState*>(png_get_progressive_ptr(png_ptr));
 
   int bit_depth, color_type, interlace_type, compression_type;
   int filter_type, channels;
@@ -246,14 +255,15 @@
     longjmp(png_jmpbuf(png_ptr), 1);
   }
 
-  state->output->resize(
-      state->width * state->output_channels * state->height);
+  state->output->resize(state->width * state->output_channels * state->height);
 }
 
-void DecodeRowCallback(png_struct* png_ptr, png_byte* new_row,
-                       png_uint_32 row_num, int pass) {
-  PngDecoderState* state = static_cast<PngDecoderState*>(
-      png_get_progressive_ptr(png_ptr));
+void DecodeRowCallback(png_struct* png_ptr,
+                       png_byte* new_row,
+                       png_uint_32 row_num,
+                       int pass) {
+  PngDecoderState* state =
+      static_cast<PngDecoderState*>(png_get_progressive_ptr(png_ptr));
 
   if (static_cast<int>(row_num) > state->height) {
     NOTREACHED();
@@ -271,8 +281,8 @@
 }
 
 void DecodeEndCallback(png_struct* png_ptr, png_info* info) {
-  PngDecoderState* state = static_cast<PngDecoderState*>(
-      png_get_progressive_ptr(png_ptr));
+  PngDecoderState* state =
+      static_cast<PngDecoderState*>(png_get_progressive_ptr(png_ptr));
 
   // Mark the image as complete, this will tell the Decode function that we
   // have successfully found the end of the data.
@@ -283,18 +293,18 @@
 // cleanup and error handling code cleaner.
 class PngReadStructDestroyer {
  public:
-  PngReadStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {
-  }
-  ~PngReadStructDestroyer() {
-    png_destroy_read_struct(ps_, pi_, NULL);
-  }
+  PngReadStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {}
+  ~PngReadStructDestroyer() { png_destroy_read_struct(ps_, pi_, NULL); }
+
  private:
   png_struct** ps_;
   png_info** pi_;
 };
 
-bool BuildPNGStruct(const unsigned char* input, size_t input_size,
-                    png_struct** png_ptr, png_info** info_ptr) {
+bool BuildPNGStruct(const unsigned char* input,
+                    size_t input_size,
+                    png_struct** png_ptr,
+                    png_info** info_ptr) {
   if (input_size < 8)
     return false;  // Input data too small to be a png
 
@@ -318,9 +328,12 @@
 }  // namespace
 
 // static
-bool Decode(const unsigned char* input, size_t input_size,
-                      ColorFormat format, std::vector<unsigned char>* output,
-                      int* w, int* h) {
+bool Decode(const unsigned char* input,
+            size_t input_size,
+            ColorFormat format,
+            std::vector<unsigned char>* output,
+            int* w,
+            int* h) {
   png_struct* png_ptr = NULL;
   png_info* info_ptr = NULL;
   if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
@@ -338,9 +351,7 @@
 
   png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
                               &DecodeRowCallback, &DecodeEndCallback);
-  png_process_data(png_ptr,
-                   info_ptr,
-                   const_cast<unsigned char*>(input),
+  png_process_data(png_ptr, info_ptr, const_cast<unsigned char*>(input),
                    input_size);
 
   if (!state.done) {
@@ -382,8 +393,10 @@
   // we're required to provide this function by libpng.
 }
 
-void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width,
-                      unsigned char* rgb, bool* is_opaque) {
+void ConvertBGRAtoRGB(const unsigned char* bgra,
+                      int pixel_width,
+                      unsigned char* rgb,
+                      bool* is_opaque) {
   for (int x = 0; x < pixel_width; x++) {
     const unsigned char* pixel_in = &bgra[x * 4];
     unsigned char* pixel_out = &rgb[x * 3];
@@ -406,8 +419,7 @@
 class CommentWriter {
  public:
   explicit CommentWriter(const std::vector<Comment>& comments)
-      : comments_(comments),
-        png_text_(new png_text[comments.size()]) {
+      : comments_(comments), png_text_(new png_text[comments.size()]) {
     for (size_t i = 0; i < comments.size(); ++i)
       AddComment(i, comments[i]);
   }
@@ -417,20 +429,14 @@
       free(png_text_[i].key);
       free(png_text_[i].text);
     }
-    delete [] png_text_;
+    delete[] png_text_;
   }
 
-  bool HasComments() {
-    return !comments_.empty();
-  }
+  bool HasComments() { return !comments_.empty(); }
 
-  png_text* get_png_text() {
-    return png_text_;
-  }
+  png_text* get_png_text() { return png_text_; }
 
-  int size() {
-    return static_cast<int>(comments_.size());
-  }
+  int size() { return static_cast<int>(comments_.size()); }
 
  private:
   void AddComment(size_t pos, const Comment& comment) {
@@ -454,18 +460,25 @@
 #endif  // PNG_TEXT_SUPPORTED
 
 // The type of functions usable for converting between pixel formats.
-typedef void (*FormatConverter)(const unsigned char* in, int w,
-                                unsigned char* out, bool* is_opaque);
+typedef void (*FormatConverter)(const unsigned char* in,
+                                int w,
+                                unsigned char* out,
+                                bool* is_opaque);
 
 // libpng uses a wacky setjmp-based API, which makes the compiler nervous.
 // We constrain all of the calls we make to libpng where the setjmp() is in
 // place to this function.
 // Returns true on success.
-bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr,
+bool DoLibpngWrite(png_struct* png_ptr,
+                   png_info* info_ptr,
                    PngEncoderState* state,
-                   int width, int height, int row_byte_width,
-                   const unsigned char* input, int compression_level,
-                   int png_output_color_type, int output_color_components,
+                   int width,
+                   int height,
+                   int row_byte_width,
+                   const unsigned char* input,
+                   int compression_level,
+                   int png_output_color_type,
+                   int output_color_components,
                    FormatConverter converter,
                    const std::vector<Comment>& comments) {
 #ifdef PNG_TEXT_SUPPORTED
@@ -501,14 +514,14 @@
 
   if (!converter) {
     // No conversion needed, give the data directly to libpng.
-    for (int y = 0; y < height; y ++) {
+    for (int y = 0; y < height; y++) {
       png_write_row(png_ptr,
                     const_cast<unsigned char*>(&input[y * row_byte_width]));
     }
   } else {
     // Needs conversion using a separate buffer.
     row_buffer = new unsigned char[width * output_color_components];
-    for (int y = 0; y < height; y ++) {
+    for (int y = 0; y < height; y++) {
       converter(&input[y * row_byte_width], width, row_buffer, NULL);
       png_write_row(png_ptr, row_buffer);
     }
@@ -522,8 +535,10 @@
 }  // namespace
 
 // static
-bool EncodeWithCompressionLevel(const unsigned char* input, ColorFormat format,
-                                const int width, const int height,
+bool EncodeWithCompressionLevel(const unsigned char* input,
+                                ColorFormat format,
+                                const int width,
+                                const int height,
                                 int row_byte_width,
                                 bool discard_transparency,
                                 const std::vector<Comment>& comments,
@@ -578,8 +593,8 @@
   if (input_color_components * width < row_byte_width)
     return false;
 
-  png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
-                                                NULL, NULL, NULL);
+  png_struct* png_ptr =
+      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (!png_ptr)
     return false;
   png_info* info_ptr = png_create_info_struct(png_ptr);
@@ -589,32 +604,35 @@
   }
 
   PngEncoderState state(output);
-  bool success = DoLibpngWrite(png_ptr, info_ptr, &state,
-                               width, height, row_byte_width,
-                               input, compression_level, png_output_color_type,
-                               output_color_components, converter, comments);
+  bool success =
+      DoLibpngWrite(png_ptr, info_ptr, &state, width, height, row_byte_width,
+                    input, compression_level, png_output_color_type,
+                    output_color_components, converter, comments);
   png_destroy_write_struct(&png_ptr, &info_ptr);
 
   return success;
 }
 
 // static
-bool Encode(const unsigned char* input, ColorFormat format,
-            const int width, const int height, int row_byte_width,
+bool Encode(const unsigned char* input,
+            ColorFormat format,
+            const int width,
+            const int height,
+            int row_byte_width,
             bool discard_transparency,
             const std::vector<Comment>& comments,
             std::vector<unsigned char>* output) {
   return EncodeWithCompressionLevel(input, format, width, height,
-                                    row_byte_width,
-                                    discard_transparency,
-                                    comments, Z_DEFAULT_COMPRESSION,
-                                    output);
+                                    row_byte_width, discard_transparency,
+                                    comments, Z_DEFAULT_COMPRESSION, output);
 }
 
 // Decode a PNG into an RGBA pixel array.
-bool DecodePNG(const unsigned char* input, size_t input_size,
+bool DecodePNG(const unsigned char* input,
+               size_t input_size,
                std::vector<unsigned char>* output,
-               int* width, int* height) {
+               int* width,
+               int* height) {
   return Decode(input, input_size, FORMAT_RGBA, output, width, height);
 }
 
@@ -624,9 +642,8 @@
                    int height,
                    int row_byte_width,
                    std::vector<unsigned char>* output) {
-  return Encode(input, FORMAT_RGBA,
-      width, height, row_byte_width, false,
-      std::vector<Comment>(), output);
+  return Encode(input, FORMAT_RGBA, width, height, row_byte_width, false,
+                std::vector<Comment>(), output);
 }
 
 // Encode an BGRA pixel array into a PNG.
@@ -636,9 +653,8 @@
                    int row_byte_width,
                    bool discard_transparency,
                    std::vector<unsigned char>* output) {
-  return Encode(input, FORMAT_BGRA,
-      width, height, row_byte_width, discard_transparency,
-      std::vector<Comment>(), output);
+  return Encode(input, FORMAT_BGRA, width, height, row_byte_width,
+                discard_transparency, std::vector<Comment>(), output);
 }
 
 }  // namespace image_diff_png
diff --git a/samples/image_diff_png.h b/testing/image_diff/image_diff_png.h
similarity index 87%
rename from samples/image_diff_png.h
rename to testing/image_diff/image_diff_png.h
index 7bb395a..4d87aa1 100644
--- a/samples/image_diff_png.h
+++ b/testing/image_diff/image_diff_png.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SAMPLES_IMAGE_DIFF_PNG_H_
-#define SAMPLES_IMAGE_DIFF_PNG_H_
+#ifndef TESTING_IMAGE_DIFF_IMAGE_DIFF_PNG_H_
+#define TESTING_IMAGE_DIFF_IMAGE_DIFF_PNG_H_
 
 #include <stdlib.h>  // for size_t.
 
@@ -35,4 +35,4 @@
 
 }  // namespace image_diff_png
 
-#endif  // SAMPLES_IMAGE_DIFF_PNG_H_
+#endif  // TESTING_IMAGE_DIFF_IMAGE_DIFF_PNG_H_