GRAPHICS: Integrate Graphics::ColorMasks with Graphics::PixelFormat

This commit is contained in:
Cameron Cawley 2021-05-14 21:59:23 +01:00 committed by Eugene Sandulenko
parent 64fc110586
commit 82a85494cd
4 changed files with 103 additions and 80 deletions

View file

@ -23,7 +23,7 @@
#ifndef GRAPHICS_COLORMASKS_H #ifndef GRAPHICS_COLORMASKS_H
#define GRAPHICS_COLORMASKS_H #define GRAPHICS_COLORMASKS_H
#include "graphics/pixelformat.h" #include "common/scummsys.h"
namespace Graphics { namespace Graphics {
@ -287,63 +287,6 @@ struct ColorMasks<8888> {
typedef uint32 PixelType; typedef uint32 PixelType;
}; };
template<class T>
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<class T>
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<class T>
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<class T>
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<int bitFormat>
PixelFormat createPixelFormat() {
PixelFormat format;
format.bytesPerPixel = ColorMasks<bitFormat>::kBytesPerPixel;
format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
format.aLoss = 8 - ColorMasks<bitFormat>::kAlphaBits;
format.rShift = ColorMasks<bitFormat>::kRedShift;
format.gShift = ColorMasks<bitFormat>::kGreenShift;
format.bShift = ColorMasks<bitFormat>::kBlueShift;
format.aShift = ColorMasks<bitFormat>::kAlphaShift;
return format;
}
} // End of namespace Graphics } // End of namespace Graphics
#endif #endif

View file

