Reland "Switch SkCodec to use skcms plus fixes""

This reverts commit 83988edfd3256dc822b961362aad7fbc3e0cdabc.

The CTS failure was actually due to another CL.

TBR=brianosman@google.com
TBR=djsollen@google.com

Bug: skia:6839
Bug: skia:8052
Bug: skia:8278
Change-Id: Id9f152ec2c66467d90f49df223cb9b7c168ac2ac
Reviewed-on: https://skia-review.googlesource.com/149483
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/include/private/SkEncodedInfo.h b/include/private/SkEncodedInfo.h
index 217b859..5d6dabe 100644
--- a/include/private/SkEncodedInfo.h
+++ b/include/private/SkEncodedInfo.h
@@ -8,12 +8,25 @@
 #ifndef SkEncodedInfo_DEFINED
 #define SkEncodedInfo_DEFINED
 
+#include "SkData.h"
 #include "SkImageInfo.h"
-
-class SkColorSpace;
+#include "../../third_party/skcms/skcms.h"
 
 struct SkEncodedInfo {
 public:
+    class ICCProfile {
+    public:
+        static std::unique_ptr<ICCProfile> Make(sk_sp<SkData>);
+        static std::unique_ptr<ICCProfile> MakeSRGB();
+        static std::unique_ptr<ICCProfile> Make(const skcms_ICCProfile&);
+
+        const skcms_ICCProfile* profile() const { return &fProfile; }
+    private:
+        ICCProfile(const skcms_ICCProfile&, sk_sp<SkData> = nullptr);
+
+        skcms_ICCProfile fProfile;
+        sk_sp<SkData>    fData;
+    };
 
     enum Alpha {
         kOpaque_Alpha,
@@ -39,6 +52,20 @@
         // PNG
         kGrayAlpha_Color,
 
+        // PNG with Skia-specific sBIT
+        // Like kGrayAlpha, except this expects to be treated as
+        // kAlpha_8_SkColorType, which ignores the gray component. If
+        // decoded to full color (e.g. kN32), the gray component is respected
+        // (so it can share code with kGrayAlpha).
+        kXAlpha_Color,
+
+        // PNG
+        // 565 images may be encoded to PNG by specifying the number of
+        // significant bits for each channel.  This is a strange 565
+        // representation because the image is still encoded with 8 bits per
+        // component.
+        k565_Color,
+
         // PNG, GIF, BMP
         kPalette_Color,
 
@@ -67,7 +94,18 @@
         kYCCK_Color,
     };
 
-    static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) {
+    static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha,
+            int bitsPerComponent) {
+        return Make(width, height, color, alpha, bitsPerComponent, nullptr);
+    }
+
+    static SkEncodedInfo MakeSRGB(int width, int height, Color color, Alpha alpha,
+            int bitsPerComponent) {
+        return Make(width, height, color, alpha, bitsPerComponent, ICCProfile::MakeSRGB());
+    }
+
+    static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha,
+            int bitsPerComponent, std::unique_ptr<ICCProfile> profile) {
         SkASSERT(1 == bitsPerComponent ||
                  2 == bitsPerComponent ||
                  4 == bitsPerComponent ||
@@ -105,29 +143,51 @@
                 SkASSERT(kOpaque_Alpha != alpha);
                 SkASSERT(8 == bitsPerComponent);
                 break;
+            case kXAlpha_Color:
+                SkASSERT(kUnpremul_Alpha == alpha);
+                SkASSERT(8 == bitsPerComponent);
+                break;
+            case k565_Color:
+                SkASSERT(kOpaque_Alpha == alpha);
+                SkASSERT(8 == bitsPerComponent);
+                break;
             default:
                 SkASSERT(false);
                 break;
         }
 
-        return SkEncodedInfo(color, alpha, bitsPerComponent);
+        return SkEncodedInfo(width, height, color, alpha, bitsPerComponent, std::move(profile));
     }
 
     /*
-     * Returns an SkImageInfo with Skia color and alpha types that are the
-     * closest possible match to the encoded info.
+     * Returns a recommended SkImageInfo.
+     *
+     * TODO: Leave this up to the client.
      */
