This is an autogenerated patch header for a single-debian-patch file. The
delta against upstream is either kept as a single patch, or maintained
in some VCS, and exported as a single patch instead of more manageable
atomic patches.

--- perceptualdiff-2.1.orig/.travis.yml
+++ perceptualdiff-2.1/.travis.yml
@@ -3,21 +3,18 @@ sudo: false
 language: cpp
 
 compiler:
-    - clang
     - gcc
 
 env:
     -
-    - EXTRA_CMAKE_FLAGS='-DOPTIMIZATION=FALSE'
     - OMP_NUM_THREADS=1
     - OMP_NUM_THREADS=4
 
 script:
     - cppcheck --error-exitcode=2 .
-    - cmake "$EXTRA_CMAKE_FLAGS" .
-    - make VERBOSE=1 check
+    - make VERBOSE=1 test
     - ./memcheck.bash
-    - bash -c './perceptualdiff | grep -i openmp'
+    - bash -c './build/perceptualdiff | grep -i openmp'
 
 after_success:
     - pip install --user cpp-coveralls
--- perceptualdiff-2.1.orig/CMakeLists.txt
+++ perceptualdiff-2.1/CMakeLists.txt
@@ -1,45 +1,46 @@
 project(perceptualdiff)
 
-cmake_minimum_required(VERSION 2.4)
+cmake_minimum_required(VERSION 3.1)
 
-add_library(
-    pdiff
-    lpyramid.cpp rgba_image.cpp metric.cpp)
-
-add_executable(
-    perceptualdiff
-    compare_args.cpp perceptualdiff.cpp)
-target_link_libraries(perceptualdiff pdiff)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+if(NOT MSVC)
+    add_compile_options(
+        -Wall -Wextra -pedantic -Wcast-qual -Wpointer-arith -Winit-self
+        -Wswitch-default -Wmissing-include-dirs -Wold-style-cast
+        -Wnon-virtual-dtor -Wshadow -Wno-unknown-pragmas)
+endif()
 
-install(TARGETS perceptualdiff DESTINATION bin)
+find_package(OpenMP)
+if(OPENMP_FOUND)
+    add_compile_options(${OpenMP_CXX_FLAGS})
+    if(NOT MSVC)
+        set(CMAKE_EXE_LINKER_FLAGS
+            "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}")
+    endif()
+endif()
 
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+option(SANITIZERS "Enable sanitizers" FALSE)
+if(SANITIZERS)
+    add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
+    set(CMAKE_EXE_LINKER_FLAGS
+        "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined")
+endif()
 
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
 set(FREEIMAGE_FIND_REQUIRED, TRUE)
 find_package(FreeImage)
-include_directories(SYSTEM ${FREEIMAGE_INCLUDE_DIRS})
-target_link_libraries(perceptualdiff ${FREEIMAGE_LIBRARIES})
 
-set(CMAKE_BUILD_TYPE Debug)
+add_library(pdiff lpyramid.cpp rgba_image.cpp metric.cpp)
+target_include_directories(pdiff SYSTEM PRIVATE ${FREEIMAGE_INCLUDE_DIRS})
+target_link_libraries(pdiff PRIVATE ${FREEIMAGE_LIBRARIES})
 
-find_package(OpenMP)
-if(OPENMP_FOUND)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
-endif()
+add_executable(perceptualdiff compare_args.cpp perceptualdiff.cpp)
+target_link_libraries(perceptualdiff PRIVATE pdiff)
 
-option(OPTIMIZATION "Enable optimization" TRUE)
-if(OPTIMIZATION)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
-else()
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
-endif()
-
-if(MSVC)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
-else()
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wextra -pedantic -Wcast-qual -Wpointer-arith -Winit-self -Wswitch-default -Wmissing-include-dirs -Wold-style-cast -Wnon-virtual-dtor -Wshadow -Wno-unknown-pragmas")
-endif(MSVC)
+install(TARGETS perceptualdiff DESTINATION bin)
 
 # Packing stuff.
 set(CPACK_PACKAGE_VERSION_MAJOR "1")
@@ -77,9 +78,3 @@ set(CPACK_SOURCE_IGNORE_FILES
     "^${PROJECT_SOURCE_DIR}/coverage_output"
 )
 include(CPack)
