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

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

Issue 2409383002: Add SkColorSpaceTransferFn to SkColorSpace (Closed)
Patch Set: Add more 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 unified diff | Download patch
« no previous file with comments | « include/core/SkColorSpace.h ('k') | src/core/SkColorSpacePriv.h » ('j') | 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 "SkColorSpace.h" 8 #include "SkColorSpace.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkColorSpacePriv.h" 10 #include "SkColorSpacePriv.h"
11 #include "SkOnce.h" 11 #include "SkOnce.h"
12 #include "SkPoint3.h" 12 #include "SkPoint3.h"
13 13
14 static inline bool is_zero_to_one(float v) {
15 return (0.0f <= v) && (v <= 1.0f);
16 }
17
18 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const { 14 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const {
19 if (!is_zero_to_one(fRX) || !is_zero_to_one(fRY) || 15 if (!is_zero_to_one(fRX) || !is_zero_to_one(fRY) ||
20 !is_zero_to_one(fGX) || !is_zero_to_one(fGY) || 16 !is_zero_to_one(fGX) || !is_zero_to_one(fGY) ||
21 !is_zero_to_one(fBX) || !is_zero_to_one(fBY) || 17 !is_zero_to_one(fBX) || !is_zero_to_one(fBY) ||
22 !is_zero_to_one(fWX) || !is_zero_to_one(fWY)) 18 !is_zero_to_one(fWX) || !is_zero_to_one(fWY))
23 { 19 {
24 return false; 20 return false;
25 } 21 }
26 22
27 // First, we need to convert xy values (primaries) to XYZ. 23 // First, we need to convert xy values (primaries) to XYZ.
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 switch (gamma) { 200 switch (gamma) {
205 case kLinear_RenderTargetGamma: 201 case kLinear_RenderTargetGamma:
206 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50); 202 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50);
207 case kSRGB_RenderTargetGamma: 203 case kSRGB_RenderTargetGamma:
208 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50); 204 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50);
209 default: 205 default:
210 return nullptr; 206 return nullptr;
211 } 207 }
212 } 208 }
213 209
210 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkColorSpaceTransferFn& coeffs,
211 const SkMatrix44& toXYZD50) {
212 if (!is_valid_transfer_fn(coeffs)) {
213 return nullptr;
214 }
215
216 if (is_almost_srgb(coeffs)) {
217 return SkColorSpace::NewRGB(kSRGB_RenderTargetGamma, toXYZD50);
218 }
219
220 if (is_almost_2dot2(coeffs)) {
221 return SkColorSpace_Base::NewRGB(k2Dot2Curve_SkGammaNamed, toXYZD50);
222 }
223
224 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransfe rFn));
225 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas());
226 SkColorSpaceTransferFn* fn = SkTAddOffset<SkColorSpaceTransferFn>(memory, si zeof(SkGammas));
227 *fn = coeffs;
228 gammas->fRedType = SkGammas::Type::kParam_Type;
229 gammas->fGreenType = SkGammas::Type::kParam_Type;
230 gammas->fBlueType = SkGammas::Type::kParam_Type;
231
232 SkGammas::Data data;
233 data.fParamOffset = 0;
234 gammas->fRedData = data;
235 gammas->fGreenData = data;
236 gammas->fBlueData = data;
237 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_SkGam maNamed,
238 std::move(gammas), toXYZD50 , nullptr));
239 }
240
214 static SkColorSpace* gAdobeRGB; 241 static SkColorSpace* gAdobeRGB;
215 static SkColorSpace* gSRGB; 242 static SkColorSpace* gSRGB;
216 static SkColorSpace* gSRGBLinear; 243 static SkColorSpace* gSRGBLinear;
217 244
218 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 245 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
219 static SkOnce sRGBOnce; 246 static SkOnce sRGBOnce;
220 static SkOnce adobeRGBOnce; 247 static SkOnce adobeRGBOnce;
221 static SkOnce sRGBLinearOnce; 248 static SkOnce sRGBLinearOnce;
222 249
223 switch (named) { 250 switch (named) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 } 320 }
294 321
295 //////////////////////////////////////////////////////////////////////////////// /////////////////// 322 //////////////////////////////////////////////////////////////////////////////// ///////////////////
296 323
297 enum Version { 324 enum Version {
298 k0_Version, // Initial version, header + flags for matrix and profile 325 k0_Version, // Initial version, header + flags for matrix and profile
299 }; 326 };
300 327
301 struct ColorSpaceHeader { 328 struct ColorSpaceHeader {
302 /** 329 /**
330 * It is only valid to set zero or one flags.
331 * Setting multiple flags is invalid.
332 */
333
334 /**
303 * If kMatrix_Flag is set, we will write 12 floats after the header. 335 * If kMatrix_Flag is set, we will write 12 floats after the header.
304 * Should not be set at the same time as the kICC_Flag or kFloatGamma_Flag.
305 */ 336 */
306 static constexpr uint8_t kMatrix_Flag = 1 << 0; 337 static constexpr uint8_t kMatrix_Flag = 1 << 0;
307 338
308 /** 339 /**
309 * If kICC_Flag is set, we will write an ICC profile after the header. 340 * If kICC_Flag is set, we will write an ICC profile after the header.
310 * The ICC profile will be written as a uint32 size, followed immediately 341 * The ICC profile will be written as a uint32 size, followed immediately
311 * by the data (padded to 4 bytes). 342 * by the data (padded to 4 bytes).
312 * Should not be set at the same time as the kMatrix_Flag or kFloatGamma_Fl ag.
313 */ 343 */
314 static constexpr uint8_t kICC_Flag = 1 << 1; 344 static constexpr uint8_t kICC_Flag = 1 << 1;
315 345
316 /** 346 /**
317 * If kFloatGamma_Flag is set, we will write 15 floats after the header. 347 * If kFloatGamma_Flag is set, we will write 15 floats after the header.
318 * The first three are the gamma values, and the next twelve are the 348 * The first three are the gamma values, and the next twelve are the
319 * matrix. 349 * matrix.
320 * Should not be set at the same time as the kICC_Flag or kMatrix_Flag.
321 */ 350 */
322 static constexpr uint8_t kFloatGamma_Flag = 1 << 2; 351 static constexpr uint8_t kFloatGamma_Flag = 1 << 2;
323 352
353 /**
354 * If kTransferFn_Flag is set, we will write 19 floats after the header.
355 * The first seven represent the transfer fn, and the next twelve are the
356 * matrix.
357 */
358 static constexpr uint8_t kTransferFn_Flag = 1 << 3;
359
324 static ColorSpaceHeader Pack(Version version, uint8_t named, uint8_t gammaNa med, uint8_t flags) 360 static ColorSpaceHeader Pack(Version version, uint8_t named, uint8_t gammaNa med, uint8_t flags)
325 { 361 {
326 ColorSpaceHeader header; 362 ColorSpaceHeader header;
327 363
328 SkASSERT(k0_Version == version); 364 SkASSERT(k0_Version == version);
329 header.fVersion = (uint8_t) version; 365 header.fVersion = (uint8_t) version;
330 366
331 SkASSERT(named <= SkColorSpace::kSRGBLinear_Named); 367 SkASSERT(named <= SkColorSpace::kSRGBLinear_Named);
332 header.fNamed = (uint8_t) named; 368 header.fNamed = (uint8_t) named;
333 369
334 SkASSERT(gammaNamed <= kNonStandard_SkGammaNamed); 370 SkASSERT(gammaNamed <= kNonStandard_SkGammaNamed);
335 header.fGammaNamed = (uint8_t) gammaNamed; 371 header.fGammaNamed = (uint8_t) gammaNamed;
336 372
337 SkASSERT(flags <= kFloatGamma_Flag); 373 SkASSERT(flags <= kTransferFn_Flag);
338 header.fFlags = flags; 374 header.fFlags = flags;
339 return header; 375 return header;
340 } 376 }
341 377
342 uint8_t fVersion; // Always zero 378 uint8_t fVersion; // Always zero
343 uint8_t fNamed; // Must be a SkColorSpace::Named 379 uint8_t fNamed; // Must be a SkColorSpace::Named
344 uint8_t fGammaNamed; // Must be a SkGammaNamed 380 uint8_t fGammaNamed; // Must be a SkGammaNamed
345 uint8_t fFlags; // Some combination of the flags listed above 381 uint8_t fFlags; // Some combination of the flags listed above
346 }; 382 };
347 383
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 if (memory) { 417 if (memory) {
382 *((ColorSpaceHeader*) memory) = 418 *((ColorSpaceHeader*) memory) =
383 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)-> fGammaNamed, 419 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)-> fGammaNamed,
384 ColorSpaceHeader::kMatrix_Fla g); 420 ColorSpaceHeader::kMatrix_Fla g);
385 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) ); 421 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) );
386 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); 422 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
387 } 423 }
388 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); 424 return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
389 } 425 }
390 default: 426 default:
391 // Otherwise, write the gamma values and the matrix. 427 const SkGammas* gammas = as_CSB(this)->gammas();
392 if (memory) { 428 SkASSERT(gammas);
393 *((ColorSpaceHeader*) memory) = 429 if (gammas->isValue(0) && gammas->isValue(1) && gammas->isValue( 2)) {
394 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)-> fGammaNamed, 430 if (memory) {
395 ColorSpaceHeader::kFloatGamma _Flag); 431 *((ColorSpaceHeader*) memory) =
396 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader) ); 432 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(thi s)->fGammaNamed,
433 ColorSpaceHeader::kFloatG amma_Flag);
434 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea der));
397 435
398 const SkGammas* gammas = as_CSB(this)->gammas(); 436 *(((float*) memory) + 0) = gammas->fRedData.fValue;
399 SkASSERT(gammas); 437 *(((float*) memory) + 1) = gammas->fGreenData.fValue;
400 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && 438 *(((float*) memory) + 2) = gammas->fBlueData.fValue;
401 SkGammas::Type::kValue_Type == gammas->fGreenType & & 439 memory = SkTAddOffset<void>(memory, 3 * sizeof(float));
402 SkGammas::Type::kValue_Type == gammas->fBlueType);
403 *(((float*) memory) + 0) = gammas->fRedData.fValue;
404 *(((float*) memory) + 1) = gammas->fGreenData.fValue;
405 *(((float*) memory) + 2) = gammas->fBlueData.fValue;
406 memory = SkTAddOffset<void>(memory, 3 * sizeof(float));
407 440
408 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); 441 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
442 }
443
444 return sizeof(ColorSpaceHeader) + 15 * sizeof(float);
445 } else {
446 SkASSERT(gammas->isParametric(0));
447 SkASSERT(gammas->isParametric(1));
448 SkASSERT(gammas->isParametric(2));
449 SkASSERT(gammas->data(0) == gammas->data(1));
450 SkASSERT(gammas->data(0) == gammas->data(2));
451
452 if (memory) {
453 *((ColorSpaceHeader*) memory) =
454 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(thi s)->fGammaNamed,
455 ColorSpaceHeader::kTransf erFn_Flag);
456 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea der));
457
458 *(((float*) memory) + 0) = gammas->params(0).fA;
459 *(((float*) memory) + 1) = gammas->params(0).fB;
460 *(((float*) memory) + 2) = gammas->params(0).fC;
461 *(((float*) memory) + 3) = gammas->params(0).fD;
462 *(((float*) memory) + 4) = gammas->params(0).fE;
463 *(((float*) memory) + 5) = gammas->params(0).fF;
464 *(((float*) memory) + 6) = gammas->params(0).fG;
465 memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
466
467 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
468 }
469
470 return sizeof(ColorSpaceHeader) + 19 * sizeof(float);
409 } 471 }
410 return sizeof(ColorSpaceHeader) + 15 * sizeof(float);
411 } 472 }
412 } 473 }
413 474
414 // Otherwise, serialize the ICC data. 475 // Otherwise, serialize the ICC data.
415 size_t profileSize = as_CSB(this)->fProfileData->size(); 476 size_t profileSize = as_CSB(this)->fProfileData->size();
416 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { 477 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) {
417 return 0; 478 return 0;
418 } 479 }
419 480
420 if (memory) { 481 if (memory) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 float gammas[3]; 555 float gammas[3];
495 gammas[0] = *(((const float*) data) + 0); 556 gammas[0] = *(((const float*) data) + 0);
496 gammas[1] = *(((const float*) data) + 1); 557 gammas[1] = *(((const float*) data) + 1);
497 gammas[2] = *(((const float*) data) + 2); 558 gammas[2] = *(((const float*) data) + 2);
498 data = SkTAddOffset<const void>(data, 3 * sizeof(float)); 559 data = SkTAddOffset<const void>(data, 3 * sizeof(float));
499 560
500 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); 561 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
501 toXYZ.set3x4RowMajorf((const float*) data); 562 toXYZ.set3x4RowMajorf((const float*) data);
502 return SkColorSpace_Base::NewRGB(gammas, toXYZ); 563 return SkColorSpace_Base::NewRGB(gammas, toXYZ);
503 } 564 }
565 case ColorSpaceHeader::kTransferFn_Flag: {
566 if (length < 19 * sizeof(float)) {
567 return nullptr;
568 }
569
570 SkColorSpaceTransferFn transferFn;
571 transferFn.fA = *(((const float*) data) + 0);
572 transferFn.fB = *(((const float*) data) + 1);
573 transferFn.fC = *(((const float*) data) + 2);
574 transferFn.fD = *(((const float*) data) + 3);
575 transferFn.fE = *(((const float*) data) + 4);
576 transferFn.fF = *(((const float*) data) + 5);
577 transferFn.fG = *(((const float*) data) + 6);
578 data = SkTAddOffset<const void>(data, 7 * sizeof(float));
579
580 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
581 toXYZ.set3x4RowMajorf((const float*) data);
582 return SkColorSpace::NewRGB(transferFn, toXYZ);
583 }
504 default: 584 default:
505 return nullptr; 585 return nullptr;
506 } 586 }
507 } 587 }
508 588
509 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { 589 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) {
510 if (src == dst) { 590 if (src == dst) {
511 return true; 591 return true;
512 } 592 }
513 593
(...skipping 25 matching lines...) Expand all
539 return false; 619 return false;
540 } 620 }
541 621
542 // It is unlikely that we will reach this case. 622 // It is unlikely that we will reach this case.
543 sk_sp<SkData> srcData = src->serialize(); 623 sk_sp<SkData> srcData = src->serialize();
544 sk_sp<SkData> dstData = dst->serialize(); 624 sk_sp<SkData> dstData = dst->serialize();
545 return srcData->size() == dstData->size() && 625 return srcData->size() == dstData->size() &&
546 0 == memcmp(srcData->data(), dstData->data(), srcData->size() ); 626 0 == memcmp(srcData->data(), dstData->data(), srcData->size() );
547 } 627 }
548 } 628 }
OLDNEW
« no previous file with comments | « include/core/SkColorSpace.h ('k') | src/core/SkColorSpacePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698