1 /**
2  * @brief Display Adaptive TMO
3  *
4  * From:
5  * Rafal Mantiuk, Scott Daly, Louis Kerofsky.
6  * Display Adaptive Tone Mapping.
7  * To appear in: ACM Transactions on Graphics (Proc. of SIGGRAPH'08) 27 (3)
8  * http://www.mpi-inf.mpg.de/resources/hdr/datmo/
9  *
10  * This file is a part of PFSTMO package.
11  * ----------------------------------------------------------------------
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  * ----------------------------------------------------------------------
26  *
27  * @author Rafal Mantiuk, <mantiuk@gmail.com>
28  *
29  * $Id: display_adaptive_tmo.h,v 1.16 2013/12/28 14:00:54 rafm Exp $
30  */
31 
32 #include <memory>
33 
34 #include "display_function.h"
35 #include "display_size.h"
36 
37 #include "pfstmo.h"
38 
39 #define DATMO_TF_TAPSIZE 4     /* Number of samples required for the temporal filter */
40 
41 class datmoToneCurve
42 {
43   bool own_y_i;
44 public:
45   size_t size;
46   const double *x_i;  /* log10 of input luminance factor */
47   double *y_i;        /* log10 of output luminance (use inverse display model to get pixel values) */
48 
49   datmoToneCurve();
50   ~datmoToneCurve();
51 
52   void init( size_t n_size, const double *n_x_i, double *n_y_i = NULL );
53   void free();
54 
55 };
56 
57 class datmoTCFilter
58 {
59   int pos, sz;
60   float y_min, y_max, fps;
61 
62   double *t_filter_a, *t_filter_b;
63 
64   datmoToneCurve ring_buffer_org[DATMO_TF_TAPSIZE]; // original
65   datmoToneCurve ring_buffer_filt[DATMO_TF_TAPSIZE]; // filtered
66   datmoToneCurve tc_filt_clamp; // filtered and clammped tone-curve
67 
68   datmoToneCurve *get_tc( datmoToneCurve *ring_buf, int time );
69 public:
70   /**
71    * Create a temporal filter for tone-curves. This shoudl be used to
72    * tonemap video sequences.
73    *
74    * @param fps - frames per second. Only certain values are allowed
75    * as all filters are precomputed at the moment. See the code for
76    * more details.
77    * @param y_min - minimum log10 display luminance (for clamping the
78    * results)
79    * @param y_max - maximum log10 display luminance (for clamping the
80    * results)
81    */
82   datmoTCFilter( float fps, float y_min, float y_max );
83 
84   /**
85    * Get the pointer to store the tone-curve.
86    */
87   datmoToneCurve *getToneCurvePtr();
88 
89   /**
90    * Get the filterted tone-curve.
91    */
92   datmoToneCurve *filterToneCurve();
93 
94 
95 };
96 
97 
98 
99 class datmoConditionalDensity
100 {
101 public:
102   virtual ~datmoConditionalDensity();
103 };
104 
105 
106 typedef int datmoVisualModel;
107 
108 #define vm_none 0
109 #define vm_luminance_masking 1
110 #define vm_contrast_masking 2
111 #define vm_csf 4
112 #define vm_full 7
113 
114 /**
115  * Tone-map RGB radiance map using the display adaptive tone
116  * mapping. This is a convienience function that calls three stages of
117  * this tone-mapping algorithm: datmo_compute_conditional_density(),
118  * datmo_compute_conditional_density(), and
119  * datmo_apply_tone_curve(). If you need a finer control over the
120  * algorithm execution or want to tone-map video, use the lower levels
121  * functions instead.
122  *
123  * @param R_out output red-channel (in pixel values). Can be the same
124  * as R_in.
125  * @param G_out output green-channel (in pixel values). Can be the same
126  * as G_in.
127  * @param B_out output blue-channel (in pixel values). Can be the same
128  * as B_in.
129  * @param width image width in pixels
130  * @param height image height in pixels
131  * @param R_in red input radiance map.
132  * @param G_in green input radiance map.
133  * @param B_in blue input radiance map.
134  * @param L_in input luminance map (L=0.212656*R + 0.715158*G + 0.072186*B)
135  * @param df display function. See DisplayFunction class documentation for more details.
136  * @param ds display size. See DisplaySize class documentation for more details.
137  * @param enh_factor conrast enhancement factor. See man
138  * pfstmo_mantiuk08 page for details
139  * @param saturation_factor color saturation factor. See man
140  * pfstmo_mantiuk08 page for details
141  * @param white_y luminance factor in the input image that should be
142  * mapped to the maximum luminance of a display. If the parameter is
143  * set to -1, the tone-mapper will not anchor to white (recommended for HDR images).
144  * @param progress_cb callback function for reporting progress or stopping computations.
145  * @return PFSTMO_OK if tone-mapping was sucessful, PFSTMO_ABORTED if
146  * it was stopped from a callback function and PFSTMO_ERROR if an
147  * error was encountered.
148  */
149 int datmo_tonemap( float *R_out, float *G_out, float *B_out, int width, int height,
150   const float *R_in, const float *G_in, const float *B_in, const float *L_in,
151   DisplayFunction *df, DisplaySize *ds, const float enh_factor = 1.f, const float saturation_factor = 0.4f,
152   const float white_y = -1, pfstmo_progress_callback progress_cb = NULL );
153 
154 /**
155  * Computes image statistics required for
156  * datmo_compute_tone_curve(). This is the most time-consuming
157  * function. If interactive tuning of the TMO parameters is needed,
158  * this function can be executed once per image and then
159  * datmo_compute_tone_curve() can be executed as many times as needed.
160  *
161  * @param width image width in pixels
162  * @param height image height in pixels
163  * @param L input luminance map (L=0.212656*R + 0.715158*G + 0.072186*B)
164  * @param progress_cb callback function for reporting progress or stopping computations.
165  * @return pointer to conditional_density or NULL if computation was
166  * aborted or an error was encountered. The conditional_density object
167  * must be freed by the calling application using the 'delete'
168  * statement.
169  */
170 std::auto_ptr<datmoConditionalDensity> datmo_compute_conditional_density( int width, int height, const float *L, pfstmo_progress_callback progress_cb = NULL );
171 
172 
173 /**
174  * Computes the best tone-curve for a given conditional_density and
175  * TMO parameters. The conditional_density must be computed with
176  * datmo_compute_conditional_density() and freed afted executing this
177  * function.
178  *
179  * @param tc datmoToneCurve where the resulting tone-curve will be stored
180  * @param conditional_density image statistics computed with datmo_compute_conditional_density()
181  * @param df display function. See DisplayFunction class documentation for more details.
182  * @param ds display size. See DisplaySize class documentation for more details.
183  * @param enh_factor conrast enhancement factor. See man
184  * pfstmo_mantiuk08 page for details
185  * @param white_y luminance factor in the input image that should be
186  * mapped to the maximum luminance of a display. If the parameter is
187  * set to -1, the tone-mapper will not anchor to white (recommended for HDR images).
188  * @param progress_cb callback function for reporting progress or stopping computations.
189  * @return PFSTMO_OK if tone-mapping was sucessful, PFSTMO_ABORTED if
190  * it was stopped from a callback function and PFSTMO_ERROR if an
191  * error was encountered.
192  */
193 int datmo_compute_tone_curve( datmoToneCurve *tc, datmoConditionalDensity *cond_dens,
194   DisplayFunction *df, DisplaySize *ds, const float enh_factor = 1.f,
195   const float white_y = -1, pfstmo_progress_callback progress_cb = NULL,
196   datmoVisualModel visualModel = vm_full, double scene_l_adapt = 1000 );
197 
198 /**
199  * Deprectaied: use datmo_apply_tone_curve_cc()
200  *
201  * Tone-map image using the tone-curve computed with datmo_compute_tone_curve().
202  *
203  * @param R_out output red-channel (in pixel values). Can be the same
204  * as R_in.
205  * @param G_out output green-channel (in pixel values). Can be the same
206  * as G_in.
207  * @param B_out output blue-channel (in pixel values). Can be the same
208  * as B_in.
209  * @param width image width in pixels
210  * @param height image height in pixels
211  * @param R_in red input radiance map.
212  * @param G_in green input radiance map.
213  * @param B_in blue input radiance map.
214  * @param L_in input luminance map (L=0.212656*R + 0.715158*G + 0.072186*B)
215  * @param tc tone-curve computed with datmo_compute_tone_curve()
216  * @param saturation_factor color saturation factor. See man
217  * pfstmo_mantiuk08 page for details
218  * @return PFSTMO_OK if tone-mapping was sucessful, PFSTMO_ABORTED if
219  * it was stopped from a callback function and PFSTMO_ERROR if an
220  * error was encountered.
221  */
222 int datmo_apply_tone_curve( float *R_out, float *G_out, float *B_out, int width, int height,
223   const float *R_in, const float *G_in, const float *B_in, const float *L_in, datmoToneCurve *tc,
224   DisplayFunction *df, const float saturation_factor = 0.4f );
225 
226 /**
227  * Tone-map image using the tone-curve computed with
228  * datmo_compute_tone_curve(). This function corrects color saturation
229  * using the method from:
230  *
231  * Color Correction for Tone Mapping
232  * Radosław Mantiuk, Rafał Mantiuk, Anna Tomaszewska, Wolfgang Heidrich.
233  * In: Computer Graphics Forum (Proc. of EUROGRAPHICS'09), 28(2), 2009
234  *
235  * @param R_out output red-channel (in pixel values). Can be the same
236  * as R_in.
237  * @param G_out output green-channel (in pixel values). Can be the same
238  * as G_in.
239  * @param B_out output blue-channel (in pixel values). Can be the same
240  * as B_in.
241  * @param width image width in pixels
242  * @param height image height in pixels
243  * @param R_in red input radiance map.
244  * @param G_in green input radiance map.
245  * @param B_in blue input radiance map.
246  * @param L_in input luminance map (L=0.212656*R + 0.715158*G + 0.072186*B)
247  * @param tc tone-curve computed with datmo_compute_tone_curve()
248  * @param saturation_factor color saturation factor. Set to 1 to preserve colors, >1 to increase color saturation, <1 to reduce color saturation.
249  * @return PFSTMO_OK if tone-mapping was sucessful, PFSTMO_ABORTED if
250  * it was stopped from a callback function and PFSTMO_ERROR if an
251  * error was encountered.
252  */
253 int datmo_apply_tone_curve_cc( float *R_out, float *G_out, float *B_out, int width, int height,
254   const float *R_in, const float *G_in, const float *B_in, const float *L_in, datmoToneCurve *tc,
255   DisplayFunction *df, const float saturation_factor );
256 
257 
258 /**
259  * Filter tone curves over time to avoid flickering. This filtering is
260  * designed for 25 frames per second.
261  *
262  * @param in_tc array of input tone curves
263  * @param count_in_tc the number of input tone curves in the array
264  * @param out_tc the output tone curve. Must be pre-allocated.
265  */
266 void datmo_filter_tone_curves( datmoToneCurve **in_tc, size_t count_in_tc, datmoToneCurve *out_tc );
267 
268