-
-# Tests.
-enable_testing()
-add_test(run_tests.bash, "${PROJECT_SOURCE_DIR}/test/run_tests.bash")
-add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
-                  DEPENDS "perceptualdiff")
--- /dev/null
+++ perceptualdiff-2.1/Makefile
@@ -0,0 +1,24 @@
+default: build
+
+NUM_JOBS := $(shell getconf _NPROCESSORS_ONLN)
+
+build:
+	mkdir -p build
+	test -f build/Makefile || cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
+	$(MAKE) --directory=build --jobs=$(NUM_JOBS)
+
+sanitizer:
+	mkdir -p build
+	test -f build/Makefile || cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DSANITIZERS=ON
+	$(MAKE) --directory=build --jobs=$(NUM_JOBS) check
+
+clean:
+	rm -rf build
+
+install: build
+	$(MAKE) --directory=build install
+
+test: build
+	./test/run_tests.bash
+
+.PHONY: build clean
--- perceptualdiff-2.1.orig/README.rst
+++ perceptualdiff-2.1/README.rst
@@ -32,13 +32,11 @@ Build Instructions
 
 #. Download CMake from http://www.cmake.org if you do not already have it on
    your system.
+
 #. Download FreeImage from https://sourceforge.net/projects/freeimage.
     - On OS X with MacPorts: ``port install freeimage``
     - On OS X with Brew: ``brew install freeimage``
     - On Ubuntu: ``apt-get install libfreeimage-dev``
-#. Type::
-
-    $ cmake .
 
 #. Type::
 
@@ -59,19 +57,20 @@ Command line::
     Compares image1 and image2 using a perceptually based image metric.
 
     Options:
-      --verbose        Turn on verbose mode
-      --fov deg        Field of view in degrees [0.1, 89.9] (default: 45.0)
-      --threshold p    Number of pixels p below which differences are ignored
-      --gamma g        Value to convert rgb into linear space (default: 2.2)
-      --luminance l    White luminance (default: 100.0 cdm^-2)
-      --luminanceonly  Only consider luminance; ignore chroma (color) in the
-                       comparison
-      --colorfactor    How much of color to use [0.0, 1.0] (default: 1.0)
-      --downsample     How many powers of two to down sample the image
-                       (default: 0)
-      --scale          Scale images to match each other's dimensions
-      --sum-errors     Print a sum of the luminance and color differences
-      --output o       Write difference to the file o
+      --verbose         Turn on verbose mode
+      --fov deg         Field of view in degrees [0.1, 89.9] (default: 45.0)
+      --threshold p     Number of pixels p below which differences are ignored
+      --gamma g         Value to convert rgb into linear space (default: 2.2)
+      --luminance l     White luminance (default: 100.0 cdm^-2)
+      --luminance-only  Only consider luminance; ignore chroma (color) in the
+                        comparison
+      --color-factor    How much of color to use [0.0, 1.0] (default: 1.0)
+      --down-sample     How many powers of two to down sample the image
+                        (default: 0)
+      --scale           Scale images to match each other's dimensions
+      --sum-errors      Print a sum of the luminance and color differences
+      --output o        Write difference to the file o
+      --version         Print version
 
 
 Check that perceptualdiff is built with OpenMP support::
@@ -111,6 +110,23 @@ Version History
 - 2.1 - Allow accessing stats directly when used as a library.
 
 
+Usage as a library
+==================
+
+.. code:: cpp
+
+    #include <perceptualdiff/metric.h>
+    #include <perceptualdiff/rgba_image.h>
+
+    int main()
+    {
+        const auto a = pdiff::read_from_file("a.png");
+        const auto b = pdiff::read_from_file("b.png");
+
+        const bool same = pdiff::yee_compare(*a, *b);
+    }
+
+
 Links
 =====
 
--- perceptualdiff-2.1.orig/compare_args.cpp
+++ perceptualdiff-2.1/compare_args.cpp
@@ -36,25 +36,26 @@ namespace pdiff
 
 
     static const auto USAGE =
-"Usage: perceptualdiff image1 image2\n"
+"Usage: perceptualdiff [options] image1 image2\n"
 "\n"
 "Compares image1 and image2 using a perceptually based image metric.\n"
