From 0d78d46a0e82af81681727a94e01ff5f309887fa Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sat, 14 Jul 2012 05:12:31 +0200 Subject: GRAPHICS: Remove crossBlit's dstBpp >= srcBpp limitation. --- graphics/conversion.cpp | 54 ++++++++++++++++++++++++++++++++----------------- graphics/conversion.h | 3 --- 2 files changed, 35 insertions(+), 22 deletions(-) (limited to 'graphics') diff --git a/graphics/conversion.cpp b/graphics/conversion.cpp index db99679d41..ece1f759d9 100644 --- a/graphics/conversion.cpp +++ b/graphics/conversion.cpp @@ -22,6 +22,8 @@ #include "graphics/conversion.h" #include "graphics/pixelformat.h" +#include "common/endian.h" + namespace Graphics { // TODO: YUV to RGB conversion function @@ -47,6 +49,30 @@ FORCEINLINE void crossBlitLogic(byte *dst, const byte *src, const uint w, const } } +template +FORCEINLINE 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) { + 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); + srcFmt.colorToARGB(color, a, r, g, b); + color = dstFmt.ARGBToColor(a, r, g, b); + *(DstColor *)dst = color; + src += 3; + dst += sizeof(DstColor); + } + src += srcDelta; + dst += dstDelta; + } +} + } // End of anonymous namespace // Function to blit a rect from one color format to another @@ -57,8 +83,7 @@ bool crossBlit(byte *dst, const byte *src, // Error out if conversion is impossible if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 3) - || (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel) - || (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel)) + || (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel)) return false; // Don't perform unnecessary conversion @@ -84,27 +109,18 @@ bool crossBlit(byte *dst, const byte *src, // TODO: optimized cases for dstDelta of 0 if (dstFmt.bytesPerPixel == 2) { - crossBlitLogic(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); + if (srcFmt.bytesPerPixel == 2) { + crossBlitLogic(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); + } else if (srcFmt.bytesPerPixel == 3) { + crossBlitLogic3BppSource(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); + } else { + crossBlitLogic(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); + } } else if (dstFmt.bytesPerPixel == 4) { if (srcFmt.bytesPerPixel == 2) { crossBlitLogic(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); } else if (srcFmt.bytesPerPixel == 3) { - 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, src += 3, dst += 4) { - memcpy(col, src, 3); - srcFmt.colorToARGB(color, a, r, g, b); - color = dstFmt.ARGBToColor(a, r, g, b); - *(uint32 *)dst = color; - } - src += srcDelta; - dst += dstDelta; - } + crossBlitLogic3BppSource(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); } else { crossBlitLogic(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta); } diff --git a/graphics/conversion.h b/graphics/conversion.h index 8fcb6ba12d..0dce3cf279 100644 --- a/graphics/conversion.h +++ b/graphics/conversion.h @@ -60,9 +60,6 @@ inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) { * false if there is an error. * * @note Blitting to a 3Bpp destination is not supported - * @note This implementation currently arbitrarily requires that the - * destination's format have at least as high a bytedepth as - * the source's. * @note This can convert a rectangle in place, if the source and * destination format have the same bytedepth. * -- cgit v1.2.3