diff --git a/project/vc8/nvimage/nvimage.vcproj b/project/vc8/nvimage/nvimage.vcproj
index 1b5d677..db24118 100644
--- a/project/vc8/nvimage/nvimage.vcproj
+++ b/project/vc8/nvimage/nvimage.vcproj
@@ -82,11 +82,12 @@
/>
+
+
@@ -327,6 +331,10 @@
RelativePath="..\..\..\src\nvimage\ColorBlock.h"
>
+
+
diff --git a/src/nvimage/CMakeLists.txt b/src/nvimage/CMakeLists.txt
index 3f66b00..6222262 100644
--- a/src/nvimage/CMakeLists.txt
+++ b/src/nvimage/CMakeLists.txt
@@ -25,7 +25,9 @@ SET(IMAGE_SRCS
NormalMipmap.h
NormalMipmap.cpp
PsdFile.h
- TgaFile.h)
+ TgaFile.h
+ ColorSpace.h
+ ColorSpace.cpp)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/nvimage/ColorSpace.cpp b/src/nvimage/ColorSpace.cpp
new file mode 100644
index 0000000..6ee87c5
--- /dev/null
+++ b/src/nvimage/ColorSpace.cpp
@@ -0,0 +1,66 @@
+#include "ColorSpace.h"
+#include
+#include
+#include
+
+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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/nvimage/ColorSpace.h b/src/nvimage/ColorSpace.h
new file mode 100644
index 0000000..1451b98
--- /dev/null
+++ b/src/nvimage/ColorSpace.h
@@ -0,0 +1,20 @@
+
+#ifndef NV_IMAGE_COLORSPACE_H
+#define NV_IMAGE_COLORSPACE_H
+
+namespace nv
+{
+ class Image;
+
+ // Defines simple mappings between different color spaces and encodes them in the
+ // input image.
+ namespace ColorSpace
+ {
+ void RGBtoYCoCg_R(Image* img);
+ void YCoCg_RtoRGB(Image* img);
+ }
+}
+
+
+
+#endif
diff --git a/src/nvtt/Compressor.cpp b/src/nvtt/Compressor.cpp
index 788724f..5bdb014 100644
--- a/src/nvtt/Compressor.cpp
+++ b/src/nvtt/Compressor.cpp
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include "Compressor.h"
#include "InputOptions.h"
@@ -482,6 +483,17 @@ bool Compressor::Private::initMipmap(Mipmap & mipmap, const InputOptions::Privat
premultiplyAlphaMipmap(mipmap, inputOptions);
}
+ // Apply gamma space color transforms:
+ if (inputOptions.colorTransform == ColorTransform_YCoCg)
+ {
+ ColorSpace::RGBtoYCoCg_R(mipmap.asMutableFixedImage());
+ }
+ else if (inputOptions.colorTransform == ColorTransform_ScaledYCoCg)
+ {
+ // @@ TODO
+ //ColorSpace::RGBtoYCoCg_R(mipmap.asMutableFixedImage());
+ }
+
return true;
}
diff --git a/src/nvtt/nvtt.h b/src/nvtt/nvtt.h
index 12fcc71..be4e72e 100644
--- a/src/nvtt/nvtt.h
+++ b/src/nvtt/nvtt.h
@@ -156,8 +156,10 @@ namespace nvtt
enum ColorTransform
{
ColorTransform_None,
- ColorTransform_Linear,
- ColorTransform_Swizzle
+ ColorTransform_Linear, ///< Not implemented.
+ ColorTransform_Swizzle, ///< Not implemented.
+ ColorTransform_YCoCg, ///< Transform into r=Co, g=Cg, b=0, a=Y
+ ColorTransform_ScaledYCoCg, ///< Not implemented.
};
/// Extents rounding mode.