+"Images can be in any FreeImage-supported format: TIF, PNG, etc.\n"
 "\n"
 "Options:\n"
-"  --verbose        Turn on verbose mode\n"
-"  --fov deg        Field of view in degrees [0.1, 89.9] (default: 45.0)\n"
-"  --threshold p    Number of pixels p below which differences are ignored\n"
-"  --gamma g        Value to convert rgb into linear space (default: 2.2)\n"
-"  --luminance l    White luminance (default: 100.0 cdm^-2)\n"
-"  --luminanceonly  Only consider luminance; ignore chroma (color) in the\n"
-"                   comparison\n"
-"  --colorfactor    How much of color to use [0.0, 1.0] (default: 1.0)\n"
-"  --downsample     How many powers of two to down sample the image\n"
-"                   (default: 0)\n"
-"  --scale          Scale images to match each other's dimensions\n"
-"  --sum-errors     Print a sum of the luminance and color differences\n"
-"  --output o       Write difference to the file o\n"
-"  --version        Print version\n"
+"  --verbose         Turn on verbose mode\n"
+"  --fov deg         Field of view in degrees [0.1, 89.9] (default: 45.0)\n"
+"  --threshold p     Number of pixels p below which differences are ignored\n"
+"  --gamma g         Value to convert rgb into linear space (default: 2.2)\n"
+"  --luminance l     White luminance (default: 100.0 cdm^-2)\n"
+"  --luminance-only  Only consider luminance; ignore chroma (color) in the\n"
+"                    comparison\n"
+"  --color-factor    How much of color to use [0.0, 1.0] (default: 1.0)\n"
+"  --down-sample     How many powers of two to down sample the image\n"
+"                    (default: 0)\n"
+"  --scale           Scale images to match each other's dimensions\n"
+"  --sum-errors      Print a sum of the luminance and color differences\n"
+"  --output o        Write difference to the file o\n"
+"  --version         Print version\n"
 "\n";
 
 
@@ -69,7 +70,8 @@ namespace pdiff
 
     CompareArgs::CompareArgs(int argc, char **argv)
         : verbose_(false),
-          sum_errors_(false)
+          sum_errors_(false),
+          down_sample_(0)
     {
         parse_args(argc, argv);
     }
@@ -147,7 +149,8 @@ namespace pdiff
                         parameters_.luminance = std::stof(argv[i]);
                     }
                 }
-                else if (option_matches(argv[i], "luminanceonly"))
+                else if (option_matches(argv[i], "luminance-only") or
+                         option_matches(argv[i], "luminanceonly"))
                 {
                     parameters_.luminance_only = true;
                 }
@@ -155,14 +158,16 @@ namespace pdiff
                 {
                     sum_errors_ = true;
                 }
-                else if (option_matches(argv[i], "colorfactor"))
+                else if (option_matches(argv[i], "color-factor") or
+                         option_matches(argv[i], "colorfactor"))
                 {
                     if (++i < argc)
                     {
                         parameters_.color_factor = std::stof(argv[i]);
                     }
                 }
-                else if (option_matches(argv[i], "downsample"))
+                else if (option_matches(argv[i], "down-sample") or
+                         option_matches(argv[i], "downsample"))
                 {
                     if (++i < argc)
                     {
@@ -172,8 +177,8 @@ namespace pdiff
                             throw PerceptualDiffException(
                                 "--downsample must be positive");
                         }
-                        parameters_.down_sample = static_cast<unsigned int>(temporary);
-                        assert(parameters_.down_sample <= INT_MAX);
+                        down_sample_ = static_cast<unsigned int>(temporary);
+                        assert(down_sample_ <= INT_MAX);
                     }
                 }
                 else if (option_matches(argv[i], "scale"))
@@ -237,7 +242,7 @@ namespace pdiff
             exit(EXIT_FAILURE);
         }
 
