1 /* 2 * Copyright 2020 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 SkImageSampling_DEFINED 9 #define SkImageSampling_DEFINED 10 11 #include "include/core/SkTypes.h" 12 13 #include <algorithm> 14 #include <new> 15 16 enum class SkFilterMode { 17 kNearest, // single sample point (nearest neighbor) 18 kLinear, // interporate between 2x2 sample points (bilinear interpolation) 19 20 kLast = kLinear, 21 }; 22 static constexpr int kSkFilterModeCount = static_cast<int>(SkFilterMode::kLast) + 1; 23 24 enum class SkMipmapMode { 25 kNone, // ignore mipmap levels, sample from the "base" 26 kNearest, // sample from the nearest level 27 kLinear, // interpolate between the two nearest levels 28 29 kLast = kLinear, 30 }; 31 static constexpr int kSkMipmapModeCount = static_cast<int>(SkMipmapMode::kLast) + 1; 32 33 /* 34 * Specify B and C (each between 0...1) to create a shader that applies the corresponding 35 * cubic reconstruction filter to the image. 36 * 37 * Example values: 38 * B = 1/3, C = 1/3 "Mitchell" filter 39 * B = 0, C = 1/2 "Catmull-Rom" filter 40 * 41 * See "Reconstruction Filters in Computer Graphics" 42 * Don P. Mitchell 43 * Arun N. Netravali 44 * 1988 45 * https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf 46 * 47 * Desmos worksheet https://www.desmos.com/calculator/aghdpicrvr 48 * Nice overview https://entropymine.com/imageworsener/bicubic/ 49 */ 50 struct SkCubicResampler { 51 float B, C; 52 53 // Historic default for kHigh_SkFilterQuality MitchellSkCubicResampler54 static constexpr SkCubicResampler Mitchell() { return {1/3.0f, 1/3.0f}; } CatmullRomSkCubicResampler55 static constexpr SkCubicResampler CatmullRom() { return {0.0f, 1/2.0f}; } 56 }; 57 58 struct SK_API SkSamplingOptions { 59 const int maxAniso = 0; 60 const bool useCubic = false; 61 const SkCubicResampler cubic = {0, 0}; 62 const SkFilterMode filter = SkFilterMode::kNearest; 63 const SkMipmapMode mipmap = SkMipmapMode::kNone; 64 65 constexpr SkSamplingOptions() = default; 66 SkSamplingOptions(const SkSamplingOptions&) = default; 67 SkSamplingOptions& operator=(const SkSamplingOptions& that) { 68 this->~SkSamplingOptions(); // A pedantic no-op. 69 new (this) SkSamplingOptions(that); 70 return *this; 71 } 72 SkSamplingOptionsSkSamplingOptions73 constexpr SkSamplingOptions(SkFilterMode fm, SkMipmapMode mm) 74 : filter(fm) 75 , mipmap(mm) {} 76 SkSamplingOptionsSkSamplingOptions77 explicit constexpr SkSamplingOptions(SkFilterMode fm) 78 : filter(fm) 79 , mipmap(SkMipmapMode::kNone) {} 80 SkSamplingOptionsSkSamplingOptions81 explicit constexpr SkSamplingOptions(const SkCubicResampler& c) 82 : useCubic(true) 83 , cubic(c) {} 84 AnisoSkSamplingOptions85 static constexpr SkSamplingOptions Aniso(int maxAniso) { 86 return SkSamplingOptions{std::max(maxAniso, 1)}; 87 } 88 89 bool operator==(const SkSamplingOptions& other) const { 90 return maxAniso == other.maxAniso 91 && useCubic == other.useCubic 92 && cubic.B == other.cubic.B 93 && cubic.C == other.cubic.C 94 && filter == other.filter 95 && mipmap == other.mipmap; 96 } 97 bool operator!=(const SkSamplingOptions& other) const { return !(*this == other); } 98 isAnisoSkSamplingOptions99 bool isAniso() const { return maxAniso != 0; } 100 101 private: SkSamplingOptionsSkSamplingOptions102 constexpr SkSamplingOptions(int maxAniso) : maxAniso(maxAniso) {} 103 }; 104 105 #endif 106