[Scummvm-git-logs] scummvm master -> fbabd7cbcae799faac86bfd4eea0d4084c41a42e
bluegr
noreply at scummvm.org
Sat Jul 5 07:38:05 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
fbabd7cbca GRAPHICS: Support scaling 24bpp surfaces
Commit: fbabd7cbcae799faac86bfd4eea0d4084c41a42e
https://github.com/scummvm/scummvm/commit/fbabd7cbcae799faac86bfd4eea0d4084c41a42e
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2025-07-05T10:38:01+03:00
Commit Message:
GRAPHICS: Support scaling 24bpp surfaces
Changed paths:
graphics/blit/blit-scale.cpp
diff --git a/graphics/blit/blit-scale.cpp b/graphics/blit/blit-scale.cpp
index d5ee3f60deb..0b8aa799920 100644
--- a/graphics/blit/blit-scale.cpp
+++ b/graphics/blit/blit-scale.cpp
@@ -28,6 +28,7 @@
#include "graphics/pixelformat.h"
#include "graphics/transform_struct.h"
+#include "common/endian.h"
#include "common/rect.h"
#include "math/utils.h"
@@ -57,7 +58,7 @@ static void scaleVertical(byte *dst, const byte *src,
}
}
-template <typename Size>
+template <typename Color, int Size>
static void scaleNN(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
@@ -74,7 +75,7 @@ static void scaleNN(byte *dst, const byte *src,
const int dstIncY = (flipy ? -static_cast<int>(dstPitch) : static_cast<int>(dstPitch));
if (flipx) {
- dst += (dstW - 1) * sizeof(Size);
+ dst += (dstW - 1) * Size;
}
if (flipy) {
@@ -82,12 +83,16 @@ static void scaleNN(byte *dst, const byte *src,
}
for (uint32 y = 0, yoff = 0; y < dstH; y++, yoff += srcIncY) {
- const Size *srcP = (const Size *)(src + ((yoff >> 16) * srcPitch));
- Size *dst1 = (Size *)dst;
+ const byte *srcP = src + ((yoff >> 16) * srcPitch);
+ byte *dst1 = dst;
for (uint32 x = 0, xoff = 0; x < dstW; x++, xoff += srcIncX) {
- Size val = srcP[xoff >> 16];
- *dst1 = val;
- dst1 += dstIncX;
+ const byte *src1 = srcP + ((xoff >> 16) * Size);
+ if (Size == sizeof(Color)) {
+ *(Color *)dst1 = *(const Color *)src1;
+ } else {
+ memcpy(dst1, src, Size);
+ }
+ dst1 += dstIncX * Size;
}
dst += dstIncY;
}
@@ -115,13 +120,16 @@ bool scaleBlit(byte *dst, const byte *src,
switch (fmt.bytesPerPixel) {
case 1:
- scaleNN<uint8>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
+ scaleNN<uint8, 1>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
return true;
case 2:
- scaleNN<uint16>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
+ scaleNN<uint16, 2>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
+ return true;
+ case 3:
+ scaleNN<uint8, 3>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
return true;
case 4:
- scaleNN<uint32>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
+ scaleNN<uint32, 4>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, flip);
return true;
default:
break;
@@ -172,35 +180,53 @@ systems and pixel formats.
namespace {
+template <typename Color, int Size>
+inline uint32 getPixel(const byte *sp) {
+ if (Size == sizeof(Color)) {
+ return *(const Color *)sp;
+ } else {
+ return READ_UINT24(sp);
+ }
+}
+
+template <typename Color, int Size>
+inline void setPixel(byte *pc, const uint32 pix) {
+ if (Size == sizeof(Color)) {
+ *(Color *)pc = pix;
+ } else {
+ WRITE_UINT24(pc, pix);
+ }
+}
+
inline byte scaleBlitBilinearInterpolate(byte c01, byte c00, byte c11, byte c10, int ex, int ey) {
int t1 = ((((c01 - c00) * ex) >> 16) + c00) & 0xff;
int t2 = ((((c11 - c10) * ex) >> 16) + c10) & 0xff;
return (((t2 - t1) * ey) >> 16) + t1;
}
-template <typename ColorMask, typename Size>
-Size scaleBlitBilinearInterpolate(Size c01, Size c00, Size c11, Size c10, int ex, int ey,
+template <typename ColorMask, typename Color, int Size>
+void scaleBlitBilinearInterpolate(byte *dp, const byte *c01, const byte *c00, const byte *c11, const byte *c10, int ex, int ey,
const Graphics::PixelFormat &fmt) {
byte c01_a, c01_r, c01_g, c01_b;
- fmt.colorToARGBT<ColorMask>(c01, c01_a, c01_r, c01_g, c01_b);
+ fmt.colorToARGBT<ColorMask>(getPixel<Color, Size>(c01), c01_a, c01_r, c01_g, c01_b);
byte c00_a, c00_r, c00_g, c00_b;
- fmt.colorToARGBT<ColorMask>(c00, c00_a, c00_r, c00_g, c00_b);
+ fmt.colorToARGBT<ColorMask>(getPixel<Color, Size>(c00), c00_a, c00_r, c00_g, c00_b);
byte c11_a, c11_r, c11_g, c11_b;
- fmt.colorToARGBT<ColorMask>(c11, c11_a, c11_r, c11_g, c11_b);
+ fmt.colorToARGBT<ColorMask>(getPixel<Color, Size>(c11), c11_a, c11_r, c11_g, c11_b);
byte c10_a, c10_r, c10_g, c10_b;
- fmt.colorToARGBT<ColorMask>(c10, c10_a, c10_r, c10_g, c10_b);
+ fmt.colorToARGBT<ColorMask>(getPixel<Color, Size>(c10), c10_a, c10_r, c10_g, c10_b);
byte dp_a = scaleBlitBilinearInterpolate(c01_a, c00_a, c11_a, c10_a, ex, ey);
byte dp_r = scaleBlitBilinearInterpolate(c01_r, c00_r, c11_r, c10_r, ex, ey);
byte dp_g = scaleBlitBilinearInterpolate(c01_g, c00_g, c11_g, c10_g, ex, ey);
byte dp_b = scaleBlitBilinearInterpolate(c01_b, c00_b, c11_b, c10_b, ex, ey);
- return fmt.ARGBToColorT<ColorMask>(dp_a, dp_r, dp_g, dp_b);
+ setPixel<Color, Size>(dp, fmt.ARGBToColorT<ColorMask>(dp_a, dp_r, dp_g, dp_b));
}
-template <typename ColorMask, typename Size>
+template <typename ColorMask, typename Color, int Size>
void scaleBlitBilinearLogic(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
@@ -216,7 +242,7 @@ void scaleBlitBilinearLogic(byte *dst, const byte *src,
const byte *sp = src;
if (flipx) {
- sp += spixelw * sizeof(Size);
+ sp += spixelw * Size;
}
if (flipy) {
sp += srcPitch * spixelh;
@@ -224,7 +250,7 @@ void scaleBlitBilinearLogic(byte *dst, const byte *src,
int *csay = say;
for (uint y = 0; y < dstH; y++) {
- Size *dp = (Size *)(dst + (dstPitch * y));
+ byte *dp = dst + (dstPitch * y);
const byte *csp = sp;
int *csax = sax;
for (uint x = 0; x < dstW; x++) {
@@ -248,18 +274,19 @@ void scaleBlitBilinearLogic(byte *dst, const byte *src,
c11 = c10;
if (cx < spixelw) {
if (flipx) {
- c01 -= sizeof(Size);
- c11 -= sizeof(Size);
+ c01 -= Size;
+ c11 -= Size;
} else {
- c01 += sizeof(Size);
- c11 += sizeof(Size);
+ c01 += Size;
+ c11 += Size;
}
}
/*
* Draw and interpolate colors
*/
- *dp = scaleBlitBilinearInterpolate<ColorMask, Size>(*(const Size *)c01, *(const Size *)c00, *(const Size *)c11, *(const Size *)c10, ex, ey, fmt);
+ scaleBlitBilinearInterpolate<ColorMask, Color, Size>(dp, c01, c00, c11, c10, ex, ey, fmt);
+
/*
* Advance source pointer x
*/
@@ -267,15 +294,15 @@ void scaleBlitBilinearLogic(byte *dst, const byte *src,
csax++;
int sstepx = (*csax >> 16) - (*salastx >> 16);
if (flipx) {
- sp -= sstepx * sizeof(Size);
+ sp -= sstepx * Size;
} else {
- sp += sstepx * sizeof(Size);
+ sp += sstepx * Size;
}
/*
* Advance destination pointer x
*/
- dp++;
+ dp += Size;
}
/*
* Advance source pointer y
@@ -292,7 +319,7 @@ void scaleBlitBilinearLogic(byte *dst, const byte *src,
}
}
-template<typename ColorMask, typename Size, bool filtering>
+template<typename ColorMask, typename Color, int Size, bool filtering>
void rotoscaleBlitLogic(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
@@ -329,7 +356,7 @@ void rotoscaleBlitLogic(byte *dst, const byte *src,
int sw = srcW - 1;
int sh = srcH - 1;
- Size *pc = (Size *)dst;
+ byte *pc = dst;
for (uint y = 0; y < dstH; y++) {
int t = cy - y;
@@ -347,15 +374,15 @@ void rotoscaleBlitLogic(byte *dst, const byte *src,
if (filtering) {
if ((dx > -1) && (dy > -1) && (dx < sw) && (dy < sh)) {
- const byte *sp = src + dy * srcPitch + dx * sizeof(Size);
- Size c00, c01, c10, c11;
- c00 = *(const Size *)sp;
- sp += sizeof(Size);
- c01 = *(const Size *)sp;
+ const byte *sp = src + dy * srcPitch + dx * Size;
+ const byte *c00, *c01, *c10, *c11;
+ c00 = sp;
+ sp += Size;
+ c01 = sp;
sp += srcPitch;
- c11 = *(const Size *)sp;
- sp -= sizeof(Size);
- c10 = *(const Size *)sp;
+ c11 = sp;
+ sp -= Size;
+ c10 = sp;
if (flipx) {
SWAP(c00, c01);
SWAP(c10, c11);
@@ -369,17 +396,21 @@ void rotoscaleBlitLogic(byte *dst, const byte *src,
*/
int ex = (sdx & 0xffff);
int ey = (sdy & 0xffff);
- *pc = scaleBlitBilinearInterpolate<ColorMask, Size>(c01, c00, c11, c10, ex, ey, fmt);
+ scaleBlitBilinearInterpolate<ColorMask, Color, Size>(pc, c01, c00, c11, c10, ex, ey, fmt);
}
} else {
if ((dx >= 0) && (dy >= 0) && (dx < (int)srcW) && (dy < (int)srcH)) {
- const byte *sp = src + dy * srcPitch + dx * sizeof(Size);
- *pc = *(const Size *)sp;
+ const byte *sp = src + dy * srcPitch + dx * Size;
+ if (Size == sizeof(Color)) {
+ *(Color *)pc = *(const Color *)sp;
+ } else {
+ memcpy(pc, sp, Size);
+ }
}
}
sdx += icosx;
sdy += isiny;
- pc++;
+ pc += Size;
}
}
}
@@ -392,7 +423,7 @@ bool scaleBlitBilinear(byte *dst, const byte *src,
const uint srcW, const uint srcH,
const Graphics::PixelFormat &fmt,
const byte flip) {
- if (fmt.bytesPerPixel != 2 && fmt.bytesPerPixel != 4)
+ if (fmt.bytesPerPixel != 2 && fmt.bytesPerPixel != 3 && fmt.bytesPerPixel != 4)
return false;
int *sax = new int[dstW + 1];
@@ -440,18 +471,20 @@ bool scaleBlitBilinear(byte *dst, const byte *src,
}
if (fmt == createPixelFormat<8888>()) {
- scaleBlitBilinearLogic<ColorMasks<8888>, uint32>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<8888>, uint32, 4>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else if (fmt == createPixelFormat<888>()) {
- scaleBlitBilinearLogic<ColorMasks<888>, uint32>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<888>, uint32, 4>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else if (fmt == createPixelFormat<565>()) {
- scaleBlitBilinearLogic<ColorMasks<565>, uint16>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<565>, uint16, 2>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else if (fmt == createPixelFormat<555>()) {
- scaleBlitBilinearLogic<ColorMasks<555>, uint16>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<555>, uint16, 2>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else if (fmt.bytesPerPixel == 4) {
- scaleBlitBilinearLogic<ColorMasks<0>, uint32>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<0>, uint32, 4>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ } else if (fmt.bytesPerPixel == 3) {
+ scaleBlitBilinearLogic<ColorMasks<0>, uint8, 3>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else if (fmt.bytesPerPixel == 2) {
- scaleBlitBilinearLogic<ColorMasks<0>, uint16>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
+ scaleBlitBilinearLogic<ColorMasks<0>, uint16, 2>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, sax, say, flip);
} else {
delete[] sax;
delete[] say;
@@ -473,11 +506,13 @@ bool rotoscaleBlit(byte *dst, const byte *src,
const TransformStruct &transform,
const Common::Point &newHotspot) {
if (fmt.bytesPerPixel == 4) {
- rotoscaleBlitLogic<ColorMasks<0>, uint32, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<0>, uint32, 4, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ } else if (fmt.bytesPerPixel == 3) {
+ rotoscaleBlitLogic<ColorMasks<0>, uint8, 3, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt.bytesPerPixel == 2) {
- rotoscaleBlitLogic<ColorMasks<0>, uint16, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<0>, uint16, 2, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt.bytesPerPixel == 1) {
- rotoscaleBlitLogic<ColorMasks<0>, uint8, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<0>, uint8, 1, false>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else {
return false;
}
@@ -493,18 +528,20 @@ bool rotoscaleBlitBilinear(byte *dst, const byte *src,
const TransformStruct &transform,
const Common::Point &newHotspot) {
if (fmt == createPixelFormat<8888>()) {
- rotoscaleBlitLogic<ColorMasks<8888>, uint32, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<8888>, uint32, 4, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt == createPixelFormat<888>()) {
- rotoscaleBlitLogic<ColorMasks<888>, uint32, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<888>, uint32, 4, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt == createPixelFormat<565>()) {
- rotoscaleBlitLogic<ColorMasks<565>, uint16, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<565>, uint16, 2, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt == createPixelFormat<555>()) {
- rotoscaleBlitLogic<ColorMasks<555>, uint16, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<555>, uint16, 2, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt.bytesPerPixel == 4) {
- rotoscaleBlitLogic<ColorMasks<0>, uint32, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<0>, uint32, 4, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ } else if (fmt.bytesPerPixel == 3) {
+ rotoscaleBlitLogic<ColorMasks<0>, uint8, 3, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else if (fmt.bytesPerPixel == 2) {
- rotoscaleBlitLogic<ColorMasks<0>, uint16, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
+ rotoscaleBlitLogic<ColorMasks<0>, uint16, 2, true>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, fmt, transform, newHotspot);
} else {
return false;
}
More information about the Scummvm-git-logs
mailing list