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

Side by Side Diff: src/core/SkColorSpace.cpp

Issue 1925733003: Drafts and half ideas (Closed) Base URL: https://skia.googlesource.com/skia.git@improveparsing
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « src/core/SkColorSpace.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkAtomics.h" 8 #include "SkAtomics.h"
9 #include "SkColorSpace.h" 9 #include "SkColorSpace.h"
10 10
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 SkDebugf("[%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f]\n", 81 SkDebugf("[%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f] [%7.4f %7.4f %7.4f]\n",
82 fMat[0], fMat[1], fMat[2], 82 fMat[0], fMat[1], fMat[2],
83 fMat[3], fMat[4], fMat[5], 83 fMat[3], fMat[4], fMat[5],
84 fMat[6], fMat[7], fMat[8]); 84 fMat[6], fMat[7], fMat[8]);
85 } 85 }
86 86
87 //////////////////////////////////////////////////////////////////////////////// ////////////////// 87 //////////////////////////////////////////////////////////////////////////////// //////////////////
88 88
89 static int32_t gUniqueColorSpaceID; 89 static int32_t gUniqueColorSpaceID;
90 90
91 SkColorSpace::SkColorSpace(const SkFloat3& gamma, const SkFloat3x3& toXYZD50, Na med named) 91 SkColorSpace::SkColorSpace(SkGammas gammas, const SkFloat3x3& toXYZD50, Named na med)
92 : fGamma(gamma) 92 : fGammas(std::move(gammas))
93 , fToXYZD50(toXYZD50) 93 , fToXYZD50(toXYZD50)
94 , fToXYZOffset({ 0.0f, 0.0f, 0.0f }) 94 , fToXYZOffset({ 0.0f, 0.0f, 0.0f })
95 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 95 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
96 , fNamed(named) 96 , fNamed(named)
97 { 97 {
98 for (int i = 0; i < 3; ++i) { 98 for (int i = 0; i < 3; ++i) {
99 SkASSERT(SkFloatIsFinite(gamma.fVec[i]));
100 for (int j = 0; j < 3; ++j) { 99 for (int j = 0; j < 3; ++j) {
101 SkASSERT(SkFloatIsFinite(toXYZD50.fMat[3*i + j])); 100 SkASSERT(SkFloatIsFinite(toXYZD50.fMat[3*i + j]));
102 } 101 }
103 } 102 }
104 } 103 }
105 104
106 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, const SkFloat3& gamma, c onst SkFloat3x3& toXYZD50, 105 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, const S kFloat3x3& toXYZD50,
107 const SkFloat3& toXYZOffset) 106 const SkFloat3& toXYZOffset)
108 : fColorLUT(std::move(colorLUT)) 107 : fColorLUT(std::move(colorLUT))
109 , fGamma(gamma) 108 , fGammas(gammas)
110 , fToXYZD50(toXYZD50) 109 , fToXYZD50(toXYZD50)
111 , fToXYZOffset(toXYZOffset) 110 , fToXYZOffset(toXYZOffset)
112 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 111 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
113 , fNamed(kUnknown_Named) 112 , fNamed(kUnknown_Named)
114 {} 113 {}
115 114
116 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, const SkFlo at3& gamma) { 115 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkFloat3x3& toXYZD50, SkGammas ga mmas) {
117 for (int i = 0; i < 3; ++i) { 116 for (int i = 0; i < 3; ++i) {
118 if (!SkFloatIsFinite(gamma.fVec[i]) || gamma.fVec[i] < 0) {
119 return nullptr;
120 }
121 for (int j = 0; j < 3; ++j) { 117 for (int j = 0; j < 3; ++j) {
122 if (!SkFloatIsFinite(toXYZD50.fMat[3*i + j])) { 118 if (!SkFloatIsFinite(toXYZD50.fMat[3*i + j])) {
123 return nullptr; 119 return nullptr;
124 } 120 }
125 } 121 }
126 } 122 }
127 123
128 // check the matrix for invertibility 124 // check the matrix for invertibility
129 float d = det(toXYZD50); 125 float d = det(toXYZD50);
130 if (!SkFloatIsFinite(d) || !SkFloatIsFinite(1 / d)) { 126 if (!SkFloatIsFinite(d) || !SkFloatIsFinite(1 / d)) {
131 return nullptr; 127 return nullptr;
132 } 128 }
133 129
134 return sk_sp<SkColorSpace>(new SkColorSpace(gamma, toXYZD50, kUnknown_Named) ); 130 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named));
135 } 131 }
136 132
137 void SkColorSpace::dump() const { 133 void SkColorSpace::dump() const {
138 fToXYZD50.dump(); 134 fToXYZD50.dump();
139 fGamma.dump();
140 } 135 }
141 136
142 //////////////////////////////////////////////////////////////////////////////// ////////////////// 137 //////////////////////////////////////////////////////////////////////////////// //////////////////
143 138
144 const SkFloat3 gDevice_gamma {{ 0, 0, 0 }};
145 const SkFloat3x3 gDevice_toXYZD50 {{ 139 const SkFloat3x3 gDevice_toXYZD50 {{
146 1, 0, 0, 140 1, 0, 0,
147 0, 1, 0, 141 0, 1, 0,
148 0, 0, 1 142 0, 0, 1
149 }}; 143 }};
150 144
151 const SkFloat3 gSRGB_gamma {{ 2.2f, 2.2f, 2.2f }};
152 const SkFloat3x3 gSRGB_toXYZD50 {{ 145 const SkFloat3x3 gSRGB_toXYZD50 {{
153 0.4358f, 0.2224f, 0.0139f, // * R 146 0.4358f, 0.2224f, 0.0139f, // * R
154 0.3853f, 0.7170f, 0.0971f, // * G 147 0.3853f, 0.7170f, 0.0971f, // * G
155 0.1430f, 0.0606f, 0.7139f, // * B 148 0.1430f, 0.0606f, 0.7139f, // * B
156 }}; 149 }};
157 150
158 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 151 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
159 switch (named) { 152 switch (named) {
160 case kDevice_Named: 153 case kDevice_Named:
161 return sk_sp<SkColorSpace>(new SkColorSpace(gDevice_gamma, gDevice_t oXYZD50, 154 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(SkGammas()), g Device_toXYZD50,
162 kDevice_Named)); 155 kDevice_Named));
163 case kSRGB_Named: 156 case kSRGB_Named:
164 return sk_sp<SkColorSpace>(new SkColorSpace(gSRGB_gamma, gSRGB_toXYZ D50, kSRGB_Named)); 157 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(SkGammas::sRGB ()), gSRGB_toXYZD50,
158 kSRGB_Named));
165 default: 159 default:
166 break; 160 break;
167 } 161 }
168 return nullptr; 162 return nullptr;
169 } 163 }
170 164
171 //////////////////////////////////////////////////////////////////////////////// /////////////////// 165 //////////////////////////////////////////////////////////////////////////////// ///////////////////
172 166
173 #include "SkFixed.h" 167 #include "SkFixed.h"
174 #include "SkTemplates.h" 168 #include "SkTemplates.h"
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16)); 359 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16));
366 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); 360 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]);
367 return true; 361 return true;
368 } 362 }
369 363
370 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v'); 364 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v');
371 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a'); 365 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a');
372 366
373 // FIXME (msarett): 367 // FIXME (msarett):
374 // We need to handle the possibility that the gamma curve does not correspond to 2.2f. 368 // We need to handle the possibility that the gamma curve does not correspond to 2.2f.
375 static bool load_gammas(float* gammas, uint32_t numGammas, const uint8_t* src, s ize_t len) { 369 static bool load_gammas(SkGamma* gammas, uint32_t numGammas, const uint8_t* src, size_t len) {
376 for (uint32_t i = 0; i < numGammas; i++) { 370 for (uint32_t i = 0; i < numGammas; i++) {
377 if (len < 12) { 371 if (len < 12) {
378 // FIXME (msarett): 372 // FIXME (msarett):
379 // We could potentially return false here after correctly parsing *s ome* of the 373 // We could potentially return false here after correctly parsing *s ome* of the
380 // gammas correctly. Should we somehow try to indicate a partial su ccess? 374 // gammas correctly. Should we somehow try to indicate a partial su ccess?
381 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); 375 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
382 return false; 376 return false;
383 } 377 }
384 378
385 // We need to count the number of bytes in the tag, so we are able to mo ve to the 379 // We need to count the number of bytes in the tag, so we are able to mo ve to the
386 // next tag on the next loop iteration. 380 // next tag on the next loop iteration.
387 size_t tagBytes; 381 size_t tagBytes;
388 382
389 uint32_t type = read_big_endian_uint(src); 383 uint32_t type = read_big_endian_uint(src);
390 switch (type) { 384 switch (type) {
391 case kTAG_CurveType: { 385 case kTAG_CurveType: {
392 uint32_t count = read_big_endian_uint(src + 8); 386 uint32_t count = read_big_endian_uint(src + 8);
393 tagBytes = 12 + count * 2; 387 tagBytes = 12 + count * 2;
394 if (0 == count) { 388 if (0 == count) {
395 // Some tags require a gamma curve, but the author doesn't a ctually want 389 // Some tags require a gamma curve, but the author doesn't a ctually want
396 // to transform the data. In this case, it is common to see a curve with 390 // to transform the data. In this case, it is common to see a curve with
397 // a count of 0. 391 // a count of 0.
398 gammas[i] = 1.0f; 392 gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
393 gammas[i].fValue = 1.0f;
399 break; 394 break;
400 } else if (len < 12 + 2 * count) { 395 } else if (len < 12 + 2 * count) {
401 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 396 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
402 return false; 397 return false;
403 } 398 }
404 399
405 const uint16_t* table = (const uint16_t*) (src + 12); 400 const uint16_t* table = (const uint16_t*) (src + 12);
406 if (1 == count) { 401 if (1 == count) {
407 // Table entry is the exponent (bias 256). 402 // Table entry is the exponent (bias 256).
408 uint16_t value = read_big_endian_short((const uint8_t*) tabl e); 403 uint16_t value = read_big_endian_short((const uint8_t*) tabl e);
409 gammas[i] = value / 256.0f; 404 gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
405 gammas[i].fValue = value / 256.0f;
410 SkColorSpacePrintf("gamma %d %g\n", value, *gamma); 406 SkColorSpacePrintf("gamma %d %g\n", value, *gamma);
411 break; 407 break;
412 } 408 }
413 409
414 // Print the interpolation table. For now, we ignore this and g uess 2.2f. 410 // Fill in the interpolation table.
415 for (uint32_t i = 0; i < count; i++) { 411 // FIXME (msarett):
416 SkColorSpacePrintf("curve[%d] %d\n", i, 412 // We should recognize commonly occurring tables and just set ga mma to 2.2f.
417 read_big_endian_short((const uint8_t*) &table[i])); 413 gammas[i].fFlag = SkGamma::kGammaUseTableFlag;
414 gammas[i].fTableSize = count;
415 gammas[i].fTable = std::unique_ptr(new float[count]);
416 for (uint32_t j = 0; j < count; j++) {
417 gammas[i].fTable[j] =
418 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f;
418 } 419 }
419
420 gammas[i] = 2.2f;
421 break; 420 break;
422 } 421 }
423 case kTAG_ParaCurveType: 422 case kTAG_ParaCurveType:
424 // Guess 2.2f. 423 // Guess 2.2f.
425 SkColorSpacePrintf("parametric curve\n"); 424 SkColorSpacePrintf("parametric curve\n");
426 gammas[i] = 2.2f; 425 gammas[i].fFlag = SkGamma::kGammaUseValueFlag;
426 gammas[i].fValue = 2.2f;
427 427
428 switch(read_big_endian_short(src + 8)) { 428 switch(read_big_endian_short(src + 8)) {
429 case 0: 429 case 0:
430 tagBytes = 12 + 4; 430 tagBytes = 12 + 4;
431 break; 431 break;
432 case 1: 432 case 1:
433 tagBytes = 12 + 12; 433 tagBytes = 12 + 12;
434 break; 434 break;
435 case 2: 435 case 2:
436 tagBytes = 12 + 16; 436 tagBytes = 12 + 16;
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 } 799 }
800 800
801 // D65 white point of Rec. 709 [8] are: 801 // D65 white point of Rec. 709 [8] are:
802 // 802 //
803 // D65 white-point in unit luminance XYZ = 0.9505, 1.0000, 1.0890 803 // D65 white-point in unit luminance XYZ = 0.9505, 1.0000, 1.0890
804 // 804 //
805 // R G B white 805 // R G B white
806 // x 0.640 0.300 0.150 0.3127 806 // x 0.640 0.300 0.150 0.3127
807 // y 0.330 0.600 0.060 0.3290 807 // y 0.330 0.600 0.060 0.3290
808 // z 0.030 0.100 0.790 0.3582 808 // z 0.030 0.100 0.790 0.3582
OLDNEW
« no previous file with comments | « src/core/SkColorSpace.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698