Add an option to create unpremultiplied bitmaps.
Currently they cannot be used directly by Skia, but
the pixels can be used elsewhere.

SkImageDecoder:
Add functions to require unpremultiplied output
and query the presence of the requirement

SkImageDecoder_libpng:
SkImageDecoder_libwebp:
SkImageDecoder_WIC:
Respect the requirement for unpremultiplied output.
TODO: Fix SkImageDecoder_CG.

SkScaledBitmapSampler:
Add procs to skip premultiplication and a boolean
parameter to use those procs.

ImageDecodingTest:
Test unpremultiplied bitmap decoding.

SampleUnpremul:
Add a sample which allows visually comparing between the
unpremultiplied version (copied into a premultiplied bitmap,
since drawing unpremultiplied is not currently supported)
and a premultiplied version of image files.

gm.h:
Add a getter for the resource path, so Samples can use it.

As of patch set 13, https://codereview.chromium.org/16816016/
and https://codereview.chromium.org/16983004/, which were
approved separately.

R=reed@google.com

Review URL: https://codereview.chromium.org/16410009

git-svn-id: http://skia.googlecode.com/svn/trunk@9612 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
index 25b32fd..ca41de9 100644
--- a/src/images/SkScaledBitmapSampler.cpp
+++ b/src/images/SkScaledBitmapSampler.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2007 The Android Open Source Project
  *
@@ -11,6 +10,7 @@
 #include "SkBitmap.h"
 #include "SkColorPriv.h"
 #include "SkDither.h"
+#include "SkTypes.h"
 
 // 8888
 
@@ -289,6 +289,41 @@
     return false;
 }
 
+// 8888 Unpremul
+
+static bool Sample_Gray_D8888_Unpremul(void* SK_RESTRICT dstRow,
+                                       const uint8_t* SK_RESTRICT src,
+                                       int width, int deltaSrc, int,
+                                       const SkPMColor[]) {
+    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[0], src[0]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+// Sample_RGBx_D8888_Unpremul is no different from Sample_RGBx_D8888, since alpha
+// is 0xFF
+
+static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow,
+                                       const uint8_t* SK_RESTRICT src,
+                                       int width, int deltaSrc, int,
+                                       const SkPMColor[]) {
+    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
+    unsigned alphaMask = 0xFF;
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+// Sample_Index_D8888_Unpremul is the same as Sample_Index_D8888, since the
+// color table has its colors inserted unpremultiplied.
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkScaledBitmapSampler.h"
@@ -334,33 +369,44 @@
 }
 
 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
-                                  const SkPMColor ctable[]) {
+                                  const SkPMColor ctable[],
+                                  bool requireUnpremul) {
     static const RowProc gProcs[] = {
         // 8888 (no dither distinction)
-        Sample_Gray_D8888,  Sample_Gray_D8888,
-        Sample_RGBx_D8888,  Sample_RGBx_D8888,
-        Sample_RGBA_D8888,  Sample_RGBA_D8888,
-        Sample_Index_D8888, Sample_Index_D8888,
-        NULL,               NULL,
+        Sample_Gray_D8888,              Sample_Gray_D8888,
+        Sample_RGBx_D8888,              Sample_RGBx_D8888,
+        Sample_RGBA_D8888,              Sample_RGBA_D8888,
+        Sample_Index_D8888,             Sample_Index_D8888,
+        NULL,                           NULL,
         // 565 (no alpha distinction)
-        Sample_Gray_D565,   Sample_Gray_D565_D,
-        Sample_RGBx_D565,   Sample_RGBx_D565_D,
-        Sample_RGBx_D565,   Sample_RGBx_D565_D,
-        Sample_Index_D565,  Sample_Index_D565_D,
-        Sample_D565_D565,   Sample_D565_D565,
+        Sample_Gray_D565,               Sample_Gray_D565_D,
+        Sample_RGBx_D565,               Sample_RGBx_D565_D,
+        Sample_RGBx_D565,               Sample_RGBx_D565_D,
+        Sample_Index_D565,              Sample_Index_D565_D,
+        Sample_D565_D565,               Sample_D565_D565,
         // 4444
-        Sample_Gray_D4444,  Sample_Gray_D4444_D,
-        Sample_RGBx_D4444,  Sample_RGBx_D4444_D,
-        Sample_RGBA_D4444,  Sample_RGBA_D4444_D,
-        Sample_Index_D4444, Sample_Index_D4444_D,
-        NULL,               NULL,
+        Sample_Gray_D4444,              Sample_Gray_D4444_D,
+        Sample_RGBx_D4444,              Sample_RGBx_D4444_D,
+        Sample_RGBA_D4444,              Sample_RGBA_D4444_D,
+        Sample_Index_D4444,             Sample_Index_D4444_D,
+        NULL,                           NULL,
         // Index8
-        NULL,               NULL,
-        NULL,               NULL,
-        NULL,               NULL,
-        Sample_Index_DI,    Sample_Index_DI,
-        NULL,               NULL,
+        NULL,                           NULL,
+        NULL,                           NULL,
+        NULL,                           NULL,
+        Sample_Index_DI,                Sample_Index_DI,
+        NULL,                           NULL,
+        // 8888 Unpremul (no dither distinction)
+        Sample_Gray_D8888_Unpremul,     Sample_Gray_D8888_Unpremul,
+        Sample_RGBx_D8888,              Sample_RGBx_D8888,
+        Sample_RGBA_D8888_Unpremul,     Sample_RGBA_D8888_Unpremul,
+        Sample_Index_D8888,             Sample_Index_D8888,
+        NULL,                           NULL,
     };
+    // The jump between dst configs in the table
+    static const int gProcDstConfigSpan = 10;
+    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 5 * gProcDstConfigSpan,
+                      gProcs_has_the_wrong_number_of_entries);
 
     fCTable = ctable;
 
@@ -399,21 +445,28 @@
 
     switch (dst->config()) {
         case SkBitmap::kARGB_8888_Config:
-            index += 0;
+            index += 0 * gProcDstConfigSpan;
             break;
         case SkBitmap::kRGB_565_Config:
-            index += 10;
+            index += 1 * gProcDstConfigSpan;
             break;
         case SkBitmap::kARGB_4444_Config:
-            index += 20;
+            index += 2 * gProcDstConfigSpan;
             break;
         case SkBitmap::kIndex8_Config:
-            index += 30;
+            index += 3 * gProcDstConfigSpan;
             break;
         default:
             return false;
     }
 
+    if (requireUnpremul) {
+        if (dst->config() != SkBitmap::kARGB_8888_Config) {
+            return false;
+        }
+        index += 4 * gProcDstConfigSpan;
+    }
+
     fRowProc = gProcs[index];
     fDstRow = (char*)dst->getPixels();
     fDstRowBytes = dst->rowBytes();