Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: src/core/SkColorSpace_ICC.cpp

Issue 2444553002: Refactored SkColorSpace_A2B to allow arbitrary ordering of elements (Closed)
Patch Set: responding to comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkColorSpace_A2B.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkColorSpace_ICC.cpp
diff --git a/src/core/SkColorSpace_ICC.cpp b/src/core/SkColorSpace_ICC.cpp
index 6fc3090caf2ce21ae98b783aec4ab362a110c0aa..6154e59d4ff6c0ded82e856d1033bf29bc22a35a 100644
--- a/src/core/SkColorSpace_ICC.cpp
+++ b/src/core/SkColorSpace_ICC.cpp
@@ -131,9 +131,18 @@ struct ICCProfileHeader {
// All the profiles we've tested so far use RGB as the input color space.
return_if_false(fInputColorSpace == kRGB_ColorSpace, "Unsupported color space");
- // TODO (msarett):
- // All the profiles we've tested so far use XYZ as the profile connection space.
- return_if_false(fPCS == kXYZ_PCSSpace || fPCS == kLAB_PCSSpace, "Unsupported PCS space");
+ switch (fPCS) {
+ case kXYZ_PCSSpace:
+ SkColorSpacePrintf("XYZ PCS\n");
+ break;
+ case kLAB_PCSSpace:
+ SkColorSpacePrintf("Lab PCS\n");
+ break;
+ default:
+ // ICC currently (V4.3) only specifices XYZ and Lab PCS spaces
+ SkColorSpacePrintf("Unsupported PCS space\n");
+ return false;
+ }
return_if_false(fSignature == kACSP_Signature, "Bad signature");
@@ -724,6 +733,8 @@ static bool parse_and_load_gamma(SkGammaNamed* gammaNamed, sk_sp<SkGammas>* gamm
SkGammas::Data rData;
SkColorSpaceTransferFn rParams;
+ *gammaNamed = kNonStandard_SkGammaNamed;
+
// On an invalid first gamma, tagBytes remains set as zero. This causes the two
// subsequent to be treated as identical (which is what we want).
size_t tagBytes = 0;
@@ -807,27 +818,12 @@ static bool parse_and_load_gamma(SkGammaNamed* gammaNamed, sk_sp<SkGammas>* gamm
return true;
}
-static bool load_a2b0(sk_sp<SkColorLookUpTable>* colorLUT,
- SkGammaNamed* aCurveNamed, sk_sp<SkGammas>* aCurve,
- SkGammaNamed* mCurveNamed, sk_sp<SkGammas>* mCurve,
- SkGammaNamed* bCurveNamed, sk_sp<SkGammas>* bCurve,
- SkMatrix44* matrix, const uint8_t* src, size_t len) {
- if (len < 32) {
- SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
- return false;
- }
-
- uint32_t type = read_big_endian_u32(src);
- if (kTAG_AtoBType != type) {
- // FIXME (msarett): Need to support lut8Type and lut16Type.
- SkColorSpacePrintf("Unsupported A to B tag type.\n");
- return false;
- }
-
- // Read the number of channels. The four bytes that we skipped are reserved and
+bool load_a2b0_a_to_b_type(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
+ size_t len) {
+ // Read the number of channels. The four bytes (4-7) that we skipped are reserved and
// must be zero.
- uint8_t inputChannels = src[8];
- uint8_t outputChannels = src[9];
+ const uint8_t inputChannels = src[8];
+ const uint8_t outputChannels = src[9];
if (3 != inputChannels || SkColorLookUpTable::kOutputChannels != outputChannels) {
// We only handle (supposedly) RGB inputs and RGB outputs. The numbers of input
// channels and output channels both must be 3.
@@ -836,52 +832,98 @@ static bool load_a2b0(sk_sp<SkColorLookUpTable>* colorLUT,
SkColorSpacePrintf("Input and output channels must equal 3 in A to B tag.\n");
return false;
}
+
+ // It is important that these are loaded in the order of application, as the
+ // order you construct an A2B color space's elements is the order it is applied
// If the offset is non-zero it indicates that the element is present.
- uint32_t offsetToACurves = read_big_endian_i32(src + 28);
+ const uint32_t offsetToACurves = read_big_endian_i32(src + 28);
if (0 != offsetToACurves && offsetToACurves < len) {
const size_t tagLen = len - offsetToACurves;
- if (!parse_and_load_gamma(aCurveNamed, aCurve, src + offsetToACurves, tagLen)) {
+ SkGammaNamed gammaNamed;
+ sk_sp<SkGammas> gammas;
+ if (!parse_and_load_gamma(&gammaNamed, &gammas, src + offsetToACurves, tagLen)) {
return false;
}
+ if (gammas) {
+ elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
+ } else {
+ elements->push_back(SkColorSpace_A2B::Element(gammaNamed));
+ }
}
- uint32_t offsetToColorLUT = read_big_endian_i32(src + 24);
+ const uint32_t offsetToColorLUT = read_big_endian_i32(src + 24);
if (0 != offsetToColorLUT && offsetToColorLUT < len) {
- if (!load_color_lut(colorLUT, inputChannels, src + offsetToColorLUT,
+ sk_sp<SkColorLookUpTable> colorLUT;
+ if (!load_color_lut(&colorLUT, inputChannels, src + offsetToColorLUT,
len - offsetToColorLUT)) {
SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n");
return false;
}
+ elements->push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));
}
- uint32_t offsetToMCurves = read_big_endian_i32(src + 20);
+ const uint32_t offsetToMCurves = read_big_endian_i32(src + 20);
if (0 != offsetToMCurves && offsetToMCurves < len) {
const size_t tagLen = len - offsetToMCurves;
- if (!parse_and_load_gamma(mCurveNamed, mCurve, src + offsetToMCurves, tagLen)) {
+ SkGammaNamed gammaNamed;
+ sk_sp<SkGammas> gammas;
+ if (!parse_and_load_gamma(&gammaNamed, &gammas, src + offsetToMCurves, tagLen)) {
return false;
}
+ if (gammas) {
+ elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
+ } else {
+ elements->push_back(SkColorSpace_A2B::Element(gammaNamed));
+ }
}
- uint32_t offsetToMatrix = read_big_endian_i32(src + 16);
+ const uint32_t offsetToMatrix = read_big_endian_i32(src + 16);
if (0 != offsetToMatrix && offsetToMatrix < len) {
- if (!load_matrix(matrix, src + offsetToMatrix, len - offsetToMatrix)) {
+ SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
+ if (!load_matrix(&matrix, src + offsetToMatrix, len - offsetToMatrix)) {
SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
- matrix->setIdentity();
+ } else {
+ elements->push_back(SkColorSpace_A2B::Element(matrix));
}
}
- uint32_t offsetToBCurves = read_big_endian_i32(src + 12);
+ const uint32_t offsetToBCurves = read_big_endian_i32(src + 12);
if (0 != offsetToBCurves && offsetToBCurves < len) {
const size_t tagLen = len - offsetToBCurves;
- if (!parse_and_load_gamma(bCurveNamed, bCurve, src + offsetToBCurves, tagLen)) {
+ SkGammaNamed gammaNamed;
+ sk_sp<SkGammas> gammas;
+ if (!parse_and_load_gamma(&gammaNamed, &gammas, src + offsetToBCurves, tagLen)) {
return false;
}
+ if (gammas) {
+ elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
+ } else {
+ elements->push_back(SkColorSpace_A2B::Element(gammaNamed));
+ }
}
return true;
}
+static bool load_a2b0(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
+ size_t len) {
+ const uint32_t type = read_big_endian_u32(src);
+ switch (type) {
+ case kTAG_AtoBType:
+ if (len < 32) {
+ SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
+ return false;
+ }
+ SkColorSpacePrintf("A2B0 tag is of type lutAtoBType\n");
+ return load_a2b0_a_to_b_type(elements, src, len);
+ default:
+ SkColorSpacePrintf("Unsupported A to B tag type: %c%c%c%c\n", (type>>24)&0xFF,
+ (type>>16)&0xFF, (type>>8)&0xFF, type&0xFF);
+ }
+ return false;
+}
+
static bool tag_equals(const ICCTag* a, const ICCTag* b, const uint8_t* base) {
if (!a || !b) {
return a == b;
@@ -952,12 +994,9 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* input, size_t len) {
const ICCTag* r = ICCTag::Find(tags.get(), tagCount, kTAG_rXYZ);
const ICCTag* g = ICCTag::Find(tags.get(), tagCount, kTAG_gXYZ);
const ICCTag* b = ICCTag::Find(tags.get(), tagCount, kTAG_bXYZ);
- if (r && g && b) {
- // Lab PCS means the profile is required to be an n-component LUT-based
- // profile, so 3-component matrix-based profiles can only have an XYZ PCS
- if (kXYZ_PCSSpace != header.fPCS) {
- return_null("Unsupported PCS space");
- }
+ // Lab PCS means the profile is required to be an n-component LUT-based
+ // profile, so 3-component matrix-based profiles can only have an XYZ PCS
+ if (r && g && b && kXYZ_PCSSpace == header.fPCS) {
float toXYZ[9];
if (!load_xyz(&toXYZ[0], r->addr(base), r->fLength) ||
!load_xyz(&toXYZ[3], g->addr(base), g->fLength) ||
@@ -1089,32 +1128,15 @@ sk_sp<SkColorSpace> SkColorSpace::NewICC(const void* input, size_t len) {
// Recognize color profile specified by A2B0 tag.
const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
if (a2b0) {
- // default to Linear transforms for when the curves are not
- // in the profile (which is legal behavior for a profile)
- SkGammaNamed aCurveNamed = kLinear_SkGammaNamed;
- SkGammaNamed mCurveNamed = kLinear_SkGammaNamed;
- SkGammaNamed bCurveNamed = kLinear_SkGammaNamed;
- sk_sp<SkGammas> aCurve = nullptr;
- sk_sp<SkGammas> mCurve = nullptr;
- sk_sp<SkGammas> bCurve = nullptr;
- sk_sp<SkColorLookUpTable> colorLUT = nullptr;
- SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
- if (!load_a2b0(&colorLUT, &aCurveNamed, &aCurve, &mCurveNamed, &mCurve,
- &bCurveNamed, &bCurve, &matrix, a2b0->addr(base), a2b0->fLength)) {
+ const SkColorSpace_A2B::PCS pcs = kXYZ_PCSSpace == header.fPCS
+ ? SkColorSpace_A2B::PCS::kXYZ
+ : SkColorSpace_A2B::PCS::kLAB;
+ std::vector<SkColorSpace_A2B::Element> elements;
+ if (!load_a2b0(&elements, a2b0->addr(base), a2b0->fLength)) {
return_null("Failed to parse A2B0 tag");
}
-
- SkColorSpace_A2B::PCS pcs = SkColorSpace_A2B::PCS::kLAB;
- if (header.fPCS == kXYZ_PCSSpace) {
- pcs = SkColorSpace_A2B::PCS::kXYZ;
- }
-
- return sk_sp<SkColorSpace>(new SkColorSpace_A2B(aCurveNamed, std::move(aCurve),
- std::move(colorLUT),
- mCurveNamed, std::move(mCurve),
- matrix,
- bCurveNamed, std::move(bCurve),
- pcs, std::move(data)));
+ return sk_sp<SkColorSpace>(new SkColorSpace_A2B(pcs, std::move(data),
+ std::move(elements)));
}
}
default:
« no previous file with comments | « src/core/SkColorSpace_A2B.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698