GRAPHICS: Remove crossBlit's dstBpp >= srcBpp limitation.

This commit is contained in:
Johannes Schickel 2012-07-14 05:12:31 +02:00
parent 3a55adbf5e
commit 0d78d46a0e
2 changed files with 35 additions and 22 deletions

View file

@ -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<typename DstColor>
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) {
if (srcFmt.bytesPerPixel == 2) {
crossBlitLogic<uint16, uint16>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
} else if (srcFmt.bytesPerPixel == 3) {
crossBlitLogic3BppSource<uint16>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
} else {
crossBlitLogic<uint32, uint16>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
}
} else if (dstFmt.bytesPerPixel == 4) {
if (srcFmt.bytesPerPixel == 2) {
crossBlitLogic<uint16, uint32>(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<uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
} else {
crossBlitLogic<uint32, uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
}

View file

@ -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.
*