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 SkColorLookUpTable_DEFINED 9 #define SkColorLookUpTable_DEFINED 10 11 #include "SkRefCnt.h" 12 #include "SkTemplates.h" 13 14 static constexpr uint8_t kMaxColorChannels = 4; 15 16 class SkColorLookUpTable : public SkRefCnt { 17 public: 18 static constexpr uint8_t kOutputChannels = 3; 19 SkColorLookUpTable(uint8_t inputChannels,const uint8_t gridPoints[kMaxColorChannels])20 SkColorLookUpTable(uint8_t inputChannels, const uint8_t gridPoints[kMaxColorChannels]) 21 : fInputChannels(inputChannels) { 22 SkASSERT(inputChannels >= 1 && inputChannels <= kMaxColorChannels); 23 memcpy(fGridPoints, gridPoints, fInputChannels * sizeof(uint8_t)); 24 25 for (int i = 0; i < inputChannels; i++) { 26 SkASSERT(fGridPoints[i] > 1); 27 } 28 } 29 30 /** 31 * If fInputChannels == kOutputChannels == 3, performs tetrahedral interpolation, otherwise 32 * performs multilinear interpolation (ie LERP for n =1, bilinear for n=2, trilinear for n=3) 33 * with fInputChannels input dimensions and kOutputChannels output dimensions. 34 * |dst| can be |src| only when fInputChannels == kOutputChannels == 3 35 * |dst| is the destination pixel, must have at least kOutputChannels elements. 36 * |src| is the source pixel, must have at least fInputChannels elements. 37 */ 38 void interp(float* dst, const float* src) const; 39 inputChannels()40 int inputChannels() const { return fInputChannels; } 41 outputChannels()42 int outputChannels() const { return kOutputChannels; } 43 gridPoints(int dimension)44 int gridPoints(int dimension) const { 45 SkASSERT(dimension >= 0 && dimension < inputChannels()); 46 return fGridPoints[dimension]; 47 } 48 49 private: table()50 const float* table() const { 51 return SkTAddOffset<const float>(this, sizeof(SkColorLookUpTable)); 52 } 53 54 /** 55 * Performs tetrahedral interpolation with 3 input and 3 output dimensions. 56 * |dst| can be |src| 57 */ 58 void interp3D(float* dst, const float* src) const; 59 60 // recursively LERPs one dimension at a time. Used by interp() for the general case 61 float interpDimension(const float* src, int inputDimension, int outputDimension, 62 int index[kMaxColorChannels]) const; 63 64 uint8_t fInputChannels; 65 uint8_t fGridPoints[kMaxColorChannels]; 66 67 public: 68 // Objects of this type are created in a custom fashion using sk_malloc_throw 69 // and therefore must be sk_freed. 70 void* operator new(size_t size) = delete; new(size_t,void * p)71 void* operator new(size_t, void* p) { return p; } delete(void * p)72 void operator delete(void* p) { sk_free(p); } 73 }; 74 75 #endif 76