-    SkImageInfo makeImageInfo(int width, int height, sk_sp<SkColorSpace> colorSpace) const {
-        auto ct = kGray_Color == fColor ? kGray_8_SkColorType   :
-                                          kN32_SkColorType      ;
+    SkImageInfo makeImageInfo() const {
+        auto ct =  kGray_Color == fColor ? kGray_8_SkColorType   :
+                 kXAlpha_Color == fColor ? kAlpha_8_SkColorType  :
+                    k565_Color == fColor ? kRGB_565_SkColorType  :
+                                           kN32_SkColorType      ;
         auto alpha = kOpaque_Alpha == fAlpha ? kOpaque_SkAlphaType
                                              : kUnpremul_SkAlphaType;
-        return SkImageInfo::Make(width, height, ct, alpha, std::move(colorSpace));
+        sk_sp<SkColorSpace> cs = fProfile ? SkColorSpace::Make(*fProfile->profile())
+                                          : nullptr;
+        if (!cs) {
+            cs = SkColorSpace::MakeSRGB();
+        }
+        return SkImageInfo::Make(fWidth, fHeight, ct, alpha, std::move(cs));
     }
 
-    Color color() const { return fColor; }
-    Alpha alpha() const { return fAlpha; }
+    int   width() const { return fWidth;  }
+    int  height() const { return fHeight; }
+    Color color() const { return fColor;  }
+    Alpha alpha() const { return fAlpha;  }
     bool opaque() const { return fAlpha == kOpaque_Alpha; }
+    const skcms_ICCProfile* profile() const {
+        if (!fProfile) return nullptr;
+        return fProfile->profile();
+    }
 
     uint8_t bitsPerComponent() const { return fBitsPerComponent; }
 
@@ -135,6 +195,7 @@
         switch (fColor) {
             case kGray_Color:
                 return fBitsPerComponent;
+            case kXAlpha_Color:
             case kGrayAlpha_Color:
                 return 2 * fBitsPerComponent;
             case kPalette_Color:
@@ -142,6 +203,7 @@
             case kRGB_Color:
             case kBGR_Color:
             case kYUV_Color:
+            case k565_Color:
                 return 3 * fBitsPerComponent;
             case kRGBA_Color:
             case kBGRA_Color:
@@ -156,17 +218,38 @@
         }
     }
 
-private:
+    SkEncodedInfo(const SkEncodedInfo& orig) = delete;
+    SkEncodedInfo& operator=(const SkEncodedInfo&) = delete;
 
-    SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent)
-        : fColor(color)
+    SkEncodedInfo(SkEncodedInfo&& orig) = default;
+    SkEncodedInfo& operator=(SkEncodedInfo&&) = default;
+
+    // Explicit copy method, to avoid accidental copying.
+    SkEncodedInfo copy() const {
+        auto copy = SkEncodedInfo::Make(fWidth, fHeight, fColor, fAlpha, fBitsPerComponent);
+        if (fProfile) {
+            copy.fProfile.reset(new ICCProfile(*fProfile.get()));
+        }
+        return copy;
+    }
+
+private:
+    SkEncodedInfo(int width, int height, Color color, Alpha alpha,
+            uint8_t bitsPerComponent, std::unique_ptr<ICCProfile> profile)
+        : fWidth(width)
+        , fHeight(height)
+        , fColor(color)
         , fAlpha(alpha)
         , fBitsPerComponent(bitsPerComponent)
+        , fProfile(std::move(profile))
     {}
 
-    Color   fColor;
-    Alpha   fAlpha;
-    uint8_t fBitsPerComponent;
+    int                         fWidth;
+    int                         fHeight;
+    Color                       fColor;
+    Alpha                       fAlpha;
+    uint8_t                     fBitsPerComponent;
+    std::unique_ptr<ICCProfile> fProfile;
 };
 
 #endif