[Scummvm-git-logs] scummvm master -> e918ce9bc689784d18349e5094a1ce79bc231336
sev-
noreply at scummvm.org
Mon Oct 16 15:31:35 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
34d04a76cb GRAPHICS: Support 3bpp destinations using crossBlit functions
1e4abf786b GRAPHICS: Use crossBlit more for converting surfaces
ca36ea9403 GRAPHICS: Fix typos
e918ce9bc6 GRAPHICS: Revert incorrect changes to error messages
Commit: 34d04a76cb0a7fdbf607dedf18fab85c09b0a979
https://github.com/scummvm/scummvm/commit/34d04a76cb0a7fdbf607dedf18fab85c09b0a979
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-10-16T17:31:30+02:00
Commit Message:
GRAPHICS: Support 3bpp destinations using crossBlit functions
Changed paths:
graphics/blit.h
graphics/blit/blit.cpp
diff --git a/graphics/blit.h b/graphics/blit.h
index 80f0a98b44d..4c9a91e0da2 100644
--- a/graphics/blit.h
+++ b/graphics/blit.h
@@ -99,7 +99,6 @@ bool keyBlit(byte *dst, const byte *src,
* @return true if conversion completes successfully,
* false if there is an error.
*
- * @note Blitting to a 3Bpp destination is not supported
* @note This can convert a surface in place, regardless of the
* source and destination format, as long as there is enough
* space for the destination. The dstPitch / srcPitch ratio
@@ -127,7 +126,6 @@ bool crossBlit(byte *dst, const byte *src,
* @return true if conversion completes successfully,
* false if there is an error.
*
- * @note Blitting to a 3Bpp destination is not supported
* @note This can convert a surface in place, regardless of the
* source and destination format, as long as there is enough
* space for the destination. The dstPitch / srcPitch ratio
diff --git a/graphics/blit/blit.cpp b/graphics/blit/blit.cpp
index 4e4abb23d96..833891bcee6 100644
--- a/graphics/blit/blit.cpp
+++ b/graphics/blit/blit.cpp
@@ -21,6 +21,7 @@
#include "graphics/blit.h"
#include "graphics/pixelformat.h"
+#include "common/endian.h"
namespace Graphics {
@@ -48,17 +49,28 @@ void copyBlit(byte *dst, const byte *src,
namespace {
-template<typename Size>
+template<typename Color, int Size>
inline void keyBlitLogic(byte *dst, const byte *src, const uint w, const uint h,
const uint srcDelta, const uint dstDelta, const uint32 key) {
+ const uint8 *col = (const uint8 *)&key;
+#ifdef SCUMM_BIG_ENDIAN
+ if (Size == 3)
+ col++;
+#endif
+
for (uint y = 0; y < h; ++y) {
for (uint x = 0; x < w; ++x) {
- uint32 color = *(const Size *)src;
- if (color != key)
- *(Size *)dst = color;
+ if (Size == sizeof(Color)) {
+ const uint32 color = *(const Color *)src;
+ if (color != key)
+ *(Color *)dst = color;
+ } else {
+ if (memcmp(src, col, Size))
+ memcpy(dst, src, Size);
+ }
- src += sizeof(Size);
- dst += sizeof(Size);
+ src += Size;
+ dst += Size;
}
src += srcDelta;
@@ -81,11 +93,13 @@ bool keyBlit(byte *dst, const byte *src,
const uint dstDelta = (dstPitch - w * bytesPerPixel);
if (bytesPerPixel == 1) {
- keyBlitLogic<uint8>(dst, src, w, h, srcDelta, dstDelta, key);
+ keyBlitLogic<uint8, 1>(dst, src, w, h, srcDelta, dstDelta, key);
} else if (bytesPerPixel == 2) {
- keyBlitLogic<uint16>(dst, src, w, h, srcDelta, dstDelta, key);
+ keyBlitLogic<uint16, 2>(dst, src, w, h, srcDelta, dstDelta, key);
+ } else if (bytesPerPixel == 3) {
+ keyBlitLogic<uint8, 3>(dst, src, w, h, srcDelta, dstDelta, key);
} else if (bytesPerPixel == 4) {
- keyBlitLogic<uint32>(dst, src, w, h, srcDelta, dstDelta, key);
+ keyBlitLogic<uint32, 4>(dst, src, w, h, srcDelta, dstDelta, key);
} else {
return false;
}
@@ -95,25 +109,41 @@ bool keyBlit(byte *dst, const byte *src,
namespace {
-template<typename SrcColor, typename DstColor, bool backward, bool hasKey>
+template<typename SrcColor, int SrcSize, typename DstColor, int DstSize, bool backward, bool hasKey>
inline void crossBlitLogic(byte *dst, const byte *src, const uint w, const uint h,
const PixelFormat &srcFmt, const PixelFormat &dstFmt,
const uint srcDelta, const uint dstDelta, const uint32 key) {
+ uint32 color;
+ byte a, r, g, b;
+ uint8 *col = (uint8 *)&color;
+#ifdef SCUMM_BIG_ENDIAN
+ if (SrcSize == 3 || DstSize == 3)
+ col++;
+#endif
+
for (uint y = 0; y < h; ++y) {
for (uint x = 0; x < w; ++x) {
- const uint32 color = *(const SrcColor *)src;
+ if (SrcSize == sizeof(SrcColor))
+ color = *(const SrcColor *)src;
+ else
+ memcpy(col, src, SrcSize);
+
if (!hasKey || color != key) {
- byte a, r, g, b;
srcFmt.colorToARGB(color, a, r, g, b);
- *(DstColor *)dst = dstFmt.ARGBToColor(a, r, g, b);
+ color = dstFmt.ARGBToColor(a, r, g, b);
+
+ if (DstSize == sizeof(DstColor))
+ *(DstColor *)dst = color;
+ else
+ memcpy(dst, col, DstSize);
}
if (backward) {
- src -= sizeof(SrcColor);
- dst -= sizeof(DstColor);
+ src -= SrcSize;
+ dst -= DstSize;
} else {
- src += sizeof(SrcColor);
- dst += sizeof(DstColor);
+ src += SrcSize;
+ dst += DstSize;
}
}
@@ -127,59 +157,26 @@ inline void crossBlitLogic(byte *dst, const byte *src, const uint w, const uint
}
}
-template<typename DstColor, bool backward, bool hasKey>
+template<typename DstColor, int DstSize, bool backward, bool hasKey>
inline void crossBlitLogic1BppSource(byte *dst, const byte *src, const uint w, const uint h,
const uint srcDelta, const uint dstDelta, const uint32 *map, const uint32 key) {
for (uint y = 0; y < h; ++y) {
for (uint x = 0; x < w; ++x) {
const byte color = *src;
if (!hasKey || color != key) {
- *(DstColor *)dst = map[color];
+ if (DstSize == sizeof(DstColor)) {
+ *(DstColor *)dst = map[color];
+ } else {
+ WRITE_UINT24(dst, map[color]);
+ }
}
if (backward) {
src -= 1;
- dst -= sizeof(DstColor);
+ dst -= DstSize;
} else {
src += 1;
- dst += sizeof(DstColor);
- }
- }
-
- if (backward) {
- src -= srcDelta;
- dst -= dstDelta;
- } else {
- src += srcDelta;
- dst += dstDelta;
- }
- }
-}
-
-template<typename DstColor, bool backward, bool hasKey>
-inline void crossBlitLogic3BppSource(byte *dst, const byte *src, const uint w, const uint h,
- const PixelFormat &srcFmt, const PixelFormat &dstFmt,
- const uint srcDelta, const uint dstDelta, const uint32 key) {
- uint32 color;
- byte r, g, b, a;
- uint8 *col = (uint8 *)&color;
-#ifdef SCUMM_BIG_ENDIAN
- col++;
-#endif
- for (uint y = 0; y < h; ++y) {
- for (uint x = 0; x < w; ++x) {
- memcpy(col, src, 3);
- if (!hasKey || color != key) {
- srcFmt.colorToARGB(color, a, r, g, b);
- *(DstColor *)dst = dstFmt.ARGBToColor(a, r, g, b);
- }
-
- if (backward) {
- src -= 3;
- dst -= sizeof(DstColor);
- } else {
- src += 3;
- dst += sizeof(DstColor);
+ dst += DstSize;
}
}
@@ -202,7 +199,6 @@ bool crossBlit(byte *dst, const byte *src,
const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) {
// Error out if conversion is impossible
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
- || (dstFmt.bytesPerPixel == 3)
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel))
return false;
@@ -219,11 +215,26 @@ bool crossBlit(byte *dst, const byte *src,
// TODO: optimized cases for dstDelta of 0
if (dstFmt.bytesPerPixel == 2) {
if (srcFmt.bytesPerPixel == 2) {
- crossBlitLogic<uint16, uint16, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint16, 2, uint16, 2, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
} else if (srcFmt.bytesPerPixel == 3) {
- crossBlitLogic3BppSource<uint16, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint8, 3, uint16, 2, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
} else {
- crossBlitLogic<uint32, uint16, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint32, 4, uint16, 2, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ }
+ } else if (dstFmt.bytesPerPixel == 3) {
+ if (srcFmt.bytesPerPixel == 2) {
+ // We need to blit the surface from bottom right to top left here.
+ // This is neeeded, because when we convert to the same memory
+ // buffer copying the surface from top left to bottom right would
+ // overwrite the source, since we have more bits per destination
+ // color than per source color.
+ dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
+ src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
+ crossBlitLogic<uint16, 2, uint8, 3, true, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ } else if (srcFmt.bytesPerPixel == 3) {
+ crossBlitLogic<uint8, 3, uint8, 3, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ } else {
+ crossBlitLogic<uint32, 4, uint8, 3, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
}
} else if (dstFmt.bytesPerPixel == 4) {
if (srcFmt.bytesPerPixel == 2) {
@@ -234,7 +245,7 @@ bool crossBlit(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
- crossBlitLogic<uint16, uint32, true, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint16, 2, uint32, 4, true, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
} else if (srcFmt.bytesPerPixel == 3) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -243,9 +254,9 @@ bool crossBlit(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
- crossBlitLogic3BppSource<uint32, true, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint8, 3, uint32, 4, true, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
} else {
- crossBlitLogic<uint32, uint32, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
+ crossBlitLogic<uint32, 4, uint32, 4, false, false>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, 0);
}
} else {
return false;
@@ -260,7 +271,6 @@ bool crossKeyBlit(byte *dst, const byte *src,
const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt, const uint32 key) {
// Error out if conversion is impossible
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
- || (dstFmt.bytesPerPixel == 3)
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel))
return false;
@@ -277,11 +287,26 @@ bool crossKeyBlit(byte *dst, const byte *src,
// TODO: optimized cases for dstDelta of 0
if (dstFmt.bytesPerPixel == 2) {
if (srcFmt.bytesPerPixel == 2) {
- crossBlitLogic<uint16, uint16, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint16, 2, uint16, 2, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ } else if (srcFmt.bytesPerPixel == 3) {
+ crossBlitLogic<uint8, 3, uint16, 2, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ } else {
+ crossBlitLogic<uint32, 4, uint16, 2, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ }
+ } else if (dstFmt.bytesPerPixel == 3) {
+ if (srcFmt.bytesPerPixel == 2) {
+ // We need to blit the surface from bottom right to top left here.
+ // This is neeeded, because when we convert to the same memory
+ // buffer copying the surface from top left to bottom right would
+ // overwrite the source, since we have more bits per destination
+ // color than per source color.
+ dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
+ src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
+ crossBlitLogic<uint16, 2, uint8, 3, true, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
} else if (srcFmt.bytesPerPixel == 3) {
- crossBlitLogic3BppSource<uint16, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint8, 3, uint8, 3, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
} else {
- crossBlitLogic<uint32, uint16, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint32, 4, uint8, 3, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
}
} else if (dstFmt.bytesPerPixel == 4) {
if (srcFmt.bytesPerPixel == 2) {
@@ -292,7 +317,7 @@ bool crossKeyBlit(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
- crossBlitLogic<uint16, uint32, true, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint16, 2, uint32, 4, true, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
} else if (srcFmt.bytesPerPixel == 3) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -301,9 +326,9 @@ bool crossKeyBlit(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - dstFmt.bytesPerPixel;
src += h * srcPitch - srcDelta - srcFmt.bytesPerPixel;
- crossBlitLogic3BppSource<uint32, true, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint8, 3, uint32, 4, true, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
} else {
- crossBlitLogic<uint32, uint32, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
+ crossBlitLogic<uint32, 4, uint32, 4, false, true>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta, key);
}
} else {
return false;
@@ -317,7 +342,7 @@ bool crossBlitMap(byte *dst, const byte *src,
const uint w, const uint h,
const uint bytesPerPixel, const uint32 *map) {
// Error out if conversion is impossible
- if ((bytesPerPixel == 3) || (!bytesPerPixel))
+ if (!bytesPerPixel)
return false;
// Faster, but larger, to provide optimized handling for each case.
@@ -325,7 +350,7 @@ bool crossBlitMap(byte *dst, const byte *src,
const uint dstDelta = (dstPitch - w * bytesPerPixel);
if (bytesPerPixel == 1) {
- crossBlitLogic1BppSource<uint8, false, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
+ crossBlitLogic1BppSource<uint8, 1, false, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
} else if (bytesPerPixel == 2) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -334,7 +359,16 @@ bool crossBlitMap(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - bytesPerPixel;
src += h * srcPitch - srcDelta - 1;
- crossBlitLogic1BppSource<uint16, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
+ crossBlitLogic1BppSource<uint16, 2, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
+ } else if (bytesPerPixel == 3) {
+ // We need to blit the surface from bottom right to top left here.
+ // This is neeeded, because when we convert to the same memory
+ // buffer copying the surface from top left to bottom right would
+ // overwrite the source, since we have more bits per destination
+ // color than per source color.
+ dst += h * dstPitch - dstDelta - bytesPerPixel;
+ src += h * srcPitch - srcDelta - 1;
+ crossBlitLogic1BppSource<uint8, 3, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
} else if (bytesPerPixel == 4) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -343,7 +377,7 @@ bool crossBlitMap(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - bytesPerPixel;
src += h * srcPitch - srcDelta - 1;
- crossBlitLogic1BppSource<uint32, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
+ crossBlitLogic1BppSource<uint32, 4, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
} else {
return false;
}
@@ -356,7 +390,7 @@ bool crossKeyBlitMap(byte *dst, const byte *src,
const uint w, const uint h,
const uint bytesPerPixel, const uint32 *map, const uint32 key) {
// Error out if conversion is impossible
- if ((bytesPerPixel == 3) || (!bytesPerPixel))
+ if (!bytesPerPixel)
return false;
// Faster, but larger, to provide optimized handling for each case.
@@ -364,7 +398,7 @@ bool crossKeyBlitMap(byte *dst, const byte *src,
const uint dstDelta = (dstPitch - w * bytesPerPixel);
if (bytesPerPixel == 1) {
- crossBlitLogic1BppSource<uint8, false, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
+ crossBlitLogic1BppSource<uint8, 1, false, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
} else if (bytesPerPixel == 2) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -373,7 +407,16 @@ bool crossKeyBlitMap(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - bytesPerPixel;
src += h * srcPitch - srcDelta - 1;
- crossBlitLogic1BppSource<uint16, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
+ crossBlitLogic1BppSource<uint16, 2, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
+ } else if (bytesPerPixel == 3) {
+ // We need to blit the surface from bottom right to top left here.
+ // This is neeeded, because when we convert to the same memory
+ // buffer copying the surface from top left to bottom right would
+ // overwrite the source, since we have more bits per destination
+ // color than per source color.
+ dst += h * dstPitch - dstDelta - bytesPerPixel;
+ src += h * srcPitch - srcDelta - 1;
+ crossBlitLogic1BppSource<uint8, 3, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
} else if (bytesPerPixel == 4) {
// We need to blit the surface from bottom right to top left here.
// This is neeeded, because when we convert to the same memory
@@ -382,7 +425,7 @@ bool crossKeyBlitMap(byte *dst, const byte *src,
// color than per source color.
dst += h * dstPitch - dstDelta - bytesPerPixel;
src += h * srcPitch - srcDelta - 1;
- crossBlitLogic1BppSource<uint32, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
+ crossBlitLogic1BppSource<uint32, 4, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
} else {
return false;
}
Commit: 1e4abf786b6f79ddb89f3dce83f312803e2d3e95
https://github.com/scummvm/scummvm/commit/1e4abf786b6f79ddb89f3dce83f312803e2d3e95
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-10-16T17:31:30+02:00
Commit Message:
GRAPHICS: Use crossBlit more for converting surfaces
Changed paths:
graphics/surface.cpp
graphics/surface.h
graphics/transparent_surface.cpp
graphics/transparent_surface.h
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index b1c680a9c2d..293e676033c 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -481,10 +481,10 @@ void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette
}
if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4)
- error("Surface::convertToInPlace(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp but have %dbpp", format.bytesPerPixel);
+ error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp but have %dbpp", format.bytesPerPixel);
- if (dstFormat.bytesPerPixel != 2 && dstFormat.bytesPerPixel != 4)
- error("Surface::convertToInPlace(): Can only convert to 2Bpp and 4Bpp but requested %dbpp", dstFormat.bytesPerPixel);
+ if (dstFormat.bytesPerPixel == 0 || dstFormat.bytesPerPixel == 1 || dstFormat.bytesPerPixel > 4)
+ error("Surface::convertTo(): Can only convert to 2Bpp, 3Bpp and 4Bpp but requested %dbpp", dstFormat.bytesPerPixel);
// In case the surface data needs more space allocate it.
if (dstFormat.bytesPerPixel > format.bytesPerPixel) {
@@ -500,28 +500,11 @@ void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette
// We need to handle 1 Bpp surfaces special here.
if (format.bytesPerPixel == 1) {
+ uint32 map[256];
assert(palette);
- for (int y = h; y > 0; --y) {
- const byte *srcRow = (const byte *)pixels + y * pitch - 1;
- byte *dstRow = (byte *)pixels + y * w * dstFormat.bytesPerPixel - dstFormat.bytesPerPixel;
-
- for (int x = 0; x < w; x++) {
- byte index = *srcRow--;
- byte r = palette[index * 3];
- byte g = palette[index * 3 + 1];
- byte b = palette[index * 3 + 2];
-
- uint32 color = dstFormat.RGBToColor(r, g, b);
-
- if (dstFormat.bytesPerPixel == 2)
- *((uint16 *)dstRow) = color;
- else
- *((uint32 *)dstRow) = color;
-
- dstRow -= dstFormat.bytesPerPixel;
- }
- }
+ convertPaletteToMap(map, palette, 256, dstFormat);
+ crossBlitMap((byte *)pixels, (const byte *)pixels, w * dstFormat.bytesPerPixel, pitch, w, h, dstFormat.bytesPerPixel, map);
} else {
crossBlit((byte *)pixels, (const byte *)pixels, w * dstFormat.bytesPerPixel, pitch, w, h, dstFormat, format);
}
@@ -573,64 +556,19 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
return surface;
}
+ const byte *src = (const byte *)getPixels();
+ byte *dst = (byte *)surface->getPixels();
+
if (format.bytesPerPixel == 1) {
// Converting from paletted to high color
assert(srcPalette);
+ uint32 map[256];
- for (int y = 0; y < h; y++) {
- const byte *srcRow = (const byte *)getBasePtr(0, y);
- byte *dstRow = (byte *)surface->getBasePtr(0, y);
-
- for (int x = 0; x < w; x++) {
- byte index = *srcRow++;
- byte r = srcPalette[index * 3];
- byte g = srcPalette[index * 3 + 1];
- byte b = srcPalette[index * 3 + 2];
-
- uint32 color = dstFormat.RGBToColor(r, g, b);
-
- if (dstFormat.bytesPerPixel == 2)
- *((uint16 *)dstRow) = color;
- else if (dstFormat.bytesPerPixel == 3)
- WRITE_UINT24(dstRow, color);
- else
- *((uint32 *)dstRow) = color;
-
- dstRow += dstFormat.bytesPerPixel;
- }
- }
+ convertPaletteToMap(map, srcPalette, 256, dstFormat);
+ crossBlitMap(dst, src, surface->pitch, pitch, w, h, dstFormat.bytesPerPixel, map);
} else {
// Converting from high color to high color
- for (int y = 0; y < h; y++) {
- const byte *srcRow = (const byte *)getBasePtr(0, y);
- byte *dstRow = (byte *)surface->getBasePtr(0, y);
-
- for (int x = 0; x < w; x++) {
- uint32 srcColor;
- if (format.bytesPerPixel == 2)
- srcColor = READ_UINT16(srcRow);
- else if (format.bytesPerPixel == 3)
- srcColor = READ_UINT24(srcRow);
- else
- srcColor = READ_UINT32(srcRow);
-
- srcRow += format.bytesPerPixel;
-
- // Convert that color to the new format
- byte r, g, b, a;
- format.colorToARGB(srcColor, a, r, g, b);
- uint32 color = dstFormat.ARGBToColor(a, r, g, b);
-
- if (dstFormat.bytesPerPixel == 2)
- *((uint16 *)dstRow) = color;
- else if (dstFormat.bytesPerPixel == 3)
- WRITE_UINT24(dstRow, color);
- else
- *((uint32 *)dstRow) = color;
-
- dstRow += dstFormat.bytesPerPixel;
- }
- }
+ crossBlit(dst, src, surface->pitch, pitch, w, h, dstFormat, format);
}
return surface;
diff --git a/graphics/surface.h b/graphics/surface.h
index 8d56d2f8316..bf1deb686df 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -373,7 +373,7 @@ public:
*/
Graphics::Surface *convertTo(const PixelFormat &dstFormat, const byte *srcPalette = 0, int srcPaletteCount = 0, const byte *dstPalette = 0, int dstPaletteCount = 0, DitherMethod method = kDitherFloyd) const;
-private:
+protected:
void ditherFloyd(const byte *srcPalette, int srcPaletteCount, Surface *dstSurf, const byte *dstPalette, int dstPaletteCount, DitherMethod method, const PixelFormat &dstFormat) const;
public:
diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp
index 5af183de056..d4eb0146688 100644
--- a/graphics/transparent_surface.cpp
+++ b/graphics/transparent_surface.cpp
@@ -294,79 +294,52 @@ TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transfo
return target;
}
-TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat, const byte *palette) const {
+TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat, const byte *srcPalette, int srcPaletteCount, const byte *dstPalette, int dstPaletteCount, DitherMethod method) const {
assert(pixels);
TransparentSurface *surface = new TransparentSurface();
// If the target format is the same, just copy
if (format == dstFormat) {
- surface->copyFrom(*this);
- return surface;
+ if (dstFormat.bytesPerPixel == 1) { // Checking if dithering could be skipped
+ if (!srcPalette // No palette is specified
+ || !dstPalette // No dst palette
+ || (srcPaletteCount == dstPaletteCount // palettes are the same
+ && !memcmp(srcPalette, dstPalette, srcPaletteCount * 3))) {
+ surface->copyFrom(*this);
+ return surface;
+ }
+ }
}
if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4)
- error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp");
+ error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp but have %dbpp", format.bytesPerPixel);
- if (dstFormat.bytesPerPixel != 2 && dstFormat.bytesPerPixel != 4)
- error("Surface::convertTo(): Can only convert to 2Bpp and 4Bpp");
+ if (dstFormat.bytesPerPixel == 0 || dstFormat.bytesPerPixel > 4)
+ error("Surface::convertTo(): Can only convert to 1Bpp, 2Bpp, 3Bpp and 4Bpp but requested %dbpp", dstFormat.bytesPerPixel);
surface->create(w, h, dstFormat);
- if (format.bytesPerPixel == 1) {
- // Converting from paletted to high color
- assert(palette);
-
- for (int y = 0; y < h; y++) {
- const byte *srcRow = (const byte *)getBasePtr(0, y);
- byte *dstRow = (byte *)surface->getBasePtr(0, y);
-
- for (int x = 0; x < w; x++) {
- byte index = *srcRow++;
- byte r = palette[index * 3];
- byte g = palette[index * 3 + 1];
- byte b = palette[index * 3 + 2];
+ // We are here when we are converting from a higher bpp or palettes are different
+ if (dstFormat.bytesPerPixel == 1) {
+ ditherFloyd(srcPalette, srcPaletteCount, surface, dstPalette, dstPaletteCount, method,
+ dstFormat);
+ return surface;
+ }
- uint32 color = dstFormat.RGBToColor(r, g, b);
+ const byte *src = (const byte *)getPixels();
+ byte *dst = (byte *)surface->getPixels();
- if (dstFormat.bytesPerPixel == 2)
- *((uint16 *)dstRow) = color;
- else
- *((uint32 *)dstRow) = color;
+ if (format.bytesPerPixel == 1) {
+ // Converting from paletted to high color
+ assert(srcPalette);
+ uint32 map[256];
- dstRow += dstFormat.bytesPerPixel;
- }
- }
+ convertPaletteToMap(map, srcPalette, 256, dstFormat);
+ crossBlitMap(dst, src, surface->pitch, pitch, w, h, dstFormat.bytesPerPixel, map);
} else {
// Converting from high color to high color
- for (int y = 0; y < h; y++) {
- const byte *srcRow = (const byte *)getBasePtr(0, y);
- byte *dstRow = (byte *)surface->getBasePtr(0, y);
-
- for (int x = 0; x < w; x++) {
- uint32 srcColor;
- if (format.bytesPerPixel == 2)
- srcColor = READ_UINT16(srcRow);
- else if (format.bytesPerPixel == 3)
- srcColor = READ_UINT24(srcRow);
- else
- srcColor = READ_UINT32(srcRow);
-
- srcRow += format.bytesPerPixel;
-
- // Convert that color to the new format
- byte r, g, b, a;
- format.colorToARGB(srcColor, a, r, g, b);
- uint32 color = dstFormat.ARGBToColor(a, r, g, b);
-
- if (dstFormat.bytesPerPixel == 2)
- *((uint16 *)dstRow) = color;
- else
- *((uint32 *)dstRow) = color;
-
- dstRow += dstFormat.bytesPerPixel;
- }
- }
+ crossBlit(dst, src, surface->pitch, pitch, w, h, dstFormat, format);
}
return surface;
diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h
index 073dd535939..cd0d602410a 100644
--- a/graphics/transparent_surface.h
+++ b/graphics/transparent_surface.h
@@ -128,7 +128,7 @@ struct TransparentSurface : public Graphics::Surface {
*/
TransparentSurface *rotoscale(const TransformStruct &transform, bool filtering = false) const;
- TransparentSurface *convertTo(const PixelFormat &dstFormat, const byte *palette = 0) const;
+ TransparentSurface *convertTo(const PixelFormat &dstFormat, const byte *srcPalette = 0, int srcPaletteCount = 0, const byte *dstPalette = 0, int dstPaletteCount = 0, DitherMethod method = kDitherFloyd) const;
float getRatio() {
if (!w)
Commit: ca36ea940348635c9697485a470390a2bb78de64
https://github.com/scummvm/scummvm/commit/ca36ea940348635c9697485a470390a2bb78de64
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2023-10-16T17:31:30+02:00
Commit Message:
GRAPHICS: Fix typos
Changed paths:
graphics/blit/blit.cpp
diff --git a/graphics/blit/blit.cpp b/graphics/blit/blit.cpp
index 833891bcee6..9ae0148a1b7 100644
--- a/graphics/blit/blit.cpp
+++ b/graphics/blit/blit.cpp
@@ -224,7 +224,7 @@ bool crossBlit(byte *dst, const byte *src,
} else if (dstFmt.bytesPerPixel == 3) {
if (srcFmt.bytesPerPixel == 2) {
// We need to blit the surface from bottom right to top left here.
- // This is neeeded, because when we convert to the same memory
+ // This is needed, because when we convert to the same memory
// buffer copying the surface from top left to bottom right would
// overwrite the source, since we have more bits per destination
// color than per source color.
@@ -296,7 +296,7 @@ bool crossKeyBlit(byte *dst, const byte *src,
} else if (dstFmt.bytesPerPixel == 3) {
if (srcFmt.bytesPerPixel == 2) {
// We need to blit the surface from bottom right to top left here.
- // This is neeeded, because when we convert to the same memory
+ // This is needed, because when we convert to the same memory
// buffer copying the surface from top left to bottom right would
// overwrite the source, since we have more bits per destination
// color than per source color.
@@ -362,7 +362,7 @@ bool crossBlitMap(byte *dst, const byte *src,
crossBlitLogic1BppSource<uint16, 2, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
} else if (bytesPerPixel == 3) {
// We need to blit the surface from bottom right to top left here.
- // This is neeeded, because when we convert to the same memory
+ // This is needed, because when we convert to the same memory
// buffer copying the surface from top left to bottom right would
// overwrite the source, since we have more bits per destination
// color than per source color.
@@ -371,7 +371,7 @@ bool crossBlitMap(byte *dst, const byte *src,
crossBlitLogic1BppSource<uint8, 3, true, false>(dst, src, w, h, srcDelta, dstDelta, map, 0);
} else if (bytesPerPixel == 4) {
// We need to blit the surface from bottom right to top left here.
- // This is neeeded, because when we convert to the same memory
+ // This is needed, because when we convert to the same memory
// buffer copying the surface from top left to bottom right would
// overwrite the source, since we have more bits per destination
// color than per source color.
@@ -410,7 +410,7 @@ bool crossKeyBlitMap(byte *dst, const byte *src,
crossBlitLogic1BppSource<uint16, 2, true, true>(dst, src, w, h, srcDelta, dstDelta, map, key);
} else if (bytesPerPixel == 3) {
// We need to blit the surface from bottom right to top left here.
- // This is neeeded, because when we convert to the same memory
+ // This is needed, because when we convert to the same memory
// buffer copying the surface from top left to bottom right would
// overwrite the source, since we have more bits per destination
// color than per source color.
Commit: e918ce9bc689784d18349e5094a1ce79bc231336
https://github.com/scummvm/scummvm/commit/e918ce9bc689784d18349e5094a1ce79bc231336
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2023-10-16T17:31:30+02:00
Commit Message:
GRAPHICS: Revert incorrect changes to error messages
Changed paths:
graphics/surface.cpp
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 293e676033c..1efb0c2a5af 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -481,10 +481,10 @@ void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette
}
if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4)
- error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp but have %dbpp", format.bytesPerPixel);
+ error("Surface::convertToInPlace(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp but have %dbpp", format.bytesPerPixel);
if (dstFormat.bytesPerPixel == 0 || dstFormat.bytesPerPixel == 1 || dstFormat.bytesPerPixel > 4)
- error("Surface::convertTo(): Can only convert to 2Bpp, 3Bpp and 4Bpp but requested %dbpp", dstFormat.bytesPerPixel);
+ error("Surface::convertToInPlace(): Can only convert to 2Bpp, 3Bpp and 4Bpp but requested %dbpp", dstFormat.bytesPerPixel);
// In case the surface data needs more space allocate it.
if (dstFormat.bytesPerPixel > format.bytesPerPixel) {
More information about the Scummvm-git-logs
mailing list