-        for (auto i = 0u; i < parameters_.down_sample; i++)
+        for (auto i = 0u; i < down_sample_; i++)
         {
             const auto tmp_a = image_a_->down_sample();
             const auto tmp_b = image_b_->down_sample();
--- perceptualdiff-2.1.orig/compare_args.h
+++ perceptualdiff-2.1/compare_args.h
@@ -47,6 +47,9 @@ namespace pdiff
         // Print a sum of the luminance and color differences of each pixel.
         bool sum_errors_;
 
+        // How much to down sample image before comparing, in powers of 2.
+        unsigned int down_sample_;
+
         PerceptualDiffParameters parameters_;
 
     private:
--- perceptualdiff-2.1.orig/lpyramid.cpp
+++ perceptualdiff-2.1/lpyramid.cpp
@@ -29,7 +29,7 @@ namespace pdiff
 {
     LPyramid::LPyramid(const std::vector<float> &image,
                        const unsigned int width, const unsigned int height)
-        : width_(width), weight_(height)
+        : width_(width), height_(height)
     {
         // Make the Laplacian pyramid by successively
         // copying the earlier levels and blurring them
@@ -41,7 +41,7 @@ namespace pdiff
             }
             else
             {
-                levels_[i].resize(width_ * weight_);
+                levels_[i].resize(static_cast<size_t>(width_) * height_);
                 convolve(levels_[i], levels_[i - 1]);
             }
         }
@@ -55,7 +55,7 @@ namespace pdiff
         assert(b.size() > 1);
 
         #pragma omp parallel for shared(a, b)
-        for (auto y = 0; y < static_cast<ptrdiff_t>(weight_); y++)
+        for (auto y = 0; y < static_cast<ptrdiff_t>(height_); y++)
         {
             for (auto x = 0u; x < width_; x++)
             {
@@ -73,9 +73,9 @@ namespace pdiff
                         {
                             nx = 2 * width_ - nx - 1;
                         }
-                        if (ny >= static_cast<long>(weight_))
+                        if (ny >= static_cast<long>(height_))
                         {
-                            ny = 2 * weight_ - ny - 1;
+                            ny = 2 * height_ - ny - 1;
                         }
 
                         const float kernel[] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
--- perceptualdiff-2.1.orig/lpyramid.h
+++ perceptualdiff-2.1/lpyramid.h
@@ -49,7 +49,7 @@ namespace pdiff
         std::vector<float> levels_[MAX_PYR_LEVELS];
 
         unsigned int width_;
-        unsigned int weight_;
+        unsigned int height_;
     };
 }
 
--- perceptualdiff-2.1.orig/metric.cpp
+++ perceptualdiff-2.1/metric.cpp
@@ -196,25 +196,24 @@ namespace pdiff
 
 
     PerceptualDiffParameters::PerceptualDiffParameters()
+        : luminance_only(false),
+          field_of_view(45.0f),
+          gamma(2.2f),
+          luminance(100.0f),
+          threshold_pixels(100),
+          color_factor(1.0f)
     {
-        luminance_only = false;
-        field_of_view = 45.0f;
-        gamma = 2.2f;
-        threshold_pixels = 100;
-        luminance = 100.0f;
-        color_factor = 1.0f;
-        down_sample = 0;
     }
 
 
-    bool yee_compare(const PerceptualDiffParameters &args,
-                     const RGBAImage &image_a,
+    bool yee_compare(const RGBAImage &image_a,
                      const RGBAImage &image_b,
-                     size_t *output_num_pixels_failed,
-                     float *output_error_sum,
-                     std::string *output_reason,
-                     RGBAImage *output_image_difference,
-                     std::ostream *output_verbose)
+                     const PerceptualDiffParameters &args,
+                     size_t *const output_num_pixels_failed,
+                     float *const output_error_sum,
+                     std::string *const output_reason,
+                     RGBAImage *const output_image_difference,
+                     std::ostream *const output_verbose)
     {
         if ((image_a.get_width()  != image_b.get_width()) or
             (image_a.get_height() != image_b.get_height()))
@@ -322,14 +321,6 @@ namespace pdiff
             }
         }
 
-        if (output_verbose)
-        {
-            *output_verbose << "Constructing Laplacian Pyramids\n";
-        }
-
-        const LPyramid la(a_lum, w, h);
-        const LPyramid lb(b_lum, w, h);
-
         const auto num_one_degree_pixels =
             to_degrees(2 *
                        std::tan(args.field_of_view * to_radians(.5f)));
