[freeimage] 18/18: d/patches: major rework of the patch queue.

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Nov 11 19:19:39 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/experimental
in repository freeimage.

commit 71059eeaa00ba74425fcf9ce2a72dd44db960b7d
Author: Ghislain Antony Vaillant <ghisvail at gmail.com>
Date:   Wed Nov 11 14:09:03 2015 +0000

    d/patches: major rework of the patch queue.
---
 .../0001-Disable-vendored-dependencies.patch       |  459 +++++
 debian/patches/0002-Use-system-dependencies.patch  |  184 ++
 ...cro-redefinition-for-64-bit-integer-types.patch |   26 +
 ...0004-Fix-compatibility-with-system-libpng.patch |   92 +
 .../patches/0005-Fix-doxygen-output-settings.patch |   52 +
 ...sable-usage-of-HTML-timestamps-in-doxygen.patch |   22 +
 ...7-Fix-unsafe-usage-of-printf-in-testsuite.patch |   21 +
 .../0008-Disable-testing-of-JPEG-transform.patch   |   42 +
 .../0009-Disable-testing-of-JXR-MemIO.patch        |   24 +
 ...0-Fix-missing-cstdio-include-in-testsuite.patch |   20 +
 debian/patches/0011-Fix-endianness-detection.patch |   21 +
 ...overflow.patch => 0012-Fix-CVE-2015-0852.patch} |   56 +-
 .../patches/build_using_libjpeg62_transupp.c.patch | 2005 --------------------
 debian/patches/disable_embedded_libraries.patch    |  359 ----
 debian/patches/fix-big-endian-detection.patch      |   48 -
 .../fix_Integer_overflow_in_ljpeg_start.patch      |   34 -
 debian/patches/fix_ftbfs_amd64.patch               |   26 -
 debian/patches/makefile_modifications.patch        |   69 -
 debian/patches/series                              |   20 +-
 debian/patches/tag_truncation.patch                |   31 -
 20 files changed, 1003 insertions(+), 2608 deletions(-)

