Index: src/core/SkImageInfo.cpp |
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp |
index e61cd7d45f398c115f36d4332744f65d95e2fdad..44fd808dc85a28c533bfd0a339face99262c3784 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 @@ |
} |
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); |
+} |