GRAPHICS: Move code for nearest neighbour scaling out of TransparentSurface

This commit is contained in:
Cameron Cawley 2020-07-05 13:29:28 +01:00 committed by Eugene Sandulenko
parent b82df5b714
commit 42019d4252
4 changed files with 63 additions and 38 deletions

View File

@ -167,4 +167,59 @@ bool crossBlit(byte *dst, const byte *src,
return true;
}
namespace {
template <typename Size>
void scaleNN(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
const uint srcW, const uint srcH,
int *scaleCacheX) {
const uint dstDelta = (dstPitch - dstW * sizeof(Size));
for (uint y = 0; y < dstH; y++) {
const Size *srcP = (const Size *)(src + ((y * srcH) / dstH) * srcPitch);
for (uint x = 0; x < dstW; x++) {
int val = srcP[scaleCacheX[x]];
*(Size *)dst = val;
dst += sizeof(Size);
}
dst += dstDelta;
}
}
} // End of anonymous namespace
bool scaleBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
const uint srcW, const uint srcH,
const Graphics::PixelFormat &fmt) {
int *scaleCacheX = new int[dstW];
for (uint x = 0; x < dstW; x++) {
scaleCacheX[x] = (x * srcW) / dstW;
}
switch (fmt.bytesPerPixel) {
case 1:
scaleNN<uint8>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX);
break;
case 2:
scaleNN<uint16>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX);
break;
case 4:
scaleNN<uint32>(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX);
break;
default:
delete[] scaleCacheX;
return false;
}
delete[] scaleCacheX;
return true;
}
} // End of namespace Graphics

View File

@ -72,6 +72,12 @@ bool crossBlit(byte *dst, const byte *src,
const uint w, const uint h,
const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt);
bool scaleBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
const uint dstW, const uint dstH,
const uint srcW, const uint srcH,
const Graphics::PixelFormat &fmt);
} // End of namespace Graphics
#endif // GRAPHICS_CONVERSION_H

View File

@ -33,6 +33,7 @@
#include "common/rect.h"
#include "common/math.h"
#include "common/textconsole.h"
#include "graphics/conversion.h"
#include "graphics/primitives.h"
#include "graphics/transparent_surface.h"
#include "graphics/transform_tools.h"
@ -1068,26 +1069,7 @@ TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight
delete[] say;
} else {
int *scaleCacheX = new int[dstW];
for (int x = 0; x < dstW; x++) {
scaleCacheX[x] = (x * srcW) / dstW;
}
switch (format.bytesPerPixel) {
case 1:
scaleNN<uint8>(scaleCacheX, target);
break;
case 2:
scaleNN<uint16>(scaleCacheX, target);
break;
case 4:
scaleNN<uint32>(scaleCacheX, target);
break;
default:
error("Can only scale 8bpp, 16bpp, and 32bpp");
}
delete[] scaleCacheX;
scaleBlit((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, dstW, dstH, srcW, srcH, format);
}
return target;
@ -1171,26 +1153,11 @@ TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat,
return surface;
}
template <typename Size>
void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const {
for (int y = 0; y < target->h; y++) {
Size *destP = (Size *)target->getBasePtr(0, y);
const Size *srcP = (const Size *)getBasePtr(0, (y * h) / target->h);
for (int x = 0; x < target->w; x++) {
*destP++ = srcP[scaleCacheX[x]];
}
}
}
template TransparentSurface *TransparentSurface::rotoscaleT<FILTER_NEAREST>(const TransformStruct &transform) const;
template TransparentSurface *TransparentSurface::rotoscaleT<FILTER_BILINEAR>(const TransformStruct &transform) const;
template TransparentSurface *TransparentSurface::scaleT<FILTER_NEAREST>(uint16 newWidth, uint16 newHeight) const;
template TransparentSurface *TransparentSurface::scaleT<FILTER_BILINEAR>(uint16 newWidth, uint16 newHeight) const;
template void TransparentSurface::scaleNN<uint8>(int *scaleCacheX, TransparentSurface *target) const;
template void TransparentSurface::scaleNN<uint16>(int *scaleCacheX, TransparentSurface *target) const;
template void TransparentSurface::scaleNN<uint32>(int *scaleCacheX, TransparentSurface *target) const;
TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
return rotoscaleT<FILTER_BILINEAR>(transform);
}

View File

@ -177,9 +177,6 @@ struct TransparentSurface : public Graphics::Surface {
void setAlphaMode(AlphaType);
private:
AlphaType _alphaMode;
template <typename Size>
void scaleNN(int *scaleCacheX, TransparentSurface *target) const;
};
/**