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