diff --git a/graphics/colormasks.h b/graphics/colormasks.h index d845b4f0886..54e38e7fed8 100644 --- a/graphics/colormasks.h +++ b/graphics/colormasks.h @@ -23,7 +23,7 @@ #ifndef GRAPHICS_COLORMASKS_H #define GRAPHICS_COLORMASKS_H -#include "graphics/pixelformat.h" +#include "common/scummsys.h" namespace Graphics { @@ -287,63 +287,6 @@ struct ColorMasks<8888> { typedef uint32 PixelType; }; -template -uint32 RGBToColor(uint8 r, uint8 g, uint8 b) { - return T::kAlphaMask | - (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) | - (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) | - (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask); -} - -template -uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) { - return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) | - (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) | - (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) | - (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask); -} - -template -void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) { - r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits); - g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits); - b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits); -} - -template -void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) { - a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits); - r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits); - g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits); - b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits); -} - - - -/** - * Convert a 'bitFormat' as defined by one of the ColorMasks - * into a PixelFormat. - */ -template -PixelFormat createPixelFormat() { - PixelFormat format; - - format.bytesPerPixel = ColorMasks::kBytesPerPixel; - - format.rLoss = 8 - ColorMasks::kRedBits; - format.gLoss = 8 - ColorMasks::kGreenBits; - format.bLoss = 8 - ColorMasks::kBlueBits; - format.aLoss = 8 - ColorMasks::kAlphaBits; - - format.rShift = ColorMasks::kRedShift; - format.gShift = ColorMasks::kGreenShift; - format.bShift = ColorMasks::kBlueShift; - format.aShift = ColorMasks::kAlphaShift; - - return format; -} - - } // End of namespace Graphics #endif diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h index 9af1919627f..7c869dc34b4 100644 --- a/graphics/pixelformat.h +++ b/graphics/pixelformat.h @@ -26,6 +26,8 @@ #include "common/scummsys.h" #include "common/str.h" +#include "graphics/colormasks.h" + namespace Graphics { /** @@ -212,6 +214,14 @@ struct PixelFormat { (( b >> bLoss) << bShift); } + template + inline uint32 RGBToColorT(uint8 r, uint8 g, uint8 b) const { + return T::kAlphaMask | + (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) | + (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) | + (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask); + } + /** Return an ARGB color value from alpha, red, green, and blue values. */ inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const { return @@ -221,6 +231,14 @@ struct PixelFormat { ((b >> bLoss) << bShift); } + template + inline uint32 ARGBToColorT(uint8 a, uint8 r, uint8 g, uint8 b) const { + return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) | + (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) | + (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) | + (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask); + } + /** Retrieve red, green, and blue values from an RGB color value. */ inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const { r = expand(rBits(), color >> rShift); @@ -228,6 +246,13 @@ struct PixelFormat { b = expand(bBits(), color >> bShift); } + template + inline void colorToRGBT(uint32 color, uint8 &r, uint8 &g, uint8 &b) const { + r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits); + g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits); + b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits); + } + /** Retrieve alpha, red, green, and blue values from an ARGB color value. */ inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const { a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift); @@ -236,6 +261,14 @@ struct PixelFormat { b = expand(bBits(), color >> bShift); } + template + inline void colorToARGBT(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const { + a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits); + r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits); + g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits); + b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits); + } + /** * @name Convenience functions for getting the number of color component bits * @{ @@ -341,6 +374,51 @@ struct PixelFormat { /** Return string representation. */ Common::String toString() const; }; + +template<> +inline uint32 PixelFormat::RGBToColorT >(uint8 r, uint8 g, uint8 b) const { + return RGBToColor(r, g, b); +} + +template<> +inline uint32 PixelFormat::ARGBToColorT >(uint8 a, uint8 r, uint8 g, uint8 b) const { + return ARGBToColor(a, r, g, b); +} + +template<> +inline void PixelFormat::colorToRGBT >(uint32 color, uint8 &r, uint8 &g, uint8 &b) const { + colorToRGB(color, r, g, b); +} + +template<> +inline void PixelFormat::colorToARGBT >(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const { + colorToARGB(color, a, r, g, b); +} + +/** + * Convert a 'bitFormat' as defined by one of the ColorMasks + * into a PixelFormat. + */ +template +PixelFormat createPixelFormat() { + PixelFormat format; + + format.bytesPerPixel = ColorMasks::kBytesPerPixel; + + format.rLoss = 8 - ColorMasks::kRedBits; + format.gLoss = 8 - ColorMasks::kGreenBits; + format.bLoss = 8 - ColorMasks::kBlueBits; + format.aLoss = 8 - ColorMasks::kAlphaBits; + + format.rShift = ColorMasks::kRedShift; + format.gShift = ColorMasks::kGreenShift; + format.bShift = ColorMasks::kBlueShift; + format.aShift = ColorMasks::kAlphaShift; + + return format; +} + + /** @} */ } // End of namespace Graphics diff --git a/graphics/scaler/thumbnail_intern.cpp b/graphics/scaler/thumbnail_intern.cpp index 78fb7828d7e..6465c79ec7b 100644 --- a/graphics/scaler/thumbnail_intern.cpp +++ b/graphics/scaler/thumbnail_intern.cpp @@ -29,7 +29,7 @@ #include "graphics/scaler/intern.h" #include "graphics/palette.h" -template +template uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) { uint16 colorx1y1 = *(((const uint16 *)src)); uint16 colorx2y1 = *(((const uint16 *)src) + 1); @@ -37,10 +37,10 @@ uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) { uint16 colorx1y2 = *(((const uint16 *)(src + srcPitch))); uint16 colorx2y2 = *(((const uint16 *)(src + srcPitch)) + 1); - return interpolate16_1_1_1_1 >(colorx1y1, colorx2y1, colorx1y2, colorx2y2); + return interpolate16_1_1_1_1(colorx1y1, colorx2y1, colorx1y2, colorx2y2); } -template +template void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { // Make sure the width and height is a multiple of 2. width &= ~1; @@ -48,14 +48,14 @@ void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 for (int y = 0; y < height; y += 2) { for (int x = 0; x < width; x += 2, dstPtr += 2) { - *((uint16 *)dstPtr) = quadBlockInterpolate(src + 2 * x, srcPitch); + *((uint16 *)dstPtr) = quadBlockInterpolate(src + 2 * x, srcPitch); } dstPtr += (dstPitch - 2 * width / 2); src += 2 * srcPitch; } } -template +template void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { // Make sure the width and height is a multiple of 4 width &= ~3; @@ -63,27 +63,28 @@ void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4, dstPtr += 2) { - uint16 upleft = quadBlockInterpolate(src + 2 * x, srcPitch); - uint16 upright = quadBlockInterpolate(src + 2 * (x + 2), srcPitch); - uint16 downleft = quadBlockInterpolate(src + srcPitch * 2 + 2 * x, srcPitch); - uint16 downright = quadBlockInterpolate(src + srcPitch * 2 + 2 * (x + 2), srcPitch); + uint16 upleft = quadBlockInterpolate(src + 2 * x, srcPitch); + uint16 upright = quadBlockInterpolate(src + 2 * (x + 2), srcPitch); + uint16 downleft = quadBlockInterpolate(src + srcPitch * 2 + 2 * x, srcPitch); + uint16 downright = quadBlockInterpolate(src + srcPitch * 2 + 2 * (x + 2), srcPitch); - *((uint16 *)dstPtr) = interpolate16_1_1_1_1 >(upleft, upright, downleft, downright); + *((uint16 *)dstPtr) = interpolate16_1_1_1_1(upleft, upright, downleft, downright); } dstPtr += (dstPitch - 2 * width / 4); src += 4 * srcPitch; } } +template static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) { while (in.w / out.w >= 4 || in.h / out.h >= 4) { - createThumbnail_4<565>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h); + createThumbnail_4((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h); in.w /= 4; in.h /= 4; } while (in.w / out.w >= 2 || in.h / out.h >= 2) { - createThumbnail_2<565>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h); + createThumbnail_2((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h); in.w /= 2; in.h /= 2; } @@ -134,13 +135,13 @@ static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) { // Look up colors at the points uint8 p1R, p1G, p1B; - Graphics::colorToRGB >(READ_UINT16(in.getBasePtr(x1, y1)), p1R, p1G, p1B); + in.format.colorToRGBT(READ_UINT16(in.getBasePtr(x1, y1)), p1R, p1G, p1B); uint8 p2R, p2G, p2B; - Graphics::colorToRGB >(READ_UINT16(in.getBasePtr(x2, y1)), p2R, p2G, p2B); + in.format.colorToRGBT(READ_UINT16(in.getBasePtr(x2, y1)), p2R, p2G, p2B); uint8 p3R, p3G, p3B; - Graphics::colorToRGB >(READ_UINT16(in.getBasePtr(x1, y2)), p3R, p3G, p3B); + in.format.colorToRGBT(READ_UINT16(in.getBasePtr(x1, y2)), p3R, p3G, p3B); uint8 p4R, p4G, p4B; - Graphics::colorToRGB >(READ_UINT16(in.getBasePtr(x2, y2)), p4R, p4G, p4B); + in.format.colorToRGBT(READ_UINT16(in.getBasePtr(x2, y2)), p4R, p4G, p4B); const float xDiff = xFrac - x1; const float yDiff = yFrac - y1; @@ -149,7 +150,7 @@ static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) { uint8 pG = (uint8)((1 - yDiff) * ((1 - xDiff) * p1G + xDiff * p2G) + yDiff * ((1 - xDiff) * p3G + xDiff * p4G)); uint8 pB = (uint8)((1 - yDiff) * ((1 - xDiff) * p1B + xDiff * p2B) + yDiff * ((1 - xDiff) * p3B + xDiff * p4B)); - WRITE_UINT16(dst, Graphics::RGBToColor >(pR, pG, pB)); + WRITE_UINT16(dst, out.format.RGBToColorT(pR, pG, pB)); dst += 2; } @@ -203,7 +204,7 @@ static bool grabScreen565(Graphics::Surface *surf) { screenFormat.colorToRGB(col, r, g, b); } - *((uint16 *)surf->getBasePtr(x, y)) = Graphics::RGBToColor >(r, g, b); + *((uint16 *)surf->getBasePtr(x, y)) = surf->format.RGBToColor(r, g, b); } } @@ -222,7 +223,8 @@ static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) { } out.create(kThumbnailWidth, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); - scaleThumbnail(in, out); + assert(out.format == Graphics::createPixelFormat<565>()); + scaleThumbnail >(in, out); in.free(); return true; } @@ -251,7 +253,7 @@ bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, g = palette[pixels[y * w + x] * 3 + 1]; b = palette[pixels[y * w + x] * 3 + 2]; - *((uint16 *)screen.getBasePtr(x, y)) = Graphics::RGBToColor >(r, g, b); + *((uint16 *)screen.getBasePtr(x, y)) = screen.format.RGBToColor(r, g, b); } } @@ -277,7 +279,7 @@ bool createScreenShot(Graphics::Surface &surf) { byte r = 0, g = 0, b = 0, a = 0; uint32 col = READ_UINT32(screen->getBasePtr(x, y)); screenFormat.colorToARGB(col, a, r, g, b); - *((uint32 *)surf.getBasePtr(x, y)) = Graphics::ARGBToColor >(a, r, g, b); + *((uint32 *)surf.getBasePtr(x, y)) = surf.format.ARGBToColor(a, r, g, b); } } g_system->unlockScreen(); diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index e59928d5cb1..2cea54dac07 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -22,7 +22,7 @@ #include "graphics/thumbnail.h" #include "graphics/scaler.h" -#include "graphics/colormasks.h" +#include "graphics/pixelformat.h" #include "common/endian.h" #include "common/algorithm.h" #include "common/system.h"