@@ -362,94 +353,116 @@ namespace pdiff
         auto pixels_failed = 0u;
         auto error_sum = 0.;
 
-        #pragma omp parallel for reduction(+ : pixels_failed, error_sum) \
-            shared(args, a_a, a_b, b_a, b_b, cpd, f_freq)
-        for (auto y = 0; y < static_cast<ptrdiff_t>(h); y++)
+        if (output_verbose)
         {
-            for (auto x = 0u; x < w; x++)
+            *output_verbose << "Constructing Laplacian Pyramids\n";
+        }
+        try
+        {
+            const LPyramid la(a_lum, w, h);
+            const LPyramid lb(b_lum, w, h);
+
+            #pragma omp parallel for reduction(+ : pixels_failed, error_sum) \
+            shared(args, a_a, a_b, b_a, b_b, cpd, f_freq)
+            for (auto y = 0; y < static_cast<ptrdiff_t>(h); y++)
             {
-                const auto index = y * w + x;
+                for (auto x = 0u; x < w; x++)
+                {
+                    const auto index = y * w + x;
 
-                const auto adapt = std::max(
-                    (la.get_value(x, y, adaptation_level) +
-                     lb.get_value(x, y, adaptation_level)) * 0.5f,
-                    1e-5f);
+                    const auto adapt =
+                        std::max((la.get_value(x, y, adaptation_level) +
+                                  lb.get_value(x, y, adaptation_level)) *
+                                     0.5f,
+                                 1e-5f);
 
-                auto sum_contrast = 0.f;
-                auto factor = 0.f;
+                    auto sum_contrast = 0.f;
+                    auto factor = 0.f;
 
-                for (auto i = 0u; i < MAX_PYR_LEVELS - 2; i++)
-                {
-                    const auto n1 =
-                        std::abs(la.get_value(x, y, i) -
-                                 la.get_value(x, y, i + 1));
-
-                    const auto n2 =
-                        std::abs(lb.get_value(x, y, i) -
-                                 lb.get_value(x, y, i + 1));
-
-                    const auto numerator = std::max(n1, n2);
-                    const auto d1 = std::abs(la.get_value(x, y, i + 2));
-                    const auto d2 = std::abs(lb.get_value(x, y, i + 2));
-                    const auto denominator = std::max(std::max(d1, d2), 1e-5f);
-                    const auto contrast = numerator / denominator;
-                    const auto f_mask = mask(contrast * csf(cpd[i], adapt));
-                    factor += contrast * f_freq[i] * f_mask;
-                    sum_contrast += contrast;
-                }
-                sum_contrast = std::max(sum_contrast, 1e-5f);
-                factor /= sum_contrast;
-                factor = std::min(std::max(factor, 1.f), 10.f);
-                const auto delta =
-                    std::abs(la.get_value(x, y, 0) - lb.get_value(x, y, 0));
-                error_sum += delta;
-                auto pass = true;
+                    for (auto i = 0u; i < MAX_PYR_LEVELS - 2; i++)
+                    {
+                        const auto n1 = std::abs(la.get_value(x, y, i) -
+                                                 la.get_value(x, y, i + 1));
 
-                // Pure luminance test.
-                if (delta > factor * tvi(adapt))
-                {
-                    pass = false;
-                }
+                        const auto n2 = std::abs(lb.get_value(x, y, i) -
+                                                 lb.get_value(x, y, i + 1));
 
-                if (not args.luminance_only)
-                {
-                    // CIE delta E test with modifications.
-                    auto color_scale = args.color_factor;
+                        const auto numerator = std::max(n1, n2);
+                        const auto d1 = std::abs(la.get_value(x, y, i + 2));
+                        const auto d2 = std::abs(lb.get_value(x, y, i + 2));
+                        const auto denominator =
+                            std::max(std::max(d1, d2), 1e-5f);
+                        const auto contrast = numerator / denominator;
+                        const auto f_mask =
+                            mask(contrast * csf(cpd[i], adapt));
+                        factor += contrast * f_freq[i] * f_mask;
+                        sum_contrast += contrast;
+                    }
+                    sum_contrast = std::max(sum_contrast, 1e-5f);
+                    factor /= sum_contrast;
+                    factor = std::min(std::max(factor, 1.f), 10.f);
+                    const auto delta = std::abs(la.get_value(x, y, 0) -
+                                                lb.get_value(x, y, 0));
+                    error_sum += delta;
+                    auto pass = true;
 
-                    // Ramp down the color test in scotopic regions.
-                    if (adapt < 10.0f)
+
+                    // Pure luminance test.
+                    if (delta > factor * tvi(adapt))
                     {
-                        // Don't do color test at all.
-                        color_scale = 0.0;
+                        pass = false;
                     }
 
-                    const auto da = a_a[index] - b_a[index];
-                    const auto db = a_b[index] - b_b[index];
-                    const auto delta_e = (da * da + db * db) * color_scale;
-                    error_sum += delta_e;
-                    if (delta_e > factor)
+                    if (not args.luminance_only)
                     {
-                        pass = false;
+                        // CIE delta E test with modifications.
+                        auto color_scale = args.color_factor;
+
+                        // Ramp down the color test in scotopic regions.
+                        if (adapt < 10.0f)
+                        {
+                            // Don't do color test at all.
+                            color_scale = 0.0;
+                        }
+
+                        const auto da = a_a[index] - b_a[index];
+                        const auto db = a_b[index] - b_b[index];
+                        const auto delta_e = (da * da + db * db) * color_scale;
+                        error_sum += delta_e;
+                        if (delta_e > factor)
+                        {
+                            pass = false;
+                        }
                     }
-                }
 
-                if (not pass)
-                {
-                    pixels_failed++;
-                    if (output_image_difference)
+                    if (pass)
                     {
-                        output_image_difference->set(255, 0, 0, 255, index);
+                        if (output_image_difference)
+                        {
+                            output_image_difference->set(0, 0, 0, 255, index);
+                        }
                     }
-                }
-                else
-                {
-                    if (output_image_difference)
+                    else
                     {
-                        output_image_difference->set(0, 0, 0, 255, index);
+                        pixels_failed++;
+                        if (output_image_difference)
+                        {
+                            output_image_difference->set(255, 0, 0, 255,
+                                                         index);
+                        }
                     }
                 }
             }
         }
+        catch (const std::bad_alloc &)
+        {
+            if (output_reason)
+            {
+                *output_reason = "Failed to Construct Laplacian pyramids. Out "
+                                 "of memory.\n";
+                return false;
+            }
+        }
 
         const auto different =
             std::to_string(pixels_failed) + " pixels are different\n";
--- perceptualdiff-2.1.orig/metric.h
+++ perceptualdiff-2.1/metric.h
@@ -52,25 +52,23 @@ namespace pdiff
         // 0.0 is the same as luminance_only_ = true,
         // 1.0 means full strength.
         float color_factor;
-
-        // How much to down sample image before comparing, in powers of 2.
-        unsigned int down_sample;
     };
 
 
     // Image comparison metric using Yee's method.
