GRAPHICS: Remove crossBlit's dstBpp >= srcBpp limitation.
This commit is contained in:
parent
3a55adbf5e
commit
0d78d46a0e
2 changed files with 35 additions and 22 deletions
|
@ -22,6 +22,8 @@
|
||||||
#include "graphics/conversion.h"
|
#include "graphics/conversion.h"
|
||||||
#include "graphics/pixelformat.h"
|
#include "graphics/pixelformat.h"
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
// TODO: YUV to RGB conversion function
|
// 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
|
} // End of anonymous namespace
|
||||||
|
|
||||||
// Function to blit a rect from one color format to another
|
// 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
|
// Error out if conversion is impossible
|
||||||
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
|
if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
|
||||||
|| (dstFmt.bytesPerPixel == 3)
|
|| (dstFmt.bytesPerPixel == 3)
|
||||||
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel)
|
|| (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel))
|
||||||
|| (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't perform unnecessary conversion
|
// Don't perform unnecessary conversion
|
||||||
|
@ -84,27 +109,18 @@ bool crossBlit(byte *dst, const byte *src,
|
||||||
|
|
||||||
// TODO: optimized cases for dstDelta of 0
|
// TODO: optimized cases for dstDelta of 0
|
||||||
if (dstFmt.bytesPerPixel == 2) {
|
if (dstFmt.bytesPerPixel == 2) {
|
||||||
crossBlitLogic<uint16, uint16>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
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) {
|
} else if (dstFmt.bytesPerPixel == 4) {
|
||||||
if (srcFmt.bytesPerPixel == 2) {
|
if (srcFmt.bytesPerPixel == 2) {
|
||||||
crossBlitLogic<uint16, uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
crossBlitLogic<uint16, uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
} else if (srcFmt.bytesPerPixel == 3) {
|
} else if (srcFmt.bytesPerPixel == 3) {
|
||||||
uint32 color;
|
crossBlitLogic3BppSource<uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
crossBlitLogic<uint32, uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
crossBlitLogic<uint32, uint32>(dst, src, w, h, srcFmt, dstFmt, srcDelta, dstDelta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* false if there is an error.
|
||||||
*
|
*
|
||||||
* @note Blitting to a 3Bpp destination is not supported
|
* @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
|
* @note This can convert a rectangle in place, if the source and
|
||||||
* destination format have the same bytedepth.
|
* destination format have the same bytedepth.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue