diff --git a/graphics/conversion.cpp b/graphics/conversion.cpp index 27180b80ad8..a9eaa7d80af 100644 --- a/graphics/conversion.cpp +++ b/graphics/conversion.cpp @@ -167,4 +167,59 @@ bool crossBlit(byte *dst, const byte *src, return true; } +namespace { + +template +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(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + case 2: + scaleNN(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + case 4: + scaleNN(dst, src, dstPitch, srcPitch, dstW, dstH, srcW, srcH, scaleCacheX); + break; + default: + delete[] scaleCacheX; + return false; + } + + delete[] scaleCacheX; + + return true; +} + } // End of namespace Graphics diff --git a/graphics/conversion.h b/graphics/conversion.h index 8ca529acc09..04240c576df 100644 --- a/graphics/conversion.h +++ b/graphics/conversion.h @@ -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 diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp index eb8d3fe5ce9..94d206ebb14 100644 --- a/graphics/transparent_surface.cpp +++ b/graphics/transparent_surface.cpp @@ -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(scaleCacheX, target); - break; - case 2: - scaleNN(scaleCacheX, target); - break; - case 4: - scaleNN(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 -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(const TransformStruct &transform) const; template TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transform) const; template TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const; template TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const; -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; -template void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const; - TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const { return rotoscaleT(transform); } diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h index 8bfddef8c1a..3c2b29b7b36 100644 --- a/graphics/transparent_surface.h +++ b/graphics/transparent_surface.h @@ -177,9 +177,6 @@ struct TransparentSurface : public Graphics::Surface { void setAlphaMode(AlphaType); private: AlphaType _alphaMode; - - template - void scaleNN(int *scaleCacheX, TransparentSurface *target) const; }; /**