-    // References: A Perceptual Metric for Production Testing, Hector Yee, Journal
-    // of Graphics Tools 2004
+    // References: A Perceptual Metric for Production Testing, Hector Yee,
+    // Journal of Graphics Tools 2004
     //
     // Return true if the images are perceptually the same.
-    bool yee_compare(const PerceptualDiffParameters &parameters,
-                     const RGBAImage &image_a,
-                     const RGBAImage &image_b,
-                     size_t *output_num_pixels_failed=NULL,
-                     float *output_sum_errors=NULL,
-                     std::string *output_reason=NULL,
-                     RGBAImage *output_image_difference=NULL,
-                     std::ostream *output_verbose=NULL);
+    bool yee_compare(
+        const RGBAImage &image_a,
+        const RGBAImage &image_b,
+        const PerceptualDiffParameters &parameters=PerceptualDiffParameters(),
+        size_t *output_num_pixels_failed=nullptr,
+        float *output_sum_errors=nullptr,
+        std::string *output_reason=nullptr,
+        RGBAImage *output_image_difference=nullptr,
+        std::ostream *output_verbose=nullptr);
 }
 
 #endif
--- perceptualdiff-2.1.orig/perceptualdiff.cpp
+++ perceptualdiff-2.1/perceptualdiff.cpp
@@ -45,14 +45,14 @@ int main(const int argc, char **const ar
         std::string reason;
         float error_sum = 0;
         const auto passed = pdiff::yee_compare(
-            args.parameters_,
             *args.image_a_,
             *args.image_b_,
-            NULL,
+            args.parameters_,
+            nullptr,
             &error_sum,
             &reason,
             args.image_difference_.get(),
-            args.verbose_ ? &std::cout : NULL);
+            args.verbose_ ? &std::cout : nullptr);
 
         if (passed)
         {
@@ -63,27 +63,27 @@ int main(const int argc, char **const ar
         }
         else
         {
-                std::cout << "FAIL: " + reason;
-        }
+            std::cout << "FAIL: " + reason;
 
-        if (args.sum_errors_)
-        {
-            const auto normalized =
-                error_sum /
-                (args.image_a_->get_width() *
-                 args.image_a_->get_height() * 255.);
+            if (args.sum_errors_)
+            {
+                const auto normalized =
+                    error_sum /
+                    (args.image_a_->get_width() *
+                     args.image_a_->get_height() * 255.);
 
-            std::cout << error_sum << " error sum\n";
-            std::cout << normalized << " normalzied error sum\n";
-        }
+                std::cout << error_sum << " error sum\n";
+                std::cout << normalized << " normalzied error sum\n";
+            }
 
-        if (args.image_difference_.get())
-        {
-            args.image_difference_->write_to_file(args.image_difference_->get_name());
+            if (args.image_difference_.get())
+            {
+                args.image_difference_->write_to_file(args.image_difference_->get_name());
 
-            std::cerr << "Wrote difference image to "
-                      << args.image_difference_->get_name()
-                      << "\n";
+                std::cerr << "Wrote difference image to "
+                          << args.image_difference_->get_name()
+                          << "\n";
+            }
         }
 
         return passed ? EXIT_SUCCESS : EXIT_FAILURE;
--- perceptualdiff-2.1.orig/rgba_image.cpp
+++ perceptualdiff-2.1/rgba_image.cpp
@@ -96,19 +96,19 @@ namespace pdiff
 
         if (h == 0)
         {
-            h = weight_ / 2;
+            h = height_ / 2;
         }
 
-        if (width_ <= 1 or weight_ <= 1)
+        if (width_ <= 1 or height_ <= 1)
         {
             return nullptr;
         }
-        if (width_ == w and weight_ == h)
+        if (width_ == w and height_ == h)
         {
             return nullptr;
         }
         assert(w <= width_);
-        assert(h <= weight_);
+        assert(h <= height_);
 
         auto bitmap = to_free_image(*this);
         std::unique_ptr<FIBITMAP, FreeImageDeleter> converted(
--- perceptualdiff-2.1.orig/rgba_image.h
+++ perceptualdiff-2.1/rgba_image.h
@@ -44,7 +44,10 @@ namespace pdiff
     public:
 
         RGBAImage(const unsigned int w, const unsigned int h, const std::string &name="")
-            : width_(w), weight_(h), name_(name), data_(w * h)
+            : width_(w),
+              height_(h),
+              name_(name),
+              data_(static_cast<size_t>(w) * h)
         {
         }
 
@@ -81,7 +84,7 @@ namespace pdiff
 
         unsigned int get_height() const
         {
-            return weight_;
+            return height_;
         }
 
         void set(const unsigned int x, const unsigned int y, const unsigned int d)
@@ -126,7 +129,7 @@ namespace pdiff
         RGBAImage &operator=(const RGBAImage &);
 
         const unsigned int width_;
-        const unsigned int weight_;
+        const unsigned int height_;
         const std::string name_;
         std::vector<unsigned int> data_;
     };
--- perceptualdiff-2.1.orig/test/run_tests.bash
+++ perceptualdiff-2.1/test/run_tests.bash
@@ -1,4 +1,6 @@
-#!/bin/bash -eux
+#!/bin/bash
+
+set -eux
 
 # Script to run pdiff against a set of image file pairs, and check that the
 # PASS or FAIL status is as expected.
@@ -22,10 +24,13 @@ FAIL alpha1.png alpha2.png
 EOF
 }
 
