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
|
# include "bitmapConfig.h"
# include "bmintern.h"
# define y0 math_y0
# define y1 math_y1
# include <math.h>
# undef y0
# undef y1
# include <appDebugon.h>
/************************************************************************/
/* */
/* Simple gamma correction of images. */
/* */
/* 1) Check input. */
/* 2) Determine the maximum value of an individual component. */
/* 3) Fill a gamma correction array for correcting the individual */
/* samples. The order of the values in the array makes it possible */
/* to map the values in the bitmap without knowing the exact color */
/* encoding scheme in the image. */
/* 4) Make an exact copy of the input image. */
/* 5) And map the component values inside the image to the mapped */
/* values. */
/* 6) Copy the result to the output destination. */
/* */
/************************************************************************/
# define MAX_COMPONENTS 4
int bmGammaCorrect( BitmapDescription * bdOut,
const BitmapDescription * bdIn,
unsigned char ** pBufOut,
const unsigned char * bufIn,
double gammaValue )
{
int map[256*MAX_COMPONENTS];
double gammas[MAX_COMPONENTS];
int * mp;
int mxv;
int i;
int j;
unsigned char * bufOut;
BitmapDescription bd;
bmInitDescription( &bd );
/* 1 */
if ( gammaValue <= 0.0001 )
{ FDEB(gammaValue); return -1; }
if ( bdIn->bdBitsPerSample > 8 )
{ LDEB(bdIn->bdBitsPerSample); return -1; }
for ( j= 0; j < bdIn->bdSamplesPerPixel; j++ )
{ gammas[j]= gammaValue; }
/* 2 */
mxv= 1;
for ( i= 0; i < bdIn->bdBitsPerSample; i++ )
{ mxv *= 2; }
mxv--;
/* 3 */
mp= map;
for ( i= 0; i <= mxv; i++ )
{
for ( j= 0; j < bdIn->bdSamplesPerPixel; j++ )
{ *(mp++)= mxv* pow( (double)i/(double)mxv, gammas[j] ); }
}
/* 4 */
bufOut= malloc( bdIn->bdBufferLength+ bdIn->bdSamplesPerPixel- 1 );
if ( ! bufOut )
{ LXDEB(bdIn->bdBufferLength,bufOut); return -1; }
if ( bmCopyDescription( &bd, bdIn ) )
{ LDEB(1); free( bufOut ); return -1; }
memcpy( bufOut, bufIn, bdIn->bdBufferLength );
/* 5 */
if ( bmMapImageColors( &bd, map, bufOut ) )
{
LDEB(1);
bmCleanDescription( &bd );
free( bufOut );
return -1;
}
/* 6 */
if ( bmCopyDescription( bdOut, &bd ) )
{
LDEB(1);
bmCleanDescription( &bd );
free( bufOut );
return -1;
}
*pBufOut= bufOut; return 0;
}
|