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

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

Issue 1950183006: Approximate common gamma tables as single values (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix tests 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 | tests/ColorSpaceTest.cpp » ('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 "SkAtomics.h" 8 #include "SkAtomics.h"
9 #include "SkColorSpace.h" 9 #include "SkColorSpace.h"
10 #include "SkOncePtr.h" 10 #include "SkOncePtr.h"
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 } else if (len < 12 + 2 * count) { 315 } else if (len < 12 + 2 * count) {
316 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ; 316 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len) ;
317 return false; 317 return false;
318 } 318 }
319 319
320 const uint16_t* table = (const uint16_t*) (src + 12); 320 const uint16_t* table = (const uint16_t*) (src + 12);
321 if (1 == count) { 321 if (1 == count) {
322 // The table entry is the gamma (with a bias of 256). 322 // The table entry is the gamma (with a bias of 256).
323 uint16_t value = read_big_endian_short((const uint8_t*) tabl e); 323 uint16_t value = read_big_endian_short((const uint8_t*) tabl e);
324 gammas[i].fValue = value / 256.0f; 324 gammas[i].fValue = value / 256.0f;
325 SkColorSpacePrintf("gamma %d %g\n", value, *gamma); 325 SkColorSpacePrintf("gamma %d %g\n", value, gammas[i].fValue) ;
326 break; 326 break;
327 } 327 }
328 328
329 // Fill in the interpolation table. 329 // Check for frequently occurring curves and use a fast approxim ation.
330 // FIXME (msarett): 330 // We do this by sampling a few values and see if they match our expectation.
331 // We should recognize commonly occurring tables and just set ga mma to 2.2f. 331 // A more robust solution would be to compare each value in this curve against
332 // a 2.2f curve see if we remain below an error threshold. At t his time,
333 // we haven't seen any images in the wild that make this kind of
334 // calculation necessary. We encounter identical gamma curves o ver and
335 // over again, but relatively few variations.
336 if (1024 == count) {
337 if (0 == read_big_endian_short((const uint8_t*) &table[0]) & &
338 3341 == read_big_endian_short((const uint8_t*) &tabl e[256]) &&
339 14057 == read_big_endian_short((const uint8_t*) &tab le[512]) &&
340 34318 == read_big_endian_short((const uint8_t*) &tab le[768]) &&
341 65535 == read_big_endian_short((const uint8_t*) &tab le[1023])) {
342 gammas[i].fValue = 2.2f;
343 break;
344 }
345 } else if (26 == count) {
346 if (0 == read_big_endian_short((const uint8_t*) &table[0]) & &
347 3062 == read_big_endian_short((const uint8_t*) &tabl e[6]) &&
348 12824 == read_big_endian_short((const uint8_t*) &tab le[12]) &&
349 31237 == read_big_endian_short((const uint8_t*) &tab le[18]) &&
350 65535 == read_big_endian_short((const uint8_t*) &tab le[25])) {
351 gammas[i].fValue = 2.2f;
352 break;
353 }
354 }
355
356 // Otherwise, fill in the interpolation table.
332 gammas[i].fTableSize = count; 357 gammas[i].fTableSize = count;
333 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]); 358 gammas[i].fTable = std::unique_ptr<float[]>(new float[count]);
334 for (uint32_t j = 0; j < count; j++) { 359 for (uint32_t j = 0; j < count; j++) {
335 gammas[i].fTable[j] = 360 gammas[i].fTable[j] =
336 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f; 361 (read_big_endian_short((const uint8_t*) &table[j])) / 65535.0f;
337 } 362 }
338 break; 363 break;
339 } 364 }
340 case kTAG_ParaCurveType: 365 case kTAG_ParaCurveType:
341 // Guess 2.2f. 366 // Guess 2.2f.
(...skipping 22 matching lines...) Expand all
364 SkColorSpacePrintf("Invalid parametric curve type\n"); 389 SkColorSpacePrintf("Invalid parametric curve type\n");
365 return false; 390 return false;
366 } 391 }
367 break; 392 break;
368 default: 393 default:
369 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type); 394 SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
370 return false; 395 return false;
371 } 396 }
372 397
373 // Adjust src and len if there is another gamma curve to load. 398 // Adjust src and len if there is another gamma curve to load.
374 if (0 != numGammas) { 399 if (i != numGammas - 1) {
375 // Each curve is padded to 4-byte alignment. 400 // Each curve is padded to 4-byte alignment.
376 tagBytes = SkAlign4(tagBytes); 401 tagBytes = SkAlign4(tagBytes);
377 if (len < tagBytes) { 402 if (len < tagBytes) {
378 return false; 403 return false;
379 } 404 }
380 405
381 src += tagBytes; 406 src += tagBytes;
382 len -= tagBytes; 407 len -= tagBytes;
383 } 408 }
384 } 409 }
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 toXYZ)); 657 toXYZ));
633 } 658 }
634 659
635 } 660 }
636 default: 661 default:
637 break; 662 break;
638 } 663 }
639 664
640 return_null("ICC profile contains unsupported colorspace"); 665 return_null("ICC profile contains unsupported colorspace");
641 } 666 }
OLDNEW
« no previous file with comments | « no previous file | tests/ColorSpaceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698