[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