Add IImage::copyToNoScaling

(Useful for const-correctness.)
This commit is contained in:
Desour 2023-04-13 23:00:58 +02:00 committed by sfan5
parent 1f15fd0805
commit 6a2a569233
3 changed files with 55 additions and 25 deletions

@ -329,6 +329,12 @@ public:
//! Sets a pixel
virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) = 0;
//! Copies this surface into another, if it has the exact same size and format.
/** NOTE: mipmaps are ignored
\return True if it was copied, false otherwise.
*/
virtual bool copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) const = 0;
//! Copies the image into the target, scaling the image to fit
/** NOTE: mipmaps are ignored */
virtual void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) =0;

@ -173,6 +173,50 @@ void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, c
}
//! copies this surface into another, if it has the exact same size and format.
bool CImage::copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch) const
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToNoScaling method doesn't work with compressed images.", ELL_WARNING);
return false;
}
if (!target || !width || !height || !Size.Width || !Size.Height)
return false;
const u32 bpp=getBitsPerPixelFromFormat(format)/8;
if (0==pitch)
pitch = width*bpp;
if (!(Format==format && Size.Width==width && Size.Height==height))
return false;
if (pitch==Pitch)
{
memcpy(target, Data, (size_t)height*pitch);
}
else
{
u8* tgtpos = (u8*) target;
u8* srcpos = Data;
const u32 bwidth = width*bpp;
const u32 rest = pitch-bwidth;
for (u32 y=0; y<height; ++y)
{
// copy scanline
memcpy(tgtpos, srcpos, bwidth);
// clear pitch
memset(tgtpos+bwidth, 0, rest);
tgtpos += pitch;
srcpos += Pitch;
}
}
return true;
}
//! copies this surface into another, scaling it to the target image size
// note: this is very very slow.
void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch)
@ -190,31 +234,8 @@ void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT fo
if (0==pitch)
pitch = width*bpp;
if (Format==format && Size.Width==width && Size.Height==height)
{
if (pitch==Pitch)
{
memcpy(target, Data, (size_t)height*pitch);
return;
}
else
{
u8* tgtpos = (u8*) target;
u8* srcpos = Data;
const u32 bwidth = width*bpp;
const u32 rest = pitch-bwidth;
for (u32 y=0; y<height; ++y)
{
// copy scanline
memcpy(tgtpos, srcpos, bwidth);
// clear pitch
memset(tgtpos+bwidth, 0, rest);
tgtpos += pitch;
srcpos += Pitch;
}
return;
}
}
if (copyToNoScaling(target, width, height, format, pitch))
return;
// NOTE: Scaling is coded to keep the border pixels intact.
// Alternatively we could for example work with first pixel being taken at half step-size.

@ -42,6 +42,9 @@ public:
//! sets a pixel
void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) override;
//! copies this surface into another, if it has the exact same size and format.
bool copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) const override;
//! copies this surface into another, scaling it to fit.
void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) override;