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