void BitmapUtil::roughScale(const U8 *srcBuffer, U8 *dstBuffer, S32 components, S32 srcWidth, S32 srcHeight, S32 dstWidth, S32 dstHeight) { int NumPixels = dstHeight; int IntPart = (srcHeight / dstHeight) * srcWidth; int FractPart = srcHeight % dstHeight; int E = 0; const U8 *PrevSource = NULL; while (NumPixels-- > 0) { if (srcBuffer == PrevSource) { memcpy(dstBuffer, dstBuffer - dstWidth * components, dstWidth * sizeof(*dstBuffer) * components); } else { scaleLine(srcBuffer, dstBuffer, components, srcWidth, dstWidth); PrevSource = srcBuffer; } /* if */ dstBuffer += dstWidth*components; srcBuffer += IntPart*components; E += FractPart; if (E >= dstHeight) { E -= dstHeight; srcBuffer += srcWidth*components; } } }
/** * Scales a passed surface, creating a new surface with the result * @param srcImage Source image to scale * @param NewWidth New width for scaled image * @param NewHeight New height for scaled image * @remarks Caller is responsible for freeing the returned surface */ static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int transIndex) { GfxSurface s; s.create(xSize, ySize); Graphics::Surface srcImage = src.lockSurface(); Graphics::Surface destImage = s.lockSurface(); int *horizUsage = scaleLine(xSize, srcImage.w); int *vertUsage = scaleLine(ySize, srcImage.h); // Loop to create scaled version for (int yp = 0; yp < ySize; ++yp) { byte *destP = (byte *)destImage.getBasePtr(0, yp); if (vertUsage[yp] == -1) { Common::set_to(destP, destP + xSize, transIndex); } else { const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]); for (int xp = 0; xp < xSize; ++xp) { if (horizUsage[xp] != -1) { const byte *tempSrcP = srcP + horizUsage[xp]; *destP++ = *tempSrcP++; } else { // Pixel overrun at the end of the line *destP++ = transIndex; } } } } // Unlock surfaces src.unlockSurface(); s.unlockSurface(); // Delete arrays and return surface delete[] horizUsage; delete[] vertUsage; return s; }
static YOPTIMIZE_SPEED int bltLineExt(unsigned char *opixels, int owidth, int oformat, const unsigned char *ipixels, int iwidth, int iformat, int *map) { int ibpp, obpp; int ialphaidx; int oalphaidx; if (owidth <= 0) { return YMAGINE_OK; } if (iwidth <= 0) { return YMAGINE_ERROR; } ibpp = colorBpp(iformat); obpp = colorBpp(oformat); if (owidth == iwidth) { if (iformat == oformat) { /* Neither scaling or color transformation */ memcpy(opixels, ipixels, owidth * obpp); return YMAGINE_OK; } /* No scaling but color conversion */ if (iformat == VBITMAP_COLOR_RGB) { if (oformat == VBITMAP_COLOR_rgbA || oformat == VBITMAP_COLOR_RGBA) { RGBtoRGBA(opixels, ipixels, iwidth); if (oformat == VBITMAP_COLOR_rgbA) { premultiplyRGBA(opixels, owidth, obpp); } return YMAGINE_OK; } if (oformat == VBITMAP_COLOR_Argb || oformat == VBITMAP_COLOR_ARGB) { RGBtoARGB(opixels, ipixels, iwidth); if (oformat == VBITMAP_COLOR_Argb) { premultiplyARGB(opixels, owidth, obpp); } return YMAGINE_OK; } } if (iformat == VBITMAP_COLOR_RGBA) { if (oformat == VBITMAP_COLOR_ARGB) { memcpy(opixels, ipixels, owidth * obpp); RGBAtoARGB(opixels, owidth, obpp); return YMAGINE_OK; } if (oformat == VBITMAP_COLOR_Argb) { memcpy(opixels, ipixels, owidth * obpp); RGBAtoARGB(opixels, owidth, obpp); premultiplyARGB(opixels, owidth, obpp); return YMAGINE_OK; } if (oformat == VBITMAP_COLOR_rgbA) { memcpy(opixels, ipixels, owidth * obpp); premultiplyRGBA(opixels, owidth, obpp); return YMAGINE_OK; } } } if (iformat != oformat) { int valid = 0; /* Only support a limited set of colorspace conversions */ if (oformat == VBITMAP_COLOR_RGBA|| oformat == VBITMAP_COLOR_ARGB || oformat == VBITMAP_COLOR_rgbA || oformat == VBITMAP_COLOR_Argb || oformat == VBITMAP_COLOR_RGB) { if (iformat == VBITMAP_COLOR_RGBA|| iformat == VBITMAP_COLOR_ARGB || iformat == VBITMAP_COLOR_rgbA || iformat == VBITMAP_COLOR_Argb || iformat == VBITMAP_COLOR_RGB || iformat == VBITMAP_COLOR_CMYK) { valid = 1; } } if (!valid) { return YMAGINE_ERROR; } } if (iformat == VBITMAP_COLOR_RGB && oformat == VBITMAP_COLOR_RGBA) { scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3, ipixels, iwidth, VBITMAP_COLOR_RGB, 3, -1, map); } else if (iformat == VBITMAP_COLOR_RGB && oformat == VBITMAP_COLOR_rgbA) { scaleLine(opixels, owidth, VBITMAP_COLOR_rgbA, 4, 3, ipixels, iwidth, VBITMAP_COLOR_RGB, 3, -1, map); } else if (iformat == VBITMAP_COLOR_RGBA && oformat == VBITMAP_COLOR_RGBA) { scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3, ipixels, iwidth, VBITMAP_COLOR_RGBA, 4, 3, map); } else if (iformat == VBITMAP_COLOR_RGBA && oformat == VBITMAP_COLOR_rgbA) { scaleLine(opixels, owidth, VBITMAP_COLOR_RGBA, 4, 3, ipixels, iwidth, VBITMAP_COLOR_rgbA, 4, 3, map); } else { if (iformat == VBITMAP_COLOR_RGBA) { ialphaidx = 3; } else { ialphaidx = -1; } if (oformat == VBITMAP_COLOR_RGBA) { oalphaidx = 3; } else { oalphaidx = -1; } scaleLine(opixels, owidth, oformat, obpp, oalphaidx, ipixels, iwidth, iformat, ibpp, ialphaidx, map); } return YMAGINE_OK; }