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/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index d967a69..729f871 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -80,8 +80,9 @@
     SkPNGImageIndex* fImageIndex;
 
     bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_ptrp);
-    bool decodePalette(png_structp png_ptr, png_infop info_ptr, bool *hasAlphap,
-                       bool *reallyHasAlphap, SkColorTable **colorTablep);
+    bool decodePalette(png_structp png_ptr, png_infop info_ptr,
+                       bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap,
+                       SkColorTable **colorTablep);
     bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
                          SkBitmap::Config *config, bool *hasAlpha,
                          bool *doDither, SkPMColor *theTranspColor);
@@ -311,7 +312,7 @@
 
     if (!reuseBitmap) {
         decodedBitmap->setConfig(config, sampler.scaledWidth(),
-                                 sampler.scaledHeight(), 0);
+                                 sampler.scaledHeight());
     }
     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
         return true;
@@ -383,7 +384,8 @@
             upscale png's palette to a direct model
          */
         SkAutoLockColors ctLock(colorTable);
-        if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) {
+        if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors(),
+                           this->getRequireUnpremultipliedColors())) {
             return false;
         }
         const int height = decodedBitmap->height();
@@ -435,6 +437,13 @@
     if (0 != theTranspColor) {
         reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
     }
+    if (reallyHasAlpha && this->getRequireUnpremultipliedColors() &&
+        SkBitmap::kARGB_8888_Config != decodedBitmap->config()) {
+        // If the caller wants an unpremultiplied bitmap, and we let them get
+        // away with a config other than 8888, and it has alpha after all,
+        // return false, since the result will have premultiplied colors.
+        return false;
+    }
     decodedBitmap->setIsOpaque(!reallyHasAlpha);
     if (reuseBitmap) {
         decodedBitmap->notifyPixelsChanged();
@@ -445,7 +454,7 @@
 
 
 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
-                                        SkBitmap::Config *configp, bool *hasAlphap,
+                                        SkBitmap::Config *configp, bool * SK_RESTRICT hasAlphap,
                                         bool *doDitherp, SkPMColor *theTranspColorp) {
     png_uint_32 origWidth, origHeight;
     int bitDepth, colorType;
@@ -546,9 +555,20 @@
         }
     }
 
-    return this->chooseFromOneChoice(*configp, origWidth, origHeight);
+    if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) {
+        return false;
+    }
+
+    // If the image has alpha and the decoder wants unpremultiplied
+    // colors, the only supported config is 8888.
+    if (this->getRequireUnpremultipliedColors() && *hasAlphap) {
+        *configp = SkBitmap::kARGB_8888_Config;
+    }
+    return true;
 }
 
+typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+
 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
                                       bool *hasAlphap, bool *reallyHasAlphap,
                                       SkColorTable **colorTablep) {
@@ -587,9 +607,17 @@
     int index = 0;
     int transLessThanFF = 0;
 
+    // Choose which function to use to create the color table. If the final destination's
+    // config is unpremultiplied, the color table will store unpremultiplied colors.
+    PackColorProc proc;
+    if (this->getRequireUnpremultipliedColors()) {
+        proc = &SkPackARGB32NoCheck;
+    } else {
+        proc = &SkPreMultiplyARGB;
+    }
     for (; index < numTrans; index++) {
         transLessThanFF |= (int)*trans - 0xFF;
-        *colorPtr++ = SkPreMultiplyARGB(*trans++, palette->red, palette->green, palette->blue);
+        *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue);
         palette++;
     }
     reallyHasAlpha |= (transLessThanFF < 0);
@@ -679,7 +707,7 @@
     SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize);
 
     SkBitmap decodedBitmap;
-    decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0);
+    decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
 
     // from here down we are concerned with colortables and pixels
 
@@ -773,7 +801,8 @@
             upscale png's palette to a direct model
          */
         SkAutoLockColors ctLock(colorTable);
-        if (!sampler.begin(&decodedBitmap, sc, doDither, ctLock.colors())) {
+        if (!sampler.begin(&decodedBitmap, sc, doDither, ctLock.colors(),
+                           this->getRequireUnpremultipliedColors())) {
             return false;
         }
         const int height = decodedBitmap.height();