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

Unified Diff: src/core/SkColorSpace.cpp

Issue 1972403002: Parse parametric gamma curves (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase Created 4 years, 7 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 | « no previous file | src/core/SkColorSpacePriv.h » ('j') | src/core/SkColorSpacePriv.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkColorSpace.cpp
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 59013fe7cb0be04cad45c7194ffab0ea1741c8f9..52e4ced85de270dc2c1d06a2c7feb550c017a2dc 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -362,7 +362,7 @@ bool SkColorSpace::LoadGammas(SkGammaCurve* gammas, uint32_t numGammas, const ui
// a count of 0.
gammas[i].fValue = 1.0f;
break;
- } else if (len < 12 + 2 * count) {
+ } else if (len < tagBytes) {
SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
return false;
}
@@ -429,27 +429,93 @@ bool SkColorSpace::LoadGammas(SkGammaCurve* gammas, uint32_t numGammas, const ui
break;
}
case kTAG_ParaCurveType:
- // Guess 2.2f.
- // FIXME (msarett): Handle parametric curves.
- SkColorSpacePrintf("parametric curve\n");
- gammas[i].fValue = 2.2f;
-
- // Determine the size of the parametric curve tag.
+ // Determine the format of the parametric curve tag.
switch(read_big_endian_short(src + 8)) {
- case 0:
+ case 0: {
tagBytes = 12 + 4;
+ if (len < tagBytes) {
+ SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
+ return false;
+ }
+
+ // Y = X^g
+ int32_t g = read_big_endian_int(src + 12);
+ gammas[i].fValue = SkFixedToFloat(g);
break;
- case 1:
+ }
+
+ // Here's where the real parametric gammas start. There are many
+ // permutations of the same equations.
+ //
+ // Y = (aX + b)^g + c for X >= d
+ // Y = eX + f otherwise
+ //
+ // We will fill in with zeros as necessary to always match the above form.
+ // Note that there is no need to actually write zero, since the struct is
+ // zero initialized.
+ case 1: {
tagBytes = 12 + 12;
+ if (len < tagBytes) {
+ SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
+ return false;
+ }
+
+ // Y = (aX + b)^g for X >= -b/a
+ // Y = 0 otherwise
+ gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
+ gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
+ gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
+ gammas[i].fD = -gammas[i].fB / gammas[i].fA;
break;
+ }
case 2:
tagBytes = 12 + 16;
+ if (len < tagBytes) {
+ SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
+ return false;
+ }
+
+ // Y = (aX + b)^g + c for X >= -b/a
+ // Y = c otherwise
+ gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
+ gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
+ gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
+ gammas[i].fC = SkFixedToFloat(read_big_endian_int(src + 24));
+ gammas[i].fD = -gammas[i].fB / gammas[i].fA;
+ gammas[i].fF = gammas[i].fC;
break;
case 3:
tagBytes = 12 + 20;
+ if (len < tagBytes) {
+ SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
+ return false;
+ }
+
+ // Y = (aX + b)^g for X >= d
+ // Y = cX otherwise
+ gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
+ gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
+ gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
+ gammas[i].fD = SkFixedToFloat(read_big_endian_int(src + 28));
+ gammas[i].fE = SkFixedToFloat(read_big_endian_int(src + 24));
break;
case 4:
tagBytes = 12 + 28;
+ if (len < tagBytes) {
+ SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
+ return false;
+ }
+
+ // Y = (aX + b)^g + c for X >= d
+ // Y = eX + f otherwise
+ // NOTE: The ICC spec writes "cX" instead of "eX" but I think it's a typo.
+ gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
+ gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
+ gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
+ gammas[i].fC = SkFixedToFloat(read_big_endian_int(src + 24));
+ gammas[i].fD = SkFixedToFloat(read_big_endian_int(src + 28));
+ gammas[i].fE = SkFixedToFloat(read_big_endian_int(src + 32));
+ gammas[i].fF = SkFixedToFloat(read_big_endian_int(src + 36));
break;
default:
SkColorSpacePrintf("Invalid parametric curve type\n");
« no previous file with comments | « no previous file | src/core/SkColorSpacePriv.h » ('j') | src/core/SkColorSpacePriv.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698