aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2014-09-02 21:56:40 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-02 21:56:40 -0700
commit2f6abdecc5c2f21da13003c615903679abc73fc7 (patch)
treecc3e4ebb378416e16767b424dc6487e6edc96818 /src
parent937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0f (diff)
Add gamma/sRGB tag to SkImageInfo
This reverts commit 1cbc68f9659f15206d920dacd434ddf4b658ad1f. requires this to land in blink https://codereview.chromium.org/531883002/ R=fmalita@google.com, reed@chromium.org Author: reed@google.com Review URL: https://codereview.chromium.org/527073003
Diffstat (limited to 'src')
-rw-r--r--src/core/SkImageInfo.cpp132
1 files changed, 111 insertions, 21 deletions
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index e61cd7d45f..44fd808dc8 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -9,34 +9,53 @@
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
-static bool alpha_type_is_valid(SkAlphaType alphaType) {
- return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
+static bool color_type_supports_sRGB(SkColorType colorType) {
+ switch (colorType) {
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ return true;
+ default:
+ return false;
+ }
}
-static bool color_type_is_valid(SkColorType colorType) {
- return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
+static bool color_type_supports_gamma(SkColorType colorType) {
+ switch (colorType) {
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ // case kLuminance ...
+ return true;
+ default:
+ return false;
+ }
}
-void SkImageInfo::unflatten(SkReadBuffer& buffer) {
- fWidth = buffer.read32();
- fHeight = buffer.read32();
-
- uint32_t packed = buffer.read32();
- SkASSERT(0 == (packed >> 16));
- fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
- fColorType = (SkColorType)((packed >> 0) & 0xFF);
- buffer.validate(alpha_type_is_valid(fAlphaType) &&
- color_type_is_valid(fColorType));
+static float pin_gamma_to_legal(float gamma) {
+ if (!SkScalarIsFinite(gamma)) {
+ return 1;
+ }
+ // these limits are just made up -- feel free to change them within reason
+ const float min_gamma = 0.01f;
+ const float max_gamma = 4.0;
+ return SkScalarPin(gamma, min_gamma, max_gamma);
}
-void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
- buffer.write32(fWidth);
- buffer.write32(fHeight);
+SkImageInfo SkImageInfo::MakeSRGB(int width, int height, SkColorType ct, SkAlphaType at) {
+ Profile p = color_type_supports_sRGB(ct) ? kSRGB_Profile : kUnknown_Profile;
+ return SkImageInfo(width, height, ct, at, p, 0);
+}
- SkASSERT(0 == (fAlphaType & ~0xFF));
- SkASSERT(0 == (fColorType & ~0xFF));
- uint32_t packed = (fAlphaType << 8) | fColorType;
- buffer.write32(packed);
+SkImageInfo SkImageInfo::MakeWithGamma(int width, int height, SkColorType ct, SkAlphaType at,
+ float gamma) {
+ Profile p;
+ if (color_type_supports_gamma(ct)) {
+ gamma = pin_gamma_to_legal(gamma);
+ p = kExponential_Profile;
+ } else {
+ p = kUnknown_Profile;
+ gamma = 0;
+ }
+ return SkImageInfo(width, height, ct, at, p, gamma);
}
bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
@@ -69,3 +88,74 @@ bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
}
return true;
}
+
+void SkImageInfo::unflatten(SkReadBuffer& buffer) {
+ *this = Unflatten(buffer);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
+static bool alpha_type_is_valid(SkAlphaType alphaType) {
+ return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
+}
+
+static bool color_type_is_valid(SkColorType colorType) {
+ return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
+}
+
+static float igamma_to_gamma(int gamma3dot9) {
+ return gamma3dot9 / 512.0f;
+}
+
+static unsigned gamma_to_igamma(float gamma) {
+ SkASSERT(gamma >= 0 && gamma < 8);
+ int igamma = SkScalarRoundToInt(gamma * 512);
+ SkASSERT(igamma >= 0 && igamma <= 0xFFF);
+ return igamma;
+}
+
+SkImageInfo SkImageInfo::Unflatten(SkReadBuffer& buffer) {
+ int width = buffer.read32();
+ int height = buffer.read32();
+ uint32_t packed = buffer.read32();
+
+ SkColorType ct = (SkColorType)((packed >> 0) & 0xFF); // 8 bits for colortype
+ SkAlphaType at = (SkAlphaType)((packed >> 8) & 0xFF); // 8 bits for alphatype
+ if (!alpha_type_is_valid(at) || !color_type_is_valid(ct)) {
+ return MakeUnknown();
+ }
+
+ // Earlier formats always stored 0 in the upper 16 bits. That corresponds to
+ // days before we had gamma/profile. That happens to correspond to kUnknown_Profile,
+ // which means we can just ignore the gamma value anyways.
+ //
+ int iprofile = ((packed >> 16) & 0xF); // 4 bits for profile
+
+ switch (iprofile) {
+ case kUnknown_Profile:
+ return Make(width, height, ct, at);
+ case kSRGB_Profile:
+ return MakeSRGB(width, height, ct, at);
+ case kExponential_Profile: {
+ int igamma = packed >> 20; // 12 bits for gamma 3.9
+ float gamma = igamma_to_gamma(igamma);
+ return MakeWithGamma(width, height, ct, at, gamma);
+ }
+ default:
+ (void)buffer.validate(false);
+ return MakeUnknown();
+ }
+}
+
+void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
+ buffer.write32(fWidth);
+ buffer.write32(fHeight);
+
+ SkASSERT(0 == (fColorType & ~0xFF)); // 8 bits for colortype
+ SkASSERT(0 == (fAlphaType & ~0xFF)); // 8 bits for alphatype
+ SkASSERT(0 == (fProfile & ~0xF)); // 4 bits for profile
+ int igamma = gamma_to_igamma(fGamma); // 12 bits for gamma (if needed)
+
+ uint32_t packed = (igamma << 20) | (fProfile << 16) | (fAlphaType << 8) | fColorType;
+ buffer.write32(packed);
+}