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