Home | History | Annotate | Download | only in core
      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