mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine/raster: optimized the scaled image rasterization
Unified common logic for scaled image raster operations, Avoid on-spot pixel computation as possible. Tested on local machine (single thread) Lottie: 0.057s -> 0.053s (-0.004s)
This commit is contained in:
parent
35ddc5fe56
commit
63613992c4
1 changed files with 115 additions and 201 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue