Just checking if this is right:
////////////////////////////////////////////////////////////
/// Copy pixels from another image onto this one.
/// This function does a slow pixel copy and should only
/// be used at initialization time
////////////////////////////////////////////////////////////
void Image::Copy(const Image& Source, unsigned int DestX, unsigned int DestY, const IntRect& SourceRect, bool ApplyAlpha)
{
// Make sure both images are valid
if ((Source.myWidth == 0) || (Source.myHeight == 0) || (myWidth == 0) || (myHeight == 0))
return;
// Make sure both images have up-to-date arrays
EnsureArrayUpdate();
Source.EnsureArrayUpdate();
// Adjust the source rectangle
IntRect SrcRect = SourceRect;
if (SrcRect.GetWidth() == 0 || (SrcRect.GetHeight() == 0))
{
SrcRect.Left = 0;
SrcRect.Top = 0;
SrcRect.Right = Source.myWidth;
SrcRect.Bottom = Source.myHeight;
}
else
{
if (SrcRect.Left < 0) SrcRect.Left = 0;
if (SrcRect.Top < 0) SrcRect.Top = 0;
if (SrcRect.Right > static_cast<int>(Source.myWidth)) SrcRect.Right = Source.myWidth;
if (SrcRect.Bottom > static_cast<int>(Source.myHeight)) SrcRect.Bottom = Source.myHeight;
}
// Then find the valid bounds of the destination rectangle
int Width = SrcRect.GetWidth();
int Height = SrcRect.GetHeight();
if (DestX + Width > myWidth) Width = myWidth - DestX;
if (DestY + Height > myHeight) Height = myHeight - DestY;
// Make sure the destination area is valid
if ((Width <= 0) || (Height <= 0))
return;
// Precompute as much as possible
int Pitch = Width * 4;
int Rows = Height;
int SrcStride = Source.myWidth * 4;
int DstStride = myWidth * 4;
const Uint8* SrcPixels = Source.GetPixelsPtr() + (SrcRect.Left + SrcRect.Top * Source.myWidth) * 4;
Uint8* DstPixels = reinterpret_cast<Uint8*>(&myPixels[0]) + (DestX + DestY * myWidth) * 4;
// Copy the pixels
if (ApplyAlpha)
{
// Interpolation using alpha values, pixel by pixel (slower)
for (int i = 0; i < Rows; ++i)
{
for (int j = 0; j < Width; ++j)
{
// Get a direct pointer to the components of the current pixel
const Uint8* Src = SrcPixels + j * 4;
Uint8* Dst = DstPixels + j * 4;
// Interpolate RGB components using the alpha value of the source pixel
Uint8 Alpha = Src[3];
Dst[0] = (Src[0] * Alpha + Dst[0] * (255 - Alpha)) / 255;
Dst[1] = (Src[1] * Alpha + Dst[1] * (255 - Alpha)) / 255;
Dst[2] = (Src[2] * Alpha + Dst[2] * (255 - Alpha)) / 255;
// Get the new alpha value for the destination pixel
Dst[3] = (Alpha * Alpha + Dst[3] * (255 - Dst[3])) / 255;
}
SrcPixels += SrcStride;
DstPixels += DstStride;
}
}
else
{
// Optimized copy ignoring alpha values, row by row (faster)
for (int i = 0; i < Rows; ++i)
{
memcpy(DstPixels, SrcPixels, Pitch);
SrcPixels += SrcStride;
DstPixels += DstStride;
}
}
// The texture will need an update
myNeedTextureUpdate = true;
}