+echo "*** tmpdir: ${tmpdir:=/tmp}"
+
 # Change to test directory
-readonly script_directory=$(dirname "$0")
+echo "*** script_directory: ${script_directory:=$(dirname "$0")}"
 cd "$script_directory"
 
+if [ -z "${pdiff:=}" ]; then
 found=0
 for d in ../build .. ../obj*; do
     pdiff="$d/perceptualdiff"
@@ -38,9 +43,9 @@ done
 if [ $found = 0 ]; then
     echo 'perceptualdiff must be built and exist in the repository root or the "build" directory'
     exit 1
-else
-    echo "*** testing executable binary $pdiff"
 fi
+fi
+echo "*** testing executable binary $pdiff"
 
 #------------------------------------------------------------------------------
 
@@ -75,29 +80,29 @@ fi
 "$pdiff" --help | grep -i 'usage'
 
 rm -f diff.png
-"$pdiff" --output diff.png --verbose fish[12].png 2>&1 | grep -q 'FAIL'
-ls diff.png
-rm -f diff.png
-
-head fish1.png > fake.png
-"$pdiff" --verbose fish1.png fake.png 2>&1 | grep -q 'Failed to load'
-rm -f fake.png
-
-mkdir -p unwritable.png
-"$pdiff" --output unwritable.png --verbose fish[12].png 2>&1 | grep -q 'Failed to save'
-rmdir unwritable.png
+"$pdiff" --output ${tmpdir}/diff.png --verbose fish{1,2}.png 2>&1 | grep -q 'FAIL'
+ls ${tmpdir}/diff.png
+rm -f ${tmpdir}/diff.png
+
+head fish1.png > ${tmpdir}/fake.png
+"$pdiff" --verbose fish1.png ${tmpdir}/fake.png 2>&1 | grep -q 'Failed to load'
+rm -f ${tmpdir}/fake.png
+
+mkdir -p ${tmpdir}/unwritable.png
+"$pdiff" --output ${tmpdir}/unwritable.png --verbose fish{1,2}.png 2>&1 | grep -q 'Failed to save'
+rmdir ${tmpdir}/unwritable.png
 
