// This code is in the public domain -- jim@tilander.org #include "ColorSpace.h" #include "nvimage/Image.h" #include "nvmath/Color.h" namespace nv { void ColorSpace::RGBtoYCoCg_R(Image* img) { const uint w = img->width(); const uint h = img->height(); for( uint y=0; y < h; y++ ) { for( uint x=0; x < w; x++ ) { Color32 pixel = img->pixel(x, y); const int r = pixel.r; const int g = pixel.g; const int b = pixel.b; const int Co = r - b; const int t = b + Co/2; const int Cg = g - t; const int Y = t + Cg/2; // Just saturate the chroma here (we loose out of one bit in each channel) // this just means that we won't have as high dynamic range. Perhaps a better option // is to loose the least significant bit instead? pixel.r = clamp(Co + 128, 0, 255); pixel.g = clamp(Cg + 128, 0, 255); pixel.b = 0; pixel.a = Y; } } } void ColorSpace::YCoCg_RtoRGB(Image* img) { const uint w = img->width(); const uint h = img->height(); for( uint y=0; y < h; y++ ) { for( uint x=0; x < w; x++ ) { Color32 pixel = img->pixel(x, y); const int Co = (int)pixel.r - 128; const int Cg = (int)pixel.g - 128; const int Y = pixel.a; const int t = Y - Cg/2; const int g = Cg + t; const int b = t - Co/2; const int r = b + Co; pixel.r = r; pixel.g = g; pixel.b = b; pixel.a = 1; } } } }