sw_engine: Keep compact image raster code.

Reduce duplicated image raster code between scaler approaches.

Although this allows for a function call per pixel,
this change does not noticeably impact performance (< error bound).

Binary Size diff: 222541 -> 218379 (-4kb)
This commit is contained in:
Hermet Park 2023-06-02 16:29:06 +09:00 committed by Hermet Park
parent a3691ff249
commit c3a002a474
3 changed files with 169 additions and 399 deletions

View file

@ -162,7 +162,7 @@ static inline uint32_t _halfScale(float scale)
}
//Bilinear Interpolation
static uint32_t _interpUpScaler(const uint32_t *img, uint32_t w, uint32_t h, float sx, float sy)
static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride, uint32_t w, uint32_t h, float sx, float sy, TVG_UNUSED uint32_t n)
{
auto rx = (uint32_t)(sx);
auto ry = (uint32_t)(sy);
@ -184,8 +184,10 @@ static uint32_t _interpUpScaler(const uint32_t *img, uint32_t w, uint32_t h, flo
//2n x 2n Mean Kernel
static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, uint32_t rx, uint32_t ry, uint32_t n)
static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, float sx, float sy, uint32_t n)
{
uint32_t rx = sx;
uint32_t ry = sy;
uint32_t c[4] = {0, 0, 0, 0};
auto n2 = n * n;
auto src = img + rx - n + (ry - n) * stride;
@ -612,57 +614,32 @@ static bool _rasterScaledMattedRleRGBAImage(SwSurface* surface, const SwImage* i
auto csize = surface->compositor->image.channelSize;
auto alpha = surface->blender.alpha(surface->compositor->method);
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto tmp = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha(cmp));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto tmp = ALPHA_BLEND(src, MULTIPLY(alpha(cmp), a));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto tmp = ALPHA_BLEND(scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha(cmp));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
}
//Center (Up-Scaled)
} else {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto tmp = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), alpha(cmp));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
auto tmp = ALPHA_BLEND(src, MULTIPLY(alpha(cmp), a));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto tmp = ALPHA_BLEND(src, MULTIPLY(alpha(cmp), a));
*dst = tmp + ALPHA_BLEND(*dst, IALPHA(tmp));
}
}
}
return true;
}
@ -671,50 +648,26 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image,
{
auto span = image->rle->spans;
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
}
//Center (Up-Scaled)
} else {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), alpha);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = ALPHA_BLEND(scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
}
}
@ -967,60 +920,32 @@ static bool _rasterScaledMattedRGBAImage(SwSurface* surface, const SwImage* imag
TVGLOG("SW_ENGINE", "Scaled Matted(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
// Down-Scaled
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = (uint32_t)(y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = dbuffer;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto temp = ALPHA_BLEND(src, alpha(cmp));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto temp = ALPHA_BLEND(src, MULTIPLY(opacity, alpha(cmp)));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = dbuffer;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto temp = ALPHA_BLEND(src, alpha(cmp));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride * csize;
}
// Up-Scaled
} else {
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = dbuffer;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
auto temp = ALPHA_BLEND(src, alpha(cmp));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
auto temp = ALPHA_BLEND(src, MULTIPLY(opacity, alpha(cmp)));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
auto temp = ALPHA_BLEND(src, MULTIPLY(opacity, alpha(cmp)));
*dst = temp + ALPHA_BLEND(*dst, IALPHA(temp));
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride * csize;
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride * csize;
}
return true;
}
@ -1029,49 +954,25 @@ static bool _rasterScaledMattedRGBAImage(SwSurface* surface, const SwImage* imag
static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale)
{
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
// Down-Scaled
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) {
auto sy = (uint32_t)(y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = dbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), opacity);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) {
auto sy = y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto dst = dbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
}
// Up-Scaled
} else {
for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) {
auto sy = fabsf(y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = dbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), opacity);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = ALPHA_BLEND(scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), opacity);
*dst = src + ALPHA_BLEND(*dst, IALPHA(src));
}
}
}

View file

