#include #include static const double gammaval = 2.2; /** * Returns a nonlinear R'G'B' channel value in 0-1 from a linear RGB * channel value in 0-1. */ double linear_to_nonlinear_rgb( double val ) { return pow( val, 1.0 / gammaval ); } /** * Returns a linear RGB channel value in 0-1 from a nonlinear R'G'B' * channel value in 0-1. */ double nonlinear_to_linear_rgb( double val ) { return pow( val, gammaval ); } void outputRgb24Scanline( unsigned char *output, Pixel *scanline, int w ) { for(; w; w-- ) { double r = scanline->r; double g = scanline->g; double b = scanline->b; if( r > 1.0 ) r = 1.0; if( r < 0.0 ) r = 0.0; if( g > 1.0 ) g = 1.0; if( g < 0.0 ) g = 0.0; if( b > 1.0 ) b = 1.0; if( b < 0.0 ) b = 0.0; r = ( linear_to_nonlinear_rgb( r ) * 255.0 ) + 0.5; g = ( linear_to_nonlinear_rgb( g ) * 255.0 ) + 0.5; b = ( linear_to_nonlinear_rgb( b ) * 255.0 ) + 0.5; *output++ = (unsigned char) r; *output++ = (unsigned char) g; *output++ = (unsigned char) b; scanline++; } } void outputRgb24ScanlineDownsample2( unsigned char *output, Pixel *top, Pixel *bot, int inw ) { int w = inw - 1; for(; w; w-- ) { double r = ( top->r + (top + 1)->r + bot->r + (bot + 1)->r ) / 4.0; double g = ( top->g + (top + 1)->g + bot->g + (bot + 1)->g ) / 4.0; double b = ( top->b + (top + 1)->b + bot->b + (bot + 1)->b ) / 4.0; if( r > 1.0 ) r = 1.0; if( r < 0.0 ) r = 0.0; if( g > 1.0 ) g = 1.0; if( g < 0.0 ) g = 0.0; if( b > 1.0 ) b = 1.0; if( b < 0.0 ) b = 0.0; r = ( linear_to_nonlinear_rgb( r ) * 255.0 ) + 0.5; g = ( linear_to_nonlinear_rgb( g ) * 255.0 ) + 0.5; b = ( linear_to_nonlinear_rgb( b ) * 255.0 ) + 0.5; *output++ = (unsigned char) r; *output++ = (unsigned char) g; *output++ = (unsigned char) b; top++; bot++; } }