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
|