void ChangeColors(double gamma, unsigned char *tab, unsigned short nb_bits) { unsigned char *pnew_val = tab ; double max_val = (double) ((1 << nb_bits) - 1) ; unsigned short i ; for ( i = 0; i <= max_val; i++, pnew_val++ ) *pnew_val = (short) ( 0.5 + GammaFunc( i, max_val, gamma ) ) ; }
Pixel ReverseDCIconverter::convert(const Pixel &pix) const { Pixel xyz = pix; // X'Y'Z' to XYZ xyz.x = GammaFunc(xyz.x, _xyz_gamma); xyz.y = GammaFunc(xyz.y, _xyz_gamma); xyz.z = GammaFunc(xyz.z, _xyz_gamma); // Convert XYZ to RGB Pixel rgb = xyz * _xyz2rgb_matrix; float &r = rgb[0]; float &g = rgb[1]; float &b = rgb[2]; // Linear RGB to Video RGB (RGB to R'G'B') if(_curve == sRGB) { r = LinTosRGB(r); g = LinTosRGB(g); b = LinTosRGB(b); } else if(_curve == Rec709) { r = LinToRec709(r); g = LinToRec709(g); b = LinToRec709(b); } else if(_curve == ProPhotoRGB) { r = LinToProPhotoRGB(r); g = LinToProPhotoRGB(g); b = LinToProPhotoRGB(b); } else if(_curve == Gamma) { r = GammaFunc(r, 1.f / _gamma); g = GammaFunc(g, 1.f / _gamma); b = GammaFunc(b, 1.f / _gamma); } else { assert(_curve == Linear); } return rgb; }
Pixel ForwardDCIconverter::convert(const Pixel &pix) const { Pixel rgb = pix; float &r = rgb[0]; float &g = rgb[1]; float &b = rgb[2]; // Video RGB to linear RGB (R'G'B' to RGB) if(_curve == sRGB) { r = sRGBtoLin(r); g = sRGBtoLin(g); b = sRGBtoLin(b); } else if(_curve == Rec709) { r = Rec709toLin(r); g = Rec709toLin(g); b = Rec709toLin(b); } else if(_curve == ProPhotoRGB) { r = ProPhotoRGBtoLin(r); g = ProPhotoRGBtoLin(g); b = ProPhotoRGBtoLin(b); } else if(_curve == Gamma) { r = GammaFunc(r, _gamma); g = GammaFunc(g, _gamma); b = GammaFunc(b, _gamma); } else { assert(_curve == Linear); } // Convert to XYZ Pixel xyz = rgb * _rgb2xyz_matrix; // XYZ to X'Y'Z' xyz.x = GammaFunc(xyz.x, 1.f / _xyz_gamma); xyz.y = GammaFunc(xyz.y, 1.f / _xyz_gamma); xyz.z = GammaFunc(xyz.z, 1.f / _xyz_gamma); return xyz; }
LDV_STATUS cdecl Run(LDV_IMAGE *in, LDV_PARAMS *params, LDV_IMAGE *out) { LDV_PALETTE *vdi_palette = &in->Palette ; VDI_ELEMENTPAL *vdi_epal ; double rgamma, ggamma, bgamma ; short vdi_index ; short cancel = 0 ; if ( (params->Param[0].s / 100.0) != gamma_rgb ) { gamma_rgb = params->Param[0].s / 100.0 ; params->Param[1].s = params->Param[0].s ; params->Param[2].s = params->Param[0].s ; params->Param[3].s = params->Param[0].s ; } rgamma = params->Param[1].s / 100.0 ; ggamma = params->Param[2].s / 100.0 ; bgamma = params->Param[3].s / 100.0 ; if ( in->Raster.fd_nplanes <= 8 ) { if ( vdi_palette == NULL ) return( ELDV_GENERALFAILURE ) ; vdi_epal = vdi_palette->Pal ; if ( vdi_epal == NULL ) return( ELDV_GENERALFAILURE ) ; for ( vdi_index = 0; vdi_index < vdi_palette->NbColors; vdi_index++, vdi_epal++ ) { vdi_epal->Red = (short) ( 0.5 + GammaFunc( vdi_epal->Red, 1000.0, rgamma ) ) ; if ( ggamma == rgamma ) vdi_epal->Green = vdi_epal->Red ; else vdi_epal->Green = (short) ( 0.5 + GammaFunc( vdi_epal->Green, 1000.0, ggamma ) ) ; if ( bgamma == rgamma ) vdi_epal->Blue = vdi_epal->Red ; else vdi_epal->Blue = (short) ( 0.5 + GammaFunc( vdi_epal->Blue, 1000.0, bgamma ) ) ; } } else { REMAP_COLORS rc ; MFDB *img = &in->Raster ; long *pt_line32, nb_pts_in_line ; short *pt_line16, y, pc, is_15bits, cancel=0 ; unsigned short nb_bits_red=8, nb_bits_green=8, nb_bits_blue=8 ; /* Sur 32 bits par defaut */ CHECK_VAPI(Vapi) ; rc.red = RedRemap ; rc.green = GreenRemap ; rc.blue = BlueRemap ; rc.nb_pts = (long) (1 + params->x2 - params->x1) ; is_15bits = Vapi->RaIs15Bits() ; if ( img->fd_nplanes == 16 ) { nb_bits_red = 5 ; nb_bits_green = is_15bits ? 5:6 ; nb_bits_blue = 5 ; } /* Remet a jour les precalculs de pourcentage sur les composantes si necessaire */ if ( rgamma != gamma_red ) ChangeColors( rgamma, RedRemap, nb_bits_red ) ; if ( ggamma != gamma_green ) ChangeColors( ggamma, GreenRemap, nb_bits_green ) ; if ( bgamma != gamma_blue ) ChangeColors( bgamma, BlueRemap, nb_bits_blue ) ; nb_pts_in_line = ALIGN16(img->fd_w) ; pt_line16 = (short *) img->fd_addr ; pt_line16 += (long)(params->y1) * nb_pts_in_line ; pt_line16 += params->x1 ; pt_line32 = (long *) img->fd_addr ; pt_line32 += (long)(params->y1) * nb_pts_in_line ; pt_line32 += params->x1 ; for ( y = params->y1; !cancel && (y <= params->y2); y++ ) { if ( img->fd_nplanes == 16 ) { rc.pt_img = pt_line16 ; pt_line16 += nb_pts_in_line ; if ( is_15bits ) Vapi->RaTC15RemapColors( &rc ) ; else Vapi->RaTC16RemapColors( &rc ) ; } else { rc.pt_img = pt_line32 ; pt_line32 += nb_pts_in_line ; Vapi->RaTC32RemapColors( &rc ) ; } if ( ( y & 0x0F ) == 0x0F ) { pc = (short) ( ( 100L * (long)(y - params->y1) ) / (long)(params->y2 - params->y1) ) ; cancel = Vapi->PrSetProgEx( pc ) ; } } } gamma_red = rgamma ; gamma_green = ggamma ; gamma_blue = bgamma ; return( cancel ? ELDV_CANCELLED : ELDV_NOERROR ) ; }