@ -26,6 +26,8 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "common/str.h" #include "common/str.h"
#include "graphics/colormasks.h"
namespace Graphics { namespace Graphics {
/** /**
@ -212,6 +214,14 @@ struct PixelFormat {
(( b >> bLoss) << bShift); (( b >> bLoss) << bShift);
} }
template<class T>
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. */ /** Return an ARGB color value from alpha, red, green, and blue values. */
inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const { inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const {
return return
@ -221,6 +231,14 @@ struct PixelFormat {
((b >> bLoss) << bShift); ((b >> bLoss) << bShift);
} }
template<class T>
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. */ /** Retrieve red, green, and blue values from an RGB color value. */
inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const { inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
r = expand(rBits(), color >> rShift); r = expand(rBits(), color >> rShift);
@ -228,6 +246,13 @@ struct PixelFormat {
b = expand(bBits(), color >> bShift); b = expand(bBits(), color >> bShift);
} }
template<class T>
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. */ /** 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 { inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift); a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift);
@ -236,6 +261,14 @@ struct PixelFormat {
b = expand(bBits(), color >> bShift); b = expand(bBits(), color >> bShift);
} }
template<class T>
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 * @name Convenience functions for getting the number of color component bits
* @{ * @{
@ -341,6 +374,51 @@ struct PixelFormat {
/** Return string representation. */ /** Return string representation. */
Common::String toString() const; Common::String toString() const;
}; };
template<>
inline uint32 PixelFormat::RGBToColorT<ColorMasks<0> >(uint8 r, uint8 g, uint8 b) const {
return RGBToColor(r, g, b);
}
template<>
inline uint32 PixelFormat::ARGBToColorT<ColorMasks<0> >(uint8 a, uint8 r, uint8 g, uint8 b) const {
return ARGBToColor(a, r, g, b);
}
template<>
inline void PixelFormat::colorToRGBT<ColorMasks<0> >(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
colorToRGB(color, r, g, b);
}
template<>
inline void PixelFormat::colorToARGBT<ColorMasks<0> >(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<int bitFormat>
PixelFormat createPixelFormat() {
PixelFormat format;
format.bytesPerPixel = ColorMasks<bitFormat>::kBytesPerPixel;
format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
format.aLoss = 8 - ColorMasks<bitFormat>::kAlphaBits;
format.rShift = ColorMasks<bitFormat>::kRedShift;
format.gShift = ColorMasks<bitFormat>::kGreenShift;
format.bShift = ColorMasks<bitFormat>::kBlueShift;
format.aShift = ColorMasks<bitFormat>::kAlphaShift;
return format;
}
/** @} */ /** @} */
} // End of namespace Graphics } // End of namespace Graphics

View file

@ -29,7 +29,7 @@
#include "graphics/scaler/intern.h" #include "graphics/scaler/intern.h"
#include "graphics/palette.h" #include "graphics/palette.h"
template<int bitFormat> template<typename ColorMask>
uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) { uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) {
uint16 colorx1y1 = *(((const uint16 *)src)); uint16 colorx1y1 = *(((const uint16 *)src));
uint16 colorx2y1 = *(((const uint16 *)src) + 1); uint16 colorx2y1 = *(((const uint16 *)src) + 1);
@ -37,10 +37,10 @@ uint16 quadBlockInterpolate(const uint8 *src, uint32 srcPitch) {
uint16 colorx1y2 = *(((const uint16 *)(src + srcPitch))); uint16 colorx1y2 = *(((const uint16 *)(src + srcPitch)));
uint16 colorx2y2 = *(((const uint16 *)(src + srcPitch)) + 1); uint16 colorx2y2 = *(((const uint16 *)(src + srcPitch)) + 1);
return interpolate16_1_1_1_1<Graphics::ColorMasks<bitFormat> >(colorx1y1, colorx2y1, colorx1y2, colorx2y2); return interpolate16_1_1_1_1<ColorMask>(colorx1y1, colorx2y1, colorx1y2, colorx2y2);
} }
template<int bitFormat> template<typename ColorMask>
void createThumbnail_2(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { 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. // Make sure the width and height is a multiple of 2.
width &= ~1; 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 y = 0; y < height; y += 2) {
for (int x = 0; x < width; x += 2, dstPtr += 2) { for (int x = 0; x < width; x += 2, dstPtr += 2) {
*((uint16 *)dstPtr) = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch); *((uint16 *)dstPtr) = quadBlockInterpolate<ColorMask>(src + 2 * x, srcPitch);
} }
dstPtr += (dstPitch - 2 * width / 2); dstPtr += (dstPitch - 2 * width / 2);
src += 2 * srcPitch; src += 2 * srcPitch;
} }
} }
template<int bitFormat> template<typename ColorMask>
void createThumbnail_4(const uint8 *src, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { 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 // Make sure the width and height is a multiple of 4
width &= ~3; 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 y = 0; y < height; y += 4) {
for (int x = 0; x < width; x += 4, dstPtr += 2) { for (int x = 0; x < width; x += 4, dstPtr += 2) {
uint16 upleft = quadBlockInterpolate<bitFormat>(src + 2 * x, srcPitch); uint16 upleft = quadBlockInterpolate<ColorMask>(src + 2 * x, srcPitch);
uint16 upright = quadBlockInterpolate<bitFormat>(src + 2 * (x + 2), srcPitch); uint16 upright = quadBlockInterpolate<ColorMask>(src + 2 * (x + 2), srcPitch);
uint16 downleft = quadBlockInterpolate<bitFormat>(src + srcPitch * 2 + 2 * x, srcPitch); uint16 downleft = quadBlockInterpolate<ColorMask>(src + srcPitch * 2 + 2 * x, srcPitch);
uint16 downright = quadBlockInterpolate<bitFormat>(src + srcPitch * 2 + 2 * (x + 2), srcPitch); uint16 downright = quadBlockInterpolate<ColorMask>(src + srcPitch * 2 + 2 * (x + 2), srcPitch);
*((uint16 *)dstPtr) = interpolate16_1_1_1_1<Graphics::ColorMasks<bitFormat> >(upleft, upright, downleft, downright); *((uint16 *)dstPtr) = interpolate16_1_1_1_1<ColorMask>(upleft, upright, downleft, downright);
} }
dstPtr += (dstPitch - 2 * width / 4); dstPtr += (dstPitch - 2 * width / 4);
src += 4 * srcPitch; src += 4 * srcPitch;
} }
} }
template<typename ColorMask>
static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) { static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) {
while (in.w / out.w >= 4 || in.h / out.h >= 4) { 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<ColorMask>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h);
in.w /= 4; in.w /= 4;
in.h /= 4; in.h /= 4;
} }
while (in.w / out.w >= 2 || in.h / out.h >= 2) { 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<ColorMask>((const uint8 *)in.getPixels(), in.pitch, (uint8 *)in.getPixels(), in.pitch, in.w, in.h);
in.w /= 2; in.w /= 2;
in.h /= 2; in.h /= 2;
} }
@ -134,13 +135,13 @@ static void scaleThumbnail(Graphics::Surface &in, Graphics::Surface &out) {
// Look up colors at the points // Look up colors at the points
uint8 p1R, p1G, p1B; uint8 p1R, p1G, p1B;
Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x1, y1)), p1R, p1G, p1B); in.format.colorToRGBT<ColorMask>(READ_UINT16(in.getBasePtr(x1, y1)), p1R, p1G, p1B);
uint8 p2R, p2G, p2B; uint8 p2R, p2G, p2B;
Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x2, y1)), p2R, p2G, p2B); in.format.colorToRGBT<ColorMask>(READ_UINT16(in.getBasePtr(x2, y1)), p2R, p2G, p2B);
uint8 p3R, p3G, p3B; uint8 p3R, p3G, p3B;
Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x1, y2)), p3R, p3G, p3B); in.format.colorToRGBT<ColorMask>(READ_UINT16(in.getBasePtr(x1, y2)), p3R, p3G, p3B);
uint8 p4R, p4G, p4B; uint8 p4R, p4G, p4B;
Graphics::colorToRGB<Graphics::ColorMasks<565> >(READ_UINT16(in.getBasePtr(x2, y2)), p4R, p4G, p4B); in.format.colorToRGBT<ColorMask>(READ_UINT16(in.getBasePtr(x2, y2)), p4R, p4G, p4B);
const float xDiff = xFrac - x1; const float xDiff = xFrac - x1;
const float yDiff = yFrac - y1; 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 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)); uint8 pB = (uint8)((1 - yDiff) * ((1 - xDiff) * p1B + xDiff * p2B) + yDiff * ((1 - xDiff) * p3B + xDiff * p4B));
WRITE_UINT16(dst, Graphics::RGBToColor<Graphics::ColorMasks<565> >(pR, pG, pB)); WRITE_UINT16(dst, out.format.RGBToColorT<ColorMask>(pR, pG, pB));
dst += 2; dst += 2;
} }
@ -203,7 +204,7 @@ static bool grabScreen565(Graphics::Surface *surf) {
screenFormat.colorToRGB(col, r, g, b); screenFormat.colorToRGB(col, r, g, b);
} }
*((uint16 *)surf->getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(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)); 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<Graphics::ColorMasks<565> >(in, out);
in.free(); in.free();
return true; 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]; g = palette[pixels[y * w + x] * 3 + 1];
b = palette[pixels[y * w + x] * 3 + 2]; b = palette[pixels[y * w + x] * 3 + 2];
*((uint16 *)screen.getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(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; byte r = 0, g = 0, b = 0, a = 0;
uint32 col = READ_UINT32(screen->getBasePtr(x, y)); uint32 col = READ_UINT32(screen->getBasePtr(x, y));
screenFormat.colorToARGB(col, a, r, g, b); screenFormat.colorToARGB(col, a, r, g, b);
*((uint32 *)surf.getBasePtr(x, y)) = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b); *((uint32 *)surf.getBasePtr(x, y)) = surf.format.ARGBToColor(a, r, g, b);
} }
} }
g_system->unlockScreen(); g_system->unlockScreen();

View file

@ -22,7 +22,7 @@
#include "graphics/thumbnail.h" #include "graphics/thumbnail.h"
#include "graphics/scaler.h" #include "graphics/scaler.h"
#include "graphics/colormasks.h" #include "graphics/pixelformat.h"
#include "common/endian.h" #include "common/endian.h"
#include "common/algorithm.h" #include "common/algorithm.h"
#include "common/system.h" #include "common/system.h"