diff options
author | reed <reed@google.com> | 2014-09-01 12:14:29 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-01 12:14:29 -0700 |
commit | c89aa509d6a094bc1b18d73135343819903a9cfb (patch) | |
tree | 5fa8d11fd6f7a057c5ccae865fc5d6851fa99222 /src/core | |
parent | eb2662c08f07764491a17e0a397cdbeb0e2c05c1 (diff) |
Add gamma/sRGB tag to SkImageInfo
This reverts commit 64ba5fa1ff428858f803523257cd862f8b33423b.
BUG=skia:
R=reed@chromium.org
Author: reed@google.com
Review URL: https://codereview.chromium.org/522813002
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkImageInfo.cpp | 132 |
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); +} |