@ -20,6 +20,8 @@
* SOFTWARE.
*/
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
#ifdef SCALED_IMAGE_INT_MASK
{
auto cbuffer = surface->compositor->image.buf32 + (surface->compositor->bbox.min.y * cstride + surface->compositor->bbox.min.x);
@ -28,47 +30,25 @@
if (y == region.min.y) {
auto cbuffer2 = cbuffer;
for (uint32_t y2 = y; y2 < region.max.y; ++y2) {
auto sy = (uint32_t)(y2 * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto sy = y2 * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto tmp = cbuffer2;
auto x = surface->compositor->bbox.min.x;
while (x < surface->compositor->bbox.max.x) {
if (x == region.min.x) {
if (opacity == 255) {
//Down-Scaled
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
//Up-Scaled
} else {
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (x + i) * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
} else {
//Down-Scaled
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), opacity);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
//Up-Scaled
} else {
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), opacity);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
for (uint32_t i = 0; i < w; ++i, ++tmp) {
auto sx = (x + i) * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = ALPHA_BLEND(scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), opacity);
*tmp = ALPHA_BLEND(*tmp, ALPHA(src));
}
}
x += w;
@ -94,78 +74,39 @@
{
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x);
// Down-Scaled
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = (uint32_t)(y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_IMAGE_ADD_MASK
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
#elif defined(SCALED_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
#elif defined(SCALED_IMAGE_DIF_MASK)
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_IMAGE_ADD_MASK
*cmp = INTERPOLATE(src, *cmp, opacity);
#elif defined(SCALED_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, opacity)));
#elif defined(SCALED_IMAGE_DIF_MASK)
src = ALPHA_BLEND(src, opacity);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
}
cbuffer += cstride;
}
// Up-Scaled
} else {
for (auto y = region.min.y; y < region.max.y; ++y) {
auto sy = y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto cmp = cbuffer;
if (opacity == 255) {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_IMAGE_ADD_MASK
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = INTERPOLATE(src, *cmp, opacity);
#elif defined(SCALED_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, opacity)));
#elif defined(SCALED_IMAGE_DIF_MASK)
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
src = ALPHA_BLEND(src, opacity);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
#ifdef SCALED_IMAGE_ADD_MASK
*cmp = INTERPOLATE(src, *cmp, opacity);
#elif defined(SCALED_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, opacity)));
#elif defined(SCALED_IMAGE_DIF_MASK)
src = ALPHA_BLEND(src, opacity);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
}
cbuffer += cstride;
}
cbuffer += cstride;
}
}
#endif
#endif

View file

@ -20,149 +20,77 @@
* SOFTWARE.
*/
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
#ifdef SCALED_RLE_IMAGE_INT_MASK
{
auto cbuffer = surface->compositor->image.buf32;
auto cstride = surface->compositor->image.stride;
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) {
auto cmp = &cbuffer[y * cstride];
for (uint32_t x = surface->compositor->bbox.min.x; x < surface->compositor->bbox.max.x; ++x) {
if (y == span->y && x == span->x && x + span->len <= surface->compositor->bbox.max.x) {
auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
} else {
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
src = ALPHA_BLEND(src, alpha);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) {
auto cmp = &cbuffer[y * cstride];
for (uint32_t x = surface->compositor->bbox.min.x; x < surface->compositor->bbox.max.x; ++x) {
if (y == span->y && x == span->x && x + span->len <= surface->compositor->bbox.max.x) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (x + i) * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
x += span->len - 1;
++span;
} else {
cmp[x] = 0;
}
}
}
//Center (Up-Scaled)
} else {
for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) {
auto cmp = &cbuffer[y * cstride];
for (uint32_t x = surface->compositor->bbox.min.x; x < surface->compositor->bbox.max.x; ++x) {
if (y == span->y && x == span->x && x + span->len <= surface->compositor->bbox.max.x) {
auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
} else {
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (uint32_t)((x + i) * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
src = ALPHA_BLEND(src, alpha);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
for (uint32_t i = 0; i < span->len; ++i) {
auto sx = (x + i) * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
src = ALPHA_BLEND(src, alpha);
cmp[x + i] = ALPHA_BLEND(cmp[x + i], ALPHA(src));
}
x += span->len - 1;
++span;
} else {
cmp[x] = 0;
}
x += span->len - 1;
++span;
} else {
cmp[x] = 0;
}
}
}
}
#else
{
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto cmp = &surface->compositor->image.buf32[span->y * surface->compositor->image.stride + span->x];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto cmp = &surface->compositor->image.buf32[span->y * surface->compositor->image.stride + span->x];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_RLE_IMAGE_ADD_MASK
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
#elif defined(SCALED_RLE_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
#elif defined(SCALED_RLE_IMAGE_DIF_MASK)
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = (uint32_t)(x * itransform->e11 + itransform->e13);
if (sx >= image->w) continue;
auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_RLE_IMAGE_ADD_MASK
*cmp = INTERPOLATE(src, *cmp, a);
#elif defined(SCALED_RLE_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, a)));
#elif defined(SCALED_RLE_IMAGE_DIF_MASK)
src = ALPHA_BLEND(src, a);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
}
}
//Center (Up-Scaled)
} else {
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto sy = span->y * itransform->e22 + itransform->e23;
if ((uint32_t)sy >= image->h) continue;
auto cmp = &surface->compositor->image.buf32[span->y * surface->compositor->image.stride + span->x];
auto a = MULTIPLY(span->coverage, opacity);
if (a == 255) {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale);
#ifdef SCALED_RLE_IMAGE_ADD_MASK
*cmp = src + ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = INTERPOLATE(src, *cmp, a);
#elif defined(SCALED_RLE_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(src));
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, a)));
#elif defined(SCALED_RLE_IMAGE_DIF_MASK)
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
src = ALPHA_BLEND(src, a);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
} else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13;
if ((uint32_t)sx >= image->w) continue;
auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy);
#ifdef SCALED_RLE_IMAGE_ADD_MASK
*cmp = INTERPOLATE(src, *cmp, a);
#elif defined(SCALED_RLE_IMAGE_SUB_MASK)
*cmp = ALPHA_BLEND(*cmp, IALPHA(ALPHA_BLEND(src, a)));
#elif defined(SCALED_RLE_IMAGE_DIF_MASK)
src = ALPHA_BLEND(src, a);
*cmp = ALPHA_BLEND(src, IALPHA(*cmp)) + ALPHA_BLEND(*cmp, IALPHA(src));
#endif
}
}
}
}