/* color.c */ #include #include #include "vector.h" #include "color.h" #include "cie.h" #include "mymath.h" #include "tonemapping.h" #include "render.h" RGB NullRGB = {0.0, 0.0, 0.0}, Black = {0.0, 0.0, 0.0}, Red = {1.0, 0.0, 0.0}, Yellow = {1.0, 1.0, 0.0}, Green = {0.0, 1.0, 0.0}, Turquoise = {0.0, 1.0, 1.0}, Blue = {0.0, 0.0, 1.0}, Magenta = {1.0, 0.0, 1.0}, White = {1.0, 1.0, 1.0}; /* --------------------------------------------------------------------------- `RescaleRadiance' Rescale real world radiance using appropiately set up tone mapping algorithm. ------------------------------------------------------------------------- */ COLOR *RescaleRadiance(COLOR in, COLOR *out) { COLORSCALE(tmopts.pow_bright_adjust, in, in); *out = TonemapScaleForDisplay(in); return out; } RGB *ColorToRGB(COLOR col, RGB *rgb) { #ifdef RGBCOLORS RGBSET(*rgb, col.spec[0], col.spec[1], col.spec[2]); #else xyz_rgb(col.spec, (float *)rgb); #endif return rgb; } COLOR *RGBToColor(RGB rgb, COLOR *col) { #ifdef RGBCOLORS COLORSET(*col, rgb.r, rgb.g, rgb.b); #else rgb_xyz((float *)&rgb, col->spec); #endif return col; } LUV *ColorToLUV(COLOR col, LUV *luv) { #ifdef RGBCOLORS { float xyz[3]; rgb_xyz(col.spec, xyz); xyz_luv(xyz, (float *)luv, CIE_WHITE_Y); /* CHECK!!! */ } #else xyz_luv(col.spec, (float *)luv, CIE_WHITE_Y); #endif return luv; } COLOR *LUVToColor(LUV luv, COLOR *col) { #ifdef RGBCOLORS { float xyz[3]; luv_xyz((float *)&luv, xyz, CIE_WHITE_Y); /* CHECK!!! */ xyz_rgb(xyz, col->spec); } #else luv_xyz((float *)&luv, col->spec, CIE_WHITE_Y); #endif return col; } LUV *ColorToDisplayLUV(COLOR col, LUV *luv) { RGB rgb; float xyz[3]; RadianceToRGB(col, &rgb); rgb_xyz((float*)&rgb, xyz); xyz_luv(xyz, (float*)luv, CIE_DISPLAY_WHITE_Y); return luv; } /* --------------------------------------------------------------------------- `ColorToRGB' Does most to convert computed radiances to RGB colors ready for display on the screen: 1) nonlinear rescale of radiance from the almost unlimited range in reality (and the computations) to the limited range of the display device. 2) colormodel conversion from the color model used for the computations to an RGB triplet for display on the screen 3) clipping of RGB values to the range [0,1]. Gamma correction is performed during rendering. MISSING: Gamut mapping ------------------------------------------------------------------------- */ /* If the largest RGB color component is larger than 1, this routine * rescales all components proportionally so the largest will be equal to * 1 now. */ static void RGBClipProp(RGB *rgb) { float s = RGBMAXCOMPONENT(*rgb); if (s > 1.) { rgb->r /= s; rgb->g /= s; rgb->b /= s; } } RGB *RadianceToRGB(COLOR color, RGB *rgb) { RescaleRadiance(color, &color); ColorToRGB(color, rgb); RGBCLIP(*rgb); /* RGBClipProp(rgb); */ return rgb; }