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

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

Issue 2263233003: More robust check for sRGB gamma tables (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clarify logic Created 4 years, 4 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 | 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 "SkColorSpace.h" 8 #include "SkColorSpace.h"
9 #include "SkColorSpace_Base.h" 9 #include "SkColorSpace_Base.h"
10 #include "SkColorSpacePriv.h" 10 #include "SkColorSpacePriv.h"
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 255
256 data->fValue = value; 256 data->fValue = value;
257 return SkGammas::Type::kValue_Type; 257 return SkGammas::Type::kValue_Type;
258 } 258 }
259 259
260 static float read_big_endian_16_dot_16(const uint8_t buf[4]) { 260 static float read_big_endian_16_dot_16(const uint8_t buf[4]) {
261 // It just so happens that SkFixed is also 16.16! 261 // It just so happens that SkFixed is also 16.16!
262 return SkFixedToFloat(read_big_endian_i32(buf)); 262 return SkFixedToFloat(read_big_endian_i32(buf));
263 } 263 }
264 264
265 static inline float srgb_fn(float x) {
266 if (x <= 0.04045f) {
267 return x * (1.0f / 12.92f);
268 }
269
270 return powf(x * (1.0f / 1.055f) + (0.055f / 1.055f), 2.4f);
271 }
272
265 /** 273 /**
266 * @param outData Set to the appropriate value on success. If we have tabl e or 274 * @param outData Set to the appropriate value on success. If we have tabl e or
267 * parametric gamma, it is the responsibility of the caller to set 275 * parametric gamma, it is the responsibility of the caller to set
268 * fOffset. 276 * fOffset.
269 * @param outParams If this is a parametric gamma, this is set to the appropr iate 277 * @param outParams If this is a parametric gamma, this is set to the appropr iate
270 * parameters on success. 278 * parameters on success.
271 * @param outTagBytes Will be set to the length of the tag on success. 279 * @param outTagBytes Will be set to the length of the tag on success.
272 * @src Pointer to tag data. 280 * @src Pointer to tag data.
273 * @len Length of tag data in bytes. 281 * @len Length of tag data in bytes.
274 * 282 *
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) && 371 if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
364 950 == read_big_endian_u16((const uint8_t*) &table[515]) && 372 950 == read_big_endian_u16((const uint8_t*) &table[515]) &&
365 3342 == read_big_endian_u16((const uint8_t*) &table[1025 ]) && 373 3342 == read_big_endian_u16((const uint8_t*) &table[1025 ]) &&
366 14079 == read_big_endian_u16((const uint8_t*) &table[205 1]) && 374 14079 == read_big_endian_u16((const uint8_t*) &table[205 1]) &&
367 65535 == read_big_endian_u16((const uint8_t*) &table[409 5])) { 375 65535 == read_big_endian_u16((const uint8_t*) &table[409 5])) {
368 outData->fNamed = SkColorSpace::kSRGB_GammaNamed; 376 outData->fNamed = SkColorSpace::kSRGB_GammaNamed;
369 return SkGammas::Type::kNamed_Type; 377 return SkGammas::Type::kNamed_Type;
370 } 378 }
371 } 379 }
372 380
373 // Otherwise, we will represent gamma with a table. 381 // Perform a more robust check for sRGB. See if the table is a clos e
374 outData->fTable.fSize = count; 382 // match to an sRGB table. This is in addition to the previous sRGB
375 return SkGammas::Type::kTable_Type; 383 // checks for a couple reasons:
384 // (1) It is much slower.
385 // (2) The 26 entry "sRGB" curve is actually so inaccurate that it f ails
386 // this check. But it still wants to be sRGB.
387 float x = 0.0f;
388 float dx = 1.0f / ((float) (count - 1));
389 for (uint32_t i = 0; i < count; i++) {
390 float y = srgb_fn(x);
391
392 // Convert y to the same format as the table (0.16 fixed point), so we can
393 // compare values.
394 uint16_t srgbY = sk_float_round2int(y * (float) (1 << 16));
395 uint16_t actualY = read_big_endian_u16((const uint8_t*) &table[i ]);
396
397 // We allow "off by 1" curves to try to not be affected by round ing decisions.
398 if (SkTAbs((int32_t) srgbY - (int32_t) actualY) > 1) {
399 // Curve is not sRGB, will use table representation.
400 outData->fTable.fSize = count;
401 return SkGammas::Type::kTable_Type;
402 }
403
404 x += dx;
405 }
406
407 outData->fNamed = SkColorSpace::kSRGB_GammaNamed;
408 return SkGammas::Type::kNamed_Type;
409
376 } 410 }
377 case kTAG_ParaCurveType: { 411 case kTAG_ParaCurveType: {
378 enum ParaCurveType { 412 enum ParaCurveType {
379 kExponential_ParaCurveType = 0, 413 kExponential_ParaCurveType = 0,
380 kGAB_ParaCurveType = 1, 414 kGAB_ParaCurveType = 1,
381 kGABC_ParaCurveType = 2, 415 kGABC_ParaCurveType = 2,
382 kGABDE_ParaCurveType = 3, 416 kGABDE_ParaCurveType = 3,
383 kGABCDEF_ParaCurveType = 4, 417 kGABCDEF_ParaCurveType = 4,
384 }; 418 };
385 419
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 ptr32[4] = SkEndian_SwapBE32(0x000116cc); 1357 ptr32[4] = SkEndian_SwapBE32(0x000116cc);
1324 ptr += kTAG_XYZ_Bytes; 1358 ptr += kTAG_XYZ_Bytes;
1325 1359
1326 // Write copyright tag 1360 // Write copyright tag
1327 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); 1361 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag));
1328 1362
1329 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if 1363 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if
1330 // the client calls again? 1364 // the client calls again?
1331 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); 1365 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
1332 } 1366 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698