Support more swizzles to 565 in SkCodec

Add more swizzling functions for swizzling to 565. Much of this
code was revived from crrev.com/1055743003 (for BMP). Also added
swizzling functions for WBMP.

Consolidate the static function conversion_possible.

In SkCodec::getPixels, check that the alphatype corresponds to the
colorType. This prevents requesting 565 + non-opaque.

In SkIcoCodec, report that the image is unpremul (instead of
whatever the largest embedded codec thinks), but modify the
requested info to have the alpha type expected/required by the
embedded codec.

Add tests for decoding to 565.

BUG=skia:3257
BUG=skia:3683

Review URL: https://codereview.chromium.org/1277213002
diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp
index d0bb646..31fd2cf 100644
--- a/src/codec/SkMaskSwizzler.cpp
+++ b/src/codec/SkMaskSwizzler.cpp
@@ -63,6 +63,24 @@
     return COMPUTE_RESULT_ALPHA;
 }
 
+// TODO (msarett): We have promoted a two byte per pixel image to 8888, only to
+// convert it back to 565. Instead, we should swizzle to 565 directly.
+static SkSwizzler::ResultAlpha swizzle_mask16_to_565(
+        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
+
+    // Use the masks to decode to the destination
+    uint16_t* srcPtr = (uint16_t*) srcRow;
+    uint16_t* dstPtr = (uint16_t*) dstRow;
+    for (int i = 0; i < width; i++) {
+        uint16_t p = srcPtr[i];
+        uint8_t red = masks->getRed(p);
+        uint8_t green = masks->getGreen(p);
+        uint8_t blue = masks->getBlue(p);
+        dstPtr[i] = SkPack888ToRGB16(red, green, blue);
+    }
+    return SkSwizzler::kOpaque_ResultAlpha;
+}
+
 static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
         void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
 
@@ -114,6 +132,21 @@
     return COMPUTE_RESULT_ALPHA;
 }
 
+static SkSwizzler::ResultAlpha swizzle_mask24_to_565(
+        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
+
+    // Use the masks to decode to the destination
+    uint16_t* dstPtr = (uint16_t*) dstRow;
+    for (int i = 0; i < 3*width; i += 3) {
+        uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
+        uint8_t red = masks->getRed(p);
+        uint8_t green = masks->getGreen(p);
+        uint8_t blue = masks->getBlue(p);
+        dstPtr[i/3] = SkPack888ToRGB16(red, green, blue);
+    }
+    return SkSwizzler::kOpaque_ResultAlpha;
+}
+
 static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque(
         void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
 
@@ -168,6 +201,21 @@
     return COMPUTE_RESULT_ALPHA;
 }
 
+static SkSwizzler::ResultAlpha swizzle_mask32_to_565(
+        void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
+    // Use the masks to decode to the destination
+    uint32_t* srcPtr = (uint32_t*) srcRow;
+    uint16_t* dstPtr = (uint16_t*) dstRow;
+    for (int i = 0; i < width; i++) {
+        uint32_t p = srcPtr[i];
+        uint8_t red = masks->getRed(p);
+        uint8_t green = masks->getGreen(p);
+        uint8_t blue = masks->getBlue(p);
+        dstPtr[i] = SkPack888ToRGB16(red, green, blue);
+    }
+    return SkSwizzler::kOpaque_ResultAlpha;
+}
+
 /*
  *
  * Create a new mask swizzler
@@ -196,6 +244,15 @@
                             break;
                     }
                     break;
+                case kRGB_565_SkColorType:
+                    switch (info.alphaType()) {
+                        case kOpaque_SkAlphaType:
+                            proc = &swizzle_mask16_to_565;
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
                 default:
                     break;
             }
@@ -217,6 +274,15 @@
                             break;
                     }
                     break;
+                case kRGB_565_SkColorType:
+                    switch (info.alphaType()) {
+                        case kOpaque_SkAlphaType:
+                            proc = &swizzle_mask24_to_565;
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
                 default:
                     break;
             }
@@ -238,6 +304,15 @@
                             break;
                     }
                     break;
+                case kRGB_565_SkColorType:
+                    switch (info.alphaType()) {
+                        case kOpaque_SkAlphaType:
+                            proc = &swizzle_mask32_to_565;
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
                 default:
                     break;
             }