|
@@ -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;
|