png_loaders: fix the wrong premultiplying operations.
authorHermet Park <chuneon.park@samsung.com>
Tue, 14 Dec 2021 07:33:17 +0000 (16:33 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 14 Dec 2021 07:51:54 +0000 (23:51 -0800)
It should not modify the alpha channel value while premultiplying
that turned out with the wrong visual result.

@Issue: https://github.com/Samsung/thorvg/issues/655

src/examples/PicturePng.cpp
src/loaders/external_png/tvgPngLoader.cpp
src/loaders/png/tvgPngLoader.cpp

index 1cccf6965f7c3eb2b722c5f28632ab00a8308259..3798ab151546678b4326a83fefa77462e8ba9812 100644 (file)
@@ -31,6 +31,12 @@ void tvgDrawCmds(tvg::Canvas* canvas)
 {
     if (!canvas) return;
 
+    //Background                            
+    auto bg = tvg::Shape::gen();
+    bg->appendRect(0, 0, WIDTH, HEIGHT, 0, 0);    //x, y, w, h, rx, ry
+    bg->fill(255, 255, 255, 255);                 //r, g, b, a
+    canvas->push(move(bg));
+
     //Load png file from path
     auto opacity = 51;
 
index 316f51dd100b9bb2437391853f2d709b39692184..c3d281482a775b1db41343d0f38196e51fb8b27a 100644 (file)
 #include "tvgLoader.h"
 #include "tvgPngLoader.h"
 
-static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
+static inline uint32_t PREMULTIPLY(uint32_t c)
 {
-    return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) +
-            ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff));
+    auto a = (c >> 24);
+    return (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
 }
 
 
@@ -36,7 +36,7 @@ static void _premultiply(uint32_t* data, uint32_t w, uint32_t h)
     for (uint32_t y = 0; y < h; ++y, buffer += w) {
         auto src = buffer;
         for (uint32_t x = 0; x < w; ++x, ++src) {
-            *src = ALPHA_BLEND(*src, (*src >> 24));
+            *src = PREMULTIPLY(*src);
         }
     }
 }
index b9388933eee415e7bec7d71f1bf1057db8e40899..c6d95be5ba69f3017162f0097eb7d010ab13fcbf 100644 (file)
 /************************************************************************/
 
 
-static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
+static inline uint32_t PREMULTIPLY(uint32_t c)
 {
-    return (((((c >> 8) & 0x00ff00ff) * a + 0x00ff00ff) & 0xff00ff00) +
-            ((((c & 0x00ff00ff) * a + 0x00ff00ff) >> 8) & 0x00ff00ff));
+    auto a = (c >> 24);
+    return (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
 }
 
 
@@ -42,7 +42,7 @@ static void _premultiply(uint32_t* data, uint32_t w, uint32_t h)
     for (uint32_t y = 0; y < h; ++y, buffer += w) {
         auto src = buffer;
         for (uint32_t x = 0; x < w; ++x, ++src) {
-            *src = ALPHA_BLEND(*src, (*src >> 24));
+            *src = PREMULTIPLY(*src);
         }
     }
 }