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 SkSamplingPriv_DEFINED 9 #define SkSamplingPriv_DEFINED 10 11 #include "include/core/SkSamplingOptions.h" 12 13 class SkReadBuffer; 14 class SkWriteBuffer; 15 16 // Given a src rect in texels to be filtered, this number of surrounding texels are needed by 17 // the kernel in x and y. 18 static constexpr int kBicubicFilterTexelPad = 2; 19 20 // Private copy of SkFilterQuality, just for legacy deserialization 21 // Matches values in SkFilterQuality 22 enum SkLegacyFQ { 23 kNone_SkLegacyFQ = 0, //!< nearest-neighbor; fastest but lowest quality 24 kLow_SkLegacyFQ = 1, //!< bilerp 25 kMedium_SkLegacyFQ = 2, //!< bilerp + mipmaps; good for down-scaling 26 kHigh_SkLegacyFQ = 3, //!< bicubic resampling; slowest but good quality 27 28 kLast_SkLegacyFQ = kHigh_SkLegacyFQ, 29 }; 30 31 // Matches values in SkSamplingOptions::MediumBehavior 32 enum SkMediumAs { 33 kNearest_SkMediumAs, 34 kLinear_SkMediumAs, 35 }; 36 37 class SkSamplingPriv { 38 public: FlatSize(const SkSamplingOptions & options)39 static size_t FlatSize(const SkSamplingOptions& options) { 40 size_t size = sizeof(uint32_t); // maxAniso 41 if (!options.isAniso()) { 42 size += 3 * sizeof(uint32_t); // bool32 + [2 floats | 2 ints] 43 } 44 return size; 45 } 46 47 // Returns true if the sampling can be ignored when the CTM is identity. NoChangeWithIdentityMatrix(const SkSamplingOptions & sampling)48 static bool NoChangeWithIdentityMatrix(const SkSamplingOptions& sampling) { 49 // If B == 0, the cubic resampler should have no effect for identity matrices 50 // https://entropymine.com/imageworsener/bicubic/ 51 // We assume aniso has no effect with an identity transform. 52 return !sampling.useCubic || sampling.cubic.B == 0; 53 } 54 55 // Makes a fallback SkSamplingOptions for cases where anisotropic filtering is not allowed. 56 // anisotropic filtering can access mip levels if present, but we don't add mipmaps to non- 57 // mipmapped images when the user requests anisotropic. So we shouldn't fall back to a 58 // sampling that would trigger mip map creation. AnisoFallback(bool imageIsMipped)59 static SkSamplingOptions AnisoFallback(bool imageIsMipped) { 60 auto mm = imageIsMipped ? SkMipmapMode::kLinear : SkMipmapMode::kNone; 61 return SkSamplingOptions(SkFilterMode::kLinear, mm); 62 } 63 64 static SkSamplingOptions FromFQ(SkLegacyFQ fq, SkMediumAs behavior = kNearest_SkMediumAs) { 65 switch (fq) { 66 case kHigh_SkLegacyFQ: 67 return SkSamplingOptions(SkCubicResampler{1/3.0f, 1/3.0f}); 68 case kMedium_SkLegacyFQ: 69 return SkSamplingOptions(SkFilterMode::kLinear, 70 behavior == kNearest_SkMediumAs ? SkMipmapMode::kNearest 71 : SkMipmapMode::kLinear); 72 case kLow_SkLegacyFQ: 73 return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone); 74 case kNone_SkLegacyFQ: 75 break; 76 } 77 return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone); 78 } 79 }; 80 81 #endif 82