@@ -423,12 +423,11 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_
423423 auto h = static_cast <uint32_t >(region.max .y - region.min .y );
424424 auto color = surface->join (r, g, b, a);
425425 auto buffer = surface->buf32 + (region.min .y * surface->stride ) + region.min .x ;
426- auto ialpha = 255 - a;
427426
428427 for (uint32_t y = 0 ; y < h; ++y) {
429428 auto dst = &buffer[y * surface->stride ];
430429 for (uint32_t x = 0 ; x < w; ++x, ++dst) {
431- *dst = surface->blender (color, *dst, ialpha );
430+ *dst = surface->blender (color, *dst, 255 );
432431 }
433432 }
434433 return true ;
@@ -595,17 +594,16 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t
595594
596595 auto span = rle->spans ;
597596 auto color = surface->join (r, g, b, a);
598- auto ialpha = 255 - a;
599597
600598 for (uint32_t i = 0 ; i < rle->size ; ++i, ++span) {
601599 auto dst = &surface->buf32 [span->y * surface->stride + span->x ];
602600 if (span->coverage == 255 ) {
603601 for (uint32_t x = 0 ; x < span->len ; ++x, ++dst) {
604- *dst = surface->blender (color, *dst, ialpha );
602+ *dst = surface->blender (color, *dst, 255 );
605603 }
606604 } else {
607605 for (uint32_t x = 0 ; x < span->len ; ++x, ++dst) {
608- auto tmp = surface->blender (color, *dst, ialpha );
606+ auto tmp = surface->blender (color, *dst, 255 );
609607 *dst = INTERPOLATE (tmp, *dst, span->coverage );
610608 }
611609 }
@@ -813,9 +811,8 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* ima
813811 for (uint32_t x = static_cast <uint32_t >(span->x ); x < static_cast <uint32_t >(span->x ) + span->len ; ++x, ++dst) {
814812 SCALED_IMAGE_RANGE_X
815813 auto src = scaleMethod (image->buf32 , image->stride , image->w , image->h , sx, sy, miny, maxy, sampleSize);
816- if (opacity < 255 ) src = ALPHA_BLEND (src, opacity);
817814 auto tmp = surface->blender (src, *dst, 255 );
818- *dst = INTERPOLATE (tmp, *dst, MULTIPLY (span-> coverage , A (src)));
815+ *dst = INTERPOLATE (tmp, *dst, MULTIPLY (alpha , A (src)));
819816 }
820817 }
821818 }
@@ -981,18 +978,12 @@ static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage* ima
981978 auto alpha = MULTIPLY (span->coverage , opacity);
982979 if (alpha == 255 ) {
983980 for (uint32_t x = 0 ; x < span->len ; ++x, ++dst, ++img) {
984- *dst = surface->blender (*img, *dst, IA (*img));
985- }
986- } else if (opacity == 255 ) {
987- for (uint32_t x = 0 ; x < span->len ; ++x, ++dst, ++img) {
988- auto tmp = surface->blender (*img, *dst, 255 );
989- *dst = INTERPOLATE (tmp, *dst, MULTIPLY (span->coverage , A (*img)));
981+ *dst = surface->blender (*img, *dst, 255 );
990982 }
991983 } else {
992984 for (uint32_t x = 0 ; x < span->len ; ++x, ++dst, ++img) {
993- auto src = ALPHA_BLEND (*img, opacity);
994- auto tmp = surface->blender (src, *dst, IA (src));
995- *dst = INTERPOLATE (tmp, *dst, MULTIPLY (span->coverage , A (src)));
985+ auto tmp = surface->blender (*img, *dst, 255 );
986+ *dst = INTERPOLATE (tmp, *dst, MULTIPLY (alpha, A (*img)));
996987 }
997988 }
998989 }
@@ -1164,9 +1155,8 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
11641155 for (auto x = region.min .x ; x < region.max .x ; ++x, ++dst) {
11651156 SCALED_IMAGE_RANGE_X
11661157 auto src = scaleMethod (image->buf32 , image->stride , image->w , image->h , sx, sy, miny, maxy, sampleSize);
1167- if (opacity < 255 ) ALPHA_BLEND (src, opacity);
11681158 auto tmp = surface->blender (src, *dst, 255 );
1169- *dst = INTERPOLATE (tmp, *dst, A (src));
1159+ *dst = INTERPOLATE (tmp, *dst, MULTIPLY (opacity, A (src) ));
11701160 }
11711161 }
11721162 return true ;
@@ -1348,11 +1338,13 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c
13481338 auto src = sbuffer;
13491339 if (opacity == 255 ) {
13501340 for (uint32_t x = 0 ; x < w; ++x, ++dst, ++src, cmp += csize) {
1351- *dst = MULTIPLY (A (*src), alpha (cmp));
1341+ auto tmp = MULTIPLY (A (*src), alpha (cmp));
1342+ *dst = tmp + MULTIPLY (*dst, 255 - tmp);
13521343 }
13531344 } else {
13541345 for (uint32_t x = 0 ; x < w; ++x, ++dst, ++src, cmp += csize) {
1355- *dst = MULTIPLY (A (*src), MULTIPLY (opacity, alpha (cmp)));
1346+ auto tmp = MULTIPLY (A (*src), MULTIPLY (opacity, alpha (cmp)));
1347+ *dst = tmp + MULTIPLY (*dst, 255 - tmp);
13561348 }
13571349 }
13581350 buffer += surface->stride ;
@@ -1384,9 +1376,8 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
13841376 }
13851377 } else {
13861378 for (auto x = region.min .x ; x < region.max .x ; x++, dst++, src++) {
1387- auto tmp = ALPHA_BLEND (*src, opacity);
1388- auto tmp2 = surface->blender (tmp, *dst, 255 );
1389- *dst = INTERPOLATE (tmp2, *dst, A (tmp));
1379+ auto tmp = surface->blender (*src, *dst, 255 );
1380+ *dst = INTERPOLATE (tmp, *dst, MULTIPLY (opacity, A (*src)));
13901381 }
13911382 }
13921383 dbuffer += surface->stride ;
@@ -1442,12 +1433,52 @@ static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const S
14421433}
14431434
14441435
1436+ static bool _rasterDirectMattedBlendingImage (SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
1437+ {
1438+ if (surface->channelSize == sizeof (uint8_t )) {
1439+ TVGERR (" SW_ENGINE" , " Not supported grayscale image!" );
1440+ return false ;
1441+ }
1442+
1443+ auto h = static_cast <uint32_t >(region.max .y - region.min .y );
1444+ auto w = static_cast <uint32_t >(region.max .x - region.min .x );
1445+ auto csize = surface->compositor ->image .channelSize ;
1446+ auto alpha = surface->alpha (surface->compositor ->method );
1447+ auto sbuffer = image->buf32 + (region.min .y + image->oy ) * image->stride + (region.min .x + image->ox );
1448+ auto cbuffer = surface->compositor ->image .buf8 + (region.min .y * surface->compositor ->image .stride + region.min .x ) * csize; // compositor buffer
1449+ auto buffer = surface->buf32 + (region.min .y * surface->stride ) + region.min .x ;
1450+
1451+ for (uint32_t y = 0 ; y < h; ++y) {
1452+ auto dst = buffer;
1453+ auto cmp = cbuffer;
1454+ auto src = sbuffer;
1455+ if (opacity == 255 ) {
1456+ for (uint32_t x = 0 ; x < w; ++x, ++dst, ++src, cmp += csize) {
1457+ auto tmp = ALPHA_BLEND (*src, alpha (cmp));
1458+ *dst = INTERPOLATE (surface->blender (tmp, *dst, 255 ), *dst, A (tmp));
1459+ }
1460+ } else {
1461+ for (uint32_t x = 0 ; x < w; ++x, ++dst, ++src, cmp += csize) {
1462+ auto tmp = ALPHA_BLEND (*src, alpha (cmp));
1463+ *dst = INTERPOLATE (surface->blender (tmp, *dst, 255 ), *dst, MULTIPLY (opacity, A (tmp)));
1464+ }
1465+ }
1466+ buffer += surface->stride ;
1467+ cbuffer += surface->compositor ->image .stride * csize;
1468+ sbuffer += image->stride ;
1469+ }
1470+ return true ;
1471+ }
1472+
1473+
14451474// Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent]
14461475static bool _directImage (SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
14471476{
14481477 if (_compositing (surface)) {
1449- if (_matting (surface)) return _rasterDirectMattedImage (surface, image, region, opacity);
1450- else return _rasterDirectMaskedImage (surface, image, region, opacity);
1478+ if (_matting (surface)) {
1479+ if (_blending (surface)) return _rasterDirectMattedBlendingImage (surface, image, region, opacity);
1480+ else return _rasterDirectMattedImage (surface, image, region, opacity);
1481+ } else return _rasterDirectMaskedImage (surface, image, region, opacity);
14511482 } else if (_blending (surface)) {
14521483 return _rasterDirectBlendingImage (surface, image, region, opacity);
14531484 } else {
@@ -1843,19 +1874,19 @@ bool rasterCompositor(SwSurface* surface)
18431874}
18441875
18451876
1846- bool rasterClear (SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
1877+ bool rasterClear (SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val )
18471878{
18481879 if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0 ) return false ;
18491880
18501881 // 32 bits
18511882 if (surface->channelSize == sizeof (uint32_t )) {
18521883 // full clear
18531884 if (w == surface->stride ) {
1854- rasterPixel32 (surface->buf32 , 0x00000000 , surface->stride * y, w * h);
1885+ rasterPixel32 (surface->buf32 , val , surface->stride * y, w * h);
18551886 // partial clear
18561887 } else {
18571888 for (uint32_t i = 0 ; i < h; i++) {
1858- rasterPixel32 (surface->buf32 , 0x00000000 , (surface->stride * y + x) + (surface->stride * i), w);
1889+ rasterPixel32 (surface->buf32 , val , (surface->stride * y + x) + (surface->stride * i), w);
18591890 }
18601891 }
18611892 // 8 bits
0 commit comments