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