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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/core/SkColorSpacePriv.h » ('j') | src/core/SkColorSpacePriv.h » ('J')
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 #include "SkColorSpacePriv.h" 10 #include "SkColorSpacePriv.h"
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 switch (type) { 355 switch (type) {
356 case kTAG_CurveType: { 356 case kTAG_CurveType: {
357 uint32_t count = read_big_endian_uint(src + 8); 357 uint32_t count = read_big_endian_uint(src + 8);
358 tagBytes = 12 + count * 2; 358 tagBytes = 12 + count * 2;
359 if (0 == count) { 359 if (0 == count) {
360 // Some tags require a gamma curve, but the author doesn't a ctually want 360 // Some tags require a gamma curve, but the author doesn't a ctually want
361 // to transform the data. In this case, it is common to see a curve with 361 // to transform the data. In this case, it is common to see a curve with
362 // a count of 0. 362 // a count of 0.
363 gammas[i].fValue = 1.0f; 363 gammas[i].fValue = 1.0f;
364 break; 364 break;
365 } else if (len < 12 + 2 * count) { 365 } else if (len < tagBytes) {
366 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 366 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
367 return false; 367 return false;
368 } 368 }
369 369
370 const uint16_t* table = (const uint16_t*) (src + 12); 370 const uint16_t* table = (const uint16_t*) (src + 12);
371 if (1 == count) { 371 if (1 == count) {
372 // The table entry is the gamma (with a bias of 256). 372 // The table entry is the gamma (with a bias of 256).
373 uint16_t value = read_big_endian_short((const uint8_t*) tabl e); 373 uint16_t value = read_big_endian_short((const uint8_t*) tabl e);
374 gammas[i].fValue = value / 256.0f; 374 gammas[i].fValue = value / 256.0f;
375 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue) ; 375 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue) ;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 // Otherwise, fill in the interpolation table. 422 // Otherwise, fill in the interpolation table.
423 gammas[i].fTableSize = count; 423 gammas[i].fTableSize = count;
424 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]); 424 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]);
425 for (uint32_t j = 0; j < count; j++) { 425 for (uint32_t j = 0; j < count; j++) {
426 gammas[i].fTable[j] = 426 gammas[i].fTable[j] =
427 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f; 427 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f;
428 } 428 }
429 break; 429 break;
430 } 430 }
431 case kTAG_ParaCurveType: 431 case kTAG_ParaCurveType:
432 // Guess 2.2f. 432 // Determine the format of the parametric curve tag.
433 // FIXME (msarett): Handle parametric curves. 433 switch(read_big_endian_short(src + 8)) {
434 SkColorSpacePrintf("parametric curve\n"); 434 case 0: {
435 gammas[i].fValue = 2.2f; 435 tagBytes = 12 + 4;
436 if (len < tagBytes) {
437 SkColorSpacePrintf("gamma tag is too small (%d bytes )", len);
438 return false;
439 }
436 440
437 // Determine the size of the parametric curve tag. 441 // Y = X^g
438 switch(read_big_endian_short(src + 8)) { 442 int32_t g = read_big_endian_int(src + 12);
439 case 0: 443 gammas[i].fValue = SkFixedToFloat(g);
440 tagBytes = 12 + 4;
441 break; 444 break;
442 case 1: 445 }
446
447 // Here's where the real parametric gammas start. There are many
448 // permutations of the same equations.
449 //
450 // Y = (aX + b)^g + c for X >= d
451 // Y = eX + f otherwise
452 //
453 // We will fill in with zeros as necessary to always match t he above form.
454 // Note that there is no need to actually write zero, since the struct is
455 // zero initialized.
456 case 1: {
443 tagBytes = 12 + 12; 457 tagBytes = 12 + 12;
458 if (len < tagBytes) {
459 SkColorSpacePrintf("gamma tag is too small (%d bytes )", len);
460 return false;
461 }
462
463 // Y = (aX + b)^g for X >= -b/a
464 // Y = 0 otherwise
465 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
466 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
467 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
468 gammas[i].fD = -gammas[i].fB / gammas[i].fA;
444 break; 469 break;
470 }
445 case 2: 471 case 2:
446 tagBytes = 12 + 16; 472 tagBytes = 12 + 16;
473 if (len < tagBytes) {
474 SkColorSpacePrintf("gamma tag is too small (%d bytes )", len);
475 return false;
476 }
477
478 // Y = (aX + b)^g + c for X >= -b/a
479 // Y = c otherwise
480 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
481 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
482 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
483 gammas[i].fC = SkFixedToFloat(read_big_endian_int(src + 24));
484 gammas[i].fD = -gammas[i].fB / gammas[i].fA;
485 gammas[i].fF = gammas[i].fC;
447 break; 486 break;
448 case 3: 487 case 3:
449 tagBytes = 12 + 20; 488 tagBytes = 12 + 20;
489 if (len < tagBytes) {
490 SkColorSpacePrintf("gamma tag is too small (%d bytes )", len);
491 return false;
492 }
493
494 // Y = (aX + b)^g for X >= d
495 // Y = cX otherwise
496 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
497 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
498 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
499 gammas[i].fD = SkFixedToFloat(read_big_endian_int(src + 28));
500 gammas[i].fE = SkFixedToFloat(read_big_endian_int(src + 24));
450 break; 501 break;
451 case 4: 502 case 4:
452 tagBytes = 12 + 28; 503 tagBytes = 12 + 28;
504 if (len < tagBytes) {
505 SkColorSpacePrintf("gamma tag is too small (%d bytes )", len);
506 return false;
507 }
508
509 // Y = (aX + b)^g + c for X >= d
510 // Y = eX + f otherwise
511 // NOTE: The ICC spec writes "cX" instead of "eX" but I think it's a typo.
512 gammas[i].fG = SkFixedToFloat(read_big_endian_int(src + 12));
513 gammas[i].fA = SkFixedToFloat(read_big_endian_int(src + 16));
514 gammas[i].fB = SkFixedToFloat(read_big_endian_int(src + 20));
515 gammas[i].fC = SkFixedToFloat(read_big_endian_int(src + 24));
516 gammas[i].fD = SkFixedToFloat(read_big_endian_int(src + 28));
517 gammas[i].fE = SkFixedToFloat(read_big_endian_int(src + 32));
518 gammas[i].fF = SkFixedToFloat(read_big_endian_int(src + 36));
453 break; 519 break;
454 default: 520 default:
455 SkColorSpacePrintf("Invalid parametric curve type\n"); 521 SkColorSpacePrintf("Invalid parametric curve type\n");
456 return false; 522 return false;
457 } 523 }
458 break; 524 break;
459 default: 525 default:
460 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type); 526 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
461 return false; 527 return false;
462 } 528 }
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 } 808 }
743 } 809 }
744 810
745 } 811 }
746 default: 812 default:
747 break; 813 break;
748 } 814 }
749 815
750 return_null("ICC profile contains unsupported colorspace"); 816 return_null("ICC profile contains unsupported colorspace");
751 } 817 }
OLDNEW
« 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