ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tonemap.h
Revision: 3.30
Committed: Tue Mar 2 20:09:14 2021 UTC (3 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.29: +3 -2 lines
Log Message:
perf: added handling of blacks in linear tone-mapping

File Contents

# User Rev Content
1 greg 3.30 /* RCSid $Id: tonemap.h,v 3.29 2021/01/07 19:13:57 greg Exp $ */
2 greg 3.1 /*
3     * Header file for tone mapping functions.
4 gwlarson 3.8 *
5     * Include after "color.h"
6 greg 3.1 */
7 schorsch 3.13 #ifndef _RAD_TONEMAP_H_
8     #define _RAD_TONEMAP_H_
9 schorsch 3.16
10 greg 3.23 #include "tiff.h" /* needed for int32, etc. */
11 schorsch 3.16
12 greg 3.11 #ifdef __cplusplus
13     extern "C" {
14     #endif
15 greg 3.15
16 greg 3.1 /**** Argument Macros ****/
17 greg 3.20 /* flags of what to do */
18 greg 3.1 #define TM_F_HCONTR 01 /* human contrast sensitivity */
19     #define TM_F_MESOPIC 02 /* mesopic color sensitivity */
20     #define TM_F_LINEAR 04 /* linear brightness mapping */
21     #define TM_F_ACUITY 010 /* acuity adjustment */
22     #define TM_F_VEIL 020 /* veiling glare */
23     #define TM_F_CWEIGHT 040 /* center weighting */
24     #define TM_F_FOVEAL 0100 /* use foveal sample size */
25     #define TM_F_BW 0200 /* luminance only */
26 greg 3.2 #define TM_F_NOSTDERR 0400 /* don't report errors to stderr */
27 greg 3.1 /* combined modes */
28     #define TM_F_CAMERA 0
29     #define TM_F_HUMAN (TM_F_HCONTR|TM_F_MESOPIC|TM_F_VEIL|\
30     TM_F_ACUITY|TM_F_FOVEAL)
31     #define TM_F_UNIMPL (TM_F_CWEIGHT|TM_F_VEIL|TM_F_ACUITY|TM_F_FOVEAL)
32    
33     /* special pointer values */
34     #define TM_XYZPRIM (RGBPRIMP)NULL /* indicate XYZ primaries (Note 1) */
35 greg 3.26 #define TM_NOCHROM (uby8 *)NULL /* indicate no chrominance */
36     #define TM_NOCHROMP (uby8 **)NULL /* indicate no chrominances */
37 greg 3.1 #define TM_GETFILE (FILE *)NULL /* indicate file must be opened */
38 gwlarson 3.8
39 greg 3.1
40     /**** Error Return Values ****/
41    
42     #define TM_E_OK 0 /* normal return status */
43     #define TM_E_NOMEM 1 /* out of memory */
44     #define TM_E_ILLEGAL 2 /* illegal argument value */
45     #define TM_E_TMINVAL 3 /* no valid tone mapping */
46     #define TM_E_TMFAIL 4 /* cannot compute tone mapping */
47     #define TM_E_BADFILE 5 /* cannot open or understand file */
48 greg 3.4 #define TM_E_CODERR1 6 /* code consistency error 1 */
49     #define TM_E_CODERR2 7 /* code consistency error 2 */
50 greg 3.1
51 greg 3.4
52 greg 3.1 /**** Conversion Constants and Table Sizes ****/
53    
54 greg 3.25 #define TM_BRTSCALE 256 /* brightness scale factor (integer) */
55 greg 3.1
56 greg 3.27 #define TM_NOBRT (~0x7fff) /* bogus brightness value */
57 greg 3.11 #define TM_NOLUM (1e-17) /* ridiculously small luminance */
58 gwlarson 3.10
59 greg 3.28 #define TM_BRES 4096 /* luminance tone-map resolution */
60    
61 greg 3.4 #define TM_MAXPKG 8 /* maximum number of color formats */
62 greg 3.1
63    
64 greg 3.4 /**** Global Data Types and Structures ****/
65    
66     #ifndef MEM_PTR
67     #define MEM_PTR void *
68     #endif
69 greg 3.27 #ifndef HIST_TYP
70     #define HIST_TYP unsigned long
71     #endif
72 greg 3.29 #ifndef TMAP_TYP
73     #define TMAP_TYP uint16
74     #endif
75 greg 3.4
76 greg 3.1 extern char *tmErrorMessage[]; /* error messages */
77    
78     typedef short TMbright; /* encoded luminance type */
79    
80     /* basic tone mapping data structure */
81 greg 3.20 typedef struct {
82 greg 3.1 int flags; /* flags of what to do */
83     RGBPRIMP monpri; /* monitor RGB primaries */
84     double mongam; /* monitor gamma value (approx.) */
85     COLOR clf; /* computed luminance coefficients */
86 greg 3.4 int cdiv[3]; /* computed color divisors */
87 greg 3.1 RGBPRIMP inppri; /* current input primaries */
88     double inpsf; /* current input scalefactor */
89 greg 3.19 MEM_PTR inpdat; /* current input client data */
90 greg 3.1 COLORMAT cmat; /* color conversion matrix */
91 gregl 3.7 TMbright hbrmin, hbrmax; /* histogram brightness limits */
92 greg 3.27 HIST_TYP *histo; /* input histogram */
93 gregl 3.7 TMbright mbrmin, mbrmax; /* mapped brightness limits */
94 greg 3.27 TMAP_TYP *lumap; /* computed luminance map */
95 greg 3.4 MEM_PTR pd[TM_MAXPKG]; /* pointers to private data */
96 greg 3.18 int lastError; /* last error incurred */
97     const char *lastFunc; /* error-generating function name */
98 greg 3.17 } TMstruct;
99 greg 3.4
100     /* conversion package functions */
101     struct tmPackage {
102 greg 3.17 MEM_PTR (*Init)(TMstruct *tms);
103     void (*NewSpace)(TMstruct *tms);
104 greg 3.4 void (*Free)(MEM_PTR pp);
105     };
106     /* our list of conversion packages */
107     extern struct tmPackage *tmPkg[TM_MAXPKG];
108     extern int tmNumPkgs; /* number of registered packages */
109    
110    
111 greg 3.1 /**** Useful Macros ****/
112    
113 greg 3.4 /* compute luminance from encoded value */
114 greg 3.11 #define tmLuminance(li) exp((li)*(1./TM_BRTSCALE))
115 greg 3.1
116 greg 3.4 /* does tone mapping need color matrix? */
117     #define tmNeedMatrix(t) ((t)->monpri != (t)->inppri)
118    
119     /* register a conversion package */
120     #define tmRegPkg(pf) ( tmNumPkgs >= TM_MAXPKG ? -1 : \
121     (tmPkg[tmNumPkgs] = (pf), tmNumPkgs++) )
122    
123     /* get the specific package's data */
124     #define tmPkgData(t,i) ((t)->pd[i]!=NULL ? (t)->pd[i] : (*tmPkg[i]->Init)(t))
125    
126    
127 greg 3.1 /**** Library Function Calls ****/
128    
129 greg 3.21 extern TMbright
130     tmCvLuminance(double lum);
131     /*
132     Convert a single luminance value to an encoded brightness value.
133     */
134 greg 3.1
135 greg 3.22 extern int
136     tmCvLums(TMbright *ls, float *scan, int len);
137     /*
138     Convert luminance values to encoded brightness values using lookup.
139    
140     ls - returned encoded luminance values.
141     scan - input scanline.
142     len - scanline length.
143    
144     returns - 0 on success, TM_E_* on error.
145     */
146    
147 greg 3.17 extern TMstruct *
148 greg 3.1 tmInit(int flags, RGBPRIMP monpri, double gamval);
149     /*
150 greg 3.17 Allocate and initialize new tone mapping.
151 greg 3.1
152     flags - TM_F_* flags indicating what is to be done.
153     monpri - display monitor primaries (Note 1).
154     gamval - display gamma response (can be approximate).
155    
156 greg 3.17 returns - new tone-mapping pointer, or NULL if no memory.
157 greg 3.1 */
158    
159     extern int
160 greg 3.19 tmSetSpace(TMstruct *tms, RGBPRIMP pri, double sf, MEM_PTR dat);
161 greg 3.1 /*
162     Set color primaries and scale factor for incoming scanlines.
163    
164 greg 3.17 tms - tone mapping structure pointer.
165 greg 3.1 pri - RGB color input primaries (Note 1).
166     sf - scale factor to get to luminance in cd/m^2.
167 greg 3.19 dat - application-specific data (NULL if not needed)
168 greg 3.1
169     returns - 0 on success, TM_E_* code on failure.
170     */
171    
172     extern void
173 greg 3.17 tmClearHisto(TMstruct *tms);
174 greg 3.1 /*
175     Clear histogram for current tone mapping.
176 greg 3.17
177     tms - tone mapping structure pointer.
178 greg 3.1 */
179    
180     extern int
181 greg 3.17 tmAddHisto(TMstruct *tms, TMbright *ls, int len, int wt);
182 greg 3.1 /*
183     Add brightness values to current histogram.
184    
185 greg 3.17 tms - tone mapping structure pointer.
186 greg 3.1 ls - encoded luminance values.
187     len - number of luminance values.
188     wt - integer weight to use for each value (usually 1 or -1).
189    
190     returns - 0 on success, TM_E_* on error.
191     */
192    
193     extern int
194 greg 3.30 tmFixedMapping(TMstruct *tms, double expmult, double gamval, double Lddyn);
195 greg 3.11 /*
196     Assign a fixed, linear tone-mapping using the given multiplier,
197     which is the ratio of maximum output to uncalibrated input.
198     This mapping will be used in subsequent calls to tmMapPixels()
199     until a new tone mapping is computed.
200     Only the min. and max. values are used from the histogram.
201    
202 greg 3.17 tms - tone mapping structure pointer.
203 greg 3.11 expmult - the fixed exposure multiplier to use.
204     gamval - display gamma response (0. for default).
205 greg 3.30 Ldmax - maximum display luminance in cd/m^2 (0. for default).
206 greg 3.18
207 greg 3.11 returns - 0 on success, TM_E_* on error.
208     */
209    
210     extern int
211 greg 3.17 tmComputeMapping(TMstruct *tms, double gamval, double Lddyn, double Ldmax);
212 greg 3.1 /*
213 greg 3.11 Compute tone mapping function from the current histogram.
214     This mapping will be used in subsequent calls to tmMapPixels()
215     until a new tone mapping is computed.
216     I.e., calls to tmAddHisto() have no immediate effect.
217 greg 3.1
218 greg 3.17 tms - tone mapping structure pointer.
219 greg 3.1 gamval - display gamma response (0. for default).
220     Lddyn - the display's dynamic range (0. for default).
221     Ldmax - maximum display luminance in cd/m^2 (0. for default).
222    
223     returns - 0 on success, TM_E_* on failure.
224     */
225    
226     extern int
227 greg 3.26 tmMapPixels(TMstruct *tms, uby8 *ps, TMbright *ls, uby8 *cs, int len);
228 greg 3.1 /*
229     Apply tone mapping function to pixel values.
230    
231 greg 3.17 tms - tone mapping structure pointer.
232 greg 3.1 ps - returned pixel values (Note 2).
233     ls - encoded luminance values.
234     cs - encoded chrominance values (Note 2).
235     len - number of pixels.
236    
237     returns - 0 on success, TM_E_* on failure.
238     */
239    
240 greg 3.17 extern TMstruct *
241     tmDup(TMstruct *orig);
242 greg 3.3 /*
243 greg 3.17 Duplicate the given tone mapping into a new struct.
244 greg 3.3
245 greg 3.17 orig - tone mapping structure to duplicate.
246 greg 3.18
247 greg 3.17 returns - pointer to new struct, or NULL on error.
248 greg 3.3 */
249    
250 greg 3.1 extern void
251 greg 3.17 tmDone(TMstruct *tms);
252 greg 3.1 /*
253     Free data associated with the given tone mapping structure.
254    
255     tms - tone mapping structure to free.
256     */
257    
258 greg 3.11 extern int
259 greg 3.22 tmCvGrays(TMstruct *tms, TMbright *ls, float *scan, int len);
260 greg 3.11 /*
261 greg 3.22 Convert gray float scanline to encoded luminance.
262 greg 3.11
263 greg 3.17 tms - tone mapping structure pointer.
264 greg 3.11 ls - returned encoded luminance values.
265     scan - input scanline.
266     len - scanline length.
267    
268     returns - 0 on success, TM_E_* on error.
269     */
270    
271     extern int
272 greg 3.26 tmCvColors(TMstruct *tms, TMbright *ls, uby8 *cs, COLOR *scan, int len);
273 greg 3.11 /*
274 greg 3.22 Convert RGB/XYZ float scanline to encoded luminance and chrominance.
275 greg 3.11
276 greg 3.17 tms - tone mapping structure pointer.
277 greg 3.11 ls - returned encoded luminance values.
278 greg 3.22 cs - returned encoded chrominance values (Note 2).
279 greg 3.11 scan - input scanline.
280     len - scanline length.
281    
282     returns - 0 on success, TM_E_* on error.
283     */
284    
285     extern int
286 greg 3.26 tmCvColrs(TMstruct *tms, TMbright *ls, uby8 *cs, COLR *scan, int len);
287 greg 3.11 /*
288     Convert RGBE/XYZE scanline to encoded luminance and chrominance.
289    
290 greg 3.17 tms - tone mapping structure pointer.
291 greg 3.11 ls - returned encoded luminance values.
292     cs - returned encoded chrominance values (Note 2).
293     scan - input scanline.
294     len - scanline length.
295    
296     returns - 0 on success, TM_E_* on error.
297     */
298    
299     extern int
300 greg 3.26 tmLoadPicture(TMstruct *tms, TMbright **lpp, uby8 **cpp, int *xp, int *yp,
301 greg 3.11 char *fname, FILE *fp);
302     /*
303     Load Radiance picture and convert to tone mapping representation.
304     Memory for the luminance and chroma arrays is allocated using
305     malloc(3), and should be freed with free(3) when no longer needed.
306     Calls tmSetSpace() to calibrate input color space.
307    
308 greg 3.17 tms - tone mapping structure pointer.
309 greg 3.11 lpp - returned array of encoded luminances, picture ordering.
310     cpp - returned array of encoded chrominances (Note 2).
311     xp, yp - returned picture dimensions.
312     fname - picture file name.
313     fp - pointer to open file (Note 3).
314    
315     returns - 0 on success, TM_E_* on failure.
316     */
317    
318     extern int
319 greg 3.26 tmMapPicture(uby8 **psp, int *xp, int *yp, int flags,
320 greg 3.11 RGBPRIMP monpri, double gamval, double Lddyn, double Ldmax,
321     char *fname, FILE *fp);
322     /*
323     Load and apply tone mapping to Radiance picture.
324     If fp is TM_GETFILE and (flags&TM_F_UNIMPL)!=0, tmMapPicture()
325     calls pcond to perform the actual conversion, which takes
326     longer but gives access to all the TM_F_* features.
327     Memory for the final pixel array is allocated using malloc(3),
328     and should be freed with free(3) when it is no longer needed.
329    
330     psp - returned array of tone mapped pixels, picture ordering.
331     xp, yp - returned picture dimensions.
332     flags - TM_F_* flags indicating what is to be done.
333     monpri - display monitor primaries (Note 1).
334     gamval - display gamma response.
335     Lddyn - the display's dynamic range (0. for default).
336     Ldmax - maximum display luminance in cd/m^2 (0. for default).
337     fname - picture file name.
338     fp - pointer to open file (Note 3).
339    
340     returns - 0 on success, TM_E_* on failure.
341     */
342    
343 greg 3.15 extern int
344 greg 3.26 tmCvRGB48(TMstruct *tms, TMbright *ls, uby8 *cs, uint16 (*scan)[3],
345 greg 3.17 int len, double gv);
346 greg 3.15 /*
347     Convert 48-bit RGB scanline to encoded luminance and chrominance.
348    
349 greg 3.17 tms - tone mapping structure pointer.
350 greg 3.15 ls - returned encoded luminance values.
351     cs - returned encoded chrominance values (Note 2).
352     scan - input scanline.
353     len - scanline length.
354     gv - input gamma value.
355    
356     returns - 0 on success, TM_E_* on error.
357     */
358    
359     extern int
360 greg 3.17 tmCvGray16(TMstruct *tms, TMbright *ls, uint16 *scan, int len, double gv);
361 greg 3.15 /*
362     Convert 16-bit gray scanline to encoded luminance.
363    
364 greg 3.17 tms - tone mapping structure pointer.
365 greg 3.15 ls - returned encoded luminance values.
366     scan - input scanline.
367     len - scanline length.
368     gv - input gamma value.
369 greg 3.4
370 greg 3.15 returns - 0 on success, TM_E_* on error.
371     */
372 greg 3.4
373 greg 3.1 /**** Notes ****/
374     /*
375     General:
376    
377     The usual sequence after calling tmInit() is to convert some
378     pixel values to chroma and luminance encodings, which can
379     be passed to tmAddHisto() to put into the tone mapping histogram.
380     This histogram is then used along with the display parameters
381 greg 3.5 by tmComputeMapping() to compute the luminance mapping function.
382 greg 3.1 (Colors are tone-mapped as they are converted if TM_F_MESOPIC
383     is set.) The encoded chroma and luminance values may then be
384     passed to tmMapPixels() to apply the computed tone mapping in
385     a second pass.
386    
387     Especially for RGBE colors in the same color space as the
388     target display, the conversion to chroma and luminance values
389     is fast enough that it may be recomputed on the second pass
390     if memory is at a premium. (Since the chroma values are only
391     used during final mapping, setting the cs parameter to TM_NOCHROM
392     on the first pass will save time.) Another memory saving option
393     if third and subsequent passes are not needed is to use the
394 greg 3.3 same array to store the mapped pixels as used to store
395 greg 3.1 the encoded chroma values. This way, only two extra bytes
396     for storing encoded luminances are required per pixel. This
397     is the method employed by tmMapPicture(), for example.
398     */
399     /*
400     Note 1:
401    
402     All RGBPRIMP values should be pointers to static structures.
403     I.e., the same pointer should be used for the same primaries,
404     and those primaries should not change from one call to the next.
405     This is because the routines use the pointer value to identify
406     computed conversion matrices, so the matrices do not have to be
407     rebuilt each time. If you are using the standard primaries,
408     use the standard primary pointer, stdprims.
409    
410     To indicate a set of input primaries are actually CIE XYZ,
411     the TM_XYZPRIM macro may be passed. If the input primaries
412     are unknown, it is wisest to pass tmTop->monpri to tmSetSpace().
413     By default, the input primaries equal the monitor primaries
414     and the scalefactor is set to WHTEFFICACY in tmInit().
415     */
416     /*
417     Note 2:
418    
419     Chrominance is optional in most of these routines, whether
420     TM_F_BW is set or not. Passing a value of TM_NOCHROM (or
421     TM_NOCHROMP for picture reading) indicates that returned
422     color values are not desired.
423    
424     If TM_NOCHROM is passed to a mapping routine expecting chroma
425     input, it will do without it and return luminance channel
426     rather than RGB pixel values. Otherwise, the array for
427     returned pixel values may be the same array used to pass
428     encoded chrominances if no other mappings are desired.
429     */
430     /*
431     Note 3:
432    
433     Picture files may either be opened by the calling routine or by
434     the library function. If opened by the calling routine, the
435     pointer to the stream is passed, which may be a pipe or other
436     non-seekable input as it is only read once. It must be
437     positioned at the beginning when the function is called, and it
438     will be positioned at the end on return. It will not be closed.
439     If the passed stream pointer is TM_GETFILE, then the library
440     function will open the file, read its contents and close it
441     before returning, whether or not an error was encountered.
442     */
443 greg 3.11
444     #ifdef __cplusplus
445     }
446     #endif
447 schorsch 3.13 #endif /* _RAD_TONEMAP_H_ */
448