diff --git a/debian/patches/0001-Disable-vendored-dependencies.patch b/debian/patches/0001-Disable-vendored-dependencies.patch
new file mode 100644
index 0000000..4442eea
--- /dev/null
+++ b/debian/patches/0001-Disable-vendored-dependencies.patch
@@ -0,0 +1,459 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Tue, 3 Nov 2015 14:39:33 +0000
+Subject: Disable vendored dependencies.
+
+This commit disables usage of the embedded dependencies for building
+FreeImage and FreeImagePlus. Functionalities which could not use the
+packaged dependencies are delibarately disabled for security reasons.
+
+This patch is based on Fedora's FreeImage-3.17.0_unbundle patch.
+---
+ Source/FreeImage.h                 | 15 ++++++-
+ Source/FreeImage/J2KHelper.cpp     |  2 +-
+ Source/FreeImage/Plugin.cpp        |  4 ++
+ Source/FreeImage/PluginEXR.cpp     | 20 +++++-----
+ Source/FreeImage/PluginJ2K.cpp     |  2 +-
+ Source/FreeImage/PluginJP2.cpp     |  2 +-
+ Source/FreeImage/PluginJPEG.cpp    |  6 +--
+ Source/FreeImage/PluginJXR.cpp     |  2 +-
+ Source/FreeImage/PluginPNG.cpp     |  4 +-
+ Source/FreeImage/PluginRAW.cpp     |  2 +-
+ Source/FreeImage/PluginTIFF.cpp    |  4 +-
+ Source/FreeImage/PluginWebP.cpp    |  8 ++--
+ Source/FreeImage/ZLibInterface.cpp |  5 +--
+ Source/Metadata/XTIFF.cpp          | 80 +++++++++++++++++++-------------------
+ genfipsrclist.sh                   |  9 +----
+ gensrclist.sh                      | 11 ++----
+ 16 files changed, 89 insertions(+), 87 deletions(-)
+
+diff --git a/Source/FreeImage.h b/Source/FreeImage.h
+index e2d1c5a..94d817d 100644
+--- a/Source/FreeImage.h
++++ b/Source/FreeImage.h
+@@ -410,7 +410,11 @@ FI_ENUM(FREE_IMAGE_FORMAT) {
+ 	FIF_DDS		= 24,
+ 	FIF_GIF     = 25,
+ 	FIF_HDR		= 26,
+-	FIF_FAXG3	= 27,
++/* Debian: The G3 fax format plugin is deliberately disabled in our build of
++   FreeImage, since it requires usage of the vendored copy of libtiff. */
++#if 0
++ 	FIF_FAXG3	= 27,
++#endif
+ 	FIF_SGI		= 28,
+ 	FIF_EXR		= 29,
+ 	FIF_J2K		= 30,
+@@ -473,6 +477,9 @@ FI_ENUM(FREE_IMAGE_DITHER) {
+ 	FID_BAYER16x16	= 6		//! Bayer ordered dispersed dot dithering (order 4 dithering matrix)
+ };
+ 
++/* Debian: The JPEGTransform functions are deliberately disabled in our build
++   of FreeImage, since they require usage of the vendored copy of libjpeg. */
++#if 0
+ /** Lossless JPEG transformations
+ Constants used in FreeImage_JPEGTransform
+ */
+@@ -486,6 +493,7 @@ FI_ENUM(FREE_IMAGE_JPEG_OPERATION) {
+ 	FIJPEG_OP_ROTATE_180	= 6,	//! 180-degree rotation
+ 	FIJPEG_OP_ROTATE_270	= 7		//! 270-degree clockwise (or 90 ccw)
+ };
++#endif
+ 
+ /** Tone mapping operators.
+ Constants used in FreeImage_ToneMapping.
+@@ -1076,7 +1084,9 @@ DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model,
+ // --------------------------------------------------------------------------
+ // JPEG lossless transformation routines
+ // --------------------------------------------------------------------------
+-
++/* Debian: The JPEGTransform functions are deliberately disabled in our build
++   of FreeImage, since they require usage of the vendored copy of libjpeg. */
++#if 0
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom);
+@@ -1085,6 +1095,7 @@ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io,
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
++#endif
+ 
+ 
+ // --------------------------------------------------------------------------
+diff --git a/Source/FreeImage/J2KHelper.cpp b/Source/FreeImage/J2KHelper.cpp
+index 1776c3b..538f1c5 100644
+--- a/Source/FreeImage/J2KHelper.cpp
++++ b/Source/FreeImage/J2KHelper.cpp
+@@ -21,7 +21,7 @@
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+-#include "../LibOpenJPEG/openjpeg.h"
++#include <openjpeg.h>
+ #include "J2KHelper.h"
+ 
+ // --------------------------------------------------------------------------
+diff --git a/Source/FreeImage/Plugin.cpp b/Source/FreeImage/Plugin.cpp
+index 57ebffd..c883a31 100644
+--- a/Source/FreeImage/Plugin.cpp
++++ b/Source/FreeImage/Plugin.cpp
+@@ -263,7 +263,11 @@ FreeImage_Initialise(BOOL load_local_plugins_only) {
+ 			s_plugins->AddNode(InitDDS);
+ 	        s_plugins->AddNode(InitGIF);
+ 	        s_plugins->AddNode(InitHDR);
++/* The G3 fax format plugin is deliberately disabled in our build of FreeImage
++   since it requires usage of the vendored copy of libtiff. */
++#if 0
+ 			s_plugins->AddNode(InitG3);
++#endif
+ 			s_plugins->AddNode(InitSGI);
+ 			s_plugins->AddNode(InitEXR);
+ 			s_plugins->AddNode(InitJ2K);
+diff --git a/Source/FreeImage/PluginEXR.cpp b/Source/FreeImage/PluginEXR.cpp
+index b286430..9bf3ada 100644
+--- a/Source/FreeImage/PluginEXR.cpp
++++ b/Source/FreeImage/PluginEXR.cpp
+@@ -28,16 +28,16 @@
+ #pragma warning (disable : 4800) // ImfVersion.h - 'const int' : forcing value to bool 'true' or 'false' (performance warning)
+ #endif 
+ 
+-#include "../OpenEXR/IlmImf/ImfIO.h"
+-#include "../OpenEXR/Iex/Iex.h"
+-#include "../OpenEXR/IlmImf/ImfOutputFile.h"
+-#include "../OpenEXR/IlmImf/ImfInputFile.h"
+-#include "../OpenEXR/IlmImf/ImfRgbaFile.h"
+-#include "../OpenEXR/IlmImf/ImfChannelList.h"
+-#include "../OpenEXR/IlmImf/ImfRgba.h"
+-#include "../OpenEXR/IlmImf/ImfArray.h"
+-#include "../OpenEXR/IlmImf/ImfPreviewImage.h"
+-#include "../OpenEXR/Half/half.h"
++#include <OpenEXR/ImfIO.h>
++#include <OpenEXR/Iex.h>
++#include <OpenEXR/ImfOutputFile.h>
++#include <OpenEXR/ImfInputFile.h>
++#include <OpenEXR/ImfRgbaFile.h>
++#include <OpenEXR/ImfChannelList.h>
++#include <OpenEXR/ImfRgba.h>
++#include <OpenEXR/ImfArray.h>
++#include <OpenEXR/ImfPreviewImage.h>
++#include <OpenEXR/half.h>
+ 
+ 
+ // ==========================================================
+diff --git a/Source/FreeImage/PluginJ2K.cpp b/Source/FreeImage/PluginJ2K.cpp
+index b8bcfc8..621a903 100644
+--- a/Source/FreeImage/PluginJ2K.cpp
++++ b/Source/FreeImage/PluginJ2K.cpp
+@@ -21,7 +21,7 @@
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+-#include "../LibOpenJPEG/openjpeg.h"
++#include <openjpeg.h>
+ #include "J2KHelper.h"
+ 
+ // ==========================================================
+diff --git a/Source/FreeImage/PluginJP2.cpp b/Source/FreeImage/PluginJP2.cpp
+index 742fe2c..c57f626 100644
+--- a/Source/FreeImage/PluginJP2.cpp
++++ b/Source/FreeImage/PluginJP2.cpp
+@@ -21,7 +21,7 @@
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+-#include "../LibOpenJPEG/openjpeg.h"
++#include <openjpeg.h>
+ #include "J2KHelper.h"
+ 
+ // ==========================================================
+diff --git a/Source/FreeImage/PluginJPEG.cpp b/Source/FreeImage/PluginJPEG.cpp
+index 573989c..aaeefa4 100644
+--- a/Source/FreeImage/PluginJPEG.cpp
++++ b/Source/FreeImage/PluginJPEG.cpp
+@@ -35,9 +35,9 @@ extern "C" {
+ #undef FAR
+ #include <setjmp.h>
+ 
+-#include "../LibJPEG/jinclude.h"
+-#include "../LibJPEG/jpeglib.h"
+-#include "../LibJPEG/jerror.h"
++#include <stdio.h>
++#include <jpeglib.h>
++#include <jerror.h>
+ }
+ 
+ #include "FreeImage.h"
+diff --git a/Source/FreeImage/PluginJXR.cpp b/Source/FreeImage/PluginJXR.cpp
+index 0e14e09..3e9fb87 100644
+--- a/Source/FreeImage/PluginJXR.cpp
++++ b/Source/FreeImage/PluginJXR.cpp
+@@ -23,7 +23,7 @@
+ #include "Utilities.h"
+ #include "../Metadata/FreeImageTag.h"
+ 
+-#include "../LibJXR/jxrgluelib/JXRGlue.h"
++#include <JXRGlue.h>
+ 
+ // ==========================================================
+ // Plugin Interface
+diff --git a/Source/FreeImage/PluginPNG.cpp b/Source/FreeImage/PluginPNG.cpp
+index ba2ef17..c3c5cd6 100644
+--- a/Source/FreeImage/PluginPNG.cpp
++++ b/Source/FreeImage/PluginPNG.cpp
+@@ -40,8 +40,8 @@
+ 
+ // ----------------------------------------------------------
+ 
+-#include "../ZLib/zlib.h"
+-#include "../LibPNG/png.h"
++#include <zlib.h>
++#include <png.h>
+ 
+ // ----------------------------------------------------------
+ 
+diff --git a/Source/FreeImage/PluginRAW.cpp b/Source/FreeImage/PluginRAW.cpp
+index e9bd5bf..c7f8758 100644
+--- a/Source/FreeImage/PluginRAW.cpp
++++ b/Source/FreeImage/PluginRAW.cpp
+@@ -19,7 +19,7 @@
+ // Use at your own risk!
+ // ==========================================================
+ 
+-#include "../LibRawLite/libraw/libraw.h"
++#include <libraw/libraw.h>
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+diff --git a/Source/FreeImage/PluginTIFF.cpp b/Source/FreeImage/PluginTIFF.cpp
+index 1b45453..3f723d4 100644
+--- a/Source/FreeImage/PluginTIFF.cpp
++++ b/Source/FreeImage/PluginTIFF.cpp
+@@ -37,9 +37,9 @@
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+-#include "../LibTIFF4/tiffiop.h"
++#include <tiffio.h>
+ #include "../Metadata/FreeImageTag.h"
+-#include "../OpenEXR/Half/half.h"
++#include <OpenEXR/half.h>
+ 
+ #include "FreeImageIO.h"
+ #include "PSDParser.h"
+diff --git a/Source/FreeImage/PluginWebP.cpp b/Source/FreeImage/PluginWebP.cpp
+index 9fb0b69..31837d4 100644
+--- a/Source/FreeImage/PluginWebP.cpp
++++ b/Source/FreeImage/PluginWebP.cpp
+@@ -24,10 +24,10 @@
+ 
+ #include "../Metadata/FreeImageTag.h"
+ 
+-#include "../LibWebP/src/webp/decode.h"
+-#include "../LibWebP/src/webp/encode.h"
+-#include "../LibWebP/src/enc/vp8enci.h"
+-#include "../LibWebP/src/webp/mux.h"
++#include <webp/decode.h>
++#include <webp/encode.h>
++// #include "../LibWebP/src/enc/vp8enci.h"
++#include <webp/mux.h>
+ 
+ // ==========================================================
+ // Plugin Interface
+diff --git a/Source/FreeImage/ZLibInterface.cpp b/Source/FreeImage/ZLibInterface.cpp
+index 3ab6d32..1a90904 100644
+--- a/Source/FreeImage/ZLibInterface.cpp
++++ b/Source/FreeImage/ZLibInterface.cpp
+@@ -19,10 +19,9 @@
+ // Use at your own risk!
+ // ==========================================================
+ 
+-#include "../ZLib/zlib.h"
++#include <zlib.h>
+ #include "FreeImage.h"
+ #include "Utilities.h"
+-#include "../ZLib/zutil.h"	/* must be the last header because of error C3163 in VS2008 (_vsnprintf defined in stdio.h) */
+ 
+ /**
+ Compresses a source buffer into a target buffer, using the ZLib library. 
+@@ -115,7 +114,7 @@ FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_s
+ 			return 0;
+         case Z_OK: {
+             // patch header, setup crc and length (stolen from mod_trace_output)
+-            BYTE *p = target + 8; *p++ = 2; *p = OS_CODE; // xflags, os_code
++            BYTE *p = target + 8; *p++ = 2; *p = 0x03; // xflags, os_code (unix)
+  	        crc = crc32(crc, source, source_size);
+ 	        memcpy(target + 4 + dest_len, &crc, 4);
+ 	        memcpy(target + 8 + dest_len, &source_size, 4);
+diff --git a/Source/Metadata/XTIFF.cpp b/Source/Metadata/XTIFF.cpp
+index d5be902..c1519ca 100644
+--- a/Source/Metadata/XTIFF.cpp
++++ b/Source/Metadata/XTIFF.cpp
+@@ -29,13 +29,18 @@
+ #pragma warning (disable : 4786) // identifier was truncated to 'number' characters
+ #endif
+ 
+-#include "../LibTIFF4/tiffiop.h"
++#include <tiffio.h>
+ 
+ #include "FreeImage.h"
+ #include "Utilities.h"
+ #include "FreeImageTag.h"
+ #include "FIRational.h"
+ 
++extern "C"
++{
++    int _TIFFDataSize(TIFFDataType type);
++}
++
+ // ----------------------------------------------------------
+ //   Extended TIFF Directory GEO Tag Support
+ // ----------------------------------------------------------
+@@ -224,6 +229,33 @@ tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) {
+ //   TIFF EXIF tag reading & writing
+ // ----------------------------------------------------------
+ 
++static uint32 exif_tag_ids[] = {
++  EXIFTAG_EXPOSURETIME, EXIFTAG_FNUMBER, EXIFTAG_EXPOSUREPROGRAM,
++  EXIFTAG_SPECTRALSENSITIVITY, EXIFTAG_ISOSPEEDRATINGS, EXIFTAG_OECF,
++  EXIFTAG_EXIFVERSION, EXIFTAG_DATETIMEORIGINAL, EXIFTAG_DATETIMEDIGITIZED,
++  EXIFTAG_COMPONENTSCONFIGURATION, EXIFTAG_COMPRESSEDBITSPERPIXEL,
++  EXIFTAG_SHUTTERSPEEDVALUE, EXIFTAG_APERTUREVALUE,
++  EXIFTAG_BRIGHTNESSVALUE, EXIFTAG_EXPOSUREBIASVALUE,
++  EXIFTAG_MAXAPERTUREVALUE, EXIFTAG_SUBJECTDISTANCE, EXIFTAG_METERINGMODE,
++  EXIFTAG_LIGHTSOURCE, EXIFTAG_FLASH, EXIFTAG_FOCALLENGTH,
++  EXIFTAG_SUBJECTAREA, EXIFTAG_MAKERNOTE, EXIFTAG_USERCOMMENT,
++  EXIFTAG_SUBSECTIME, EXIFTAG_SUBSECTIMEORIGINAL,
++  EXIFTAG_SUBSECTIMEDIGITIZED, EXIFTAG_FLASHPIXVERSION, EXIFTAG_COLORSPACE,
++  EXIFTAG_PIXELXDIMENSION, EXIFTAG_PIXELYDIMENSION,
++  EXIFTAG_RELATEDSOUNDFILE, EXIFTAG_FLASHENERGY,
++  EXIFTAG_SPATIALFREQUENCYRESPONSE, EXIFTAG_FOCALPLANEXRESOLUTION,
++  EXIFTAG_FOCALPLANEYRESOLUTION, EXIFTAG_FOCALPLANERESOLUTIONUNIT,
++  EXIFTAG_SUBJECTLOCATION, EXIFTAG_EXPOSUREINDEX, EXIFTAG_SENSINGMETHOD,
++  EXIFTAG_FILESOURCE, EXIFTAG_SCENETYPE, EXIFTAG_CFAPATTERN,
++  EXIFTAG_CUSTOMRENDERED, EXIFTAG_EXPOSUREMODE, EXIFTAG_WHITEBALANCE,
++  EXIFTAG_DIGITALZOOMRATIO, EXIFTAG_FOCALLENGTHIN35MMFILM,
++  EXIFTAG_SCENECAPTURETYPE, EXIFTAG_GAINCONTROL, EXIFTAG_CONTRAST,
++  EXIFTAG_SATURATION, EXIFTAG_SHARPNESS, EXIFTAG_DEVICESETTINGDESCRIPTION,
++  EXIFTAG_SUBJECTDISTANCERANGE, EXIFTAG_GAINCONTROL, EXIFTAG_GAINCONTROL,
++  EXIFTAG_IMAGEUNIQUEID
++};
++static int nExifTags = sizeof(exif_tag_ids) / sizeof(exif_tag_ids[0]);
++
+ /**
+ Read a single Exif tag
+ 
+@@ -575,43 +607,10 @@ tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
+ 
+ 	// loop over all Core Directory Tags
+ 	// ### uses private data, but there is no other way
++	// -> Fedora: Best we can do without private headers is to hard-code a list of known EXIF tags and read those
+ 	if(md_model == TagLib::EXIF_MAIN) {
+-		const TIFFDirectory *td = &tif->tif_dir;
+-
+-		uint32 lastTag = 0;	//<- used to prevent reading some tags twice (as stored in tif_fieldinfo)
+-
+-		for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
+-			const TIFFField *fld = tif->tif_fields[fi];
+-
+-			const uint32 tag_id = TIFFFieldTag(fld);
+-
+-			if(tag_id == lastTag) {
+-				continue;
+-			}
+-
+-			// test if tag value is set
+-			// (lifted directly from LibTiff _TIFFWriteDirectory)
+-
+-			if( fld->field_bit == FIELD_CUSTOM ) {
+-				int is_set = FALSE;
+-
+-				for(int ci = 0; ci < td->td_customValueCount; ci++ ) {
+-					is_set |= (td->td_customValues[ci].info == fld);
+-				}
+-
+-				if( !is_set ) {
+-					continue;
+-				}
+-
+-			} else if(!TIFFFieldSet(tif, fld->field_bit)) {
+-				continue;
+-			}
+-
+-			// process *all* other tags (some will be ignored)
+-
+-			tiff_read_exif_tag(tif, tag_id, dib, md_model);
+-
+-			lastTag = tag_id;
++		for (int i = 0; i < nExifTags; ++i) {
++			tiff_read_exif_tag(tif, exif_tag_ids[i], dib, md_model);
+ 		}
+ 
+ 	}
+@@ -723,10 +722,9 @@ tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
+ 	
+ 	TagLib& tag_lib = TagLib::instance();
+ 	
+-	for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) {
+-		const TIFFField *fld = tif->tif_fields[fi];
+-		
+-		const uint32 tag_id = TIFFFieldTag(fld);
++	for (int fi = 0, nfi = nExifTags; nfi > 0; nfi--, fi++) {
++		const uint32 tag_id = exif_tag_ids[fi];
++		const TIFFField *fld = TIFFFieldWithTag(tif, tag_id);
+ 
+ 		if(skip_write_field(tif, tag_id)) {
+ 			// skip tags that are already handled by the LibTIFF writing process
+diff --git a/genfipsrclist.sh b/genfipsrclist.sh
+index 41f946d..a605d4b 100644
+--- a/genfipsrclist.sh
++++ b/genfipsrclist.sh
+@@ -1,18 +1,13 @@
+ #!/bin/sh
+ 
+-DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/OpenEXR/IexMath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Source/LibWebP Source/LibJXR Source/LibJXR/common/include Source/LibJXR/image/sys Source/LibJXR/ [...]
++DIRLIST="Wrapper/FreeImagePlus"
+ 
+ 
+ echo "VER_MAJOR = 3" > fipMakefile.srcs
+ echo "VER_MINOR = 17.0" >> fipMakefile.srcs
+ 
+ echo -n "SRCS = " >> fipMakefile.srcs
+-for DIR in $DIRLIST; do
+-	VCPRJS=`echo $DIR/*.2008.vcproj`
+-	if [ "$VCPRJS" != "$DIR/*.2008.vcproj" ]; then
+-		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> fipMakefile.srcs
+-	fi
+-done
++find Wrapper/FreeImagePlus/src -name '*.cpp' -print | sort | xargs echo -n >> fipMakefile.srcs
+ echo >> fipMakefile.srcs
+ 
+ echo -n "INCLUDE =" >> fipMakefile.srcs
+diff --git a/gensrclist.sh b/gensrclist.sh
+index dbfb98d..78a7293 100644
+--- a/gensrclist.sh
++++ b/gensrclist.sh
+@@ -1,21 +1,16 @@
+ #!/bin/sh
+ 
+-DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/OpenEXR/IexMath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Source/LibWebP Source/LibJXR Source/LibJXR/common/include Source/LibJXR/image/sys Source/LibJXR/ [...]
++DIRLIST=`find Source -type d | sort`
+ 
+ echo "VER_MAJOR = 3" > Makefile.srcs
+ echo "VER_MINOR = 17.0" >> Makefile.srcs
+ 
+ echo -n "SRCS = " >> Makefile.srcs
+-for DIR in $DIRLIST; do
+-	VCPRJS=`echo $DIR/*.2008.vcproj`
+-	if [ "$VCPRJS" != "$DIR/*.2008.vcproj" ]; then
+-		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> Makefile.srcs
+-	fi
+-done
++find Source -name '*.c' -or -name '*.cpp' -not -name 'PluginG3.cpp' -not -name 'JPEGTransform.cpp' | sort | xargs echo -n >> Makefile.srcs
+ echo >> Makefile.srcs
+ 
+ echo -n "INCLS = " >> Makefile.srcs
+-find . -name "*.h" -print | xargs echo >> Makefile.srcs
++find Source -name '*.h' | sort | xargs echo -n >> Makefile.srcs
+ echo >> Makefile.srcs
+ 
+ echo -n "INCLUDE =" >> Makefile.srcs
diff --git a/debian/patches/0002-Use-system-dependencies.patch b/debian/patches/0002-Use-system-dependencies.patch
new file mode 100644
index 0000000..6dd30f6
--- /dev/null
+++ b/debian/patches/0002-Use-system-dependencies.patch
@@ -0,0 +1,184 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Thu, 5 Nov 2015 22:47:13 +0000
+Subject: Use system dependencies.
+
+This commit patches the build system to use the packaged dependencies
+for building FreeImage and FreeImagePlus. This patch also modifies some
+targets in the corresponding Makefiles to help with the package build process.
+---
+ Makefile.fip | 45 +++++++++++++++++----------------------------
+ Makefile.gnu | 41 ++++++++++++++++++++---------------------
+ 2 files changed, 37 insertions(+), 49 deletions(-)
+
+diff --git a/Makefile.fip b/Makefile.fip
+index b59c419..98733cf 100644
+--- a/Makefile.fip
++++ b/Makefile.fip
+@@ -11,27 +11,16 @@ INSTALLDIR ?= $(DESTDIR)/usr/lib
+ # Converts cr/lf to just lf
+ DOS2UNIX = dos2unix
+ 
+-LIBRARIES = -lstdc++
++LIBRARIES = -lstdc++ -LDist -lfreeimage
+ 
+ MODULES = $(SRCS:.c=.o)
+ MODULES := $(MODULES:.cpp=.o)
+-CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden
+-# OpenJPEG
+-CFLAGS += -DOPJ_STATIC
+-# LibRaw
+-CFLAGS += -DNO_LCMS
+-# LibJXR
+-CFLAGS += -DDISABLE_PERF_MEASUREMENT -D__ANSI__
+-CFLAGS += $(INCLUDE)
+-CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
+-# LibJXR
+-CXXFLAGS += -D__ANSI__
+-CXXFLAGS += $(INCLUDE)
+-
+-ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
+-	CFLAGS += -fPIC
+-	CXXFLAGS += -fPIC
+-endif
++CFLAGS ?= -O3 -fPIC
++override CFLAGS += -fexceptions -fvisibility=hidden
++override CFLAGS += $(INCLUDE) -IDist
++CXXFLAGS ?= -O3 -fPIC
++override CXXFLAGS += -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
++override CXXFLAGS += $(INCLUDE) -IDist
+ 
+ TARGET  = freeimageplus
+ STATICLIB = lib$(TARGET).a
+@@ -48,31 +37,31 @@ all: dist
+ 
+ dist: FreeImage
+ 	mkdir -p Dist
+-	cp *.a Dist/
+-	cp *.so Dist/
+-	cp Source/FreeImage.h Dist/
+-	cp Wrapper/FreeImagePlus/FreeImagePlus.h Dist/
++	cp $(STATICLIB) Dist/
++	cp $(SHAREDLIB) Dist/
++	cp $(HEADERFIP) Dist/
++	ln -sf $(SHAREDLIB) Dist/$(VERLIBNAME)
++	ln -sf $(VERLIBNAME) Dist/$(LIBNAME)
+ 
+ dos2unix:
+-	@$(DOS2UNIX) $(SRCS)
++	@$(DOS2UNIX) $(SRCS) $(HEADERFIP)
+ 
+ FreeImage: $(STATICLIB) $(SHAREDLIB)
+ 
+ .c.o:
+-	$(CC) $(CFLAGS) -c $< -o $@
++	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+ 
+ .cpp.o:
+-	$(CXX) $(CXXFLAGS) -c $< -o $@
++	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
+ 
+ $(STATICLIB): $(MODULES)
+ 	$(AR) r $@ $(MODULES)
+ 
+ $(SHAREDLIB): $(MODULES)
+-	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
++	$(CC) -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
+ 
+ install:
+ 	install -d $(INCDIR) $(INSTALLDIR)
+-	install -m 644 -o root -g root $(HEADER) $(INCDIR)
+ 	install -m 644 -o root -g root $(HEADERFIP) $(INCDIR)
+ 	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
+ 	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
+@@ -80,5 +69,5 @@ install:
+ 	ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)	
+ 
+ clean:
+-	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
++	rm -f Dist/lib$(TARGET)* Dist/FreeImagePlus.h $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+ 
+diff --git a/Makefile.gnu b/Makefile.gnu
+index 92f6358..4e61efa 100644
+--- a/Makefile.gnu
++++ b/Makefile.gnu
+@@ -11,27 +11,24 @@ INSTALLDIR ?= $(DESTDIR)/usr/lib
+ # Converts cr/lf to just lf
+ DOS2UNIX = dos2unix
+ 
+-LIBRARIES = -lstdc++
++LIBRARIES = -lstdc++ -ljxrglue $(shell pkg-config --libs libjpeg libopenjp2 libpng libraw libtiff-4 libwebpmux OpenEXR zlib) -lm
+ 
+ MODULES = $(SRCS:.c=.o)
+ MODULES := $(MODULES:.cpp=.o)
+-CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden
++CFLAGS ?= -O3 -fPIC
++override CFLAGS += -fexceptions -fvisibility=hidden
+ # OpenJPEG
+-CFLAGS += -DOPJ_STATIC
++override CFLAGS += -DOPJ_STATIC
+ # LibRaw
+-CFLAGS += -DNO_LCMS
++override CFLAGS += -DNO_LCMS
+ # LibJXR
+-CFLAGS += -DDISABLE_PERF_MEASUREMENT -D__ANSI__
+-CFLAGS += $(INCLUDE)
+-CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
++override CFLAGS += -DDISABLE_PERF_MEASUREMENT -D__ANSI__
++override CFLAGS += $(INCLUDE) -I/usr/include/jxrlib $(shell pkg-config --cflags libjpeg libopenjp2 libpng libraw libtiff-4 libwebpmux OpenEXR zlib)
++CXXFLAGS ?= -O3 -fPIC
++override CXXFLAGS += -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
+ # LibJXR
+-CXXFLAGS += -D__ANSI__
+-CXXFLAGS += $(INCLUDE)
+-
+-ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
+-	CFLAGS += -fPIC
+-	CXXFLAGS += -fPIC
+-endif
++override CXXFLAGS += -D__ANSI__
++override CXXFLAGS += $(INCLUDE) -I/usr/include/jxrlib $(shell pkg-config --cflags libjpeg libopenjp2 libpng libraw libtiff-4 libwebpmux OpenEXR zlib)
+ 
+ TARGET  = freeimage
+ STATICLIB = lib$(TARGET).a
+@@ -48,9 +45,11 @@ all: dist
+ 
+ dist: FreeImage
+ 	mkdir -p Dist
+-	cp *.a Dist/
+-	cp *.so Dist/
+-	cp Source/FreeImage.h Dist/
++	cp $(STATICLIB) Dist/
++	cp $(SHAREDLIB) Dist/
++	cp $(HEADER) Dist/
++	ln -sf $(SHAREDLIB) Dist/$(VERLIBNAME)
++	ln -sf $(VERLIBNAME) Dist/$(LIBNAME)
+ 
+ dos2unix:
+ 	@$(DOS2UNIX) $(SRCS) $(INCLS)
+@@ -58,16 +57,16 @@ dos2unix:
+ FreeImage: $(STATICLIB) $(SHAREDLIB)
+ 
+ .c.o:
+-	$(CC) $(CFLAGS) -c $< -o $@
++	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+ 
+ .cpp.o:
+-	$(CXX) $(CXXFLAGS) -c $< -o $@
++	$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
+ 
+ $(STATICLIB): $(MODULES)
+ 	$(AR) r $@ $(MODULES)
+ 
+ $(SHAREDLIB): $(MODULES)
+-	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
++	$(CC) -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
+ 
+ install:
+ 	install -d $(INCDIR) $(INSTALLDIR)
+@@ -79,5 +78,5 @@ install:
+ #	ldconfig
+ 
+ clean:
+-	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
++	rm -f Dist/lib$(TARGET)* Dist/FreeImage.h $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
+ 
diff --git a/debian/patches/0003-Fix-macro-redefinition-for-64-bit-integer-types.patch b/debian/patches/0003-Fix-macro-redefinition-for-64-bit-integer-types.patch
new file mode 100644
index 0000000..aec1839
--- /dev/null
+++ b/debian/patches/0003-Fix-macro-redefinition-for-64-bit-integer-types.patch
@@ -0,0 +1,26 @@
+From: Debian QA Group <packages at qa.debian.org>
+Date: Fri, 6 Nov 2015 13:51:20 +0000
+Subject: Fix macro redefinition for 64-bit integer types.
+
+Both FreeImage and LibRAW defines INT64 and UINT64 aliases in their respective
+public headers via macros. This commit guards against macro redefinitions for
+these types inside the FreeImage.h public header.
+---
+ Source/FreeImage.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Source/FreeImage.h b/Source/FreeImage.h
+index 94d817d..38910b8 100644
+--- a/Source/FreeImage.h
++++ b/Source/FreeImage.h
+@@ -155,8 +155,10 @@ typedef uint8_t BYTE;
+ typedef uint16_t WORD;
+ typedef uint32_t DWORD;
+ typedef int32_t LONG;
++#ifndef _LIBRAW_TYPES_H
+ typedef int64_t INT64;
+ typedef uint64_t UINT64;
++#endif
+ #else
+ // MS is not C99 ISO compliant
+ typedef long BOOL;
diff --git a/debian/patches/0004-Fix-compatibility-with-system-libpng.patch b/debian/patches/0004-Fix-compatibility-with-system-libpng.patch
new file mode 100644
index 0000000..7a731b3
--- /dev/null
+++ b/debian/patches/0004-Fix-compatibility-with-system-libpng.patch
@@ -0,0 +1,92 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Tue, 3 Nov 2015 15:20:45 +0000
+Subject: Fix compatibility with system libpng.
+
+The PNG plugin of FreeImage makes use of optional features of libpng, which
+are not enabled in Debian. This commit adds the necessary guards for FreeImage
+to compile and run without these features.
+---
+ Source/FreeImage/PluginPNG.cpp | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/Source/FreeImage/PluginPNG.cpp b/Source/FreeImage/PluginPNG.cpp
+index c3c5cd6..3c8f0e0 100644
+--- a/Source/FreeImage/PluginPNG.cpp
++++ b/Source/FreeImage/PluginPNG.cpp
+@@ -109,9 +109,11 @@ ReadMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
+ 			// create a tag
+ 			tag = FreeImage_CreateTag();
+ 			if(!tag) return FALSE;
+-
++#ifdef PNG_iTXt_SUPPORTED
+ 			DWORD tag_length = (DWORD) MAX(text_ptr[i].text_length, text_ptr[i].itxt_length);
+-
++#else
++			DWORD tag_length = text_ptr[i].text_length;
++#endif
+ 			FreeImage_SetTagLength(tag, tag_length);
+ 			FreeImage_SetTagCount(tag, tag_length);
+ 			FreeImage_SetTagType(tag, FIDT_ASCII);
+@@ -179,14 +181,19 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
+ 	if(mdhandle) {
+ 		do {
+ 			memset(&text_metadata, 0, sizeof(png_text));
++#ifdef PNG_iTXt_SUPPORTED
+ 			text_metadata.compression = 1;							// iTXt, none
++#else
++			text_metadata.compression = -1;
++#endif
+ 			text_metadata.key = (char*)FreeImage_GetTagKey(tag);	// keyword, 1-79 character description of "text"
+ 			text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
+ 			text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
++#ifdef PNG_iTXt_SUPPORTED
+ 			text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
+ 			text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
+ 			text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
+-
++#endif
+ 			// set the tag 
+ 			png_set_text(png_ptr, info_ptr, &text_metadata, 1);
+ 
+@@ -205,10 +212,11 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
+ 		text_metadata.key = (char*)g_png_xmp_keyword;			// keyword, 1-79 character description of "text"
+ 		text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
+ 		text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
++#ifdef PNG_iTXt_SUPPORTED
+ 		text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
+ 		text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
+ 		text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
+-
++#endif
+ 		// set the tag 
+ 		png_set_text(png_ptr, info_ptr, &text_metadata, 1);
+ 		bResult &= TRUE;
+@@ -705,7 +713,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+ 
+ 			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
+ 				png_charp profile_name = NULL;
+-				png_bytep profile_data = NULL;
++				png_charp profile_data = NULL;
+ 				png_uint_32 profile_length = 0;
+ 				int  compression_type;
+ 
+@@ -744,8 +752,9 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
+ 			for (png_uint_32 k = 0; k < height; k++) {
+ 				row_pointers[height - 1 - k] = FreeImage_GetScanLine(dib, k);
+ 			}
+-
++#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ 			png_set_benign_errors(png_ptr, 1);
++#endif
+ 			png_read_image(png_ptr, row_pointers);
+ 
+ 			// check if the bitmap contains transparency, if so enable it in the header
+@@ -991,7 +1000,7 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
+ 
+ 			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
+ 			if (iccProfile->size && iccProfile->data) {
+-				png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_const_bytep)iccProfile->data, iccProfile->size);
++				png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_charp)iccProfile->data, iccProfile->size);
+ 			}
+ 
+ 			// write metadata
diff --git a/debian/patches/0005-Fix-doxygen-output-settings.patch b/debian/patches/0005-Fix-doxygen-output-settings.patch
new file mode 100644
index 0000000..49ff8cb
--- /dev/null
+++ b/debian/patches/0005-Fix-doxygen-output-settings.patch
@@ -0,0 +1,52 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Wed, 4 Nov 2015 19:07:47 +0000
+Subject: Fix doxygen output settings.
+
+>From Fedora's FreeImage-3.17.0_doxygen patch. Uses relative paths for output
+directory, logfile and input, instead of hardcoded Windows paths.
+---
+ Wrapper/FreeImagePlus/doc/FreeImagePlus.dox | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox b/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
+index 8c32d39..33fa374 100644
+--- a/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
++++ b/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
+@@ -31,7 +31,7 @@ PROJECT_NAME           = FreeImagePlus
+ # This could be handy for archiving the generated documentation or 
+ # if some version control system is used.
+ 
+-PROJECT_NUMBER         = "- FreeImage 3.15.1"
++PROJECT_NUMBER         = "- FreeImage 3.17.0"
+ 
+ # Using the PROJECT_BRIEF tag one can provide an optional one line description 
+ # for a project that appears at the top of each page and should give viewer 
+@@ -51,7 +51,7 @@ PROJECT_LOGO           =
+ # If a relative path is entered, it will be relative to the location 
+ # where doxygen was started. If left blank the current directory will be used.
+ 
+-OUTPUT_DIRECTORY       = D:/Projects/FreeImage/Wrapper/FreeImagePlus/
++OUTPUT_DIRECTORY       =
+ 
+ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+ # 4096 sub-directories (in 2 levels) under the output directory of each output 
+@@ -598,7 +598,7 @@ WARN_FORMAT            = "$file:$line: $text"
+ # and error messages should be written. If left blank the output is written 
+ # to stderr.
+ 
+-WARN_LOGFILE           = D:\Projects\FreeImage\Wrapper\FreeImagePlus\doc\doxygen.log
++WARN_LOGFILE           =
+ 
+ #---------------------------------------------------------------------------
+ # configuration options related to the input files
+@@ -609,8 +609,8 @@ WARN_LOGFILE           = D:\Projects\FreeImage\Wrapper\FreeImagePlus\doc\doxygen
+ # directories like "/usr/src/myproject". Separate the files or directories 
+ # with spaces.
+ 
+-INPUT                  = D:/Projects/FreeImage/Source/FreeImage.h \
+-                         D:/Projects/FreeImage/Wrapper/FreeImagePlus/FreeImagePlus.h
++INPUT                  = ../../../Source/FreeImage.h \
++                         ../FreeImagePlus.h
+ 
+ # This tag can be used to specify the character encoding of the source files 
+ # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
diff --git a/debian/patches/0006-Disable-usage-of-HTML-timestamps-in-doxygen.patch b/debian/patches/0006-Disable-usage-of-HTML-timestamps-in-doxygen.patch
new file mode 100644
index 0000000..1f82fb0
--- /dev/null
+++ b/debian/patches/0006-Disable-usage-of-HTML-timestamps-in-doxygen.patch
@@ -0,0 +1,22 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Tue, 10 Nov 2015 13:50:59 +0000
+Subject: Disable usage of HTML timestamps in doxygen.
+
+Improves package reproducibility.
+---
+ Wrapper/FreeImagePlus/doc/FreeImagePlus.dox | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox b/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
+index 33fa374..d4ece42 100644
+--- a/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
++++ b/Wrapper/FreeImagePlus/doc/FreeImagePlus.dox
+@@ -888,7 +888,7 @@ HTML_COLORSTYLE_GAMMA  = 80
+ # page will contain the date and time when the page was generated. Setting 
+ # this to NO can help when comparing the output of multiple runs.
+ 
+-HTML_TIMESTAMP         = YES
++HTML_TIMESTAMP         = NO
+ 
+ # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+ # files or namespaces will be aligned in HTML using tables. If set to 
diff --git a/debian/patches/0007-Fix-unsafe-usage-of-printf-in-testsuite.patch b/debian/patches/0007-Fix-unsafe-usage-of-printf-in-testsuite.patch
new file mode 100644
index 0000000..7cc5aad
--- /dev/null
+++ b/debian/patches/0007-Fix-unsafe-usage-of-printf-in-testsuite.patch
@@ -0,0 +1,21 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Tue, 3 Nov 2015 17:59:42 +0000
+Subject: Fix unsafe usage of printf in testsuite.
+
+---
+ TestAPI/MainTestSuite.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/TestAPI/MainTestSuite.cpp b/TestAPI/MainTestSuite.cpp
+index 7944c22..1b5a1b5 100644
+--- a/TestAPI/MainTestSuite.cpp
++++ b/TestAPI/MainTestSuite.cpp
+@@ -34,7 +34,7 @@ void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
+ 	if(fif != FIF_UNKNOWN) {
+ 		printf("%s Format\n", FreeImage_GetFormatFromFIF(fif));
+ 	}
+-	printf(message);
++	printf("%s", message);
+ 	printf(" ***\n");
+ }
+ 
diff --git a/debian/patches/0008-Disable-testing-of-JPEG-transform.patch b/debian/patches/0008-Disable-testing-of-JPEG-transform.patch
new file mode 100644
index 0000000..468fbe0
--- /dev/null
+++ b/debian/patches/0008-Disable-testing-of-JPEG-transform.patch
@@ -0,0 +1,42 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Tue, 3 Nov 2015 18:15:18 +0000
+Subject: Disable testing of JPEG transform.
+
+Reason: the JPEG transform features are disabled from the Debian build as a
+result of the stripping of the vendored dependencies.
+---
+ TestAPI/testJPEG.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/TestAPI/testJPEG.cpp b/TestAPI/testJPEG.cpp
+index 798033d..94638b9 100644
+--- a/TestAPI/testJPEG.cpp
++++ b/TestAPI/testJPEG.cpp
+@@ -25,6 +25,7 @@
+ // Local test functions
+ // ----------------------------------------------------------
+ 
++#if 0
+ void testJPEGTransform(const char *src_file) {
+ 	BOOL bResult;
+ 	BOOL perfect;
+@@ -193,11 +194,13 @@ void testJPEGSameFile(const char *src_file) {
+ 	bResult = FreeImage_JPEGTransform("test.jpg", "test.jpg", FIJPEG_OP_ROTATE_270, perfect);
+ 	assert(bResult);
+ }
++#endif
+ 
+ // Main test function
+ // ----------------------------------------------------------
+ 
+ void testJPEG() {
++#if 0
+ 	const char *src_file = "exif.jpg";
+ 
+ 	printf("testJPEG (should throw exceptions) ...\n");
+@@ -213,4 +216,5 @@ void testJPEG() {
+ 
+ 	// using the same file for src & dst is allowed
+ 	testJPEGSameFile(src_file);
++#endif
+ }
diff --git a/debian/patches/0009-Disable-testing-of-JXR-MemIO.patch b/debian/patches/0009-Disable-testing-of-JXR-MemIO.patch
new file mode 100644
index 0000000..4bc9d4f
--- /dev/null
+++ b/debian/patches/0009-Disable-testing-of-JXR-MemIO.patch
@@ -0,0 +1,24 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Thu, 5 Nov 2015 23:47:23 +0000
+Subject: Disable testing of JXR MemIO.
+
+Reason: The JXR MemIO test raises an assertion error, whose origin is unknown
+and needs to be assessed with upstream. Meanwhile the failing test should be
+temporarily disabled.
+---
+ TestAPI/MainTestSuite.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/TestAPI/MainTestSuite.cpp b/TestAPI/MainTestSuite.cpp
+index 1b5a1b5..540ec47 100644
+--- a/TestAPI/MainTestSuite.cpp
++++ b/TestAPI/MainTestSuite.cpp
+@@ -73,7 +73,7 @@ int main(int argc, char *argv[]) {
+ 
+ 	// test memory IO
+ 	testMemIO("sample.png");
+-	testMemIO("exif.jxr");
++	//testMemIO("exif.jxr");
+ 
+ 	// test multipage functions
+ 	testMultiPage("sample.png");
diff --git a/debian/patches/0010-Fix-missing-cstdio-include-in-testsuite.patch b/debian/patches/0010-Fix-missing-cstdio-include-in-testsuite.patch
new file mode 100644
index 0000000..01bd785
--- /dev/null
+++ b/debian/patches/0010-Fix-missing-cstdio-include-in-testsuite.patch
@@ -0,0 +1,20 @@
+From: Ghislain Antony Vaillant <ghisvail at gmail.com>
+Date: Wed, 4 Nov 2015 08:41:35 +0000
+Subject: Fix missing cstdio include in testsuite.
+
+---
+ Wrapper/FreeImagePlus/test/fipTest.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Wrapper/FreeImagePlus/test/fipTest.h b/Wrapper/FreeImagePlus/test/fipTest.h
+index 3b8d1de..e8f98fc 100644
+--- a/Wrapper/FreeImagePlus/test/fipTest.h
++++ b/Wrapper/FreeImagePlus/test/fipTest.h
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ 
+ #include <iostream>
++#include <cstdio>
+ 
+ // --------------------------------------------------------------------------
+ // Memory IO test scripts
diff --git a/debian/patches/0011-Fix-endianness-detection.patch b/debian/patches/0011-Fix-endianness-detection.patch
new file mode 100644
index 0000000..7040af2
--- /dev/null
+++ b/debian/patches/0011-Fix-endianness-detection.patch
@@ -0,0 +1,21 @@
+From: Dejan Latinovic <Dejan.Latinovic at imgtec.com>
+Date: Wed, 1 Oct 2014 11:12:37 +0100
+Subject: Fix endianness detection.
+
+---
+ Source/FreeImage.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Source/FreeImage.h b/Source/FreeImage.h
+index 38910b8..43a84ae 100644
+--- a/Source/FreeImage.h
++++ b/Source/FreeImage.h
+@@ -75,7 +75,7 @@
+ // or define any of FREEIMAGE_BIGENDIAN and FREEIMAGE_LITTLEENDIAN directly
+ // to specify the desired endianness.
+ #if (!defined(FREEIMAGE_BIGENDIAN) && !defined(FREEIMAGE_LITTLEENDIAN))
+-	#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || defined(__BIG_ENDIAN__)
++	#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
+ 		#define FREEIMAGE_BIGENDIAN
+ 	#endif // BYTE_ORDER
+ #endif // !FREEIMAGE_[BIG|LITTLE]ENDIAN
diff --git a/debian/patches/fix_integer_overflow.patch b/debian/patches/0012-Fix-CVE-2015-0852.patch
similarity index 75%
rename from debian/patches/fix_integer_overflow.patch
rename to debian/patches/0012-Fix-CVE-2015-0852.patch
index 28a5bf9..f114bf8 100644
--- a/debian/patches/fix_integer_overflow.patch
+++ b/debian/patches/0012-Fix-CVE-2015-0852.patch
@@ -1,16 +1,17 @@
-Description: fix integer overflow
-Origin: upstream
- http://freeimage.cvs.sourceforge.net/viewvc/freeimage/FreeImage/Source/FreeImage/PluginPCX.cpp?view=patch&r1=1.17&r2=1.18&pathrev=MAIN
- http://freeimage.cvs.sourceforge.net/viewvc/freeimage/FreeImage/Source/FreeImage/PluginPCX.cpp?view=patch&r1=1.18&r2=1.19&pathrev=MAIN
-Bug-Debian: https://bugs.debian.org/797165
-Last-Update: 2015-09-14
+From: Debian QA Group <packages at qa.debian.org>
+Date: Fri, 6 Nov 2015 13:51:20 +0000
+Subject: Fix CVE-2015-0852
+
+CVE-2015-0852: multiple integer underflows in PluginPCX.cpp.
 ---
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: freeimage/Source/FreeImage/PluginPCX.cpp
-===================================================================
---- freeimage.orig/Source/FreeImage/PluginPCX.cpp
-+++ freeimage/Source/FreeImage/PluginPCX.cpp
-@@ -347,12 +347,14 @@ Load(FreeImageIO *io, fi_handle handle,
+ Source/FreeImage/PluginPCX.cpp | 76 +++++++++++++++++++++++++++---------------
+ 1 file changed, 50 insertions(+), 26 deletions(-)
+
+diff --git a/Source/FreeImage/PluginPCX.cpp b/Source/FreeImage/PluginPCX.cpp
+index cd75629..dcd9d61 100644
+--- a/Source/FreeImage/PluginPCX.cpp
++++ b/Source/FreeImage/PluginPCX.cpp
+@@ -347,12 +347,14 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  
  	try {
  		// check PCX identifier
@@ -31,7 +32,7 @@ Index: freeimage/Source/FreeImage/PluginPCX.cpp
  		}
  
  		// process the header
-@@ -366,20 +368,38 @@ Load(FreeImageIO *io, fi_handle handle,
+@@ -366,20 +368,38 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  		SwapHeader(&header);
  #endif
  
@@ -42,25 +43,23 @@ Index: freeimage/Source/FreeImage/PluginPCX.cpp
 +		const int top		= window[1];
 +		const int right		= window[2];
 +		const int bottom	= window[3];
++
++		// check image size
++		if((left >= right) || (top >= bottom)) {
++			throw FI_MSG_ERROR_PARSING;
++		}
  
 -		unsigned width = header.window[2] - header.window[0] + 1;
 -		unsigned height = header.window[3] - header.window[1] + 1;
 -		unsigned bitcount = header.bpp * header.planes;
--
++		const unsigned width = right - left + 1;
++		const unsigned height = bottom - top + 1;
++		const unsigned bitcount = header.bpp * header.planes;
+ 
 -		if (bitcount == 24) {
 -			dib = FreeImage_AllocateHeader(header_only, width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
 -		} else {
 -			dib = FreeImage_AllocateHeader(header_only, width, height, bitcount);			
-+		// check image size
-+		if((left >= right) || (top >= bottom)) {
-+			throw FI_MSG_ERROR_PARSING;
- 		}
- 
--		// if the dib couldn't be allocated, throw an error
-+		const unsigned width = right - left + 1;
-+		const unsigned height = bottom - top + 1;
-+		const unsigned bitcount = header.bpp * header.planes;
-+
 +		// allocate a new DIB
 +		switch(bitcount) {
 +			case 1:
@@ -74,13 +73,14 @@ Index: freeimage/Source/FreeImage/PluginPCX.cpp
 +			default:
 +				throw FI_MSG_ERROR_DIB_MEMORY;
 +				break;
-+		}
+ 		}
  
-+		// if the dib couldn't be allocated, throw an error
+ 		// if the dib couldn't be allocated, throw an error
+-
  		if (!dib) {
  			throw FI_MSG_ERROR_DIB_MEMORY;
  		}
-@@ -426,19 +446,23 @@ Load(FreeImageIO *io, fi_handle handle,
+@@ -426,19 +446,23 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  
  				if (palette_id == 0x0C) {
  					BYTE *cmap = (BYTE*)malloc(768 * sizeof(BYTE));
@@ -113,7 +113,7 @@ Index: freeimage/Source/FreeImage/PluginPCX.cpp
  				}
  
  				// wrong palette ID, perhaps a gray scale is needed ?
-@@ -466,9 +490,9 @@ Load(FreeImageIO *io, fi_handle handle,
+@@ -466,9 +490,9 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  		// calculate the line length for the PCX and the DIB
  
  		// length of raster line in bytes
diff --git a/debian/patches/build_using_libjpeg62_transupp.c.patch b/debian/patches/build_using_libjpeg62_transupp.c.patch
deleted file mode 100644
index 749613c..0000000
--- a/debian/patches/build_using_libjpeg62_transupp.c.patch
+++ /dev/null
@@ -1,2005 +0,0 @@
---- freeimage.orig/gensrclist.sh
-+++ freeimage/gensrclist.sh
-@@ -12,7 +12,7 @@ for DIR in $DIRLIST; do
- 		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> Makefile.srcs
- 	fi
- done
--echo -n ' Source/LibJPEG/transupp.c' >> Makefile.srcs
-+echo -n ' jpeg/transupp.c' >> Makefile.srcs
- echo >> Makefile.srcs
- 
- echo -n "INCLS = " >> Makefile.srcs
---- /dev/null
-+++ freeimage/jpeg/jinclude.h
-@@ -0,0 +1,91 @@
-+/*
-+ * jinclude.h
-+ *
-+ * Copyright (C) 1991-1994, Thomas G. Lane.
-+ * This file is part of the Independent JPEG Group's software.
-+ * For conditions of distribution and use, see the accompanying README file.
-+ *
-+ * This file exists to provide a single place to fix any problems with
-+ * including the wrong system include files.  (Common problems are taken
-+ * care of by the standard jconfig symbols, but on really weird systems
-+ * you may have to edit this file.)
-+ *
-+ * NOTE: this file is NOT intended to be included by applications using the
-+ * JPEG library.  Most applications need only include jpeglib.h.
-+ */
-+
-+
-+/* Include auto-config file to find out which system include files we need. */
-+
-+#include "jconfig.h"		/* auto configuration options */
-+#define JCONFIG_INCLUDED	/* so that jpeglib.h doesn't do it again */
-+
-+/*
-+ * We need the NULL macro and size_t typedef.
-+ * On an ANSI-conforming system it is sufficient to include <stddef.h>.
-+ * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
-+ * pull in <sys/types.h> as well.
-+ * Note that the core JPEG library does not require <stdio.h>;
-+ * only the default error handler and data source/destination modules do.
-+ * But we must pull it in because of the references to FILE in jpeglib.h.
-+ * You can remove those references if you want to compile without <stdio.h>.
-+ */
-+
-+#ifdef HAVE_STDDEF_H
-+#include <stddef.h>
-+#endif
-+
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+
-+#ifdef NEED_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include <stdio.h>
-+
-+/*
-+ * We need memory copying and zeroing functions, plus strncpy().
-+ * ANSI and System V implementations declare these in <string.h>.
-+ * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
-+ * Some systems may declare memset and memcpy in <memory.h>.
-+ *
-+ * NOTE: we assume the size parameters to these functions are of type size_t.
-+ * Change the casts in these macros if not!
-+ */
-+
-+#ifdef NEED_BSD_STRINGS
-+
-+#include <strings.h>
-+#define MEMZERO(target,size)	bzero((void *)(target), (size_t)(size))
-+#define MEMCOPY(dest,src,size)	bcopy((const void *)(src), (void *)(dest), (size_t)(size))
-+
-+#else /* not BSD, assume ANSI/SysV string lib */
-+
-+#include <string.h>
-+#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size))
-+#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size))
-+
-+#endif
-+
-+/*
-+ * In ANSI C, and indeed any rational implementation, size_t is also the
-+ * type returned by sizeof().  However, it seems there are some irrational
-+ * implementations out there, in which sizeof() returns an int even though
-+ * size_t is defined as long or unsigned long.  To ensure consistent results
-+ * we always use this SIZEOF() macro in place of using sizeof() directly.
-+ */
-+
-+#define SIZEOF(object)	((size_t) sizeof(object))
-+
-+/*
-+ * The modules that use fread() and fwrite() always invoke them through
-+ * these macros.  On some systems you may need to twiddle the argument casts.
-+ * CAUTION: argument order is different from underlying functions!
-+ */
-+
-+#define JFREAD(file,buf,sizeofbuf)  \
-+  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
-+#define JFWRITE(file,buf,sizeofbuf)  \
-+  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
---- /dev/null
-+++ freeimage/jpeg/jpegcomp.h
-@@ -0,0 +1,30 @@
-+/*
-+ * jpegcomp.h
-+ *
-+ * Copyright (C) 2010, D. R. Commander
-+ * For conditions of distribution and use, see the accompanying README file.
-+ *
-+ * JPEG compatibility macros
-+ * These declarations are considered internal to the JPEG library; most
-+ * applications using the library shouldn't need to include this file.
-+ */
-+
-+#if JPEG_LIB_VERSION >= 70
-+#define _DCT_scaled_size DCT_h_scaled_size
-+#define _DCT_h_scaled_size DCT_h_scaled_size
-+#define _DCT_v_scaled_size DCT_v_scaled_size
-+#define _min_DCT_scaled_size min_DCT_h_scaled_size
-+#define _min_DCT_h_scaled_size min_DCT_h_scaled_size
-+#define _min_DCT_v_scaled_size min_DCT_v_scaled_size
-+#define _jpeg_width jpeg_width
-+#define _jpeg_height jpeg_height
-+#else
-+#define _DCT_scaled_size DCT_scaled_size
-+#define _DCT_h_scaled_size DCT_scaled_size
-+#define _DCT_v_scaled_size DCT_scaled_size
-+#define _min_DCT_scaled_size min_DCT_scaled_size
-+#define _min_DCT_h_scaled_size min_DCT_scaled_size
-+#define _min_DCT_v_scaled_size min_DCT_scaled_size
-+#define _jpeg_width image_width
-+#define _jpeg_height image_height
-+#endif
---- /dev/null
-+++ freeimage/jpeg/transupp.c
-@@ -0,0 +1,1630 @@
-+/*
-+ * transupp.c
-+ *
-+ * This file was part of the Independent JPEG Group's software:
-+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
-+ * libjpeg-turbo Modifications:
-+ * Copyright (C) 2010, D. R. Commander.
-+ * For conditions of distribution and use, see the accompanying README file.
-+ *
-+ * This file contains image transformation routines and other utility code
-+ * used by the jpegtran sample application.  These are NOT part of the core
-+ * JPEG library.  But we keep these routines separate from jpegtran.c to
-+ * ease the task of maintaining jpegtran-like programs that have other user
-+ * interfaces.
-+ */
-+
-+/* Although this file really shouldn't have access to the library internals,
-+ * it's helpful to let it call jround_up() and jcopy_block_row().
-+ */
-+#define JPEG_INTERNALS
-+
-+#include "jinclude.h"
-+#include "jpeglib.h"
-+#include "transupp.h"		/* My own external interface */
-+#include "jpegcomp.h"
-+#include <ctype.h>		/* to declare isdigit() */
-+
-+
-+#if JPEG_LIB_VERSION >= 70
-+#define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
-+#define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
-+#else
-+#define dstinfo_min_DCT_h_scaled_size DCTSIZE
-+#define dstinfo_min_DCT_v_scaled_size DCTSIZE
-+#endif
-+
-+
-+#if TRANSFORMS_SUPPORTED
-+
-+/*
-+ * Lossless image transformation routines.  These routines work on DCT
-+ * coefficient arrays and thus do not require any lossy decompression
-+ * or recompression of the image.
-+ * Thanks to Guido Vollbeding for the initial design and code of this feature,
-+ * and to Ben Jackson for introducing the cropping feature.
-+ *
-+ * Horizontal flipping is done in-place, using a single top-to-bottom
-+ * pass through the virtual source array.  It will thus be much the
-+ * fastest option for images larger than main memory.
-+ *
-+ * The other routines require a set of destination virtual arrays, so they
-+ * need twice as much memory as jpegtran normally does.  The destination
-+ * arrays are always written in normal scan order (top to bottom) because
-+ * the virtual array manager expects this.  The source arrays will be scanned
-+ * in the corresponding order, which means multiple passes through the source
-+ * arrays for most of the transforms.  That could result in much thrashing
-+ * if the image is larger than main memory.
-+ *
-+ * If cropping or trimming is involved, the destination arrays may be smaller
-+ * than the source arrays.  Note it is not possible to do horizontal flip
-+ * in-place when a nonzero Y crop offset is specified, since we'd have to move
-+ * data from one block row to another but the virtual array manager doesn't
-+ * guarantee we can touch more than one row at a time.  So in that case,
-+ * we have to use a separate destination array.
-+ *
-+ * Some notes about the operating environment of the individual transform
-+ * routines:
-+ * 1. Both the source and destination virtual arrays are allocated from the
-+ *    source JPEG object, and therefore should be manipulated by calling the
-+ *    source's memory manager.
-+ * 2. The destination's component count should be used.  It may be smaller
-+ *    than the source's when forcing to grayscale.
-+ * 3. Likewise the destination's sampling factors should be used.  When
-+ *    forcing to grayscale the destination's sampling factors will be all 1,
-+ *    and we may as well take that as the effective iMCU size.
-+ * 4. When "trim" is in effect, the destination's dimensions will be the
-+ *    trimmed values but the source's will be untrimmed.
-+ * 5. When "crop" is in effect, the destination's dimensions will be the
-+ *    cropped values but the source's will be uncropped.  Each transform
-+ *    routine is responsible for picking up source data starting at the
-+ *    correct X and Y offset for the crop region.  (The X and Y offsets
-+ *    passed to the transform routines are measured in iMCU blocks of the
-+ *    destination.)
-+ * 6. All the routines assume that the source and destination buffers are
-+ *    padded out to a full iMCU boundary.  This is true, although for the
-+ *    source buffer it is an undocumented property of jdcoefct.c.
-+ */
-+
-+
-+LOCAL(void)
-+do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	 jvirt_barray_ptr *src_coef_arrays,
-+	 jvirt_barray_ptr *dst_coef_arrays)
-+/* Crop.  This is only used when no rotate/flip is requested with the crop. */
-+{
-+  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
-+  int ci, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  jpeg_component_info *compptr;
-+
-+  /* We simply have to copy the right amount of data (the destination's
-+   * image size) starting at the given X and Y offsets in the source.
-+   */
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      src_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	 dst_blk_y + y_crop_blocks,
-+	 (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
-+			dst_buffer[offset_y],
-+			compptr->width_in_blocks);
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+		   JDIMENSION x_crop_offset,
-+		   jvirt_barray_ptr *src_coef_arrays)
-+/* Horizontal flip; done in-place, so no separate dest array is required.
-+ * NB: this only works when y_crop_offset is zero.
-+ */
-+{
-+  JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
-+  int ci, k, offset_y;
-+  JBLOCKARRAY buffer;
-+  JCOEFPTR ptr1, ptr2;
-+  JCOEF temp1, temp2;
-+  jpeg_component_info *compptr;
-+
-+  /* Horizontal mirroring of DCT blocks is accomplished by swapping
-+   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
-+   * mirroring by changing the signs of odd-numbered columns.
-+   * Partial iMCUs at the right edge are left untouched.
-+   */
-+  MCU_cols = srcinfo->output_width /
-+    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_width = MCU_cols * compptr->h_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    for (blk_y = 0; blk_y < compptr->height_in_blocks;
-+	 blk_y += compptr->v_samp_factor) {
-+      buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	/* Do the mirroring */
-+	for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
-+	  ptr1 = buffer[offset_y][blk_x];
-+	  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
-+	  /* this unrolled loop doesn't need to know which row it's on... */
-+	  for (k = 0; k < DCTSIZE2; k += 2) {
-+	    temp1 = *ptr1;	/* swap even column */
-+	    temp2 = *ptr2;
-+	    *ptr1++ = temp2;
-+	    *ptr2++ = temp1;
-+	    temp1 = *ptr1;	/* swap odd column with sign change */
-+	    temp2 = *ptr2;
-+	    *ptr1++ = -temp2;
-+	    *ptr2++ = -temp1;
-+	  }
-+	}
-+	if (x_crop_blocks > 0) {
-+	  /* Now left-justify the portion of the data to be kept.
-+	   * We can't use a single jcopy_block_row() call because that routine
-+	   * depends on memcpy(), whose behavior is unspecified for overlapping
-+	   * source and destination areas.  Sigh.
-+	   */
-+	  for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
-+	    jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
-+			    buffer[offset_y] + blk_x,
-+			    (JDIMENSION) 1);
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	   jvirt_barray_ptr *src_coef_arrays,
-+	   jvirt_barray_ptr *dst_coef_arrays)
-+/* Horizontal flip in general cropping case */
-+{
-+  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, k, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JBLOCKROW src_row_ptr, dst_row_ptr;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  /* Here we must output into a separate array because we can't touch
-+   * different rows of a single virtual array simultaneously.  Otherwise,
-+   * this is essentially the same as the routine above.
-+   */
-+  MCU_cols = srcinfo->output_width /
-+    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_width = MCU_cols * compptr->h_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      src_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	 dst_blk_y + y_crop_blocks,
-+	 (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	dst_row_ptr = dst_buffer[offset_y];
-+	src_row_ptr = src_buffer[offset_y];
-+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
-+	  if (x_crop_blocks + dst_blk_x < comp_width) {
-+	    /* Do the mirrorable blocks */
-+	    dst_ptr = dst_row_ptr[dst_blk_x];
-+	    src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
-+	    /* this unrolled loop doesn't need to know which row it's on... */
-+	    for (k = 0; k < DCTSIZE2; k += 2) {
-+	      *dst_ptr++ = *src_ptr++;	 /* copy even column */
-+	      *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
-+	    }
-+	  } else {
-+	    /* Copy last partial block(s) verbatim */
-+	    jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
-+			    dst_row_ptr + dst_blk_x,
-+			    (JDIMENSION) 1);
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	   jvirt_barray_ptr *src_coef_arrays,
-+	   jvirt_barray_ptr *dst_coef_arrays)
-+/* Vertical flip */
-+{
-+  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JBLOCKROW src_row_ptr, dst_row_ptr;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  /* We output into a separate array because we can't touch different
-+   * rows of the source virtual array simultaneously.  Otherwise, this
-+   * is a pretty straightforward analog of horizontal flip.
-+   * Within a DCT block, vertical mirroring is done by changing the signs
-+   * of odd-numbered rows.
-+   * Partial iMCUs at the bottom edge are copied verbatim.
-+   */
-+  MCU_rows = srcinfo->output_height /
-+    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_height = MCU_rows * compptr->v_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      if (y_crop_blocks + dst_blk_y < comp_height) {
-+	/* Row is within the mirrorable area. */
-+	src_buffer = (*srcinfo->mem->access_virt_barray)
-+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	   comp_height - y_crop_blocks - dst_blk_y -
-+	   (JDIMENSION) compptr->v_samp_factor,
-+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      } else {
-+	/* Bottom-edge blocks will be copied verbatim. */
-+	src_buffer = (*srcinfo->mem->access_virt_barray)
-+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	   dst_blk_y + y_crop_blocks,
-+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      }
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	if (y_crop_blocks + dst_blk_y < comp_height) {
-+	  /* Row is within the mirrorable area. */
-+	  dst_row_ptr = dst_buffer[offset_y];
-+	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
-+	  src_row_ptr += x_crop_blocks;
-+	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
-+	       dst_blk_x++) {
-+	    dst_ptr = dst_row_ptr[dst_blk_x];
-+	    src_ptr = src_row_ptr[dst_blk_x];
-+	    for (i = 0; i < DCTSIZE; i += 2) {
-+	      /* copy even row */
-+	      for (j = 0; j < DCTSIZE; j++)
-+		*dst_ptr++ = *src_ptr++;
-+	      /* copy odd row with sign change */
-+	      for (j = 0; j < DCTSIZE; j++)
-+		*dst_ptr++ = - *src_ptr++;
-+	    }
-+	  }
-+	} else {
-+	  /* Just copy row verbatim. */
-+	  jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
-+			  dst_buffer[offset_y],
-+			  compptr->width_in_blocks);
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	      JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	      jvirt_barray_ptr *src_coef_arrays,
-+	      jvirt_barray_ptr *dst_coef_arrays)
-+/* Transpose source into destination */
-+{
-+  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_x, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  /* Transposing pixels within a block just requires transposing the
-+   * DCT coefficients.
-+   * Partial iMCUs at the edges require no special treatment; we simply
-+   * process all the available DCT blocks for every component.
-+   */
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
-+	     dst_blk_x += compptr->h_samp_factor) {
-+	  src_buffer = (*srcinfo->mem->access_virt_barray)
-+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	     dst_blk_x + x_crop_blocks,
-+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
-+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
-+	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
-+	    for (i = 0; i < DCTSIZE; i++)
-+	      for (j = 0; j < DCTSIZE; j++)
-+		dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	   jvirt_barray_ptr *src_coef_arrays,
-+	   jvirt_barray_ptr *dst_coef_arrays)
-+/* 90 degree rotation is equivalent to
-+ *   1. Transposing the image;
-+ *   2. Horizontal mirroring.
-+ * These two steps are merged into a single processing routine.
-+ */
-+{
-+  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_x, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  /* Because of the horizontal mirror step, we can't process partial iMCUs
-+   * at the (output) right edge properly.  They just get transposed and
-+   * not mirrored.
-+   */
-+  MCU_cols = srcinfo->output_height /
-+    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_width = MCU_cols * compptr->h_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
-+	     dst_blk_x += compptr->h_samp_factor) {
-+	  if (x_crop_blocks + dst_blk_x < comp_width) {
-+	    /* Block is within the mirrorable area. */
-+	    src_buffer = (*srcinfo->mem->access_virt_barray)
-+	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	       comp_width - x_crop_blocks - dst_blk_x -
-+	       (JDIMENSION) compptr->h_samp_factor,
-+	       (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  } else {
-+	    /* Edge blocks are transposed but not mirrored. */
-+	    src_buffer = (*srcinfo->mem->access_virt_barray)
-+	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	       dst_blk_x + x_crop_blocks,
-+	       (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  }
-+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
-+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
-+	    if (x_crop_blocks + dst_blk_x < comp_width) {
-+	      /* Block is within the mirrorable area. */
-+	      src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
-+		[dst_blk_y + offset_y + y_crop_blocks];
-+	      for (i = 0; i < DCTSIZE; i++) {
-+		for (j = 0; j < DCTSIZE; j++)
-+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		i++;
-+		for (j = 0; j < DCTSIZE; j++)
-+		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+	      }
-+	    } else {
-+	      /* Edge blocks are transposed but not mirrored. */
-+	      src_ptr = src_buffer[offset_x]
-+		[dst_blk_y + offset_y + y_crop_blocks];
-+	      for (i = 0; i < DCTSIZE; i++)
-+		for (j = 0; j < DCTSIZE; j++)
-+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+	    }
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	    jvirt_barray_ptr *src_coef_arrays,
-+	    jvirt_barray_ptr *dst_coef_arrays)
-+/* 270 degree rotation is equivalent to
-+ *   1. Horizontal mirroring;
-+ *   2. Transposing the image.
-+ * These two steps are merged into a single processing routine.
-+ */
-+{
-+  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_x, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  /* Because of the horizontal mirror step, we can't process partial iMCUs
-+   * at the (output) bottom edge properly.  They just get transposed and
-+   * not mirrored.
-+   */
-+  MCU_rows = srcinfo->output_width /
-+    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_height = MCU_rows * compptr->v_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
-+	     dst_blk_x += compptr->h_samp_factor) {
-+	  src_buffer = (*srcinfo->mem->access_virt_barray)
-+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	     dst_blk_x + x_crop_blocks,
-+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
-+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
-+	    if (y_crop_blocks + dst_blk_y < comp_height) {
-+	      /* Block is within the mirrorable area. */
-+	      src_ptr = src_buffer[offset_x]
-+		[comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
-+	      for (i = 0; i < DCTSIZE; i++) {
-+		for (j = 0; j < DCTSIZE; j++) {
-+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		  j++;
-+		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+		}
-+	      }
-+	    } else {
-+	      /* Edge blocks are transposed but not mirrored. */
-+	      src_ptr = src_buffer[offset_x]
-+		[dst_blk_y + offset_y + y_crop_blocks];
-+	      for (i = 0; i < DCTSIZE; i++)
-+		for (j = 0; j < DCTSIZE; j++)
-+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+	    }
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	    jvirt_barray_ptr *src_coef_arrays,
-+	    jvirt_barray_ptr *dst_coef_arrays)
-+/* 180 degree rotation is equivalent to
-+ *   1. Vertical mirroring;
-+ *   2. Horizontal mirroring.
-+ * These two steps are merged into a single processing routine.
-+ */
-+{
-+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JBLOCKROW src_row_ptr, dst_row_ptr;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  MCU_cols = srcinfo->output_width /
-+    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
-+  MCU_rows = srcinfo->output_height /
-+    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_width = MCU_cols * compptr->h_samp_factor;
-+    comp_height = MCU_rows * compptr->v_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      if (y_crop_blocks + dst_blk_y < comp_height) {
-+	/* Row is within the vertically mirrorable area. */
-+	src_buffer = (*srcinfo->mem->access_virt_barray)
-+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	   comp_height - y_crop_blocks - dst_blk_y -
-+	   (JDIMENSION) compptr->v_samp_factor,
-+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      } else {
-+	/* Bottom-edge rows are only mirrored horizontally. */
-+	src_buffer = (*srcinfo->mem->access_virt_barray)
-+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	   dst_blk_y + y_crop_blocks,
-+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
-+      }
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	dst_row_ptr = dst_buffer[offset_y];
-+	if (y_crop_blocks + dst_blk_y < comp_height) {
-+	  /* Row is within the mirrorable area. */
-+	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
-+	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
-+	    dst_ptr = dst_row_ptr[dst_blk_x];
-+	    if (x_crop_blocks + dst_blk_x < comp_width) {
-+	      /* Process the blocks that can be mirrored both ways. */
-+	      src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
-+	      for (i = 0; i < DCTSIZE; i += 2) {
-+		/* For even row, negate every odd column. */
-+		for (j = 0; j < DCTSIZE; j += 2) {
-+		  *dst_ptr++ = *src_ptr++;
-+		  *dst_ptr++ = - *src_ptr++;
-+		}
-+		/* For odd row, negate every even column. */
-+		for (j = 0; j < DCTSIZE; j += 2) {
-+		  *dst_ptr++ = - *src_ptr++;
-+		  *dst_ptr++ = *src_ptr++;
-+		}
-+	      }
-+	    } else {
-+	      /* Any remaining right-edge blocks are only mirrored vertically. */
-+	      src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
-+	      for (i = 0; i < DCTSIZE; i += 2) {
-+		for (j = 0; j < DCTSIZE; j++)
-+		  *dst_ptr++ = *src_ptr++;
-+		for (j = 0; j < DCTSIZE; j++)
-+		  *dst_ptr++ = - *src_ptr++;
-+	      }
-+	    }
-+	  }
-+	} else {
-+	  /* Remaining rows are just mirrored horizontally. */
-+	  src_row_ptr = src_buffer[offset_y];
-+	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
-+	    if (x_crop_blocks + dst_blk_x < comp_width) {
-+	      /* Process the blocks that can be mirrored. */
-+	      dst_ptr = dst_row_ptr[dst_blk_x];
-+	      src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
-+	      for (i = 0; i < DCTSIZE2; i += 2) {
-+		*dst_ptr++ = *src_ptr++;
-+		*dst_ptr++ = - *src_ptr++;
-+	      }
-+	    } else {
-+	      /* Any remaining right-edge blocks are only copied. */
-+	      jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
-+			      dst_row_ptr + dst_blk_x,
-+			      (JDIMENSION) 1);
-+	    }
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+LOCAL(void)
-+do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	       JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
-+	       jvirt_barray_ptr *src_coef_arrays,
-+	       jvirt_barray_ptr *dst_coef_arrays)
-+/* Transverse transpose is equivalent to
-+ *   1. 180 degree rotation;
-+ *   2. Transposition;
-+ * or
-+ *   1. Horizontal mirroring;
-+ *   2. Transposition;
-+ *   3. Horizontal mirroring.
-+ * These steps are merged into a single processing routine.
-+ */
-+{
-+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
-+  JDIMENSION x_crop_blocks, y_crop_blocks;
-+  int ci, i, j, offset_x, offset_y;
-+  JBLOCKARRAY src_buffer, dst_buffer;
-+  JCOEFPTR src_ptr, dst_ptr;
-+  jpeg_component_info *compptr;
-+
-+  MCU_cols = srcinfo->output_height /
-+    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
-+  MCU_rows = srcinfo->output_width /
-+    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
-+
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    comp_width = MCU_cols * compptr->h_samp_factor;
-+    comp_height = MCU_rows * compptr->v_samp_factor;
-+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
-+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
-+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
-+	 dst_blk_y += compptr->v_samp_factor) {
-+      dst_buffer = (*srcinfo->mem->access_virt_barray)
-+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
-+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
-+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
-+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
-+	     dst_blk_x += compptr->h_samp_factor) {
-+	  if (x_crop_blocks + dst_blk_x < comp_width) {
-+	    /* Block is within the mirrorable area. */
-+	    src_buffer = (*srcinfo->mem->access_virt_barray)
-+	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	       comp_width - x_crop_blocks - dst_blk_x -
-+	       (JDIMENSION) compptr->h_samp_factor,
-+	       (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  } else {
-+	    src_buffer = (*srcinfo->mem->access_virt_barray)
-+	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
-+	       dst_blk_x + x_crop_blocks,
-+	       (JDIMENSION) compptr->h_samp_factor, FALSE);
-+	  }
-+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
-+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
-+	    if (y_crop_blocks + dst_blk_y < comp_height) {
-+	      if (x_crop_blocks + dst_blk_x < comp_width) {
-+		/* Block is within the mirrorable area. */
-+		src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
-+		  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
-+		for (i = 0; i < DCTSIZE; i++) {
-+		  for (j = 0; j < DCTSIZE; j++) {
-+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		    j++;
-+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+		  }
-+		  i++;
-+		  for (j = 0; j < DCTSIZE; j++) {
-+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+		    j++;
-+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		  }
-+		}
-+	      } else {
-+		/* Right-edge blocks are mirrored in y only */
-+		src_ptr = src_buffer[offset_x]
-+		  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
-+		for (i = 0; i < DCTSIZE; i++) {
-+		  for (j = 0; j < DCTSIZE; j++) {
-+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		    j++;
-+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+		  }
-+		}
-+	      }
-+	    } else {
-+	      if (x_crop_blocks + dst_blk_x < comp_width) {
-+		/* Bottom-edge blocks are mirrored in x only */
-+		src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
-+		  [dst_blk_y + offset_y + y_crop_blocks];
-+		for (i = 0; i < DCTSIZE; i++) {
-+		  for (j = 0; j < DCTSIZE; j++)
-+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+		  i++;
-+		  for (j = 0; j < DCTSIZE; j++)
-+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
-+		}
-+	      } else {
-+		/* At lower right corner, just transpose, no mirroring */
-+		src_ptr = src_buffer[offset_x]
-+		  [dst_blk_y + offset_y + y_crop_blocks];
-+		for (i = 0; i < DCTSIZE; i++)
-+		  for (j = 0; j < DCTSIZE; j++)
-+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
-+	      }
-+	    }
-+	  }
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
-+ * Returns TRUE if valid integer found, FALSE if not.
-+ * *strptr is advanced over the digit string, and *result is set to its value.
-+ */
-+
-+LOCAL(boolean)
-+jt_read_integer (const char ** strptr, JDIMENSION * result)
-+{
-+  const char * ptr = *strptr;
-+  JDIMENSION val = 0;
-+
-+  for (; isdigit(*ptr); ptr++) {
-+    val = val * 10 + (JDIMENSION) (*ptr - '0');
-+  }
-+  *result = val;
-+  if (ptr == *strptr)
-+    return FALSE;		/* oops, no digits */
-+  *strptr = ptr;
-+  return TRUE;
-+}
-+
-+
-+/* Parse a crop specification (written in X11 geometry style).
-+ * The routine returns TRUE if the spec string is valid, FALSE if not.
-+ *
-+ * The crop spec string should have the format
-+ *	<width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
-+ * where width, height, xoffset, and yoffset are unsigned integers.
-+ * Each of the elements can be omitted to indicate a default value.
-+ * (A weakness of this style is that it is not possible to omit xoffset
-+ * while specifying yoffset, since they look alike.)
-+ *
-+ * This code is loosely based on XParseGeometry from the X11 distribution.
-+ */
-+
-+GLOBAL(boolean)
-+jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
-+{
-+  info->crop = FALSE;
-+  info->crop_width_set = JCROP_UNSET;
-+  info->crop_height_set = JCROP_UNSET;
-+  info->crop_xoffset_set = JCROP_UNSET;
-+  info->crop_yoffset_set = JCROP_UNSET;
-+
-+  if (isdigit(*spec)) {
-+    /* fetch width */
-+    if (! jt_read_integer(&spec, &info->crop_width))
-+      return FALSE;
-+    if (*spec == 'f' || *spec == 'F') {
-+      spec++;
-+      info->crop_width_set = JCROP_FORCE;
-+    } else
-+      info->crop_width_set = JCROP_POS;
-+  }
-+  if (*spec == 'x' || *spec == 'X') {
-+    /* fetch height */
-+    spec++;
-+    if (! jt_read_integer(&spec, &info->crop_height))
-+      return FALSE;
-+    if (*spec == 'f' || *spec == 'F') {
-+      spec++;
-+      info->crop_height_set = JCROP_FORCE;
-+    } else
-+      info->crop_height_set = JCROP_POS;
-+  }
-+  if (*spec == '+' || *spec == '-') {
-+    /* fetch xoffset */
-+    info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
-+    spec++;
-+    if (! jt_read_integer(&spec, &info->crop_xoffset))
-+      return FALSE;
-+  }
-+  if (*spec == '+' || *spec == '-') {
-+    /* fetch yoffset */
-+    info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
-+    spec++;
-+    if (! jt_read_integer(&spec, &info->crop_yoffset))
-+      return FALSE;
-+  }
-+  /* We had better have gotten to the end of the string. */
-+  if (*spec != '\0')
-+    return FALSE;
-+  info->crop = TRUE;
-+  return TRUE;
-+}
-+
-+
-+/* Trim off any partial iMCUs on the indicated destination edge */
-+
-+LOCAL(void)
-+trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
-+{
-+  JDIMENSION MCU_cols;
-+
-+  MCU_cols = info->output_width / info->iMCU_sample_width;
-+  if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
-+      full_width / info->iMCU_sample_width)
-+    info->output_width = MCU_cols * info->iMCU_sample_width;
-+}
-+
-+LOCAL(void)
-+trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
-+{
-+  JDIMENSION MCU_rows;
-+
-+  MCU_rows = info->output_height / info->iMCU_sample_height;
-+  if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
-+      full_height / info->iMCU_sample_height)
-+    info->output_height = MCU_rows * info->iMCU_sample_height;
-+}
-+
-+
-+/* Request any required workspace.
-+ *
-+ * This routine figures out the size that the output image will be
-+ * (which implies that all the transform parameters must be set before
-+ * it is called).
-+ *
-+ * We allocate the workspace virtual arrays from the source decompression
-+ * object, so that all the arrays (both the original data and the workspace)
-+ * will be taken into account while making memory management decisions.
-+ * Hence, this routine must be called after jpeg_read_header (which reads
-+ * the image dimensions) and before jpeg_read_coefficients (which realizes
-+ * the source's virtual arrays).
-+ *
-+ * This function returns FALSE right away if -perfect is given
-+ * and transformation is not perfect.  Otherwise returns TRUE.
-+ */
-+
-+GLOBAL(boolean)
-+jtransform_request_workspace (j_decompress_ptr srcinfo,
-+			      jpeg_transform_info *info)
-+{
-+  jvirt_barray_ptr *coef_arrays;
-+  boolean need_workspace, transpose_it;
-+  jpeg_component_info *compptr;
-+  JDIMENSION xoffset, yoffset;
-+  JDIMENSION width_in_iMCUs, height_in_iMCUs;
-+  JDIMENSION width_in_blocks, height_in_blocks;
-+  int ci, h_samp_factor, v_samp_factor;
-+
-+  /* Determine number of components in output image */
-+  if (info->force_grayscale &&
-+      srcinfo->jpeg_color_space == JCS_YCbCr &&
-+      srcinfo->num_components == 3)
-+    /* We'll only process the first component */
-+    info->num_components = 1;
-+  else
-+    /* Process all the components */
-+    info->num_components = srcinfo->num_components;
-+
-+  /* Compute output image dimensions and related values. */
-+#if JPEG_LIB_VERSION >= 80
-+  jpeg_core_output_dimensions(srcinfo);
-+#else
-+  srcinfo->output_width = srcinfo->image_width;
-+  srcinfo->output_height = srcinfo->image_height;
-+#endif
-+
-+  /* Return right away if -perfect is given and transformation is not perfect.
-+   */
-+  if (info->perfect) {
-+    if (info->num_components == 1) {
-+      if (!jtransform_perfect_transform(srcinfo->output_width,
-+	  srcinfo->output_height,
-+	  srcinfo->_min_DCT_h_scaled_size,
-+	  srcinfo->_min_DCT_v_scaled_size,
-+	  info->transform))
-+	return FALSE;
-+    } else {
-+      if (!jtransform_perfect_transform(srcinfo->output_width,
-+	  srcinfo->output_height,
-+	  srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size,
-+	  srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size,
-+	  info->transform))
-+	return FALSE;
-+    }
-+  }
-+
-+  /* If there is only one output component, force the iMCU size to be 1;
-+   * else use the source iMCU size.  (This allows us to do the right thing
-+   * when reducing color to grayscale, and also provides a handy way of
-+   * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
-+   */
-+  switch (info->transform) {
-+  case JXFORM_TRANSPOSE:
-+  case JXFORM_TRANSVERSE:
-+  case JXFORM_ROT_90:
-+  case JXFORM_ROT_270:
-+    info->output_width = srcinfo->output_height;
-+    info->output_height = srcinfo->output_width;
-+    if (info->num_components == 1) {
-+      info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size;
-+      info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size;
-+    } else {
-+      info->iMCU_sample_width =
-+	srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
-+      info->iMCU_sample_height =
-+	srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
-+    }
-+    break;
-+  default:
-+    info->output_width = srcinfo->output_width;
-+    info->output_height = srcinfo->output_height;
-+    if (info->num_components == 1) {
-+      info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size;
-+      info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size;
-+    } else {
-+      info->iMCU_sample_width =
-+	srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
-+      info->iMCU_sample_height =
-+	srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
-+    }
-+    break;
-+  }
-+
-+  /* If cropping has been requested, compute the crop area's position and
-+   * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
-+   */
-+  if (info->crop) {
-+    /* Insert default values for unset crop parameters */
-+    if (info->crop_xoffset_set == JCROP_UNSET)
-+      info->crop_xoffset = 0;	/* default to +0 */
-+    if (info->crop_yoffset_set == JCROP_UNSET)
-+      info->crop_yoffset = 0;	/* default to +0 */
-+    if (info->crop_xoffset >= info->output_width ||
-+	info->crop_yoffset >= info->output_height)
-+      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
-+    if (info->crop_width_set == JCROP_UNSET)
-+      info->crop_width = info->output_width - info->crop_xoffset;
-+    if (info->crop_height_set == JCROP_UNSET)
-+      info->crop_height = info->output_height - info->crop_yoffset;
-+    /* Ensure parameters are valid */
-+    if (info->crop_width <= 0 || info->crop_width > info->output_width ||
-+	info->crop_height <= 0 || info->crop_height > info->output_height ||
-+	info->crop_xoffset > info->output_width - info->crop_width ||
-+	info->crop_yoffset > info->output_height - info->crop_height)
-+      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
-+    /* Convert negative crop offsets into regular offsets */
-+    if (info->crop_xoffset_set == JCROP_NEG)
-+      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
-+    else
-+      xoffset = info->crop_xoffset;
-+    if (info->crop_yoffset_set == JCROP_NEG)
-+      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
-+    else
-+      yoffset = info->crop_yoffset;
-+    /* Now adjust so that upper left corner falls at an iMCU boundary */
-+    if (info->crop_width_set == JCROP_FORCE)
-+      info->output_width = info->crop_width;
-+    else
-+      info->output_width =
-+        info->crop_width + (xoffset % info->iMCU_sample_width);
-+    if (info->crop_height_set == JCROP_FORCE)
-+      info->output_height = info->crop_height;
-+    else
-+      info->output_height =
-+        info->crop_height + (yoffset % info->iMCU_sample_height);
-+    /* Save x/y offsets measured in iMCUs */
-+    info->x_crop_offset = xoffset / info->iMCU_sample_width;
-+    info->y_crop_offset = yoffset / info->iMCU_sample_height;
-+  } else {
-+    info->x_crop_offset = 0;
-+    info->y_crop_offset = 0;
-+  }
-+
-+  /* Figure out whether we need workspace arrays,
-+   * and if so whether they are transposed relative to the source.
-+   */
-+  need_workspace = FALSE;
-+  transpose_it = FALSE;
-+  switch (info->transform) {
-+  case JXFORM_NONE:
-+    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
-+      need_workspace = TRUE;
-+    /* No workspace needed if neither cropping nor transforming */
-+    break;
-+  case JXFORM_FLIP_H:
-+    if (info->trim)
-+      trim_right_edge(info, srcinfo->output_width);
-+    if (info->y_crop_offset != 0 || info->slow_hflip)
-+      need_workspace = TRUE;
-+    /* do_flip_h_no_crop doesn't need a workspace array */
-+    break;
-+  case JXFORM_FLIP_V:
-+    if (info->trim)
-+      trim_bottom_edge(info, srcinfo->output_height);
-+    /* Need workspace arrays having same dimensions as source image. */
-+    need_workspace = TRUE;
-+    break;
-+  case JXFORM_TRANSPOSE:
-+    /* transpose does NOT have to trim anything */
-+    /* Need workspace arrays having transposed dimensions. */
-+    need_workspace = TRUE;
-+    transpose_it = TRUE;
-+    break;
-+  case JXFORM_TRANSVERSE:
-+    if (info->trim) {
-+      trim_right_edge(info, srcinfo->output_height);
-+      trim_bottom_edge(info, srcinfo->output_width);
-+    }
-+    /* Need workspace arrays having transposed dimensions. */
-+    need_workspace = TRUE;
-+    transpose_it = TRUE;
-+    break;
-+  case JXFORM_ROT_90:
-+    if (info->trim)
-+      trim_right_edge(info, srcinfo->output_height);
-+    /* Need workspace arrays having transposed dimensions. */
-+    need_workspace = TRUE;
-+    transpose_it = TRUE;
-+    break;
-+  case JXFORM_ROT_180:
-+    if (info->trim) {
-+      trim_right_edge(info, srcinfo->output_width);
-+      trim_bottom_edge(info, srcinfo->output_height);
-+    }
-+    /* Need workspace arrays having same dimensions as source image. */
-+    need_workspace = TRUE;
-+    break;
-+  case JXFORM_ROT_270:
-+    if (info->trim)
-+      trim_bottom_edge(info, srcinfo->output_width);
-+    /* Need workspace arrays having transposed dimensions. */
-+    need_workspace = TRUE;
-+    transpose_it = TRUE;
-+    break;
-+  }
-+
-+  /* Allocate workspace if needed.
-+   * Note that we allocate arrays padded out to the next iMCU boundary,
-+   * so that transform routines need not worry about missing edge blocks.
-+   */
-+  if (need_workspace) {
-+    coef_arrays = (jvirt_barray_ptr *)
-+      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
-+		SIZEOF(jvirt_barray_ptr) * info->num_components);
-+    width_in_iMCUs = (JDIMENSION)
-+      jdiv_round_up((long) info->output_width,
-+		    (long) info->iMCU_sample_width);
-+    height_in_iMCUs = (JDIMENSION)
-+      jdiv_round_up((long) info->output_height,
-+		    (long) info->iMCU_sample_height);
-+    for (ci = 0; ci < info->num_components; ci++) {
-+      compptr = srcinfo->comp_info + ci;
-+      if (info->num_components == 1) {
-+	/* we're going to force samp factors to 1x1 in this case */
-+	h_samp_factor = v_samp_factor = 1;
-+      } else if (transpose_it) {
-+	h_samp_factor = compptr->v_samp_factor;
-+	v_samp_factor = compptr->h_samp_factor;
-+      } else {
-+	h_samp_factor = compptr->h_samp_factor;
-+	v_samp_factor = compptr->v_samp_factor;
-+      }
-+      width_in_blocks = width_in_iMCUs * h_samp_factor;
-+      height_in_blocks = height_in_iMCUs * v_samp_factor;
-+      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
-+	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
-+	 width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
-+    }
-+    info->workspace_coef_arrays = coef_arrays;
-+  } else
-+    info->workspace_coef_arrays = NULL;
-+
-+  return TRUE;
-+}
-+
-+
-+/* Transpose destination image parameters */
-+
-+LOCAL(void)
-+transpose_critical_parameters (j_compress_ptr dstinfo)
-+{
-+  int tblno, i, j, ci, itemp;
-+  jpeg_component_info *compptr;
-+  JQUANT_TBL *qtblptr;
-+  JDIMENSION jtemp;
-+  UINT16 qtemp;
-+
-+  /* Transpose image dimensions */
-+  jtemp = dstinfo->image_width;
-+  dstinfo->image_width = dstinfo->image_height;
-+  dstinfo->image_height = jtemp;
-+#if JPEG_LIB_VERSION >= 70
-+  itemp = dstinfo->min_DCT_h_scaled_size;
-+  dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
-+  dstinfo->min_DCT_v_scaled_size = itemp;
-+#endif
-+
-+  /* Transpose sampling factors */
-+  for (ci = 0; ci < dstinfo->num_components; ci++) {
-+    compptr = dstinfo->comp_info + ci;
-+    itemp = compptr->h_samp_factor;
-+    compptr->h_samp_factor = compptr->v_samp_factor;
-+    compptr->v_samp_factor = itemp;
-+  }
-+
-+  /* Transpose quantization tables */
-+  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
-+    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
-+    if (qtblptr != NULL) {
-+      for (i = 0; i < DCTSIZE; i++) {
-+	for (j = 0; j < i; j++) {
-+	  qtemp = qtblptr->quantval[i*DCTSIZE+j];
-+	  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
-+	  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
-+	}
-+      }
-+    }
-+  }
-+}
-+
-+
-+/* Adjust Exif image parameters.
-+ *
-+ * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
-+ */
-+
-+#if JPEG_LIB_VERSION >= 70
-+LOCAL(void)
-+adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
-+			JDIMENSION new_width, JDIMENSION new_height)
-+{
-+  boolean is_motorola; /* Flag for byte order */
-+  unsigned int number_of_tags, tagnum;
-+  unsigned int firstoffset, offset;
-+  JDIMENSION new_value;
-+
-+  if (length < 12) return; /* Length of an IFD entry */
-+
-+  /* Discover byte order */
-+  if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
-+    is_motorola = FALSE;
-+  else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
-+    is_motorola = TRUE;
-+  else
-+    return;
-+
-+  /* Check Tag Mark */
-+  if (is_motorola) {
-+    if (GETJOCTET(data[2]) != 0) return;
-+    if (GETJOCTET(data[3]) != 0x2A) return;
-+  } else {
-+    if (GETJOCTET(data[3]) != 0) return;
-+    if (GETJOCTET(data[2]) != 0x2A) return;
-+  }
-+
-+  /* Get first IFD offset (offset to IFD0) */
-+  if (is_motorola) {
-+    if (GETJOCTET(data[4]) != 0) return;
-+    if (GETJOCTET(data[5]) != 0) return;
-+    firstoffset = GETJOCTET(data[6]);
-+    firstoffset <<= 8;
-+    firstoffset += GETJOCTET(data[7]);
-+  } else {
-+    if (GETJOCTET(data[7]) != 0) return;
-+    if (GETJOCTET(data[6]) != 0) return;
-+    firstoffset = GETJOCTET(data[5]);
-+    firstoffset <<= 8;
-+    firstoffset += GETJOCTET(data[4]);
-+  }
-+  if (firstoffset > length - 2) return; /* check end of data segment */
-+
-+  /* Get the number of directory entries contained in this IFD */
-+  if (is_motorola) {
-+    number_of_tags = GETJOCTET(data[firstoffset]);
-+    number_of_tags <<= 8;
-+    number_of_tags += GETJOCTET(data[firstoffset+1]);
-+  } else {
-+    number_of_tags = GETJOCTET(data[firstoffset+1]);
-+    number_of_tags <<= 8;
-+    number_of_tags += GETJOCTET(data[firstoffset]);
-+  }
-+  if (number_of_tags == 0) return;
-+  firstoffset += 2;
-+
-+  /* Search for ExifSubIFD offset Tag in IFD0 */
-+  for (;;) {
-+    if (firstoffset > length - 12) return; /* check end of data segment */
-+    /* Get Tag number */
-+    if (is_motorola) {
-+      tagnum = GETJOCTET(data[firstoffset]);
-+      tagnum <<= 8;
-+      tagnum += GETJOCTET(data[firstoffset+1]);
-+    } else {
-+      tagnum = GETJOCTET(data[firstoffset+1]);
-+      tagnum <<= 8;
-+      tagnum += GETJOCTET(data[firstoffset]);
-+    }
-+    if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
-+    if (--number_of_tags == 0) return;
-+    firstoffset += 12;
-+  }
-+
-+  /* Get the ExifSubIFD offset */
-+  if (is_motorola) {
-+    if (GETJOCTET(data[firstoffset+8]) != 0) return;
-+    if (GETJOCTET(data[firstoffset+9]) != 0) return;
-+    offset = GETJOCTET(data[firstoffset+10]);
-+    offset <<= 8;
-+    offset += GETJOCTET(data[firstoffset+11]);
-+  } else {
-+    if (GETJOCTET(data[firstoffset+11]) != 0) return;
-+    if (GETJOCTET(data[firstoffset+10]) != 0) return;
-+    offset = GETJOCTET(data[firstoffset+9]);
-+    offset <<= 8;
-+    offset += GETJOCTET(data[firstoffset+8]);
-+  }
-+  if (offset > length - 2) return; /* check end of data segment */
-+
-+  /* Get the number of directory entries contained in this SubIFD */
-+  if (is_motorola) {
-+    number_of_tags = GETJOCTET(data[offset]);
-+    number_of_tags <<= 8;
-+    number_of_tags += GETJOCTET(data[offset+1]);
-+  } else {
-+    number_of_tags = GETJOCTET(data[offset+1]);
-+    number_of_tags <<= 8;
-+    number_of_tags += GETJOCTET(data[offset]);
-+  }
-+  if (number_of_tags < 2) return;
-+  offset += 2;
-+
-+  /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
-+  do {
-+    if (offset > length - 12) return; /* check end of data segment */
-+    /* Get Tag number */
-+    if (is_motorola) {
-+      tagnum = GETJOCTET(data[offset]);
-+      tagnum <<= 8;
-+      tagnum += GETJOCTET(data[offset+1]);
-+    } else {
-+      tagnum = GETJOCTET(data[offset+1]);
-+      tagnum <<= 8;
-+      tagnum += GETJOCTET(data[offset]);
-+    }
-+    if (tagnum == 0xA002 || tagnum == 0xA003) {
-+      if (tagnum == 0xA002)
-+	new_value = new_width; /* ExifImageWidth Tag */
-+      else
-+	new_value = new_height; /* ExifImageHeight Tag */
-+      if (is_motorola) {
-+	data[offset+2] = 0; /* Format = unsigned long (4 octets) */
-+	data[offset+3] = 4;
-+	data[offset+4] = 0; /* Number Of Components = 1 */
-+	data[offset+5] = 0;
-+	data[offset+6] = 0;
-+	data[offset+7] = 1;
-+	data[offset+8] = 0;
-+	data[offset+9] = 0;
-+	data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
-+	data[offset+11] = (JOCTET)(new_value & 0xFF);
-+      } else {
-+	data[offset+2] = 4; /* Format = unsigned long (4 octets) */
-+	data[offset+3] = 0;
-+	data[offset+4] = 1; /* Number Of Components = 1 */
-+	data[offset+5] = 0;
-+	data[offset+6] = 0;
-+	data[offset+7] = 0;
-+	data[offset+8] = (JOCTET)(new_value & 0xFF);
-+	data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
-+	data[offset+10] = 0;
-+	data[offset+11] = 0;
-+      }
-+    }
-+    offset += 12;
-+  } while (--number_of_tags);
-+}
-+#endif
-+
-+
-+/* Adjust output image parameters as needed.
-+ *
-+ * This must be called after jpeg_copy_critical_parameters()
-+ * and before jpeg_write_coefficients().
-+ *
-+ * The return value is the set of virtual coefficient arrays to be written
-+ * (either the ones allocated by jtransform_request_workspace, or the
-+ * original source data arrays).  The caller will need to pass this value
-+ * to jpeg_write_coefficients().
-+ */
-+
-+GLOBAL(jvirt_barray_ptr *)
-+jtransform_adjust_parameters (j_decompress_ptr srcinfo,
-+			      j_compress_ptr dstinfo,
-+			      jvirt_barray_ptr *src_coef_arrays,
-+			      jpeg_transform_info *info)
-+{
-+  /* If force-to-grayscale is requested, adjust destination parameters */
-+  if (info->force_grayscale) {
-+    /* First, ensure we have YCbCr or grayscale data, and that the source's
-+     * Y channel is full resolution.  (No reasonable person would make Y
-+     * be less than full resolution, so actually coping with that case
-+     * isn't worth extra code space.  But we check it to avoid crashing.)
-+     */
-+    if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
-+	  dstinfo->num_components == 3) ||
-+	 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
-+	  dstinfo->num_components == 1)) &&
-+	srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
-+	srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
-+      /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
-+       * properly.  Among other things, it sets the target h_samp_factor &
-+       * v_samp_factor to 1, which typically won't match the source.
-+       * We have to preserve the source's quantization table number, however.
-+       */
-+      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
-+      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
-+      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
-+    } else {
-+      /* Sorry, can't do it */
-+      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
-+    }
-+  } else if (info->num_components == 1) {
-+    /* For a single-component source, we force the destination sampling factors
-+     * to 1x1, with or without force_grayscale.  This is useful because some
-+     * decoders choke on grayscale images with other sampling factors.
-+     */
-+    dstinfo->comp_info[0].h_samp_factor = 1;
-+    dstinfo->comp_info[0].v_samp_factor = 1;
-+  }
-+
-+  /* Correct the destination's image dimensions as necessary
-+   * for rotate/flip, resize, and crop operations.
-+   */
-+#if JPEG_LIB_VERSION >= 70
-+  dstinfo->jpeg_width = info->output_width;
-+  dstinfo->jpeg_height = info->output_height;
-+#endif
-+
-+  /* Transpose destination image parameters */
-+  switch (info->transform) {
-+  case JXFORM_TRANSPOSE:
-+  case JXFORM_TRANSVERSE:
-+  case JXFORM_ROT_90:
-+  case JXFORM_ROT_270:
-+#if JPEG_LIB_VERSION < 70
-+    dstinfo->image_width = info->output_height;
-+    dstinfo->image_height = info->output_width;
-+#endif
-+    transpose_critical_parameters(dstinfo);
-+    break;
-+  default:
-+#if JPEG_LIB_VERSION < 70
-+    dstinfo->image_width = info->output_width;
-+    dstinfo->image_height = info->output_height;
-+#endif
-+    break;
-+  }
-+
-+  /* Adjust Exif properties */
-+  if (srcinfo->marker_list != NULL &&
-+      srcinfo->marker_list->marker == JPEG_APP0+1 &&
-+      srcinfo->marker_list->data_length >= 6 &&
-+      GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
-+      GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
-+      GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
-+      GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
-+      GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
-+      GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
-+    /* Suppress output of JFIF marker */
-+    dstinfo->write_JFIF_header = FALSE;
-+#if JPEG_LIB_VERSION >= 70
-+    /* Adjust Exif image parameters */
-+    if (dstinfo->jpeg_width != srcinfo->image_width ||
-+	dstinfo->jpeg_height != srcinfo->image_height)
-+      /* Align data segment to start of TIFF structure for parsing */
-+      adjust_exif_parameters(srcinfo->marker_list->data + 6,
-+	srcinfo->marker_list->data_length - 6,
-+	dstinfo->jpeg_width, dstinfo->jpeg_height);
-+#endif
-+  }
-+
-+  /* Return the appropriate output data set */
-+  if (info->workspace_coef_arrays != NULL)
-+    return info->workspace_coef_arrays;
-+  return src_coef_arrays;
-+}
-+
-+
-+/* Execute the actual transformation, if any.
-+ *
-+ * This must be called *after* jpeg_write_coefficients, because it depends
-+ * on jpeg_write_coefficients to have computed subsidiary values such as
-+ * the per-component width and height fields in the destination object.
-+ *
-+ * Note that some transformations will modify the source data arrays!
-+ */
-+
-+GLOBAL(void)
-+jtransform_execute_transform (j_decompress_ptr srcinfo,
-+			      j_compress_ptr dstinfo,
-+			      jvirt_barray_ptr *src_coef_arrays,
-+			      jpeg_transform_info *info)
-+{
-+  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
-+
-+  /* Note: conditions tested here should match those in switch statement
-+   * in jtransform_request_workspace()
-+   */
-+  switch (info->transform) {
-+  case JXFORM_NONE:
-+    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
-+      do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+	      src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_FLIP_H:
-+    if (info->y_crop_offset != 0 || info->slow_hflip)
-+      do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+		src_coef_arrays, dst_coef_arrays);
-+    else
-+      do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
-+			src_coef_arrays);
-+    break;
-+  case JXFORM_FLIP_V:
-+    do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+	      src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_TRANSPOSE:
-+    do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+		 src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_TRANSVERSE:
-+    do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+		  src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_ROT_90:
-+    do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+	      src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_ROT_180:
-+    do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+	       src_coef_arrays, dst_coef_arrays);
-+    break;
-+  case JXFORM_ROT_270:
-+    do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
-+	       src_coef_arrays, dst_coef_arrays);
-+    break;
-+  }
-+}
-+
-+/* jtransform_perfect_transform
-+ *
-+ * Determine whether lossless transformation is perfectly
-+ * possible for a specified image and transformation.
-+ *
-+ * Inputs:
-+ *   image_width, image_height: source image dimensions.
-+ *   MCU_width, MCU_height: pixel dimensions of MCU.
-+ *   transform: transformation identifier.
-+ * Parameter sources from initialized jpeg_struct
-+ * (after reading source header):
-+ *   image_width = cinfo.image_width
-+ *   image_height = cinfo.image_height
-+ *   MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
-+ *   MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
-+ * Result:
-+ *   TRUE = perfect transformation possible
-+ *   FALSE = perfect transformation not possible
-+ *           (may use custom action then)
-+ */
-+
-+GLOBAL(boolean)
-+jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
-+			     int MCU_width, int MCU_height,
-+			     JXFORM_CODE transform)
-+{
-+  boolean result = TRUE; /* initialize TRUE */
-+
-+  switch (transform) {
-+  case JXFORM_FLIP_H:
-+  case JXFORM_ROT_270:
-+    if (image_width % (JDIMENSION) MCU_width)
-+      result = FALSE;
-+    break;
-+  case JXFORM_FLIP_V:
-+  case JXFORM_ROT_90:
-+    if (image_height % (JDIMENSION) MCU_height)
-+      result = FALSE;
-+    break;
-+  case JXFORM_TRANSVERSE:
-+  case JXFORM_ROT_180:
-+    if (image_width % (JDIMENSION) MCU_width)
-+      result = FALSE;
-+    if (image_height % (JDIMENSION) MCU_height)
-+      result = FALSE;
-+    break;
-+  default:
-+    break;
-+  }
-+
-+  return result;
-+}
-+
-+#endif /* TRANSFORMS_SUPPORTED */
-+
-+
-+/* Setup decompression object to save desired markers in memory.
-+ * This must be called before jpeg_read_header() to have the desired effect.
-+ */
-+
-+GLOBAL(void)
-+jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
-+{
-+#ifdef SAVE_MARKERS_SUPPORTED
-+  int m;
-+
-+  /* Save comments except under NONE option */
-+  if (option != JCOPYOPT_NONE) {
-+    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
-+  }
-+  /* Save all types of APPn markers iff ALL option */
-+  if (option == JCOPYOPT_ALL) {
-+    for (m = 0; m < 16; m++)
-+      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
-+  }
-+#endif /* SAVE_MARKERS_SUPPORTED */
-+}
-+
-+/* Copy markers saved in the given source object to the destination object.
-+ * This should be called just after jpeg_start_compress() or
-+ * jpeg_write_coefficients().
-+ * Note that those routines will have written the SOI, and also the
-+ * JFIF APP0 or Adobe APP14 markers if selected.
-+ */
-+
-+GLOBAL(void)
-+jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+		       JCOPY_OPTION option)
-+{
-+  jpeg_saved_marker_ptr marker;
-+
-+  /* In the current implementation, we don't actually need to examine the
-+   * option flag here; we just copy everything that got saved.
-+   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
-+   * if the encoder library already wrote one.
-+   */
-+  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
-+    if (dstinfo->write_JFIF_header &&
-+	marker->marker == JPEG_APP0 &&
-+	marker->data_length >= 5 &&
-+	GETJOCTET(marker->data[0]) == 0x4A &&
-+	GETJOCTET(marker->data[1]) == 0x46 &&
-+	GETJOCTET(marker->data[2]) == 0x49 &&
-+	GETJOCTET(marker->data[3]) == 0x46 &&
-+	GETJOCTET(marker->data[4]) == 0)
-+      continue;			/* reject duplicate JFIF */
-+    if (dstinfo->write_Adobe_marker &&
-+	marker->marker == JPEG_APP0+14 &&
-+	marker->data_length >= 5 &&
-+	GETJOCTET(marker->data[0]) == 0x41 &&
-+	GETJOCTET(marker->data[1]) == 0x64 &&
-+	GETJOCTET(marker->data[2]) == 0x6F &&
-+	GETJOCTET(marker->data[3]) == 0x62 &&
-+	GETJOCTET(marker->data[4]) == 0x65)
-+      continue;			/* reject duplicate Adobe */
-+#ifdef NEED_FAR_POINTERS
-+    /* We could use jpeg_write_marker if the data weren't FAR... */
-+    {
-+      unsigned int i;
-+      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
-+      for (i = 0; i < marker->data_length; i++)
-+	jpeg_write_m_byte(dstinfo, marker->data[i]);
-+    }
-+#else
-+    jpeg_write_marker(dstinfo, marker->marker,
-+		      marker->data, marker->data_length);
-+#endif
-+  }
-+}
---- /dev/null
-+++ freeimage/jpeg/transupp.h
-@@ -0,0 +1,220 @@
-+/*
-+ * transupp.h
-+ *
-+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
-+ * This file is part of the Independent JPEG Group's software.
-+ * For conditions of distribution and use, see the accompanying README file.
-+ *
-+ * This file contains declarations for image transformation routines and
-+ * other utility code used by the jpegtran sample application.  These are
-+ * NOT part of the core JPEG library.  But we keep these routines separate
-+ * from jpegtran.c to ease the task of maintaining jpegtran-like programs
-+ * that have other user interfaces.
-+ *
-+ * NOTE: all the routines declared here have very specific requirements
-+ * about when they are to be executed during the reading and writing of the
-+ * source and destination files.  See the comments in transupp.c, or see
-+ * jpegtran.c for an example of correct usage.
-+ */
-+
-+/* If you happen not to want the image transform support, disable it here */
-+#ifndef TRANSFORMS_SUPPORTED
-+#define TRANSFORMS_SUPPORTED 1		/* 0 disables transform code */
-+#endif
-+
-+/*
-+ * Although rotating and flipping data expressed as DCT coefficients is not
-+ * hard, there is an asymmetry in the JPEG format specification for images
-+ * whose dimensions aren't multiples of the iMCU size.  The right and bottom
-+ * image edges are padded out to the next iMCU boundary with junk data; but
-+ * no padding is possible at the top and left edges.  If we were to flip
-+ * the whole image including the pad data, then pad garbage would become
-+ * visible at the top and/or left, and real pixels would disappear into the
-+ * pad margins --- perhaps permanently, since encoders & decoders may not
-+ * bother to preserve DCT blocks that appear to be completely outside the
-+ * nominal image area.  So, we have to exclude any partial iMCUs from the
-+ * basic transformation.
-+ *
-+ * Transpose is the only transformation that can handle partial iMCUs at the
-+ * right and bottom edges completely cleanly.  flip_h can flip partial iMCUs
-+ * at the bottom, but leaves any partial iMCUs at the right edge untouched.
-+ * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
-+ * The other transforms are defined as combinations of these basic transforms
-+ * and process edge blocks in a way that preserves the equivalence.
-+ *
-+ * The "trim" option causes untransformable partial iMCUs to be dropped;
-+ * this is not strictly lossless, but it usually gives the best-looking
-+ * result for odd-size images.  Note that when this option is active,
-+ * the expected mathematical equivalences between the transforms may not hold.
-+ * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
-+ * followed by -rot 180 -trim trims both edges.)
-+ *
-+ * We also offer a lossless-crop option, which discards data outside a given
-+ * image region but losslessly preserves what is inside.  Like the rotate and
-+ * flip transforms, lossless crop is restricted by the JPEG format: the upper
-+ * left corner of the selected region must fall on an iMCU boundary.  If this
-+ * does not hold for the given crop parameters, we silently move the upper left
-+ * corner up and/or left to make it so, simultaneously increasing the region
-+ * dimensions to keep the lower right crop corner unchanged.  (Thus, the
-+ * output image covers at least the requested region, but may cover more.)
-+ * The adjustment of the region dimensions may be optionally disabled.
-+ *
-+ * We also provide a lossless-resize option, which is kind of a lossless-crop
-+ * operation in the DCT coefficient block domain - it discards higher-order
-+ * coefficients and losslessly preserves lower-order coefficients of a
-+ * sub-block.
-+ *
-+ * Rotate/flip transform, resize, and crop can be requested together in a
-+ * single invocation.  The crop is applied last --- that is, the crop region
-+ * is specified in terms of the destination image after transform/resize.
-+ *
-+ * We also offer a "force to grayscale" option, which simply discards the
-+ * chrominance channels of a YCbCr image.  This is lossless in the sense that
-+ * the luminance channel is preserved exactly.  It's not the same kind of
-+ * thing as the rotate/flip transformations, but it's convenient to handle it
-+ * as part of this package, mainly because the transformation routines have to
-+ * be aware of the option to know how many components to work on.
-+ */
-+
-+
-+/* Short forms of external names for systems with brain-damaged linkers. */
-+
-+#ifdef NEED_SHORT_EXTERNAL_NAMES
-+#define jtransform_parse_crop_spec	jTrParCrop
-+#define jtransform_request_workspace	jTrRequest
-+#define jtransform_adjust_parameters	jTrAdjust
-+#define jtransform_execute_transform	jTrExec
-+#define jtransform_perfect_transform	jTrPerfect
-+#define jcopy_markers_setup		jCMrkSetup
-+#define jcopy_markers_execute		jCMrkExec
-+#endif /* NEED_SHORT_EXTERNAL_NAMES */
-+
-+
-+/*
-+ * Codes for supported types of image transformations.
-+ */
-+
-+typedef enum {
-+	JXFORM_NONE,		/* no transformation */
-+	JXFORM_FLIP_H,		/* horizontal flip */
-+	JXFORM_FLIP_V,		/* vertical flip */
-+	JXFORM_TRANSPOSE,	/* transpose across UL-to-LR axis */
-+	JXFORM_TRANSVERSE,	/* transpose across UR-to-LL axis */
-+	JXFORM_ROT_90,		/* 90-degree clockwise rotation */
-+	JXFORM_ROT_180,		/* 180-degree rotation */
-+	JXFORM_ROT_270		/* 270-degree clockwise (or 90 ccw) */
-+} JXFORM_CODE;
-+
-+/*
-+ * Codes for crop parameters, which can individually be unspecified,
-+ * positive or negative for xoffset or yoffset,
-+ * positive or forced for width or height.
-+ */
-+
-+typedef enum {
-+        JCROP_UNSET,
-+        JCROP_POS,
-+        JCROP_NEG,
-+        JCROP_FORCE
-+} JCROP_CODE;
-+
-+/*
-+ * Transform parameters struct.
-+ * NB: application must not change any elements of this struct after
-+ * calling jtransform_request_workspace.
-+ */
-+
-+typedef struct {
-+  /* Options: set by caller */
-+  JXFORM_CODE transform;	/* image transform operator */
-+  boolean perfect;		/* if TRUE, fail if partial MCUs are requested */
-+  boolean trim;			/* if TRUE, trim partial MCUs as needed */
-+  boolean force_grayscale;	/* if TRUE, convert color image to grayscale */
-+  boolean crop;			/* if TRUE, crop source image */
-+  boolean slow_hflip;  /* For best performance, the JXFORM_FLIP_H transform
-+                          normally modifies the source coefficients in place.
-+                          Setting this to TRUE will instead use a slower,
-+                          double-buffered algorithm, which leaves the source
-+                          coefficients in tact (necessary if other transformed
-+                          images must be generated from the same set of
-+                          coefficients. */
-+
-+  /* Crop parameters: application need not set these unless crop is TRUE.
-+   * These can be filled in by jtransform_parse_crop_spec().
-+   */
-+  JDIMENSION crop_width;	/* Width of selected region */
-+  JCROP_CODE crop_width_set;	/* (forced disables adjustment) */
-+  JDIMENSION crop_height;	/* Height of selected region */
-+  JCROP_CODE crop_height_set;	/* (forced disables adjustment) */
-+  JDIMENSION crop_xoffset;	/* X offset of selected region */
-+  JCROP_CODE crop_xoffset_set;	/* (negative measures from right edge) */
-+  JDIMENSION crop_yoffset;	/* Y offset of selected region */
-+  JCROP_CODE crop_yoffset_set;	/* (negative measures from bottom edge) */
-+
-+  /* Internal workspace: caller should not touch these */
-+  int num_components;		/* # of components in workspace */
-+  jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
-+  JDIMENSION output_width;	/* cropped destination dimensions */
-+  JDIMENSION output_height;
-+  JDIMENSION x_crop_offset;	/* destination crop offsets measured in iMCUs */
-+  JDIMENSION y_crop_offset;
-+  int iMCU_sample_width;	/* destination iMCU size */
-+  int iMCU_sample_height;
-+} jpeg_transform_info;
-+
-+
-+#if TRANSFORMS_SUPPORTED
-+
-+/* Parse a crop specification (written in X11 geometry style) */
-+EXTERN(boolean) jtransform_parse_crop_spec
-+	JPP((jpeg_transform_info *info, const char *spec));
-+/* Request any required workspace */
-+EXTERN(boolean) jtransform_request_workspace
-+	JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
-+/* Adjust output image parameters */
-+EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
-+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	     jvirt_barray_ptr *src_coef_arrays,
-+	     jpeg_transform_info *info));
-+/* Execute the actual transformation, if any */
-+EXTERN(void) jtransform_execute_transform
-+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	     jvirt_barray_ptr *src_coef_arrays,
-+	     jpeg_transform_info *info));
-+/* Determine whether lossless transformation is perfectly
-+ * possible for a specified image and transformation.
-+ */
-+EXTERN(boolean) jtransform_perfect_transform
-+	JPP((JDIMENSION image_width, JDIMENSION image_height,
-+	     int MCU_width, int MCU_height,
-+	     JXFORM_CODE transform));
-+
-+/* jtransform_execute_transform used to be called
-+ * jtransform_execute_transformation, but some compilers complain about
-+ * routine names that long.  This macro is here to avoid breaking any
-+ * old source code that uses the original name...
-+ */
-+#define jtransform_execute_transformation	jtransform_execute_transform
-+
-+#endif /* TRANSFORMS_SUPPORTED */
-+
-+
-+/*
-+ * Support for copying optional markers from source to destination file.
-+ */
-+
-+typedef enum {
-+	JCOPYOPT_NONE,		/* copy no optional markers */
-+	JCOPYOPT_COMMENTS,	/* copy only comment (COM) markers */
-+	JCOPYOPT_ALL		/* copy all optional markers */
-+} JCOPY_OPTION;
-+
-+#define JCOPYOPT_DEFAULT  JCOPYOPT_COMMENTS	/* recommended default */
-+
-+/* Setup decompression object to save desired markers in memory */
-+EXTERN(void) jcopy_markers_setup
-+	JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
-+/* Copy markers saved in the given source object to the destination object */
-+EXTERN(void) jcopy_markers_execute
-+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
-+	     JCOPY_OPTION option));
---- freeimage.orig/genfipsrclist.sh
-+++ freeimage/genfipsrclist.sh
-@@ -13,7 +13,7 @@ for DIR in $DIRLIST; do
- 		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> fipMakefile.srcs
- 	fi
- done
--echo -n ' Source/LibJPEG/transupp.c' >> fipMakefile.srcs
-+echo -n ' jpeg/transupp.c' >> fipMakefile.srcs
- echo >> fipMakefile.srcs
- 
- echo -n "INCLUDE =" >> fipMakefile.srcs
diff --git a/debian/patches/disable_embedded_libraries.patch b/debian/patches/disable_embedded_libraries.patch
deleted file mode 100644
index 603b63d..0000000
--- a/debian/patches/disable_embedded_libraries.patch
+++ /dev/null
@@ -1,359 +0,0 @@
-Description: Disable embedded libraries
- freeimage normally builds with embedded copies of libjpeg, libpng,
- libmng, libopenjpeg, libopenexr, zlib, libtiff.
- .
- Switch to using packaged versions for all of these except libtiff,
- where freeimage digs deep into its internals.
- .
- This patch does not modify Makefile.srcs and fipMakefile.srcs - those
- are patched as part of the patch build process.
-Origin: vendor
-Forwarded: no
-Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=595560
-Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/freeimage/+bug/898825
-Author: Julien Cristau <jcristau at debian.org>
-Author: Evan Broder <evan at ebroder.net>
-Last-Update: 2011-12-04
-
-Index: freeimage-3.15.4/gensrclist.sh
-===================================================================
---- freeimage-3.15.4.orig/gensrclist.sh
-+++ freeimage-3.15.4/gensrclist.sh
-@@ -1,6 +1,6 @@
- #!/bin/sh
- 
--DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src"
-+DIRLIST=". Source Source/Metadata Source/FreeImageToolkit"
- 
- echo "VER_MAJOR = 3" > Makefile.srcs
- echo "VER_MINOR = 15.4" >> Makefile.srcs
-@@ -12,15 +12,17 @@ for DIR in $DIRLIST; do
- 		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> Makefile.srcs
- 	fi
- done
-+echo -n ' Source/LibJPEG/transupp.c' >> Makefile.srcs
- echo >> Makefile.srcs
- 
- echo -n "INCLS = " >> Makefile.srcs
--find . -name "*.h" -print | xargs echo >> Makefile.srcs
-+find . \( -name 'Lib*' -or -name 'OpenEXR' -or -name 'ZLib' \) -prune -or -name '*.h' -print | sort | xargs echo -n >> Makefile.srcs
- echo >> Makefile.srcs
- 
- echo -n "INCLUDE =" >> Makefile.srcs
- for DIR in $DIRLIST; do
- 	echo -n " -I$DIR" >> Makefile.srcs
- done
-+echo ' $(shell pkg-config --cflags zlib OpenEXR libraw libpng libtiff-4)' >> Makefile.srcs
- echo >> Makefile.srcs
- 
-Index: freeimage-3.15.4/genfipsrclist.sh
-===================================================================
---- freeimage-3.15.4.orig/genfipsrclist.sh
-+++ freeimage-3.15.4/genfipsrclist.sh
-@@ -1,6 +1,6 @@
- #!/bin/sh
- 
--DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Source/LibJPEG Source/LibPNG Source/LibTIFF4 Source/ZLib Source/LibOpenJPEG Source/OpenEXR Source/OpenEXR/Half Source/OpenEXR/Iex Source/OpenEXR/IlmImf Source/OpenEXR/IlmThread Source/OpenEXR/Imath Source/LibRawLite Source/LibRawLite/dcraw Source/LibRawLite/internal Source/LibRawLite/libraw Source/LibRawLite/src Wrapper/FreeImagePlus"
-+DIRLIST=". Source Source/Metadata Source/FreeImageToolkit Wrapper/FreeImagePlus"
- 
- 
- echo "VER_MAJOR = 3" > fipMakefile.srcs
-@@ -13,11 +13,13 @@ for DIR in $DIRLIST; do
- 		egrep 'RelativePath=.*\.(c|cpp)' $DIR/*.2008.vcproj | cut -d'"' -f2 | tr '\\' '/' | awk '{print "'$DIR'/"$0}' | tr '\r\n' '  ' | tr -s ' ' >> fipMakefile.srcs
- 	fi
- done
-+echo -n ' Source/LibJPEG/transupp.c' >> fipMakefile.srcs
- echo >> fipMakefile.srcs
- 
- echo -n "INCLUDE =" >> fipMakefile.srcs
- for DIR in $DIRLIST; do
- 	echo -n " -I$DIR" >> fipMakefile.srcs
- done
-+echo ' $(shell pkg-config --cflags zlib OpenEXR libraw libpng libtiff-4)' >> fipMakefile.srcs
- echo >> fipMakefile.srcs
- 
-Index: freeimage-3.15.4/Source/FreeImage/ZLibInterface.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/ZLibInterface.cpp
-+++ freeimage-3.15.4/Source/FreeImage/ZLibInterface.cpp
-@@ -19,10 +19,10 @@
- // Use at your own risk!
- // ==========================================================
- 
--#include "../ZLib/zlib.h"
-+#include <zlib.h>
- #include "FreeImage.h"
- #include "Utilities.h"
--#include "../ZLib/zutil.h"	/* must be the last header because of error C3163 in VS2008 (_vsnprintf defined in stdio.h) */
-+//#include "../ZLib/zutil.h"	/* must be the last header because of error C3163 in VS2008 (_vsnprintf defined in stdio.h) */
- 
- /**
- Compresses a source buffer into a target buffer, using the ZLib library. 
-@@ -115,7 +115,7 @@ FreeImage_ZLibGZip(BYTE *target, DWORD t
- 			return 0;
-         case Z_OK: {
-             // patch header, setup crc and length (stolen from mod_trace_output)
--            BYTE *p = target + 8; *p++ = 2; *p = OS_CODE; // xflags, os_code
-+            BYTE *p = target + 8; *p++ = 2; *p = 0x03; // xflags, os_code
-  	        crc = crc32(crc, source, source_size);
- 	        memcpy(target + 4 + dest_len, &crc, 4);
- 	        memcpy(target + 8 + dest_len, &source_size, 4);
-Index: freeimage-3.15.4/Source/FreeImage/PluginJPEG.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginJPEG.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginJPEG.cpp
-@@ -35,9 +35,10 @@ extern "C" {
- #undef FAR
- #include <setjmp.h>
- 
--#include "../LibJPEG/jinclude.h"
--#include "../LibJPEG/jpeglib.h"
--#include "../LibJPEG/jerror.h"
-+#include <sys/types.h>
-+#include <stdio.h>
-+#include <jpeglib.h>
-+#include <jerror.h>
- }
- 
- #include "FreeImage.h"
-Index: freeimage-3.15.4/Source/FreeImage/PluginEXR.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginEXR.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginEXR.cpp
-@@ -22,16 +22,16 @@
- 
- #include "FreeImage.h"
- #include "Utilities.h"
--#include "../OpenEXR/IlmImf/ImfIO.h"
--#include "../OpenEXR/Iex/Iex.h"
--#include "../OpenEXR/IlmImf/ImfOutputFile.h"
--#include "../OpenEXR/IlmImf/ImfInputFile.h"
--#include "../OpenEXR/IlmImf/ImfRgbaFile.h"
--#include "../OpenEXR/IlmImf/ImfChannelList.h"
--#include "../OpenEXR/IlmImf/ImfRgba.h"
--#include "../OpenEXR/IlmImf/ImfArray.h"
--#include "../OpenEXR/IlmImf/ImfPreviewImage.h"
--#include "../OpenEXR/Half/half.h"
-+#include <OpenEXR/ImfIO.h>
-+#include <OpenEXR/Iex.h>
-+#include <OpenEXR/ImfOutputFile.h>
-+#include <OpenEXR/ImfInputFile.h>
-+#include <OpenEXR/ImfRgbaFile.h>
-+#include <OpenEXR/ImfPreviewImage.h>
-+#include <OpenEXR/ImfChannelList.h>
-+#include <OpenEXR/ImfRgba.h>
-+#include <OpenEXR/ImfArray.h>
-+#include <OpenEXR/half.h>
- 
- 
- // ==========================================================
-Index: freeimage-3.15.4/Source/FreeImage/PluginJ2K.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginJ2K.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginJ2K.cpp
-@@ -21,7 +21,7 @@
- 
- #include "FreeImage.h"
- #include "Utilities.h"
--#include "../LibOpenJPEG/openjpeg.h"
-+#include <openjpeg.h>
- 
- // ==========================================================
- // Plugin Interface
-Index: freeimage-3.15.4/Source/FreeImage/PluginPNG.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginPNG.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginPNG.cpp
-@@ -37,8 +37,7 @@
- 
- // ----------------------------------------------------------
- 
--#include "../ZLib/zlib.h"
--#include "../LibPNG/png.h"
-+#include <png.h>
- 
- // ----------------------------------------------------------
- 
-@@ -106,7 +105,10 @@ ReadMetadata(png_structp png_ptr, png_in
- 			tag = FreeImage_CreateTag();
- 			if(!tag) return FALSE;
- 
--			DWORD tag_length = (DWORD) MAX(text_ptr[i].text_length, text_ptr[i].itxt_length);
-+			DWORD tag_length = text_ptr[i].text_length;
-+#ifdef PNG_iTXt_SUPPORTED
-+			tag_length = MAX(tag_length, text_ptr[i].itxt_length);
-+#endif
- 
- 			FreeImage_SetTagLength(tag, tag_length);
- 			FreeImage_SetTagCount(tag, tag_length);
-@@ -149,13 +151,19 @@ WriteMetadata(png_structp png_ptr, png_i
- 	if(mdhandle) {
- 		do {
- 			memset(&text_metadata, 0, sizeof(png_text));
-+#ifdef PNG_iTXt_SUPPORTED
- 			text_metadata.compression = 1;							// iTXt, none
-+#else
-+			text_metadata.compression = -1;
-+#endif
- 			text_metadata.key = (char*)FreeImage_GetTagKey(tag);	// keyword, 1-79 character description of "text"
- 			text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
- 			text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
-+#ifdef PNG_iTXt_SUPPORTED
- 			text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
- 			text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
- 			text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
-+#endif
- 
- 			// set the tag 
- 			png_set_text(png_ptr, info_ptr, &text_metadata, 1);
-@@ -175,9 +183,11 @@ WriteMetadata(png_structp png_ptr, png_i
- 		text_metadata.key = (char*)g_png_xmp_keyword;					// keyword, 1-79 character description of "text"
- 		text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
- 		text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
-+#ifdef PNG_iTXt_SUPPORTED
- 		text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
- 		text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
- 		text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
-+#endif
- 
- 		// set the tag 
- 		png_set_text(png_ptr, info_ptr, &text_metadata, 1);
-@@ -559,7 +569,7 @@ Load(FreeImageIO *io, fi_handle handle,
- 
- 			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
- 				png_charp profile_name = NULL;
--				png_bytep profile_data = NULL;
-+				png_charp profile_data = NULL;
- 				png_uint_32 profile_length = 0;
- 				int  compression_type;
- 
-@@ -599,7 +609,9 @@ Load(FreeImageIO *io, fi_handle handle,
- 				row_pointers[height - 1 - k] = FreeImage_GetScanLine(dib, k);			
- 			}
- 
-+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
- 			png_set_benign_errors(png_ptr, 1);
-+#endif
- 			png_read_image(png_ptr, row_pointers);
- 
- 			// check if the bitmap contains transparency, if so enable it in the header
-@@ -843,7 +855,7 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_
- 
- 			FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
- 			if (iccProfile->size && iccProfile->data) {
--				png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_const_bytep)iccProfile->data, iccProfile->size);
-+				png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_charp)iccProfile->data, iccProfile->size);
- 			}
- 
- 			// write metadata
-Index: freeimage-3.15.4/Source/FreeImage/J2KHelper.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/J2KHelper.cpp
-+++ freeimage-3.15.4/Source/FreeImage/J2KHelper.cpp
-@@ -21,7 +21,7 @@
- 
- #include "FreeImage.h"
- #include "Utilities.h"
--#include "../LibOpenJPEG/openjpeg.h"
-+#include <openjpeg.h>
- 
- /**
- Divide an integer by a power of 2 and round upwards
-Index: freeimage-3.15.4/Source/FreeImage/PluginJP2.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginJP2.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginJP2.cpp
-@@ -21,7 +21,7 @@
- 
- #include "FreeImage.h"
- #include "Utilities.h"
--#include "../LibOpenJPEG/openjpeg.h"
-+#include <openjpeg.h>
- 
- // ==========================================================
- // Plugin Interface
-Index: freeimage-3.15.4/Source/FreeImage/PluginRAW.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginRAW.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginRAW.cpp
-@@ -19,7 +19,7 @@
- // Use at your own risk!
- // ==========================================================
- 
--#include "../LibRawLite/libraw/libraw.h"
-+#include <libraw/libraw.h>
- 
- #include "FreeImage.h"
- #include "Utilities.h"
-Index: freeimage-3.15.4/Source/FreeImageToolkit/JPEGTransform.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImageToolkit/JPEGTransform.cpp
-+++ freeimage-3.15.4/Source/FreeImageToolkit/JPEGTransform.cpp
-@@ -25,9 +25,10 @@ extern "C" {
- #undef FAR
- #include <setjmp.h>
- 
--#include "../LibJPEG/jinclude.h"
--#include "../LibJPEG/jpeglib.h"
--#include "../LibJPEG/jerror.h"
-+#include <sys/types.h>
-+#include <stdio.h>
-+#include <jpeglib.h>
-+#include <jerror.h>
- #include "../LibJPEG/transupp.h"
- }
- 
-Index: freeimage-3.15.4/Makefile.fip
-===================================================================
---- freeimage-3.15.4.orig/Makefile.fip
-+++ freeimage-3.15.4/Makefile.fip
-@@ -11,7 +11,7 @@ INSTALLDIR ?= $(DESTDIR)/usr/lib
- # Converts cr/lf to just lf
- DOS2UNIX = dos2unix
- 
--LIBRARIES = -lstdc++
-+LIBRARIES = -lstdc++ -lmng -ljpeg -lopenjpeg $(shell pkg-config --libs zlib OpenEXR libraw libpng libtiff-4)
- 
- MODULES = $(SRCS:.c=.o)
- MODULES := $(MODULES:.cpp=.o)
-Index: freeimage-3.15.4/Makefile.gnu
-===================================================================
---- freeimage-3.15.4.orig/Makefile.gnu
-+++ freeimage-3.15.4/Makefile.gnu
-@@ -11,7 +11,7 @@ INSTALLDIR ?= $(DESTDIR)/usr/lib
- # Converts cr/lf to just lf
- DOS2UNIX = dos2unix
- 
--LIBRARIES = -lstdc++
-+LIBRARIES = -lstdc++ -ljpeg -lmng -lopenjpeg $(shell pkg-config --libs zlib OpenEXR libraw libpng libtiff-4) -lm
- 
- MODULES = $(SRCS:.c=.o)
- MODULES := $(MODULES:.cpp=.o)
-Index: freeimage-3.15.4/Source/FreeImage/PluginTIFF.cpp
-===================================================================
---- freeimage-3.15.4.orig/Source/FreeImage/PluginTIFF.cpp
-+++ freeimage-3.15.4/Source/FreeImage/PluginTIFF.cpp
-@@ -39,7 +39,7 @@
- #include "Utilities.h"
- #include "../LibTIFF4/tiffiop.h"
- #include "../Metadata/FreeImageTag.h"
--#include "../OpenEXR/Half/half.h"
-+#include <OpenEXR/half.h>
- 
- #include "FreeImageIO.h"
- #include "PSDParser.h"
-Index: freeimage-3.15.4/Source/LibTIFF4/tiffiop.h
-===================================================================
---- freeimage-3.15.4.orig/Source/LibTIFF4/tiffiop.h
-+++ freeimage-3.15.4/Source/LibTIFF4/tiffiop.h
-@@ -30,7 +30,9 @@
-  * ``Library-private'' definitions.
-  */
- 
--#include "tif_config.h"
-+#include <tiffconf.h>
-+#define HAVE_SEARCH_H
-+#define HAVE_FCNTL_H
- 
- #ifdef HAVE_FCNTL_H
- # include <fcntl.h>
diff --git a/debian/patches/fix-big-endian-detection.patch b/debian/patches/fix-big-endian-detection.patch
deleted file mode 100644
index 69d4838..0000000
--- a/debian/patches/fix-big-endian-detection.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-Date: Wed, 1 Oct 2014 11:12:37 +0100
-From: Dejan Latinovic <Dejan.Latinovic at imgtec.com>
-Subject: fix for skimage
-
-Package skimage FTBFS on mips (and other BE arch except ppc), on testing.
-
-> ======================================================================
-> FAIL: test_freeimage.test_imread
-> ----------------------------------------------------------------------
-> Traceback (most recent call last):
->   File "/usr/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
->     self.test(*self.arg)
->   File "/usr/lib/python2.7/dist-packages/numpy/testing/decorators.py", line 146, in skipper_func
->     return f(*args, **kwargs)
->   File "/�PKGBUILDDIR�/debian/tmp/usr/lib/python2.7/dist-packages/skimage/io/tests/test_freeimage.py", line 38, in
-test_imread
->     assert all(img[274, 135] == [0, 130, 253])
-> AssertionError
->
-> ----------------------------------------------------------------------
-> Ran 1033 tests in 1239.576s
->
-> FAILED (SKIP=20, failures=1)
-
-Test reads info from color.png with coordinates [274, 135].  Obtained result is
-[253 130 0], instead of expected [0, 130, 253].  I seems that color format is
-twisted (RGB -> BGR) during loading of PNG.  The reason for that is a fact that
-big endian was not detected right in FreeImage.h.
-
-Patch that improves big endian detection in freeimage is attached.
-
-Beside that, freeimage FTBFS on amd64, mips, mipsel and probably other archs
-because of missing build dependency.  Patch that adds this dependency is
-attached.
-
-Using freeimage built with patches below, I was able to build skimage
-successfully with all tests passing.
-
---- freeimage.orig/Source/FreeImage.h
-+++ freeimage/Source/FreeImage.h
-@@ -73,6 +73,7 @@
- // If your big endian system isn't being detected, add an OS specific check
- #if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
- 	(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
-+	(defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) || \
- 	defined(__BIG_ENDIAN__)
- #define FREEIMAGE_BIGENDIAN
- #endif // BYTE_ORDER
diff --git a/debian/patches/fix_Integer_overflow_in_ljpeg_start.patch b/debian/patches/fix_Integer_overflow_in_ljpeg_start.patch
deleted file mode 100644
index 0137127..0000000
--- a/debian/patches/fix_Integer_overflow_in_ljpeg_start.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-Description: Fix integer overflow in the ljpeg_start function in dcraw
-Author: Alex Tutubalin <lexa at lexa.ru>
-Bug-Debian: https://bugs.debian.org/786790
-Origin: https://github.com/LibRaw/LibRaw/commit/4606c28f494a750892c5c1ac7903e62dd1c6fdb5
-        https://github.com/rawstudio/rawstudio/commit/983bda1f0fa5fa86884381208274198a620f006e
-Bug: https://security-tracker.debian.org/tracker/CVE-2015-3885
-Bug: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3885
-Reviewed-By: Anton Gladky <gladk at debian.org>
-Last-Update: 2015-10-29
-
---- freeimage-3.15.4.orig/Source/LibRawLite/dcraw/dcraw.c
-+++ freeimage-3.15.4/Source/LibRawLite/dcraw/dcraw.c
-@@ -768,7 +768,8 @@ struct jhead {
- 
- int CLASS ljpeg_start (struct jhead *jh, int info_only)
- {
--  int c, tag, len;
-+  int c, tag;
-+  ushort len;
-   uchar data[0x10000];
-   const uchar *dp;
- 
---- freeimage-3.15.4.orig/Source/LibRawLite/internal/dcraw_common.cpp
-+++ freeimage-3.15.4/Source/LibRawLite/internal/dcraw_common.cpp
-@@ -630,7 +630,8 @@ void CLASS canon_compressed_load_raw()
- 
- int CLASS ljpeg_start (struct jhead *jh, int info_only)
- {
--  int c, tag, len;
-+  int c, tag;
-+  ushort len;
-   uchar data[0x10000];
-   const uchar *dp;
- 
diff --git a/debian/patches/fix_ftbfs_amd64.patch b/debian/patches/fix_ftbfs_amd64.patch
deleted file mode 100644
index 81ee72f..0000000
--- a/debian/patches/fix_ftbfs_amd64.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Patch that fixes several problems for building on amd64. Thanks Fedora guys.
-=====================================================================
---- freeimage.orig/Source/FreeImage/PluginBMP.cpp
-+++ freeimage/Source/FreeImage/PluginBMP.cpp
-@@ -192,6 +192,8 @@ LoadPixelData(FreeImageIO *io, fi_handle
- 	return TRUE;
- }
- 
-+#define MIN(a, b) ( ((a) < (b))? (a):(b) )
-+
- /**
- Load image pixels for 4-bit RLE compressed dib
- @param io FreeImage IO
---- freeimage.orig/Source/FreeImage.h
-+++ freeimage/Source/FreeImage.h
-@@ -141,8 +141,10 @@ typedef uint8_t BYTE;
- typedef uint16_t WORD;
- typedef uint32_t DWORD;
- typedef int32_t LONG;
-+#ifndef _LIBRAW_TYPES_H
- typedef int64_t INT64;
- typedef uint64_t UINT64;
-+#endif
- #else
- // MS is not C99 ISO compliant
- typedef long BOOL;
diff --git a/debian/patches/makefile_modifications.patch b/debian/patches/makefile_modifications.patch
deleted file mode 100644
index f1df7aa..0000000
--- a/debian/patches/makefile_modifications.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-Some modificatoins to the makefiles to help in build Debian packages.
-Also removed -s (strip) option so we can make debug package. With the compiler
-options we're using by default, debugging should still be possible.
-==========================================================================
---- freeimage.orig/Makefile.fip
-+++ freeimage/Makefile.fip
-@@ -15,10 +15,12 @@ LIBRARIES = -lstdc++ -lmng -ljpeg -lopen
- 
- MODULES = $(SRCS:.c=.o)
- MODULES := $(MODULES:.cpp=.o)
--CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -DNO_LCMS
--CFLAGS += $(INCLUDE)
--CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
--CXXFLAGS += $(INCLUDE)
-+CFLAGS ?= -O3 -fPIC
-+override CFLAGS += -fexceptions -fvisibility=hidden -DNO_LCMS
-+override CFLAGS += $(INCLUDE)
-+CXXFLAGS ?= -O3 -fPIC
-+override CXXFLAGS += -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
-+override CXXFLAGS += $(INCLUDE)
- 
- ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
- 	CFLAGS += -fPIC
-@@ -59,7 +61,7 @@ $(STATICLIB): $(MODULES)
- 	$(AR) r $@ $(MODULES)
- 
- $(SHAREDLIB): $(MODULES)
--	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
-+	$(CXX) -shared -Wl,-soname,$(VERLIBNAME) -Wl,-z,defs $(LDFLAGS) -o $@ $(MODULES) $(CXXFLAGS) $(LIBRARIES)
- 
- install:
- 	install -d $(INCDIR) $(INSTALLDIR)
-@@ -67,6 +69,8 @@ install:
- 	install -m 644 -o root -g root $(HEADERFIP) $(INCDIR)
- 	install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR)
- 	install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR)
-+	ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(VERLIBNAME)
-+	ln -sf $(VERLIBNAME) $(INSTALLDIR)/$(LIBNAME)
- 
- clean:
- 	rm -f core Dist/*.* u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME)
---- freeimage.orig/Makefile.gnu
-+++ freeimage/Makefile.gnu
-@@ -15,10 +15,12 @@ LIBRARIES = -lstdc++ -ljpeg -lmng -lopen
- 
- MODULES = $(SRCS:.c=.o)
- MODULES := $(MODULES:.cpp=.o)
--CFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -DNO_LCMS
--CFLAGS += $(INCLUDE)
--CXXFLAGS ?= -O3 -fPIC -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
--CXXFLAGS += $(INCLUDE)
-+CFLAGS ?= -O3 -fPIC
-+override CFLAGS += -fexceptions -fvisibility=hidden -DNO_LCMS
-+override CFLAGS += $(INCLUDE)
-+CXXFLAGS ?= -O3 -fPIC
-+override CXXFLAGS += -fexceptions -fvisibility=hidden -Wno-ctor-dtor-privacy
-+override CXXFLAGS += $(INCLUDE)
- 
- ifeq ($(shell sh -c 'uname -m 2>/dev/null || echo not'),x86_64)
- 	CFLAGS += -fPIC
-@@ -58,7 +60,7 @@ $(STATICLIB): $(MODULES)
- 	$(AR) r $@ $(MODULES)
- 
- $(SHAREDLIB): $(MODULES)
--	$(CC) -s -shared -Wl,-soname,$(VERLIBNAME) $(LDFLAGS) -o $@ $(MODULES) $(LIBRARIES)
-+	$(CXX) -shared -Wl,-soname,$(VERLIBNAME) -Wl,-z,defs $(LDFLAGS) -o $@ $(MODULES) $(CXXFLAGS) $(LIBRARIES)
- 
- install:
- 	install -d $(INCDIR) $(INSTALLDIR)
diff --git a/debian/patches/series b/debian/patches/series
index 72d1912..e635433 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,8 +1,12 @@
-disable_embedded_libraries.patch
-fix_ftbfs_amd64.patch
-makefile_modifications.patch
-tag_truncation.patch
-fix-big-endian-detection.patch
-build_using_libjpeg62_transupp.c.patch
-fix_integer_overflow.patch
-fix_Integer_overflow_in_ljpeg_start.patch
+0001-Disable-vendored-dependencies.patch
+0002-Use-system-dependencies.patch
+0003-Fix-macro-redefinition-for-64-bit-integer-types.patch
+0004-Fix-compatibility-with-system-libpng.patch
+0005-Fix-doxygen-output-settings.patch
+0006-Disable-usage-of-HTML-timestamps-in-doxygen.patch
+0007-Fix-unsafe-usage-of-printf-in-testsuite.patch
+0008-Disable-testing-of-JPEG-transform.patch
+0009-Disable-testing-of-JXR-MemIO.patch
+0010-Fix-missing-cstdio-include-in-testsuite.patch
+0011-Fix-endianness-detection.patch
+0012-Fix-CVE-2015-0852.patch
diff --git a/debian/patches/tag_truncation.patch b/debian/patches/tag_truncation.patch
deleted file mode 100644
index 8d6ca05..0000000
--- a/debian/patches/tag_truncation.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Description: fixes tag truncation bug in TIFF files
-Origin: http://sourceforge.net/p/freeimage/discussion/36110/thread/3738788c/
-http://freeimage.cvs.sourceforge.net/viewvc/freeimage/FreeImage/Source/Metadata/XTIFF.cpp?r1=1.23&r2=1.24&view=patch
-Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=735847
-
---- freeimage.orig/Source/Metadata/XTIFF.cpp
-+++ freeimage/Source/Metadata/XTIFF.cpp
-@@ -451,10 +451,20 @@ tiff_read_exif_tag(TIFF *tif, TagLib::MD
- 			FreeImage_SetTagValue(fitag, raw_data);
- 			break;
- 
-+                case TIFF_ASCII:
- 		default: {
--			// remember that raw_data = _TIFFmalloc(value_size * value_count);
--			const int value_size = _TIFFDataSize(fip->field_type);
--			size_t length = value_size * value_count;
-+                        size_t length = 0;
-+                        if(!mem_alloc && (fip->field_type == TIFF_ASCII) && (fip->field_readcount == TIFF_VARIABLE)) {
-+                                // when metadata tag is of type ASCII and it's value is of variable size (TIFF_VARIABLE),
-+                                // tiff_read_exif_tag function gives length of 1 so all strings are truncated ...
-+                                // ... try to avoid this by using an explicit calculation for 'length'
-+                                length = strlen((char*)raw_data) + 1;
-+                        }
-+                        else {
-+                                // remember that raw_data = _TIFFmalloc(value_size * value_count);
-+                                const int value_size = _TIFFDataSize(fip->field_type);
-+                                length = value_size * value_count;
-+                        }
- 			FreeImage_SetTagType(fitag, FIDT_ASCII);
- 			FreeImage_SetTagLength(fitag, (DWORD)length);
- 			FreeImage_SetTagCount(fitag, (DWORD)length);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/freeimage.git



More information about the debian-science-commits mailing list