File: LynkeosGammaCorrecter.h

package info (click to toggle)
lynkeos.app 3.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 15,740 kB
  • sloc: objc: 36,412; ansic: 684; cpp: 148; sh: 68; makefile: 21
file content (158 lines) | stat: -rw-r--r-- 4,875 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
//  Lynkeos
//  $Id: LynkeosGammaCorrecter.h 585 2018-09-08 21:30:37Z j-etienne $
//
//  Created by Jean-Etienne LAMIAUD on Sun Aug 17 2008.
//  Copyright (c) 2008. Jean-Etienne LAMIAUD
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//

/*!
 * @header
 * @abstract Definitions for the gamma correcter utility class.
 */

#ifndef __LYNKEOSGAMMACORRECTER_H
#define __LYNKEOSGAMMACORRECTER_H

#import <Foundation/Foundation.h>

/*!
 * @abstract Class which handle the gamma correction
 * @discussion It is instanciated once per window controller to allow caching
 *    gamma related data (LUT for instance).
 * @ingroup Support
 */
@interface LynkeosGammaCorrecter : NSObject
{
@public
   double _gamma;          //!< Current gamma value
   double _exponent;       //!< Real exponent applied to the curve
   double _linearExtent;   //!< Raw value extent of the linear part
   double _offset;         //!< Offset for the linear part
   double _slope;          //!< Slope of the linear part
   u_char *_lut;           //!< Look Up Table for 8 bit conversion
   u_long _lutSize;        //!< Size of the LUT

   u_long _inUse;          //!< To avoid changing the gamma while used
}

/*!
 * @abstract get a converter for a gamma value, it is created if needed
 * @param gamma The gamma value
 * @result The converter
 */
+ (LynkeosGammaCorrecter*) getCorrecterForGamma:(double)gamma ;

/*!
 * @abstract Let the gamma converter be reused for another gamma value if needed
 */
- (void) releaseCorrecter ;

@end

// "Friend" methods to inline the processing

/*!
 * @abstract Convert raw pixel value to a "displayable" value
 * @param value Raw pixel value
 * @param back Black level in raw data
 * @param white White level in raw data
 * @result The corrected value, the range is 0 for black to 1 for white
 */
static inline double correctedValuewithBlackAndWhite( LynkeosGammaCorrecter *c, 
                                                     double value,
                                                     double black,
                                                     double white )
{
   double res = 0.0;

   if ( value <= black )
      res = 0.0;

   else if ( value >= white )
      res = 1.0;

   else
   {
      res = (value - black)/(white - black);

      if ( c->_exponent != 1.0 )
      {
         if ( res <= c->_linearExtent )
            res *= c->_slope;

         else
         {
            if ( c->_exponent < 1.0 )
               res = (1.0+c->_offset)*pow(res,c->_exponent) - c->_offset;

            else
               res = pow((res+c->_offset)/(1.0+c->_offset),c->_exponent);
         }
      }
   }

   return( res );
}

/*!
 * @abstract Convert a [0..1] pixel value to a "displayable" value
 * @param value pixel value
 * @result The corrected value, the range is 0 for black to 1 for white
 */
static inline double correctedValue( LynkeosGammaCorrecter *c, double v ) 
{
   return( correctedValuewithBlackAndWhite( c, v, 0.0, 1.0 ) );
}

/*!
 * @abstract Convert raw pixel value to a 8 bits pixel for screen display
 * @param value Raw pixel value
 * @param back Black level in raw data
 * @param white White level in raw data
 * @result The corrected value, the range is 0 for black to 255 for white
 */
static inline u_char screenCorrectedValueWithBlackAndWhite(
                                                      LynkeosGammaCorrecter *c,
                                                      double value,
                                                      double black,
                                                      double white )
{
   u_char res;

   if (!isfinite(value) || value <= black)
      res = 0;
   else if ( value >= white )
      res = 255;
   else
      res = c->_lut[(u_long)((value - black)/(white - black)*c->_lutSize)];

   return( res );
}

/*!
 * @abstract Convert a [0..1] pixel value to a 8 bits pixel for screen display
 * @param value pixel value
 * @result The corrected value, the range is 0 for black to 255 for white
 */
static inline u_char screenCorrectedValue( LynkeosGammaCorrecter *c,
                                          double value )
{
   return( screenCorrectedValueWithBlackAndWhite(c,value,0.0,1.0) );
}

#endif