aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanilo <danilo@FreeBSD.org>2014-06-20 23:46:27 +0800
committerdanilo <danilo@FreeBSD.org>2014-06-20 23:46:27 +0800
commitaf9089a69184582b18144b3a29a43a4bc6c222e8 (patch)
tree41773c3ed11d26e208ef76c83f5405c2e6ae4929
parentbcdc2b6590e64af1b67e43a8833dbd9ec19525ba (diff)
downloadfreebsd-ports-gnome-af9089a69184582b18144b3a29a43a4bc6c222e8.tar.gz
freebsd-ports-gnome-af9089a69184582b18144b3a29a43a4bc6c222e8.tar.zst
freebsd-ports-gnome-af9089a69184582b18144b3a29a43a4bc6c222e8.zip
- Update from 1.2 to 1.5
- Add stage support PR: ports/191180 Submitted by: ii@any.com.ru
-rw-r--r--graphics/pfstmo/Makefile34
-rw-r--r--graphics/pfstmo/distinfo4
-rw-r--r--graphics/pfstmo/files/patch-configure11
-rw-r--r--graphics/pfstmo/files/patch-src-durand02-fastbilateral.cpp27
-rw-r--r--graphics/pfstmo/files/patch-src-fattal02-pde.cpp185
-rw-r--r--graphics/pfstmo/files/patch-src-fattal02-tmo_fattal02.cpp10
-rw-r--r--graphics/pfstmo/files/patch-src-mantiuk06-contrast_domain.cpp279
-rw-r--r--graphics/pfstmo/files/patch-src-mantiuk06-pfstmo_mantiuk06.cpp17
-rw-r--r--graphics/pfstmo/files/patch-src-mantiuk08-display_adaptive_tmo.cpp20
-rw-r--r--graphics/pfstmo/files/patch-src-mantiuk08-pfstmo_mantiuk08.cpp25
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard02-approx.cpp223
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.163
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.cpp142
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.cpp726
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.h27
-rw-r--r--graphics/pfstmo/files/patch-src-reinhard05-pfstmo_reinhard05.cpp17
-rw-r--r--graphics/pfstmo/pkg-plist9
17 files changed, 1779 insertions, 40 deletions
diff --git a/graphics/pfstmo/Makefile b/graphics/pfstmo/Makefile
index 128042220674..85be1a90b6c2 100644
--- a/graphics/pfstmo/Makefile
+++ b/graphics/pfstmo/Makefile
@@ -2,37 +2,27 @@
# $FreeBSD$
PORTNAME= pfstmo
-PORTVERSION= 1.2
-PORTREVISION= 3
+PORTVERSION= 1.5
CATEGORIES= graphics
-MASTER_SITES= SF/pfstools/${PORTNAME}/${PORTVERSION}
+MASTER_SITES= SF
+MASTER_SITE_SUBDIR= pfstools/${PORTNAME}/${PORTVERSION}
MAINTAINER= ii@any.com.ru
COMMENT= Tone mapping operators
-LIB_DEPENDS= pfs-1.2:${PORTSDIR}/graphics/pfstools
+LIB_DEPENDS= libpfs-1.2.so:${PORTSDIR}/graphics/pfstools \
+ libfftw3.so:${PORTSDIR}/math/fftw3 \
+ libfftw3f.so:${PORTSDIR}/math/fftw3-float \
+ libgsl.so:${PORTSDIR}/math/gsl
PFS_CPPFLAGS= -I${LOCALBASE}/include
PFS_LDFLAGS= -L${LOCALBASE}/lib
-USES= pkgconfig gmake
GNU_CONFIGURE= yes
-CPPFLAGS+= ${PFS_CPPFLAGS}
-LDFLAGS+= ${PFS_LDFLAGS}
+CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
+CONFIGURE_ENV+= CPPFLAGS="${PFS_CPPFLAGS} ${DEBUG_FLAGS}" \
+ LDFLAGS="${PFS_LDFLAGS}"
-MAN1= pfstmo_pattanaik00.1 \
- pfstmo_reinhard05.1 \
- pfstmo_reinhard02.1 \
- pfstmo_durand02.1 \
- pfstmo_drago03.1 \
- pfstmo_mantiuk06.1 \
- pfstmo_fattal02.1
+USES= gmake pkgconfig compiler:openmp
-NO_STAGE= yes
-.include <bsd.port.pre.mk>
-
-.if defined(WITH_FFTW3F)
-LIB_DEPENDS+= fftw3f:${PORTSDIR}/math/fftw3-float
-.endif
-
-.include <bsd.port.post.mk>
+.include <bsd.port.mk>
diff --git a/graphics/pfstmo/distinfo b/graphics/pfstmo/distinfo
index e6fdc6d14024..66315e796e82 100644
--- a/graphics/pfstmo/distinfo
+++ b/graphics/pfstmo/distinfo
@@ -1,2 +1,2 @@
-SHA256 (pfstmo-1.2.tar.gz) = 796555f3c60fc8f2cb56e4288dc035aa3f0a6b8812a7388ce3c002103c2e5aa1
-SIZE (pfstmo-1.2.tar.gz) = 384037
+SHA256 (pfstmo-1.5.tar.gz) = 614599faecddb925cf51458f0d111f42bb624d91a9181181b63c81cbb9cc8ac9
+SIZE (pfstmo-1.5.tar.gz) = 461375
diff --git a/graphics/pfstmo/files/patch-configure b/graphics/pfstmo/files/patch-configure
new file mode 100644
index 000000000000..e7059cb99e24
--- /dev/null
+++ b/graphics/pfstmo/files/patch-configure
@@ -0,0 +1,11 @@
+--- configure.orig 2012-06-25 13:03:44.000000000 +0000
++++ configure 2014-06-18 15:31:54.008958029 +0000
+@@ -14272,7 +14272,7 @@
+
+
+
+-#CXXFLAGS="-O3 -funroll-loops -fstrength-reduce -fschedule-insns2 -felide-constructors -frerun-loop-opt -fexceptions -fno-strict-aliasing -fexpensive-optimizations -ffast-math -pipe"
++#CXXFLAGS="-O3 -funroll-loops -fstrength-reduce -felide-constructors -fexceptions -fno-strict-aliasing -fexpensive-optimizations -ffast-math -pipe"
+ enable_fftw3f="yes"
+
+
diff --git a/graphics/pfstmo/files/patch-src-durand02-fastbilateral.cpp b/graphics/pfstmo/files/patch-src-durand02-fastbilateral.cpp
new file mode 100644
index 000000000000..30dca26d81d3
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-durand02-fastbilateral.cpp
@@ -0,0 +1,27 @@
+--- src/durand02/fastbilateral.cpp.orig 2008-09-09 18:10:49.000000000 +0000
++++ src/durand02/fastbilateral.cpp 2014-06-18 15:29:52.288954426 +0000
+@@ -66,11 +66,11 @@
+ {
+ int ox = nx;
+ int oy = ny/2 + 1; // saves half of the data
+- const int osize = ox * oy;
+- source = (float*)fftwf_malloc(sizeof(float) * nx * 2 * (ny/2+1) );
++ const size_t osize = ox * oy;
++ source = (float*)fftwf_malloc(sizeof(float) * (size_t)nx * 2 * ((size_t)ny/2+1) );
+ freq = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * osize);
+-// if( source == NULL || freq == NULL )
+- //TODO: throw exception
++ if( source == NULL || freq == NULL )
++ throw std::bad_alloc();
+ fplan_fw = fftwf_plan_dft_r2c_2d(nx, ny, source, freq, FFTW_ESTIMATE);
+ fplan_in = fftwf_plan_dft_c2r_2d(nx, ny, freq, source, FFTW_ESTIMATE);
+ }
+@@ -100,7 +100,7 @@
+ for( x=0 ; x<ox/2 ; x++ )
+ for( y=0 ; y<oy ; y++ )
+ {
+- float d2 = x*x + y*y;
++ float d2 = (float)x*x + (float)y*y;
+ float kernel = exp( -d2 / sig2 );
+
+ freq[x*oy+y][0] *= kernel;
diff --git a/graphics/pfstmo/files/patch-src-fattal02-pde.cpp b/graphics/pfstmo/files/patch-src-fattal02-pde.cpp
new file mode 100644
index 000000000000..1e3e9e4b9526
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-fattal02-pde.cpp
@@ -0,0 +1,185 @@
+--- src/fattal02/pde.cpp.orig 2012-06-21 13:27:13.000000000 +0000
++++ src/fattal02/pde.cpp 2014-06-18 15:29:52.288954426 +0000
+@@ -70,15 +70,15 @@
+ // precision
+ #define EPS 1.0e-12
+
+-void linbcg(unsigned long n, float b[], float x[], int itol, float tol,
++static void linbcg(unsigned long n, float b[], float x[], int itol, float tol,
+ int itmax, int *iter, float *err);
+
+-inline float max( float a, float b )
++static inline float max( float a, float b )
+ {
+ return a > b ? a : b;
+ }
+
+-inline float min( float a, float b )
++static inline float min( float a, float b )
+ {
+ return a < b ? a : b;
+ }
+@@ -109,7 +109,7 @@
+ // Full Multigrid Algorithm for solving partial differential equations
+ //////////////////////////////////////////////////////////////////////
+
+-void restrict( const pfstmo::Array2D *in, pfstmo::Array2D *out )
++static void restrict( const pfstmo::Array2D *in, pfstmo::Array2D *out )
+ {
+ const float inRows = in->getRows();
+ const float inCols = in->getCols();
+@@ -172,7 +172,7 @@
+ // }
+
+
+-void prolongate( const pfstmo::Array2D *in, pfstmo::Array2D *out )
++static void prolongate( const pfstmo::Array2D *in, pfstmo::Array2D *out )
+ {
+ float dx = (float)in->getCols() / (float)out->getCols();
+ float dy = (float)in->getRows() / (float)out->getRows();
+@@ -216,7 +216,7 @@
+ }
+
+ // to_level<from_level, from_size<to_size
+-void prolongate_old( pfstmo::Array2D *F, pfstmo::Array2D *T )
++static void prolongate_old( pfstmo::Array2D *F, pfstmo::Array2D *T )
+ {
+ // DEBUG_STR << "prolongate" << endl;
+
+@@ -277,7 +277,7 @@
+ }
+ }
+
+-void exact_sollution( pfstmo::Array2D *F, pfstmo::Array2D *U )
++static void exact_sollution( pfstmo::Array2D *F, pfstmo::Array2D *U )
+ {
+ // DEBUG_STR << "exact sollution" << endl;
+
+@@ -314,13 +314,13 @@
+
+ static int rows, cols;
+
+-inline int idx( int r, int c )
++static inline int idx( int r, int c )
+ {
+ return r*cols+c+1;
+ }
+
+ // smooth u using f at level
+-void smooth( pfstmo::Array2D *U, pfstmo::Array2D *F )
++static void smooth( pfstmo::Array2D *U, pfstmo::Array2D *F )
+ {
+ // DEBUG_STR << "smooth" << endl;
+
+@@ -369,7 +369,7 @@
+ // }
+ }
+
+-void calculate_defect( pfstmo::Array2D *D, pfstmo::Array2D *U, pfstmo::Array2D *F )
++static void calculate_defect( pfstmo::Array2D *D, pfstmo::Array2D *U, pfstmo::Array2D *F )
+ {
+ // DEBUG_STR << "calculate defect" << endl;
+
+@@ -395,7 +395,7 @@
+
+ }
+
+-void add_correction( pfstmo::Array2D *U, pfstmo::Array2D *C )
++static void add_correction( pfstmo::Array2D *U, pfstmo::Array2D *C )
+ {
+ // DEBUG_STR << "add_correction" << endl;
+
+@@ -646,7 +646,7 @@
+
+ //#define EPS 1.0e-14
+
+-void asolve(unsigned long n, float b[], float x[], int itrnsp)
++static void asolve(float b[], float x[])
+ {
+ for( int r = 0; r < rows; r++ )
+ for( int c = 0; c < cols; c++ ) {
+@@ -654,7 +654,7 @@
+ }
+ }
+
+-void atimes(unsigned long n, float x[], float res[], int itrnsp)
++static void atimes(float x[], float res[])
+ {
+ for( int r = 1; r < rows-1; r++ )
+ for( int c = 1; c < cols-1; c++ ) {
+@@ -682,7 +682,7 @@
+ - 2*x[idx(rows-1,cols-1)];
+ }
+
+-float snrm(unsigned long n, float sx[], int itol)
++static float snrm(unsigned long n, float sx[], int itol)
+ {
+ unsigned long i,isamax;
+ float ans;
+@@ -704,7 +704,7 @@
+ * Biconjugate Gradient Method
+ * from Numerical Recipes in C
+ */
+-void linbcg(unsigned long n, float b[], float x[], int itol, float tol, int itmax, int *iter, float *err)
++static void linbcg(unsigned long n, float b[], float x[], int itol, float tol, int itmax, int *iter, float *err)
+ {
+ unsigned long j;
+ float ak,akden,bk,bkden,bknum,bnrm,dxnrm,xnrm,zm1nrm,znrm;
+@@ -718,30 +718,30 @@
+ zz=new float[n+1];
+
+ *iter=0;
+- atimes(n,x,r,0);
++ atimes(x,r);
+ for (j=1;j<=n;j++) {
+ r[j]=b[j]-r[j];
+ rr[j]=r[j];
+ }
+- atimes(n,r,rr,0); // minimum residual
++ atimes(r,rr); // minimum residual
+ znrm=1.0;
+ if (itol == 1) bnrm=snrm(n,b,itol);
+ else if (itol == 2) {
+- asolve(n,b,z,0);
++ asolve(b,z);
+ bnrm=snrm(n,z,itol);
+ }
+ else if (itol == 3 || itol == 4) {
+- asolve(n,b,z,0);
++ asolve(b,z);
+ bnrm=snrm(n,z,itol);
+- asolve(n,r,z,0);
++ asolve(r,z);
+ znrm=snrm(n,z,itol);
+ } else printf("illegal itol in linbcg");
+- asolve(n,r,z,0);
++ asolve(r,z);
+
+ while (*iter <= itmax) {
+ ++(*iter);
+ zm1nrm=znrm;
+- asolve(n,rr,zz,1);
++ asolve(rr,zz);
+ for (bknum=0.0,j=1;j<=n;j++) bknum += z[j]*rr[j];
+ if (*iter == 1) {
+ for (j=1;j<=n;j++) {
+@@ -757,16 +757,16 @@
+ }
+ }
+ bkden=bknum;
+- atimes(n,p,z,0);
++ atimes(p,z);
+ for (akden=0.0,j=1;j<=n;j++) akden += z[j]*pp[j];
+ ak=bknum/akden;
+- atimes(n,pp,zz,1);
++ atimes(pp,zz);
+ for (j=1;j<=n;j++) {
+ x[j] += ak*p[j];
+ r[j] -= ak*z[j];
+ rr[j] -= ak*zz[j];
+ }
+- asolve(n,r,z,0);
++ asolve(r,z);
+ if (itol == 1 || itol == 2) {
+ znrm=1.0;
+ *err=snrm(n,r,itol)/bnrm;
diff --git a/graphics/pfstmo/files/patch-src-fattal02-tmo_fattal02.cpp b/graphics/pfstmo/files/patch-src-fattal02-tmo_fattal02.cpp
new file mode 100644
index 000000000000..5a7f898beb7d
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-fattal02-tmo_fattal02.cpp
@@ -0,0 +1,10 @@
+--- src/fattal02/tmo_fattal02.cpp.orig 2012-06-22 10:59:15.000000000 +0000
++++ src/fattal02/tmo_fattal02.cpp 2014-06-18 15:29:52.298957047 +0000
+@@ -105,7 +105,6 @@
+ {
+ int width = I->getCols();
+ int height = I->getRows();
+- int size = width*height;
+ int x,y;
+
+ pfstmo::Array2D* T = new pfstmo::Array2D(width,height);
diff --git a/graphics/pfstmo/files/patch-src-mantiuk06-contrast_domain.cpp b/graphics/pfstmo/files/patch-src-mantiuk06-contrast_domain.cpp
index 72a69932b74c..2ab3c8ffa99a 100644
--- a/graphics/pfstmo/files/patch-src-mantiuk06-contrast_domain.cpp
+++ b/graphics/pfstmo/files/patch-src-mantiuk06-contrast_domain.cpp
@@ -1,16 +1,263 @@
---- src/mantiuk06/contrast_domain.cpp.orig 2008-03-12 09:20:28.000000000 +0000
-+++ src/mantiuk06/contrast_domain.cpp 2008-03-12 09:27:16.000000000 +0000
-@@ -58,6 +58,13 @@
- #define LOOKUP_W_TO_R 107
-
-
-+#if defined(__FreeBSD__)
-+static inline float exp10f(float x) {
-+ return powf(10.,x);
-+}
-+#endif
-+
-+
- static void contrast_equalization( pyramid_t *pp, const float contrastFactor );
-
- static void transform_to_luminance(pyramid_t* pyramid, float* const x, progress_callback progress_cb, const bool bcg);
+--- src/mantiuk06/contrast_domain.cpp.orig 2012-04-22 13:14:14.000000000 +0000
++++ src/mantiuk06/contrast_domain.cpp 2014-06-18 15:29:52.298957047 +0000
+@@ -74,8 +74,6 @@
+ static void matrix_copy(const int n, const float* const a, float* const b);
+ static void matrix_multiply_const(const int n, float* const a, const float val);
+ static void matrix_divide(const int n, const float* const a, float* const b);
+-static float* matrix_alloc(const int size);
+-static void matrix_free(float* m);
+ static float matrix_DotProduct(const int n, const float* const a, const float* const b);
+ static void matrix_zero(const int n, float* const m);
+ static void calculate_and_add_divergence(const int rows, const int cols, const float* const Gx, const float* const Gy, float* const divG);
+@@ -317,24 +315,6 @@
+ }
+
+
+-// alloc memory for the float table
+-static inline float* matrix_alloc(int size){
+-
+- float* m = (float*)malloc(sizeof(float)*size);
+- if(m == NULL){
+- fprintf(stderr, "ERROR: malloc in matrix_alloc() (size:%d)", size);
+- exit(155);
+- }
+-
+- return m;
+-}
+-
+-// free memory for matrix
+-static inline void matrix_free(float* m){
+- if(m != NULL)
+- free(m);
+-}
+-
+ // multiply vector by vector (each vector should have one dimension equal to 1)
+ static inline float matrix_DotProduct(const int n, const float* const a, const float* const b){
+ float val = 0;
+@@ -382,7 +362,7 @@
+ // temp is a temporary matrix of size (cols, rows), assumed to already be allocated
+ static void pyramid_calculate_divergence_sum(pyramid_t* pyramid, float* divG_sum)
+ {
+- float* temp = matrix_alloc(pyramid->rows*pyramid->cols);
++ float* temp = new float[pyramid->rows*pyramid->cols];
+
+ // Find the coarsest pyramid, and the number of pyramid levels
+ int levels = 1;
+@@ -426,7 +406,7 @@
+ pyramid = pyramid->prev;
+ }
+
+- matrix_free(temp);
++ delete[] temp;
+ }
+
+ // calculate scale factors (Cx,Cy) for gradients (Gx,Gy)
+@@ -495,20 +475,10 @@
+ {
+ while (pyramid)
+ {
+- if(pyramid->Gx != NULL)
+- {
+- free(pyramid->Gx);
+- pyramid->Gx = NULL;
+- }
+- if(pyramid->Gy != NULL)
+- {
+- free(pyramid->Gy);
+- pyramid->Gy = NULL;
+- }
++ delete[] pyramid->Gx;
++ delete[] pyramid->Gy;
+ pyramid_t* const next = pyramid->next;
+- pyramid->prev = NULL;
+- pyramid->next = NULL;
+- free(pyramid);
++ delete pyramid;
+ pyramid = next;
+ }
+ }
+@@ -523,19 +493,14 @@
+
+ while(rows >= PYRAMID_MIN_PIXELS && cols >= PYRAMID_MIN_PIXELS)
+ {
+- level = (pyramid_t *) malloc(sizeof(pyramid_t));
+- if(level == NULL)
+- {
+- fprintf(stderr, "ERROR: malloc in pyramid_alloc() (size:%d)", (int)sizeof(pyramid_t));
+- exit(155);
+- }
++ level = new pyramid_t;
+ memset( level, 0, sizeof(pyramid_t) );
+
+ level->rows = rows;
+ level->cols = cols;
+ const int size = level->rows * level->cols;
+- level->Gx = matrix_alloc(size);
+- level->Gy = matrix_alloc(size);
++ level->Gx = new float[size];
++ level->Gy = new float[size];
+
+ level->prev = prev;
+ if(prev != NULL)
+@@ -598,7 +563,7 @@
+ // lum_temp gets overwritten!
+ static void pyramid_calculate_gradient(pyramid_t* pyramid, float* lum_temp)
+ {
+- float* temp = matrix_alloc((pyramid->rows/2)*(pyramid->cols/2));
++ float* temp = new float[(pyramid->rows/2)*(pyramid->cols/2)];
+ float* const temp_saved = temp;
+
+ calculate_gradient(pyramid->cols, pyramid->rows, lum_temp, pyramid->Gx, pyramid->Gy);
+@@ -626,7 +591,7 @@
+ pyramid = pyramid->next;
+ }
+
+- matrix_free(temp_saved);
++ delete[] temp_saved;
+ }
+
+
+@@ -658,13 +623,13 @@
+ const int n = rows*cols;
+ const float tol2 = tol*tol;
+
+- float* const z = matrix_alloc(n);
+- float* const zz = matrix_alloc(n);
+- float* const p = matrix_alloc(n);
+- float* const pp = matrix_alloc(n);
+- float* const r = matrix_alloc(n);
+- float* const rr = matrix_alloc(n);
+- float* const x_save = matrix_alloc(n);
++ float* const z = new float[n];
++ float* const zz = new float[n];
++ float* const p = new float[n];
++ float* const pp = new float[n];
++ float* const r = new float[n];
++ float* const rr = new float[n];
++ float* const x_save = new float[n];
+
+ const float bnrm2 = matrix_DotProduct(n, b, b);
+
+@@ -799,13 +764,13 @@
+ progress_cb(100);
+
+
+- matrix_free(x_save);
+- matrix_free(p);
+- matrix_free(pp);
+- matrix_free(z);
+- matrix_free(zz);
+- matrix_free(r);
+- matrix_free(rr);
++ delete[] x_save;
++ delete[] p;
++ delete[] pp;
++ delete[] z;
++ delete[] zz;
++ delete[] r;
++ delete[] rr;
+ }
+
+
+@@ -818,10 +783,10 @@
+ const int n = rows*cols;
+ const float tol2 = tol*tol;
+
+- float* const x_save = matrix_alloc(n);
+- float* const r = matrix_alloc(n);
+- float* const p = matrix_alloc(n);
+- float* const Ap = matrix_alloc(n);
++ float* const x_save = new float[n];
++ float* const r = new float[n];
++ float* const p = new float[n];
++ float* const Ap = new float[n];
+
+ // bnrm2 = ||b||
+ const float bnrm2 = matrix_DotProduct(n, b, b);
+@@ -943,10 +908,10 @@
+ else if (progress_cb != NULL)
+ progress_cb(100);
+
+- matrix_free(x_save);
+- matrix_free(p);
+- matrix_free(Ap);
+- matrix_free(r);
++ delete[] x_save;
++ delete[] p;
++ delete[] Ap;
++ delete[] r;
+ }
+
+
+@@ -1070,7 +1035,7 @@
+ pyramid_calculate_scale_factor(pp, pC); // calculate (Cx,Cy)
+ pyramid_scale_gradient(pp, pC); // scale small gradients by (Cx,Cy);
+
+- float* b = matrix_alloc(pp->cols * pp->rows);
++ float* b = new float[pp->cols * pp->rows];
+ pyramid_calculate_divergence_sum(pp, b); // calculate the sum of divergences (equal to b)
+
+ // calculate luminances from gradients
+@@ -1079,7 +1044,7 @@
+ else
+ lincg(pp, pC, b, x, itmax, tol, progress_cb);
+
+- matrix_free(b);
++ delete[] b;
+ pyramid_free(pC);
+ }
+
+@@ -1121,12 +1086,7 @@
+ }
+
+ // Allocate memory
+- struct hist_data* hist = (struct hist_data*) malloc(sizeof(struct hist_data) * total_pixels);
+- if (hist == NULL)
+- {
+- fprintf(stderr, "ERROR: malloc in contrast_equalization() (size:%d)", (int)sizeof(struct hist_data) * total_pixels);
+- exit(155);
+- }
++ struct hist_data* hist = new hist_data[total_pixels];
+
+ // Build histogram info
+ l = pp;
+@@ -1175,7 +1135,7 @@
+ l = l->next;
+ }
+
+- free(hist);
++ delete[] hist;
+ }
+
+
+@@ -1211,10 +1171,10 @@
+ }
+
+ pyramid_t* pp = pyramid_allocate(c,r); // create pyramid
+- float* tY = matrix_alloc(n);
++ float* tY = new float[n];
+ matrix_copy(n, Y, tY); // copy Y to tY
+ pyramid_calculate_gradient(pp,tY); // calculate gradients for pyramid, destroys tY
+- matrix_free(tY);
++ delete[] tY;
+ pyramid_transform_to_R(pp); // transform gradients to R
+
+ /* Contrast map */
+@@ -1228,7 +1188,7 @@
+ pyramid_free(pp);
+
+ /* Renormalize luminance */
+- float* temp = matrix_alloc(n);
++ float* temp = new float[n];
+
+ matrix_copy(n, Y, temp); // copy Y to temp
+ qsort(temp, n, sizeof(float), sort_float); // sort temp in ascending order
+@@ -1244,7 +1204,7 @@
+ delta = trim - floorf(trim);
+ const float l_max = temp[(int)floorf(trim)] * delta + temp[(int)ceilf(trim)] * (1.0f-delta);
+
+- matrix_free(temp);
++ delete[] temp;
+
+ const float disp_dyn_range = 2.3f;
+ #pragma omp parallel for schedule(static)
diff --git a/graphics/pfstmo/files/patch-src-mantiuk06-pfstmo_mantiuk06.cpp b/graphics/pfstmo/files/patch-src-mantiuk06-pfstmo_mantiuk06.cpp
new file mode 100644
index 000000000000..3cd1ec7ee330
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-mantiuk06-pfstmo_mantiuk06.cpp
@@ -0,0 +1,17 @@
+--- src/mantiuk06/pfstmo_mantiuk06.cpp.orig 2009-09-02 01:11:39.000000000 +0000
++++ src/mantiuk06/pfstmo_mantiuk06.cpp 2014-06-18 15:29:52.298957047 +0000
+@@ -219,6 +219,14 @@
+ try {
+ tmo_mantiuk06( argc, argv );
+ }
++ catch (std::bad_alloc ex) {
++ fprintf(stderr, PROG_NAME " error: out of memory\n");
++ return EXIT_FAILURE;
++ }
++ catch (std::exception ex) {
++ fprintf(stderr, PROG_NAME " error: %s\n", ex.what());
++ return EXIT_FAILURE;
++ }
+ catch( pfs::Exception ex ) {
+ fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() );
+ return EXIT_FAILURE;
diff --git a/graphics/pfstmo/files/patch-src-mantiuk08-display_adaptive_tmo.cpp b/graphics/pfstmo/files/patch-src-mantiuk08-display_adaptive_tmo.cpp
new file mode 100644
index 000000000000..b3db9b0c018d
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-mantiuk08-display_adaptive_tmo.cpp
@@ -0,0 +1,20 @@
+--- src/mantiuk08/display_adaptive_tmo.cpp.orig 2012-06-25 13:03:28.000000000 +0000
++++ src/mantiuk08/display_adaptive_tmo.cpp 2014-06-18 15:29:52.308951834 +0000
+@@ -201,7 +201,7 @@
+
+ };
+
+-#define PFSEOL "\x0a"
++/*#define PFSEOL "\x0a"
+ static void dumpPFS( const char *fileName, const int width, const int height, float *data, const char *channelName )
+ {
+ FILE *fh = fopen( fileName, "wb" );
+@@ -216,7 +216,7 @@
+ }
+
+ fclose( fh );
+-}
++}*/
+
+
+ void compute_gaussian_level( const int width, const int height, const pfstmo::Array2D& in, pfstmo::Array2D& out, int level, pfstmo::Array2D& temp )
diff --git a/graphics/pfstmo/files/patch-src-mantiuk08-pfstmo_mantiuk08.cpp b/graphics/pfstmo/files/patch-src-mantiuk08-pfstmo_mantiuk08.cpp
new file mode 100644
index 000000000000..1b21e64f98e6
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-mantiuk08-pfstmo_mantiuk08.cpp
@@ -0,0 +1,25 @@
+--- src/mantiuk08/pfstmo_mantiuk08.cpp.orig 2012-06-25 13:03:28.000000000 +0000
++++ src/mantiuk08/pfstmo_mantiuk08.cpp 2014-06-18 15:29:52.308951834 +0000
+@@ -31,7 +31,6 @@
+
+ #include <config.h>
+
+-#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
+@@ -356,6 +355,14 @@
+ try {
+ tmo_mantiuk08( argc, argv );
+ }
++ catch (std::bad_alloc ex) {
++ fprintf(stderr, PROG_NAME " error: out of memory\n");
++ return EXIT_FAILURE;
++ }
++ catch (std::exception ex) {
++ fprintf(stderr, PROG_NAME " error: %s\n", ex.what());
++ return EXIT_FAILURE;
++ }
+ catch( pfs::Exception ex ) {
+ fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() );
+ return EXIT_FAILURE;
diff --git a/graphics/pfstmo/files/patch-src-reinhard02-approx.cpp b/graphics/pfstmo/files/patch-src-reinhard02-approx.cpp
new file mode 100644
index 000000000000..f663d6f87fbe
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard02-approx.cpp
@@ -0,0 +1,223 @@
+--- src/reinhard02/approx.cpp.orig 2007-06-14 16:41:30.000000000 +0000
++++ src/reinhard02/approx.cpp 2014-06-18 15:29:52.308951834 +0000
+@@ -17,36 +17,36 @@
+ #include <stdio.h>
+ #include <math.h>
+
++#include <pfstmo.h>
++
+ // interpolated version of approximation (always use this one!) (:krawczyk)
+ #define INTERPOLATED
+
+-extern double **luminance;
+-int ImageWidth, ImageHeight;
++extern pfstmo::Array2D *lum;
++extern int width, height;
+
+-double ***Pyramid;
+-int PyramidHeight;
+-int PyramidWidth0;
++int PyramidHeight;
+
+-void build_pyramid( double **luminance, int ImageWidth, int ImageHeight );
+-double V1( int x, int y, int level );
++static float ***Pyramid;
++static int PyramidWidth0;
+
+-int div2( const unsigned int n )
++static int div2( const unsigned int n )
+ {
+ const int q = n/2;
+ return(2*q < n ? q + 1 : q);
+ }
+
+-double pyramid_lookup( int x, int y, int level )
++static float pyramid_lookup( int x, int y, int level )
+ /* PRE: */
+ {
+ int n, s;
+
+ /* Level 0 is a special case, the value is just the image */
+ if (level == 0) {
+- if ( (x < 0) || (y < 0) || (x >= ImageWidth) || (y >= ImageHeight) )
++ if ( (x < 0) || (y < 0) || (x >= width) || (y >= height) )
+ return(0.0);
+ else
+- return(luminance[y][x]);
++ return((*lum)(x,y));
+ }
+
+ /* Compute the size of the slice */
+@@ -58,25 +58,24 @@
+ //y = y >> level;
+
+ if ( (x < 0) || (y < 0) || (x >= s) || (y >= s) )
+- return(0.0);
++ return(0.0f);
+ else
+ return(Pyramid[level][y][x]);
+ }
+
+-void build_pyramid( double **luminance, int image_width, int image_height )
++void build_pyramid()
+ {
+ int k;
+ int x, y;
+ int i, j;
+- int width, height;
+ int max_dim;
+- int pyramid_height;
+- double sum = 0;
++ int pyramid_width;
++ double sum = 0.f;
+
+- double a = 0.4;
+- double b = 0.25;
+- double c = b - a/2;
+- double w[5];
++ float a = 0.4f;
++ float b = 0.25f;
++ float c = b - a/2.f;
++ float w[5];
+
+ /* Compute the "filter kernel" */
+ w[0] = c;
+@@ -90,50 +89,35 @@
+ /* For simplicity, the first level is padded to a square whose side is a */
+ /* power of two. */
+
+- ImageWidth = image_width;
+- ImageHeight = image_height;
+-
+ /* Compute the size of the Pyramid array */
+- max_dim = (ImageHeight > ImageWidth ? ImageHeight : ImageWidth);
+- PyramidHeight = (int) floor(log(max_dim - 0.5)/log(2)) + 1;
++ max_dim = (height > width ? height : width);
++ PyramidHeight = (int)floorf(logf(max_dim - 0.5f)/logf(2)) + 1;
+
+ /* Compute the dimensions of the first level */
+- width = 1 << (PyramidHeight - 1);
+- PyramidWidth0 = width;
++ pyramid_width = 1 << (PyramidHeight - 1);
++ PyramidWidth0 = pyramid_width;
+
+ // fprintf(stderr, "max_dim %d height %d\n", max_dim, PyramidHeight);
+
+ /* Allocate the outer Pyramid array */
+- Pyramid = (double***) calloc(PyramidHeight, sizeof(double**));
+- if (!Pyramid) {
+- fprintf(stderr, "Unable to allocate pyramid array.\n");
+- exit(1);
+- }
++ Pyramid = new float**[PyramidHeight];
+
+ /* Allocate and assign the Pyramid slices */
+ k = 0;
+
+- while (width) {
++ while (pyramid_width) {
+
+ // fprintf(stderr, "level %d, width = %d\n", k, width);
+
+ /* Allocate the slice */
+- Pyramid[k] = (double**) calloc(width, sizeof(double*));
+- if (!Pyramid[k]) {
+- fprintf(stderr, "Unable to allocate pyramid array.\n");
+- exit(1);
+- }
+- for (y = 0; y < width; y++) {
+- Pyramid[k][y] = (double*) calloc(width, sizeof(double));
+- if (!Pyramid[k][y]) {
+- fprintf(stderr, "Unable to allocate pyramid array.\n");
+- exit(1);
+- }
++ Pyramid[k] = new float*[pyramid_width];
++ for (y = 0; y < pyramid_width; y++) {
++ Pyramid[k][y] = new float[pyramid_width];
+ }
+
+ /* Compute the values in the slice */
+- for (y = 0; y < width; y++) {
+- for (x = 0; x < width; x++) {
++ for (y = 0; y < pyramid_width; y++) {
++ for (x = 0; x < pyramid_width; x++) {
+
+ sum = 0;
+ for (i = 0; i < 5; i++) {
+@@ -146,7 +130,7 @@
+ }
+
+ /* compute the width of the next slice */
+- width /= 2;
++ pyramid_width /= 2;
+ k++;
+ }
+ }
+@@ -154,27 +138,27 @@
+ void clean_pyramid()
+ {
+ int k=0;
+- int width = PyramidWidth0;
+- while(width)
++ int pyramid_width = PyramidWidth0;
++ while(pyramid_width)
+ {
+- for( int y=0 ; y<width ; y++ )
+- free(Pyramid[k][y]);
+- free(Pyramid[k]);
++ for( int y=0 ; y<pyramid_width ; y++ )
++ delete[] Pyramid[k][y];
++ delete[] Pyramid[k];
+ k++;
+- width /= 2;
++ pyramid_width /= 2;
+ }
+- free(Pyramid);
++ delete[] Pyramid;
+ }
+
+ #ifndef INTERPOLATED
+-double V1( int x, int y, int level )
++float V1( int x, int y, int level )
+ /* PRE: */
+ {
+ int n, s;
+
+ /* Level 0 is a special case, the value is just the image */
+ if (level <= 0)
+- return(luminance[y][x]);
++ return((*lum)(x,y));
+
+ /* Compute the size of the slice */
+
+@@ -184,16 +168,16 @@
+ return(Pyramid[level-1][y][x]);
+ }
+ #else
+-double V1( int x, int y, int level )
++float V1( int x, int y, int level )
+ /* PRE: */
+ {
+ int x0, y0;
+ int l, size;
+- double s, t;
++ float s, t;
+
+ /* Level 0 is a special case, the value is just the image */
+ if (level == 0)
+- return(luminance[y][x]);
++ return((*lum)(x,y));
+
+ /* Compute the size of the slice */
+ l = 1 << level;
+@@ -204,8 +188,8 @@
+ x0 = (x0 >= size ? size - 1 : x0);
+ y0 = (y0 >= size ? size - 1 : y0);
+
+- s = (double)(x - x0*l)/(double)l;
+- t = (double)(y - y0*l)/(double)l;
++ s = (float)(x - x0*l)/(float)l;
++ t = (float)(y - y0*l)/(float)l;
+
+ level--;
+
diff --git a/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.1 b/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.1
new file mode 100644
index 000000000000..bf9f1f4315e6
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.1
@@ -0,0 +1,63 @@
+--- src/reinhard02/pfstmo_reinhard02.1.orig 2007-06-14 16:41:30.000000000 +0000
++++ src/reinhard02/pfstmo_reinhard02.1 2014-06-18 15:29:52.318951701 +0000
+@@ -6,6 +6,7 @@
+ [--scales] [--key <val>] [--phi <val>]
+ [--range <val>] [--lower <val>] [--upper <val>]
+ [--temporal-coherent]
++[--border <val>]
+ [--verbose] [--help]
+ .SH DESCRIPTION
+ This command implements a tone mapping operator as described in:
+@@ -17,32 +18,32 @@
+ According to the paper, results of this TMO require gamma correction.
+ .SH OPTIONS
+ .TP
+-[--scales]
++[--scales] [-s]
+
+ Use scales to calculate local adaptation. That means: use local
+ version of this operator. By default, global version is used.
+ .TP
+-[--key <val>]
++[--key <val>] [-k <val>]
+
+ Set key value for the image (refer to paper for details).
+ Default value: 0.18, accepted range <0..1>.
+ .TP
+-[--phi <val>]
++[--phi <val>] [-p <val>]
+
+ Set phi value (refer to paper for details).
+ Default value: 1.0, accepted range >=0.0.
+ .TP
+-[--range <val>]
++[--range <val>] [-r <val>]
+
+ Set range size (refer to paper for details).
+ Default value: 8, accepted range >1.
+ .TP
+-[--lower <val>]
++[--lower <val>] [-l <val>]
+
+ Set lower scale size (refer to paper for details).
+ Default value: 1, accepted range >=1.
+ .TP
+-[--upper <val>]
++[--upper <val>] [-u <val>]
+
+ Set upper scale size (refer to paper for details).
+ Default value: 43, accepted range >=1.
+@@ -54,6 +55,13 @@
+ luminance value can change at most by 1% between two consecutive
+ frames.
+ .TP
++[--border <val>] [-b <val>]
++
++Use border mechanism with specified relative border width.
++Actual border size will be calculated as the minimal size of the image
++(width or height) multiplied on relative border width.
++Default value: 0 (don't use border mechanism), accepted range: 0 >= b < 0.5.
++.TP
+ --verbose
+
+ Print additional information during program execution.
diff --git a/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.cpp b/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.cpp
new file mode 100644
index 000000000000..43cdd316edc7
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard02-pfstmo_reinhard02.cpp
@@ -0,0 +1,142 @@
+--- src/reinhard02/pfstmo_reinhard02.cpp.orig 2008-09-04 12:46:49.000000000 +0000
++++ src/reinhard02/pfstmo_reinhard02.cpp 2014-06-18 15:29:52.318951701 +0000
+@@ -33,6 +33,7 @@
+
+ #include <config.h>
+
++#include <exception>
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -40,8 +41,9 @@
+ #include <math.h>
+
+ #include <pfs.h>
++#include <pfstmo.h>
+
+-#include <tmo_reinhard02.h>
++#include "tmo_reinhard02.h"
+
+ using namespace std;
+
+@@ -61,6 +63,7 @@
+ "\t[--key <val>] [--phi <val>] \n"
+ "\t[--range <val>] [--lower <val>] [--upper <val>] \n"
+ "\t[--temporal-coherent]\n"
++ "\t[--border <val>] \n"
+ "\t[--verbose] [--help] \n"
+ "See man page for more information.\n" );
+ }
+@@ -77,6 +80,7 @@
+ int high = 43;
+ bool use_scales = false;
+ bool temporal_coherent = false;
++ float border = 0.f;
+
+ static struct option cmdLineOptions[] = {
+ { "help", no_argument, NULL, 'h' },
+@@ -88,12 +92,13 @@
+ { "lower", required_argument, NULL, 'l' },
+ { "upper", required_argument, NULL, 'u' },
+ { "temporal-coherent", no_argument, NULL, 't' },
++ { "border", required_argument, NULL, 'b' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ int optionIndex = 0;
+ while( 1 ) {
+- int c = getopt_long (argc, argv, "hvsk:p:r:l:u:t", cmdLineOptions, &optionIndex);
++ int c = getopt_long (argc, argv, "hvsk:p:r:l:u:tb:", cmdLineOptions, &optionIndex);
+ if( c == -1 ) break;
+ switch( c ) {
+ case 'h':
+@@ -133,6 +138,11 @@
+ case 't':
+ temporal_coherent = true;
+ break;
++ case 'b':
++ border = (float)strtod( optarg, NULL );
++ if( border<0.0f || border>=0.5f )
++ throw pfs::Exception("border width value out of range, should be >=0 and <0.5");
++ break;
+ case '?':
+ throw QuietException();
+ case ':':
+@@ -140,17 +150,23 @@
+ }
+ }
+
+- VERBOSE_STR << "use scales: " << (use_scales ? "yes" : "no" ) << endl;
+ VERBOSE_STR << "key value: " << key << endl;
+- VERBOSE_STR << "phi value: " << phi << endl;
++ VERBOSE_STR << "use scales: " << (use_scales ? "yes" : "no" ) << endl;
+ if( use_scales )
+ {
+- VERBOSE_STR << "number of scales: " << num << endl;
+- VERBOSE_STR << "lower scale size: " << low << endl;
+- VERBOSE_STR << "upper scale size: " << high << endl;
+ #ifndef HAVE_ZFFT
+ VERBOSE_STR << "approximate implementation of scales" << endl;
+ #endif
++ VERBOSE_STR << "number of scales: " << num << endl;
++ VERBOSE_STR << "lower scale size: " << low << endl;
++ VERBOSE_STR << "upper scale size: " << high << endl;
++ VERBOSE_STR << "phi value: " << phi << endl;
++ }
++ VERBOSE_STR << "temporal coherent: " << (temporal_coherent ? "yes" : "no" ) << endl;
++ VERBOSE_STR << "use border: " << (border>0.f ? "yes" : "no" ) << endl;
++ if( border>0.f )
++ {
++ VERBOSE_STR << "border width: " << border << endl;
+ }
+
+ while( true )
+@@ -169,21 +185,19 @@
+ // tone mapping
+ int w = Y->getCols();
+ int h = Y->getRows();
+- pfs::Array2DImpl* L = new pfs::Array2DImpl(w,h);
+-
+- tmo_reinhard02( w, h, Y->getRawData(), L->getRawData(), use_scales, key, phi, num, low, high, temporal_coherent );
++ const pfstmo::Array2D ay(w, h, const_cast<float*>(Y->getRawData()));
++ pfstmo::Array2D al(w,h);
++ tmo_reinhard02( &ay, &al, use_scales, key, phi, num, low, high, temporal_coherent, border );
+
+ for( int x=0 ; x<w ; x++ )
+ for( int y=0 ; y<h ; y++ )
+ {
+- float scale = (*L)(x,y) / (*Y)(x,y);
++ float scale = al(x,y) / ay(x,y);
+ (*Y)(x,y) *= scale;
+ (*X)(x,y) *= scale;
+ (*Z)(x,y) *= scale;
+ }
+
+- delete L;
+-
+ //---
+ pfsio.writeFrame( frame, stdout );
+ pfsio.freeFrame( frame );
+@@ -195,11 +209,19 @@
+ try {
+ pfstmo_reinhard02( argc, argv );
+ }
+- catch( pfs::Exception ex ) {
+- fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() );
++ catch (std::bad_alloc ex) {
++ fprintf(stderr, PROG_NAME " error: out of memory\n");
++ return EXIT_FAILURE;
++ }
++ catch (std::exception ex) {
++ fprintf(stderr, PROG_NAME " error: %s\n", ex.what());
++ return EXIT_FAILURE;
++ }
++ catch (pfs::Exception ex) {
++ fprintf(stderr, PROG_NAME " error: %s\n", ex.getMessage());
+ return EXIT_FAILURE;
+ }
+- catch( QuietException ex ) {
++ catch (QuietException ex) {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
diff --git a/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.cpp b/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.cpp
new file mode 100644
index 000000000000..67e62bb9ad6d
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.cpp
@@ -0,0 +1,726 @@
+--- src/reinhard02/tmo_reinhard02.cpp.orig 2009-04-15 11:49:32.000000000 +0000
++++ src/reinhard02/tmo_reinhard02.cpp 2014-06-18 15:29:52.328951402 +0000
+@@ -17,11 +17,12 @@
+
+ #include <config.h>
+
++#include <memory>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <math.h>
+
+-#include "pfstmo.h"
++#include <pfstmo.h>
+
+ #ifdef HAVE_ZFFT
+ #include <fft.h>
+@@ -30,53 +31,44 @@
+ #define APPROXIMATE
+ #endif
+
+-//--- from defines.h
+-typedef struct {
+- int xmax, ymax; /* image dimensions */
+-} CVTS;
+
+-typedef double COLOR[3]; /* red, green, blue (or X,Y,Z) */
+-//--- end of defines.h
+-
+-
+-static int width, height, scale;
+-static COLOR **image;
+-static double ***convolved_image;
+-static double sigma_0, sigma_1;
+-double **luminance;
+-
+-static double k = 1. / (2. * 1.4142136);
+-static double key = 0.18;
+-static double threshold = 0.05;
+-static double phi = 8.;
+-static double white = 1e20;
+-static int scale_low = 1;
+-static int scale_high = 43; // 1.6^8 = 43
+-static int range = 8;
+-static int use_scales = 0;
+-static int use_border = 0;
+-static CVTS cvts = {0, 0};
++static int scale;
++static float sigma_0, sigma_1;
++static pfstmo::Array2D *img = 0;
++pfstmo::Array2D *lum = 0;
++int width, height;
++
++static float k = 1.f / (2.f * 1.4142136f);
++static float key = 0.18f;
++static float threshold = 0.05f;
++static float phi = 8.f;
++static float white = 1e20f;
++static int scale_low = 1;
++static int scale_high = 43; // 1.6^8 = 43
++static int range = 8;
++static int use_scales = 0;
++static float border = 0.f;
+
+ static bool temporal_coherent;
+
+ #ifdef APPROXIMATE
+ extern int PyramidHeight; // set by build_pyramid, defines actual pyramid size
+-extern double V1 (int x, int y, int level);
+-extern void build_pyramid (double **luminance, int image_width, int image_height);
+-extern void clean_pyramid ();
++extern float V1(int x, int y, int level);
++extern void build_pyramid();
++extern void clean_pyramid();
+ #else
+-
++static double ***convolved_image;
+ static zomplex **filter_fft;
+ static zomplex *image_fft, *coeff;
+
+-#define V1(x,y,i) (convolved_image[i][x][y])
++#define V1(x,y,i) ((float)convolved_image[i][x][y])
+
+ #endif
+
+-#define SIGMA_I(i) (sigma_0 + ((double)i/(double)range)*(sigma_1 - sigma_0))
+-#define S_I(i) (exp (SIGMA_I(i)))
+-#define V2(x,y,i) (V1(x,y,i+1))
+-#define ACTIVITY(x,y,i) ((V1(x,y,i) - V2(x,y,i)) / (((key * pow (2., phi))/(S_I(i)*S_I(i))) + V1(x,y,i)))
++#define SIGMA_I(i) (sigma_0 + ((float)i/(float)range)*(sigma_1 - sigma_0))
++#define S_I(i) (expf(SIGMA_I(i)))
++#define V2(x,y,i) (V1(x,y,i+1))
++#define ACTIVITY(x,y,i) ((V1(x,y,i) - V2(x,y,i)) / (((key * powf(2.f, phi))/(S_I(i)*S_I(i))) + V1(x,y,i)))
+
+
+
+@@ -119,32 +111,32 @@
+ };
+
+
+-static TemporalSmoothVariable<double> avg_luminance, max_luminance;
++static TemporalSmoothVariable<float> avg_luminance, max_luminance;
+
+
+ /*
+ * Kaiser-Bessel stuff
+ */
+
+-static double alpha = 2.; /* Kaiser-Bessel window parameter */
+-static double bbeta; /* Will contain bessel (PI * alpha) */
++static float alpha = 2.f; /* Kaiser-Bessel window parameter */
++static float bbeta; /* Will contain bessel (PI * alpha) */
+
+ /*
+ * Modified zeroeth order bessel function of the first kind
+ */
+
+-double bessel (double x)
++static float bessel (float x)
+ {
+- const double f = 1e-9;
++ const float f = 1e-9f;
+ int n = 1;
+- double s = 1.;
+- double d = 1.;
++ float s = 1.f;
++ float d = 1.f;
+
+- double t;
++ float t;
+
+ while (d > f * s)
+ {
+- t = x / (2. * n);
++ t = x / (2.f * n);
+ n++;
+ d *= t * t;
+ s += d;
+@@ -156,7 +148,7 @@
+ * Initialiser for Kaiser-Bessel computations
+ */
+
+-void compute_bessel ()
++static void compute_bessel ()
+ {
+ bbeta = bessel (M_PI * alpha);
+ }
+@@ -166,12 +158,12 @@
+ * Window length M = min (width, height) / 2
+ */
+
+-double kaiserbessel (double x, double y, double M)
++static float kaiserbessel (float x, float y, float M)
+ {
+- double d = 1. - ((x*x + y*y) / (M * M));
+- if (d <= 0.)
+- return 0.;
+- return bessel (M_PI * alpha * sqrt (d)) / bbeta;
++ float d = 1.f - ((x*x + y*y) / (M * M));
++ if (d <= 0.f)
++ return 0.f;
++ return bessel(M_PI * alpha * sqrtf(d)) / bbeta;
+ }
+
+
+@@ -180,57 +172,57 @@
+ */
+ #ifdef HAVE_ZFFT
+
+-void initialise_fft (int width, int height)
++static void initialise_fft (int width, int height)
+ {
+ coeff = zfft2di (width, height, NULL);
+ }
+
+-void compute_fft (zomplex *array, int width, int height)
++static void compute_fft (zomplex *array, int width, int height)
+ {
+ zfft2d (-1, width, height, array, width, coeff);
+ }
+
+-void compute_inverse_fft (zomplex *array, int width, int height)
++static void compute_inverse_fft (zomplex *array, int width, int height)
+ {
+ zfft2d (1, width, height, array, width, coeff);
+ }
+
+
+ // Compute Gaussian blurred images
+-void gaussian_filter (zomplex *filter, double scale, double k )
++static void gaussian_filter (zomplex *filter, double scale, double k )
+ {
+ int x, y;
+ double x1, y1, s;
+ double a = 1. / (k * scale);
+ double c = 1. / 4.;
+
+- for (y = 0; y < cvts.ymax; y++)
++ for (y = 0; y < height; y++)
+ {
+- y1 = (y >= cvts.ymax / 2) ? y - cvts.ymax : y;
++ y1 = (y >= height / 2) ? y - height : y;
+ s = erf (a * (y1 - .5)) - erf (a * (y1 + .5));
+- for (x = 0; x < cvts.xmax; x++)
++ for (x = 0; x < width; x++)
+ {
+- x1 = (x >= cvts.xmax / 2) ? x - cvts.xmax : x;
+- filter[y*cvts.xmax + x].re = s * (erf (a * (x1 - .5)) - erf (a * (x1 + .5))) * c;
+- filter[y*cvts.xmax + x].im = 0.;
++ x1 = (x >= width / 2) ? x - width : x;
++ filter[y*width + x].re = s * (erf (a * (x1 - .5)) - erf (a * (x1 + .5))) * c;
++ filter[y*width + x].im = 0.;
+ }
+ }
+ }
+
+-void build_gaussian_fft ()
++static void build_gaussian_fft ()
+ {
+- int i;
+- double length = cvts.xmax * cvts.ymax;
+- double fft_scale = 1. / sqrt (length);
+- filter_fft = (zomplex**) calloc (range, sizeof (zomplex*));
++ int i;
++ int length = width * height;
++ double fft_scale = 1. / sqrt((double)length);
++ filter_fft = new zomplex*[range];
+
+ for (scale = 0; scale < range; scale++)
+ {
+ fprintf (stderr, "Computing FFT of Gaussian at scale %i (size %i x %i)%c",
+- scale, cvts.xmax, cvts.ymax, (char)13);
+- filter_fft[scale] = (zomplex*) calloc (length, sizeof (zomplex));
++ scale, width, height, (char)13);
++ filter_fft[scale] = new zomplex[length];
+ gaussian_filter (filter_fft[scale], S_I(scale), k);
+- compute_fft (filter_fft[scale], cvts.xmax, cvts.ymax);
++ compute_fft (filter_fft[scale], width, height);
+ for (i = 0; i < length; i++)
+ {
+ filter_fft[scale][i].re *= fft_scale;
+@@ -240,20 +232,20 @@
+ fprintf (stderr, "\n");
+ }
+
+-void build_image_fft ()
++static void build_image_fft ()
+ {
+- int i, x, y;
+- double length = cvts.xmax * cvts.ymax;
+- double fft_scale = 1. / sqrt (length);
++ int i, x, y;
++ int length = width * height;
++ double fft_scale = 1. / sqrt((double)length);
+
+ fprintf (stderr, "Computing image FFT\n");
+- image_fft = (zomplex*) calloc (length, sizeof (zomplex));
++ image_fft = new zomplex[length];
+
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
+- image_fft[y*cvts.xmax + x].re = luminance[y][x];
++ for (y = 0; y < height; y++)
++ for (x = 0; x < width; x++)
++ image_fft[y*width + x].re = (*lum)(x,y);
+
+- compute_fft (image_fft, cvts.xmax, cvts.ymax);
++ compute_fft (image_fft, width, height);
+ for (i = 0; i < length; i++)
+ {
+ image_fft[i].re *= fft_scale;
+@@ -261,47 +253,61 @@
+ }
+ }
+
+-void convolve_filter (int scale, zomplex *convolution_fft)
++static void convolve_filter (int scale, zomplex *convolution_fft)
+ {
+ int i, x, y;
+
+- for (i = 0; i < cvts.xmax * cvts.ymax; i++)
++ for (i = 0; i < width * height; i++)
+ {
+ convolution_fft[i].re = image_fft[i].re * filter_fft[scale][i].re -
+ image_fft[i].im * filter_fft[scale][i].im;
+ convolution_fft[i].im = image_fft[i].re * filter_fft[scale][i].im +
+ image_fft[i].im * filter_fft[scale][i].re;
+ }
+- compute_inverse_fft (convolution_fft, cvts.xmax, cvts.ymax);
++ compute_inverse_fft (convolution_fft, width, height);
+ i = 0;
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
++ for (y = 0; y < height; y++)
++ for (x = 0; x < width; x++)
+ convolved_image[scale][x][y] = convolution_fft[i++].re;
+ }
+
+-void compute_fourier_convolution ()
++static void compute_fourier_convolution ()
+ {
+ int x;
+ zomplex *convolution_fft;
+
+- initialise_fft (cvts.xmax, cvts.ymax);
++ initialise_fft (width, height);
+ build_image_fft ();
+ build_gaussian_fft ();
+- convolved_image = (double ***) malloc (range * sizeof (double **));
++ convolved_image = new double**[range];
+
+- convolution_fft = (zomplex *) calloc (cvts.xmax * cvts.ymax, sizeof (zomplex));
++ convolution_fft = new zomplex[width * height];
+ for (scale = 0; scale < range; scale++)
+ {
+ fprintf (stderr, "Computing convolved image at scale %i%c", scale, (char)13);
+- convolved_image[scale] = (double **) malloc (cvts.xmax * sizeof (double *));
+- for (x = 0; x < cvts.xmax; x++)
+- convolved_image[scale][x] = (double *) malloc (cvts.ymax * sizeof (double));
++ convolved_image[scale] = new double*[width];
++ for (x = 0; x < width; x++)
++ convolved_image[scale][x] = new double[height];
+ convolve_filter (scale, convolution_fft);
+- free (filter_fft[scale]);
++ delete[] filter_fft[scale];
+ }
++ delete[] filter_fft;
+ fprintf (stderr, "\n");
+- free (convolution_fft);
+- free (image_fft);
++ delete[] convolution_fft;
++ delete[] image_fft;
++}
++
++static void clean_convolved_image()
++{
++ for (scale = 0; scale < range; scale++)
++ {
++ for (x = 0; x < width; x++)
++ {
++ delete[] convolved_image[scale][x];
++ }
++ delete[] convolved_image[scale];
++ }
++ delete[] convolved_image;
+ }
+
+ #endif // #ifdef HAVE_ZFFT
+@@ -312,188 +318,141 @@
+ * Tonemapping routines
+ */
+
+-double get_maxvalue ()
++static void tonemap()
+ {
+- double max = 0.;
+- int x, y;
+-
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
+- max = (max < image[y][x][0]) ? image[y][x][0] : max;
+- return max;
+-}
+-
+-void tonemap_image ()
+-{
+- double Lmax2;
+- int x, y;
+- int scale, prefscale;
+-
+- if (white < 1e20)
+- Lmax2 = white * white;
+- else
++ for (int y = 0; y<height; y++)
+ {
+- if( temporal_coherent ) {
+- max_luminance.set( get_maxvalue() );
+- Lmax2 = max_luminance.get();
+- } else Lmax2 = get_maxvalue();
+- Lmax2 *= Lmax2;
+- }
+-
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
++ for (int x = 0; x<width; x++)
+ {
+- if (use_scales)
++ int prefscale = range-1;
++ for (int scale = 0; scale<range-1; scale++)
+ {
+- prefscale = range - 1;
+- for (scale = 0; scale < range - 1; scale++)
+- if ( scale >= PyramidHeight || fabs (ACTIVITY(x,y,scale)) > threshold)
++ if (scale>=PyramidHeight || fabsf(ACTIVITY(x,y,scale))>threshold)
+ {
+ prefscale = scale;
+ break;
+ }
+- image[y][x][0] /= 1. + V1(x,y,prefscale);
+ }
+- else
+- image[y][x][0] = image[y][x][0] * (1. + (image[y][x][0] / Lmax2)) / (1. + image[y][x][0]);
+- // image[y][x][0] /= (1. + image[y][x][0]);
++ (*img)(x,y) = (*lum)(x,y)/(1.f+V1(x,y,prefscale));
+ }
++ }
+ }
+
+-/*
+- * Miscellaneous functions
+- */
+-
+-void clamp_image ()
++static float get_maxvalue()
+ {
+- int x, y;
+-
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
+- {
+- image[y][x][0] = (image[y][x][0] > 1.) ? 1. : image[y][x][0];
+- image[y][x][1] = (image[y][x][1] > 1.) ? 1. : image[y][x][1];
+- image[y][x][2] = (image[y][x][2] > 1.) ? 1. : image[y][x][2];
+- }
++ float max = 0.f;
++ int x, y;
++ for (int i = width*height; i--; )
++ {
++ float l = (*img)(i);
++ if (max<l) max = l;
++ }
++ return max;
+ }
+
+-double log_average ()
++static void tonecompress()
+ {
+- int x, y;
+- double sum = 0.;
+-
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
+- sum += log (0.00001 + luminance[y][x]);
+- return exp (sum / (double)(cvts.xmax * cvts.ymax));
+-}
+-
+-void scale_to_midtone ()
+-{
+- int x, y, u, v, d;
+- double factor;
+- double scale_factor;
+- double low_tone = key / 3.;
+- int border_size = (cvts.xmax < cvts.ymax) ? int(cvts.xmax / 5.) : int(cvts.ymax / 5.);
+- int hw = cvts.xmax >> 1;
+- int hh = cvts.ymax >> 1;
+-
+- double avg;
+- if( temporal_coherent ) {
+- avg_luminance.set( log_average() );
+- avg = avg_luminance.get();
+- } else avg = log_average();
+-
+- scale_factor = 1.0 / avg;
+- for (y = 0; y < cvts.ymax; y++)
+- for (x = 0; x < cvts.xmax; x++)
++ float Lmax2;
++ if (white<1e20f)
++ {
++ Lmax2 = white;
++ }
++ else
++ {
++ if (temporal_coherent)
+ {
+- if (use_border)
+- {
+- u = (x > hw) ? cvts.xmax - x : x;
+- v = (y > hh) ? cvts.ymax - y : y;
+- d = (u < v) ? u : v;
+- factor = (d < border_size) ? (key - low_tone) *
+- kaiserbessel (border_size - d, 0, border_size) +
+- low_tone : key;
+- }
+- else
+- factor = key;
+- image[y][x][0] *= scale_factor * factor;
+- luminance[y][x] *= scale_factor * factor;
++ max_luminance.set(get_maxvalue());
++ Lmax2 = max_luminance.get();
+ }
+-}
+-
+-void copy_luminance ()
+-{
+- int x, y;
+-
+- for (x = 0; x < cvts.xmax; x++)
+- for (y = 0; y < cvts.ymax; y++)
+- luminance[y][x] = image[y][x][0];
++ else
++ {
++ Lmax2 = get_maxvalue();
++ }
++ }
++ Lmax2 *= Lmax2;
++ for (int i = width*height; i--; )
++ {
++ (*img)(i) = (*lum)(i)*(1.f+(*lum)(i)/Lmax2)/(1.f+(*lum)(i));
++ }
+ }
+
+ /*
+- * Memory allocation
++ * Miscellaneous functions
+ */
+-void allocate_memory ()
+-{
+- int y;
+
+- luminance = (double **) malloc (cvts.ymax * sizeof (double *));
+- image = (COLOR **) malloc (cvts.ymax * sizeof (COLOR *));
+- for (y = 0; y < cvts.ymax; y++)
++static float log_average()
++{
++ double sum = 0.;
++ int s = width*height;
++ for (int i = s; i--; )
+ {
+- luminance[y] = (double *) malloc (cvts.xmax * sizeof (double));
+- image[y] = (COLOR *) malloc (cvts.xmax * sizeof (COLOR));
++ sum += log(0.00001+(*lum)(i));
+ }
++ return expf((float)sum/(float)s);
+ }
+
+-void deallocate_memory ()
++static void scale_to_midtone()
+ {
+- int y;
++ float avg, scale_factor;
++ int border_size = (int)(((width<height) ? width : height)*border);
+
+- for (y = 0; y < cvts.ymax; y++)
++ avg = log_average();
++ if (temporal_coherent)
+ {
+- free(luminance[y]);
+- free(image[y]);
++ avg_luminance.set(avg);
++ avg = avg_luminance.get();
+ }
+- free( luminance );
+- free( image );
+-}
+-
+-
+-void dynamic_range ()
+-{
+- int x, y;
+- double minval = 1e20;
+- double maxval = -1e20;
+-
+- for (x = 0; x < cvts.xmax; x++)
+- for (y = 0; y < cvts.ymax; y++)
++
++ scale_factor = key / avg;
++ for (int i = width*height; i--; )
++ {
++ (*lum)(i) *= scale_factor;
++ }
++ if (border_size)
++ {
++ int hw = width >> 1;
++ int hh = height >> 1;
++ for (int y = 0; y < height; y++)
+ {
+- if ((luminance[y][x] < minval) &&
+- (luminance[y][x] > 0.0))
+- minval = luminance[y][x];
+- if (luminance[y][x] > maxval)
+- maxval = luminance[y][x];
++ int v = (y > hh) ? height - y : y;
++ for (int x = 0; x < width; x++)
++ {
++ int u = (x > hw) ? width - x : x;
++ int d = (u < v) ? u : v;
++ if (d < border_size)
++ (*lum)(x,y) *=
++ (2.f * kaiserbessel(border_size - d, 0, border_size) + 1.f) / 3.f;
++ }
+ }
+- fprintf (stderr, "\tRange of values = %9.8f - %9.8f\n", minval, maxval);
+- fprintf (stderr, "\tDynamic range = %i:1\n", (int)(maxval/minval));
++ }
+ }
+
+-void print_parameter_settings ()
++static void dynamic_range()
+ {
+- fprintf (stderr, "\tImage size = %i %i\n", cvts.xmax, cvts.ymax);
+- fprintf (stderr, "\tLowest scale = %i pixels\t\t(-low <integer>)\n", scale_low);
+- fprintf (stderr, "\tHighest scale = %i pixels\t\t(-high <integer>)\n", scale_high);
+- fprintf (stderr, "\tNumber of scales = %i\t\t\t(-num <integer>)\n", range);
+- fprintf (stderr, "\tScale spacing = %f\n", S_I(1) / S_I(0));
+- fprintf (stderr, "\tKey value = %f\t\t(-key <float>)\n", key);
+- fprintf (stderr, "\tWhite value = %f\t\t(-white <float>)\n", white);
+- fprintf (stderr, "\tPhi = %f\t\t(-phi <float>)\n", phi);
+- fprintf (stderr, "\tThreshold = %f\t\t(-threshold <float>)\n", threshold);
+- dynamic_range ();
++ float min = 1e20f;
++ float max = -1e20f;
++ for (int i = width*height; i--; )
++ {
++ float l = (*lum)(i);
++ if (min>l && l>0.f) min = l;
++ if (max<l) max = l;
++ }
++ fprintf(stderr, "\tRange of values = %9.8f - %9.8f\n", min, max);
++ fprintf(stderr, "\tDynamic range = %i:1\n", (int)(max/min));
++}
++
++static void print_parameter_settings()
++{
++ fprintf(stderr, "\tImage size = %i %i\n", width, height);
++ fprintf(stderr, "\tLowest scale = %i pixels\t\t(-low <integer>)\n", scale_low);
++ fprintf(stderr, "\tHighest scale = %i pixels\t\t(-high <integer>)\n", scale_high);
++ fprintf(stderr, "\tNumber of scales = %i\t\t\t(-num <integer>)\n", range);
++ fprintf(stderr, "\tScale spacing = %f\n", S_I(1) / S_I(0));
++ fprintf(stderr, "\tKey value = %f\t\t(-key <float>)\n", key);
++ fprintf(stderr, "\tWhite value = %f\t\t(-white <float>)\n", white);
++ fprintf(stderr, "\tPhi = %f\t\t(-phi <float>)\n", phi);
++ fprintf(stderr, "\tThreshold = %f\t\t(-threshold <float>)\n", threshold);
++ dynamic_range();
+ }
+
+ /*
+@@ -507,16 +466,15 @@
+ * @param num number of scales to use in computation (default: 8)
+ * @param low size in pixels of smallest scale (should be kept at 1)
+ * @param high size in pixels of largest scale (default 1.6^8 = 43)
++ * @param temporal_coherent tone mapping is time coherent for video sequences
++ * @param border relative width of image area scaled to midtone separately (default: 0 - use key for whole image)
+ */
+ void tmo_reinhard02(
+- unsigned int width, unsigned int height,
+- const float *nY, float *nL,
++ const pfstmo::Array2D *Y, pfstmo::Array2D *L,
+ bool use_scales, float key, float phi,
+- int num, int low, int high, bool temporal_coherent )
++ int num, int low, int high, bool temporal_coherent, float border)
+ {
+- const pfstmo::Array2D* Y = new pfstmo::Array2D(width, height, const_cast<float*>(nY));
+- pfstmo::Array2D* L = new pfstmo::Array2D(width, height, nL);
+-
++ std::auto_ptr<pfstmo::Array2D> l(0);
+ int x,y;
+
+ ::key = key;
+@@ -526,45 +484,45 @@
+ ::scale_high = high;
+ ::use_scales = (use_scales) ? 1 : 0;
+ ::temporal_coherent = temporal_coherent;
++ ::border = border;
+
+- cvts.xmax = Y->getCols();
+- cvts.ymax = Y->getRows();
++ width = Y->getCols();
++ height = Y->getRows();
+
+- sigma_0 = log (scale_low);
+- sigma_1 = log (scale_high);
++ sigma_0 = logf(scale_low);
++ sigma_1 = logf(scale_high);
+
+ compute_bessel();
+- allocate_memory ();
+
+- // reading image
+- for( y=0 ; y<cvts.ymax ; y++ )
+- for( x=0 ; x<cvts.xmax ; x++ )
+- image[y][x][0] = (*Y)(x,y);
++ img = lum = L;
++ if (use_scales)
++ {
++ l.reset(new pfstmo::Array2D(width,height));
++ lum = l.get();
++ }
++ copyArray(Y,lum);
+
+- copy_luminance();
+ scale_to_midtone();
+
+- if( use_scales )
++ if (use_scales)
+ {
+ #ifdef APPROXIMATE
+- build_pyramid(luminance, cvts.xmax, cvts.ymax);
++ build_pyramid();
+ #else
+ compute_fourier_convolution();
+ #endif
++ tonemap();
++ }
++ else
++ {
++ tonecompress();
+ }
+-
+- tonemap_image();
+-
+- // saving image
+- for( y=0 ; y<cvts.ymax ; y++ )
+- for( x=0 ; x<cvts.xmax ; x++ )
+- (*L)(x,y) = image[y][x][0];
+
+ // print_parameter_settings();
+
+- deallocate_memory();
++#ifdef APPROXIMATE
+ clean_pyramid();
+-
+- delete L;
+- delete Y;
++#else
++ clean_convolved_image();
++#endif
+ }
diff --git a/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.h b/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.h
new file mode 100644
index 000000000000..817007cb1b9d
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard02-tmo_reinhard02.h
@@ -0,0 +1,27 @@
+--- src/reinhard02/tmo_reinhard02.h.orig 2008-09-04 12:46:49.000000000 +0000
++++ src/reinhard02/tmo_reinhard02.h 2014-06-18 15:29:52.328951402 +0000
+@@ -13,8 +13,6 @@
+ /*
+ * @brief Photographic tone-reproduction
+ *
+- * @param width image width
+- * @param height image height
+ * @param Y input luminance
+ * @param L output tonemapped intensities
+ * @param use_scales true: local version, false: global version of TMO
+@@ -23,10 +21,12 @@
+ * @param num number of scales to use in computation (default: 8)
+ * @param low size in pixels of smallest scale (should be kept at 1)
+ * @param high size in pixels of largest scale (default 1.6^8 = 43)
++ * @param temporal_coherent tone mapping is time coherent for video sequences
++ * @param border relative width of image area scaled to midtone separately (default: 0 - use key for whole image)
+ */
+-void tmo_reinhard02(unsigned int width, unsigned int height,
+- const float *Y, float *L,
++void tmo_reinhard02(
++ const pfstmo::Array2D *Y, pfstmo::Array2D *L,
+ bool use_scales, float key, float phi,
+- int num, int low, int high, bool temporal_coherent );
++ int num, int low, int high, bool temporal_coherent, float border = 0.f);
+
+ #endif /* _tmo_reinhard02_h_ */
diff --git a/graphics/pfstmo/files/patch-src-reinhard05-pfstmo_reinhard05.cpp b/graphics/pfstmo/files/patch-src-reinhard05-pfstmo_reinhard05.cpp
new file mode 100644
index 000000000000..445c5b36a7d4
--- /dev/null
+++ b/graphics/pfstmo/files/patch-src-reinhard05-pfstmo_reinhard05.cpp
@@ -0,0 +1,17 @@
+--- src/reinhard05/pfstmo_reinhard05.cpp.orig 2008-09-04 12:46:49.000000000 +0000
++++ src/reinhard05/pfstmo_reinhard05.cpp 2014-06-18 15:29:52.328951402 +0000
+@@ -157,6 +157,14 @@
+ try {
+ pfstmo_reinhard05( argc, argv );
+ }
++ catch (std::bad_alloc ex) {
++ fprintf(stderr, PROG_NAME " error: out of memory\n");
++ return EXIT_FAILURE;
++ }
++ catch (std::exception ex) {
++ fprintf(stderr, PROG_NAME " error: %s\n", ex.what());
++ return EXIT_FAILURE;
++ }
+ catch( pfs::Exception ex ) {
+ fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() );
+ return EXIT_FAILURE;
diff --git a/graphics/pfstmo/pkg-plist b/graphics/pfstmo/pkg-plist
index 1fc052ecb0c0..404699f467c3 100644
--- a/graphics/pfstmo/pkg-plist
+++ b/graphics/pfstmo/pkg-plist
@@ -4,4 +4,13 @@ bin/pfstmo_reinhard02
bin/pfstmo_durand02
bin/pfstmo_drago03
bin/pfstmo_mantiuk06
+bin/pfstmo_mantiuk08
bin/pfstmo_fattal02
+man/man1/pfstmo_pattanaik00.1.gz
+man/man1/pfstmo_reinhard05.1.gz
+man/man1/pfstmo_reinhard02.1.gz
+man/man1/pfstmo_durand02.1.gz
+man/man1/pfstmo_drago03.1.gz
+man/man1/pfstmo_mantiuk06.1.gz
+man/man1/pfstmo_mantiuk08.1.gz
+man/man1/pfstmo_fattal02.1.gz