aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2014-08-17 17:49:37 -0400
committerMatthew Hoops2014-08-17 17:49:37 -0400
commit6642f6df9ed8097fa9aca293ba28b0f7384344f0 (patch)
tree0c5af50a6df153e6f16ab0c0d18e6baa46c2ca8c
parent422922fec206b768de8e2a9333851b366bd13fd4 (diff)
downloadscummvm-rg350-6642f6df9ed8097fa9aca293ba28b0f7384344f0.tar.gz
scummvm-rg350-6642f6df9ed8097fa9aca293ba28b0f7384344f0.tar.bz2
scummvm-rg350-6642f6df9ed8097fa9aca293ba28b0f7384344f0.zip
GRAPHICS: Improve color bit depth conversion
Data is no longer truncated it so should be more accurate. See pull request #486 for more info.
-rw-r--r--graphics/pixelformat.h132
1 files changed, 125 insertions, 7 deletions
diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h
index 792833a8e3..00db6702fc 100644
--- a/graphics/pixelformat.h
+++ b/graphics/pixelformat.h
@@ -27,6 +27,97 @@
namespace Graphics {
+/** Template to expand from an n-bit component to an 8-bit component */
+template<int depth>
+struct ColorComponent {
+};
+
+template<>
+struct ColorComponent<0> {
+ static inline uint expand(uint value) {
+ return 0;
+ }
+};
+
+template<>
+struct ColorComponent<1> {
+ static inline uint expand(uint value) {
+ value &= 1;
+ return value |
+ (value << 1) |
+ (value << 2) |
+ (value << 3) |
+ (value << 4) |
+ (value << 5) |
+ (value << 6) |
+ (value << 7);
+ }
+};
+
+template<>
+struct ColorComponent<2> {
+ static inline uint expand(uint value) {
+ value &= 3;
+ return value |
+ (value << 2) |
+ (value << 4) |
+ (value << 6);
+ }
+};
+
+template<>
+struct ColorComponent<3> {
+ static inline uint expand(uint value) {
+ value &= 7;
+ return (value << 5) |
+ (value << 2) |
+ (value >> 1);
+ }
+};
+
+template<>
+struct ColorComponent<4> {
+ static inline uint expand(uint value) {
+ value &= 15;
+ return value |
+ (value << 4);
+ }
+};
+
+template<>
+struct ColorComponent<5> {
+ static inline uint expand(uint value) {
+ value &= 31;
+ return (value << 3) |
+ (value >> 2);
+ }
+};
+
+template<>
+struct ColorComponent<6> {
+ static inline uint expand(uint value) {
+ value &= 63;
+ return (value << 2) |
+ (value >> 4);
+ }
+};
+
+template<>
+struct ColorComponent<7> {
+ static inline uint expand(uint value) {
+ value &= 127;
+ return (value << 1) |
+ (value >> 6);
+ }
+};
+
+template<>
+struct ColorComponent<8> {
+ static inline uint expand(uint value) {
+ return value & 255;
+ }
+};
+
/**
* A pixel format description.
*
@@ -91,16 +182,16 @@ struct PixelFormat {
}
inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
- r = ((color >> rShift) << rLoss) & 0xFF;
- g = ((color >> gShift) << gLoss) & 0xFF;
- b = ((color >> bShift) << bLoss) & 0xFF;
+ r = expand(rBits(), color >> rShift);
+ g = expand(gBits(), color >> gShift);
+ b = expand(bBits(), color >> bShift);
}
inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
- a = (aBits() == 0) ? 0xFF : (((color >> aShift) << aLoss) & 0xFF);
- r = ((color >> rShift) << rLoss) & 0xFF;
- g = ((color >> gShift) << gLoss) & 0xFF;
- b = ((color >> bShift) << bLoss) & 0xFF;
+ a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift);
+ r = expand(rBits(), color >> rShift);
+ g = expand(gBits(), color >> gShift);
+ b = expand(bBits(), color >> bShift);
}
//////////////////////////////////////////////////////////////////////
@@ -142,6 +233,33 @@ struct PixelFormat {
inline uint aMax() const {
return (1 << aBits()) - 1;
}
+
+ /** Expand a given bit-depth component to a full 8-bit component */
+ static inline uint expand(uint bits, uint color) {
+ switch (bits) {
+ case 0:
+ return ColorComponent<0>::expand(color);
+ case 1:
+ return ColorComponent<1>::expand(color);
+ case 2:
+ return ColorComponent<2>::expand(color);
+ case 3:
+ return ColorComponent<3>::expand(color);
+ case 4:
+ return ColorComponent<4>::expand(color);
+ case 5:
+ return ColorComponent<5>::expand(color);
+ case 6:
+ return ColorComponent<6>::expand(color);
+ case 7:
+ return ColorComponent<7>::expand(color);
+ case 8:
+ return ColorComponent<8>::expand(color);
+ }
+
+ // Unsupported
+ return 0;
+ }
};
} // End of namespace Graphics