1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-21 00:25:50 +00:00

- Update from 1.2 to 1.5

- Add stage support

PR:		ports/191180
Submitted by:	ii@any.com.ru
This commit is contained in:
Danilo Egea Gondolfo 2014-06-20 15:46:27 +00:00
parent 9914368937
commit 86b70fb123
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=358594
17 changed files with 1776 additions and 37 deletions

View File

@ -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>

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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
--- 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 @@
}
+#if defined(__FreeBSD__)
+static inline float exp10f(float x) {
+ return powf(10.,x);
+}
+#endif
+
+
static void contrast_equalization( pyramid_t *pp, const float contrastFactor );
-// 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];
static void transform_to_luminance(pyramid_t* pyramid, float* const x, progress_callback progress_cb, const bool bcg);
// 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)

View File

@ -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;

View File

@ -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 )

View File

@ -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;

View File

@ -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--;

View File

@ -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.

View File

@ -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;

View File

@ -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
}

View File

@ -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_ */

View File

@ -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;

View File

@ -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