png_loader: correct colorspace
authorHermet Park <chuneon.park@samsung.com>
Thu, 11 Nov 2021 12:44:01 +0000 (21:44 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Fri, 12 Nov 2021 01:46:50 +0000 (10:46 +0900)
decoding color channels rgba -> bgra

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

src/loaders/png/tvgLodePng.cpp

index b50c7e5..f2dfa02 100644 (file)
@@ -2089,30 +2089,44 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
 
     size_t i;
     switch (filterType) {
-        case 0:
-            for (i = 0; i != length; ++i) recon[i] = scanline[i];
+        case 0: {
+            if (bytewidth == 4) {
+                for (i = 0; i < length; i += 4) {
+                    //RGBA -> BGRA
+                    recon[i + 0] = scanline[i + 2];
+                    recon[i + 1] = scanline[i + 1];
+                    recon[i + 2] = scanline[i + 0];
+                    recon[i + 3] = scanline[i + 3];
+                }
+            } else {
+                for (i = 0; i != length; ++i) recon[i] = scanline[i];
+            }
             break;
-        case 1:
+        }
+        case 1: {
             for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
             for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
             break;
-        case 2:
+        }
+        case 2: {
+            if (precon) {
+                for (i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
+            } else {
+                for (i = 0; i != length; ++i) recon[i] = scanline[i];
+            }
+            break;
+        }
+        case 3: {
             if (precon) {
-                for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
+                for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
+                for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u);
             } else {
-                for(i = 0; i != length; ++i) recon[i] = scanline[i];
+                for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
+                for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u);
             }
             break;
-        case 3:
-          if (precon) {
-              for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
-              for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u);
-          } else {
-              for (i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
-              for (i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u);
-          }
-          break;
-        case 4:
+        }
+        case 4: {
             if (precon) {
                 for (i = 0; i != bytewidth; ++i) {
                     recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
@@ -2168,6 +2182,7 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
                 }
             }
             break;
+        }
         default: return 36; /* error: invalid filter type given */
     }
     return 0;