diff options
author | danilo <danilo@FreeBSD.org> | 2014-06-20 23:46:27 +0800 |
---|---|---|
committer | danilo <danilo@FreeBSD.org> | 2014-06-20 23:46:27 +0800 |
commit | af9089a69184582b18144b3a29a43a4bc6c222e8 (patch) | |
tree | 41773c3ed11d26e208ef76c83f5405c2e6ae4929 | |
parent | bcdc2b6590e64af1b67e43a8833dbd9ec19525ba (diff) | |
download | freebsd-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
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 |