Line data Source code
1 : /*
2 : * Copyright 2016 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef SkColorSpaceXformPriv_DEFINED
9 : #define SkColorSpaceXformPriv_DEFINED
10 :
11 : #include "SkColorSpace_Base.h"
12 : #include "SkColorSpaceXform.h"
13 : #include "SkHalf.h"
14 : #include "SkSRGB.h"
15 :
16 : #define SkCSXformPrintfDefined 0
17 : #define SkCSXformPrintf(...)
18 :
19 : // Interpolating lookup in a variably sized table.
20 0 : static inline float interp_lut(float input, const float* table, int tableSize) {
21 0 : float index = input * (tableSize - 1);
22 0 : float diff = index - sk_float_floor2int(index);
23 0 : return table[(int) sk_float_floor2int(index)] * (1.0f - diff) +
24 0 : table[(int) sk_float_ceil2int(index)] * diff;
25 : }
26 :
27 : // Expand range from 0-1 to 0-255, then convert.
28 0 : static inline uint8_t clamp_normalized_float_to_byte(float v) {
29 : // The ordering of the logic is a little strange here in order
30 : // to make sure we convert NaNs to 0.
31 0 : v = v * 255.0f;
32 0 : if (v >= 254.5f) {
33 0 : return 255;
34 0 : } else if (v >= 0.5f) {
35 0 : return (uint8_t) (v + 0.5f);
36 : } else {
37 0 : return 0;
38 : }
39 : }
40 :
41 0 : static inline float clamp_0_1(float v) {
42 : // The ordering of the logic is a little strange here in order
43 : // to make sure we convert NaNs to 0.
44 0 : if (v >= 1.0f) {
45 0 : return 1.0f;
46 0 : } else if (v >= 0.0f) {
47 0 : return v;
48 : } else {
49 0 : return 0.0f;
50 : }
51 : }
52 :
53 : /**
54 : * Invert table lookup. Ex: what indices corresponds to the input values?
55 : * This will have strange results when the table is not increasing.
56 : * But any sane gamma function will be increasing.
57 : * @param outTableFloat Destination table for float (0-1) results. Can be nullptr if not wanted.
58 : * @param outTableByte Destination table for byte (0-255) results. Can be nullptr if not wanted.
59 : * @param outTableSize Number of elements in |outTableFloat| or |outTableBytes|
60 : * @param inTable The source table to invert
61 : * @param inTableSize The number of elements in |inTable|
62 : */
63 0 : static inline void invert_table_gamma(float* outTableFloat, uint8_t* outTableByte,
64 : int outTableSize, const float* inTable, int inTableSize) {
65 : // should never have a gamma table this small anyway, 0/1 are either not allowed
66 : // or imply a non-table gamma such as linear/exponential
67 0 : SkASSERT(inTableSize >= 2);
68 0 : int inIndex = 1;
69 0 : for (int outIndex = 0; outIndex < outTableSize; ++outIndex) {
70 0 : const float input = outIndex / (outTableSize - 1.0f);
71 0 : while (inIndex < inTableSize - 1 && inTable[inIndex] < input) {
72 0 : ++inIndex;
73 : }
74 0 : const float diff = input - inTable[inIndex - 1];
75 0 : const float distance = inTable[inIndex] - inTable[inIndex - 1];
76 0 : const float normalizedIndex = (inIndex - 1) + diff / distance;
77 0 : const float index = normalizedIndex / (inTableSize - 1);
78 0 : if (outTableByte) {
79 0 : outTableByte[outIndex] = clamp_normalized_float_to_byte(index);
80 : }
81 0 : if (outTableFloat) {
82 0 : outTableFloat[outIndex] = clamp_0_1(index);
83 : }
84 : }
85 0 : }
86 :
87 0 : static inline SkColorSpaceXform::ColorFormat select_xform_format(SkColorType colorType) {
88 0 : switch (colorType) {
89 : case kRGBA_8888_SkColorType:
90 0 : return SkColorSpaceXform::kRGBA_8888_ColorFormat;
91 : case kBGRA_8888_SkColorType:
92 0 : return SkColorSpaceXform::kBGRA_8888_ColorFormat;
93 : case kRGBA_F16_SkColorType:
94 0 : return SkColorSpaceXform::kRGBA_F16_ColorFormat;
95 : case kRGB_565_SkColorType:
96 0 : return SkColorSpaceXform::kBGR_565_ColorFormat;
97 : default:
98 0 : SkASSERT(false);
99 0 : return SkColorSpaceXform::kRGBA_8888_ColorFormat;
100 : }
101 : }
102 :
103 : #endif
|