-"$pdiff" fish[12].png --output foo 2>&1 | grep -q 'unknown filetype'
+"$pdiff" fish{1,2}.png --output ${tmpdir}/foo 2>&1 | grep -q 'unknown filetype'
 "$pdiff" --verbose fish1.png 2>&1 | grep -q 'Not enough'
-"$pdiff" --downsample -3 fish1.png Aqsis_vase.png 2>&1 | grep -q 'Invalid'
+"$pdiff" --down-sample -3 fish1.png Aqsis_vase.png 2>&1 | grep -q 'Invalid'
 "$pdiff" --threshold -3 fish1.png Aqsis_vase.png 2>&1 | grep -q 'Invalid'
 "$pdiff" cam_mb_ref.tif cam_mb.tif --fake-option
 "$pdiff" --verbose --scale fish1.png Aqsis_vase.png 2>&1 | grep -q 'FAIL'
-"$pdiff" --downsample 2 fish1.png Aqsis_vase.png 2>&1 | grep -q 'FAIL'
+"$pdiff" --down-sample 2 fish1.png Aqsis_vase.png 2>&1 | grep -q 'FAIL'
 "$pdiff"  /dev/null /dev/null 2>&1 | grep -q 'Unknown filetype'
-"$pdiff" --verbose --sum-errors fish[12].png 2>&1 | grep -q 'sum'
-"$pdiff" --colorfactor .5 -threshold 1000 --gamma 3 --luminance 90 cam_mb_ref.tif cam_mb.tif
-"$pdiff" --verbose -downsample 30 -scale --luminanceonly --fov 80 cam_mb_ref.tif cam_mb.tif
+"$pdiff" --verbose --sum-errors fish{1,2}.png 2>&1 | grep -q 'sum'
+"$pdiff" --color-factor .5 -threshold 1000 --gamma 3 --luminance 90 cam_mb_ref.tif cam_mb.tif
+"$pdiff" --verbose -down-sample 30 -scale --luminance-only --fov 80 cam_mb_ref.tif cam_mb.tif
 "$pdiff" --fov wrong fish1.png fish1.png 2>&1 | grep -q 'Invalid argument'
 
 echo -e '\x1b[01;32mOK\x1b[0m'
