OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |