summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp')
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp316
1 files changed, 115 insertions, 201 deletions
diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
index 4b1ba59100..96a0ed35ad 100644
--- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
+++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
@@ -248,17 +248,17 @@ static inline uint32_t _sampleSize(float scale)
//Bilinear Interpolation
//OPTIMIZE_ME: Skip the function pointer access
-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, TVG_UNUSED uint32_t n2)
+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 int32_t miny, TVG_UNUSED int32_t maxy, TVG_UNUSED int32_t n)
{
- auto rx = (uint32_t)(sx);
- auto ry = (uint32_t)(sy);
+ auto rx = (size_t)(sx);
+ auto ry = (size_t)(sy);
auto rx2 = rx + 1;
if (rx2 >= w) rx2 = w - 1;
auto ry2 = ry + 1;
if (ry2 >= h) ry2 = h - 1;
- auto dx = static_cast<uint32_t>((sx - rx) * 255.0f);
- auto dy = static_cast<uint32_t>((sy - ry) * 255.0f);
+ auto dx = static_cast<size_t>((sx - rx) * 255.0f);
+ auto dy = static_cast<size_t>((sy - ry) * 255.0f);
auto c1 = img[rx + ry * w];
auto c2 = img[rx2 + ry * w];
@@ -271,18 +271,21 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride,
//2n x 2n Mean Kernel
//OPTIMIZE_ME: Skip the function pointer access
-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 n2)
+static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, float sx, TVG_UNUSED float sy, int32_t miny, int32_t maxy, int32_t n)
{
- uint32_t rx = lroundf(sx);
- uint32_t ry = lroundf(sy);
- uint32_t c[4] = {0, 0, 0, 0};
- auto src = img + rx - n + (ry - n) * stride;
+ size_t c[4] = {0, 0, 0, 0};
- for (auto y = ry - n; y < ry + n; ++y) {
- if (y >= h) continue;
+ int32_t minx = (int32_t)sx - n;
+ if (minx < 0) minx = 0;
+
+ int32_t maxx = (int32_t)sx + n;
+ if (maxx >= (int32_t)w) maxx = w;
+
+ auto src = img + minx + miny * stride;
+
+ for (auto y = miny; y < maxy; ++y) {
auto p = src;
- for (auto x = rx - n; x < rx + n; ++x, ++p) {
- if (x >= w) continue;
+ for (auto x = minx; x < maxx; ++x, ++p) {
c[0] += *p >> 24;
c[1] += (*p >> 16) & 0xff;
c[2] += (*p >> 8) & 0xff;
@@ -290,9 +293,14 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t
}
src += stride;
}
- for (auto i = 0; i < 4; ++i) {
- c[i] = (c[i] >> 2) / n2;
- }
+
+ n = (maxy - miny) * (maxx - minx);
+
+ c[0] /= n;
+ c[1] /= n;
+ c[2] /= n;
+ c[3] /= n;
+
return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
@@ -660,34 +668,39 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
/* RLE Scaled Image */
/************************************************************************/
+#define SCALED_IMAGE_RANGE_Y(y) \
+ auto sy = (y) * itransform->e22 + itransform->e23; \
+ auto my = (int32_t)round(sy); \
+ if (my < 0 || (uint32_t)sy >= image->h) continue; \
+ if (scaleMethod == _interpDownScaler) { \
+ miny = my - (int32_t)sampleSize; \
+ if (miny < 0) miny = 0; \
+ maxy = my + (int32_t)sampleSize; \
+ if (maxy >= (int32_t)image->h) maxy = (int32_t)image->h; \
+ }
+
+#define SCALED_IMAGE_RANGE_X \
+ auto sx = x * itransform->e11 + itransform->e13; \
+ if ((int32_t)round(sx) < 0 || (uint32_t) sx >= image->w) continue;
+
+
#if 0 //Enable it when GRAYSCALE image is supported
static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity)
{
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
auto span = image->rle->spans;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(span->y)
auto cmp = &surface->compositor->image.buf8[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->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- *cmp = maskOp(src, *cmp, ~src);
- }
- } 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->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = MULTIPLY(src, a);
- *cmp = maskOp(tmp, *cmp, ~tmp);
- }
+ for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (a < 255) src = MULTIPLY(src, a);
+ *cmp = maskOp(src, *cmp, ~src);
}
}
return true;
@@ -698,31 +711,20 @@ static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage*
{
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
auto span = image->rle->spans;
+ int32_t miny = 0, maxy = 0;
- 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;
+ for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
+ SCALED_IMAGE_RANGE_Y(span->y)
auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x];
auto dst = &surface->buf8[span->y * surface->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, ++dst) {
- auto sx = x * itransform->e11 + itransform->e13;
- if ((uint32_t)sx >= image->w) continue;
- auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = maskOp(src, *cmp, 0); //not use alpha
- *dst = tmp + MULTIPLY(*dst, ~tmp);
- }
- } else {
- for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
- auto sx = x * itransform->e11 + itransform->e13;
- if ((uint32_t)sx >= image->w) continue;
- auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = maskOp(MULTIPLY(src, a), *cmp, 0); //not use alpha
- *dst = tmp + MULTIPLY(*dst, ~tmp);
- }
+ for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (a < 255) src = MULTIPLY(src, a);
+ src = maskOp(src, *cmp, 0); //not use alpha
+ *dst = src + MULTIPLY(*dst, ~src);
}
}
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
@@ -752,32 +754,20 @@ static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image
auto span = image->rle->spans;
auto csize = surface->compositor->image.channelSize;
auto alpha = surface->alpha(surface->compositor->method);
-
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(span->y)
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, sampleSize, sampleSize2), alpha(cmp));
- *dst = tmp + ALPHA_BLEND(*dst, IA(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, sampleSize, sampleSize2);
- auto tmp = ALPHA_BLEND(src, MULTIPLY(alpha(cmp), a));
- *dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
- }
+ for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst, cmp += csize) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ src = ALPHA_BLEND(src, (a == 255) ? alpha(cmp) : MULTIPLY(alpha(cmp), a));
+ *dst = src + ALPHA_BLEND(*dst, IA(src));
}
}
@@ -790,34 +780,24 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* ima
auto span = image->rle->spans;
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(span->y)
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, sampleSize, sampleSize2);
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
auto tmp = surface->blender(src, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, A(src));
}
- } else if (opacity == 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, sampleSize, sampleSize2);
- auto tmp = surface->blender(src, *dst, 255);
- *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(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, sampleSize, sampleSize2), opacity);
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (opacity < 255) src = ALPHA_BLEND(src, opacity);
auto tmp = surface->blender(src, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src)));
}
@@ -832,27 +812,17 @@ static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, cons
auto span = image->rle->spans;
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(span->y)
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, sampleSize, sampleSize2);
- *dst = src + ALPHA_BLEND(*dst, IA(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, sampleSize, sampleSize2), alpha);
- *dst = src + ALPHA_BLEND(*dst, IA(src));
- }
+ for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (alpha < 255) src = ALPHA_BLEND(src, alpha);
+ *dst = src + ALPHA_BLEND(*dst, IA(src));
}
}
return true;
@@ -1067,29 +1037,18 @@ static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage*
{
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
auto cstride = surface->compositor->image.stride;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(y)
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->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- *cmp = maskOp(src, *cmp, ~src);
- }
- } 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->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = MULTIPLY(src, opacity);
- *cmp = maskOp(tmp, *cmp, ~tmp);
- }
+ for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (opacity < 255) src = MULTIPLY(src, opacity);
+ *cmp = maskOp(src, *cmp, ~src);
}
cbuffer += cstride;
}
@@ -1101,33 +1060,21 @@ static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* im
{
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
auto cstride = surface->compositor->image.stride;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x);
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(y)
auto cmp = cbuffer;
auto dst = dbuffer;
- if (opacity == 255) {
- for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
- auto sx = x * itransform->e11 + itransform->e13;
- if ((uint32_t)sx >= image->w) continue;
- auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = maskOp(src, *cmp, 0); //not use alpha
- *dst = tmp + MULTIPLY(*dst, ~tmp);
- }
- } else {
- for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
- auto sx = x * itransform->e11 + itransform->e13;
- if ((uint32_t)sx >= image->w) continue;
- auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
- auto tmp = MULTIPLY(src, opacity);
- auto tmp2 = maskOp(tmp, *cmp, 0); //not use alpha
- *dst = tmp2 + MULTIPLY(*dst, ~tmp2);
- }
+ for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (opacity < 255) src = MULTIPLY(src, opacity);
+ src = maskOp(src, *cmp, 0); //not use alpha
+ *dst = src + MULTIPLY(*dst, ~src);
}
cbuffer += cstride;
dbuffer += surface->stride;
@@ -1160,29 +1107,17 @@ static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, c
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(y)
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, sampleSize, sampleSize2);
- auto temp = ALPHA_BLEND(src, alpha(cmp));
- *dst = temp + ALPHA_BLEND(*dst, IA(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, sampleSize, sampleSize2);
- auto temp = ALPHA_BLEND(src, MULTIPLY(opacity, alpha(cmp)));
- *dst = temp + ALPHA_BLEND(*dst, IA(temp));
- }
+ for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ auto tmp = ALPHA_BLEND(src, opacity == 255 ? alpha(cmp) : MULTIPLY(opacity, alpha(cmp)));
+ *dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride * csize;
@@ -1196,28 +1131,17 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(y)
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, sampleSize, sampleSize2);
- auto tmp = surface->blender(src, *dst, 255);
- *dst = INTERPOLATE(tmp, *dst, A(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, sampleSize, sampleSize2), opacity);
- auto tmp = surface->blender(src, *dst, 255);
- *dst = INTERPOLATE(tmp, *dst, A(src));
- }
+ for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (opacity < 255) ALPHA_BLEND(src, opacity);
+ auto tmp = surface->blender(src, *dst, 255);
+ *dst = INTERPOLATE(tmp, *dst, A(src));
}
}
return true;
@@ -1229,26 +1153,16 @@ static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const M
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
- auto sampleSize2 = sampleSize * sampleSize;
+ int32_t miny = 0, maxy = 0;
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;
+ SCALED_IMAGE_RANGE_Y(y)
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, sampleSize, sampleSize2);
- *dst = src + ALPHA_BLEND(*dst, IA(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, sampleSize, sampleSize2), opacity);
- *dst = src + ALPHA_BLEND(*dst, IA(src));
- }
+ for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
+ SCALED_IMAGE_RANGE_X
+ auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
+ if (opacity < 255) src = ALPHA_BLEND(src, opacity);
+ *dst = src + ALPHA_BLEND(*dst, IA(src));
}
}
return true;