1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef SkImageSampling_DEFINED
9cb93a386Sopenharmony_ci#define SkImageSampling_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
12cb93a386Sopenharmony_ci#include <new>
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_cienum class SkFilterMode {
15cb93a386Sopenharmony_ci    kNearest,   // single sample point (nearest neighbor)
16cb93a386Sopenharmony_ci    kLinear,    // interporate between 2x2 sample points (bilinear interpolation)
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ci    kLast = kLinear,
19cb93a386Sopenharmony_ci};
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_cienum class SkMipmapMode {
22cb93a386Sopenharmony_ci    kNone,      // ignore mipmap levels, sample from the "base"
23cb93a386Sopenharmony_ci    kNearest,   // sample from the nearest level
24cb93a386Sopenharmony_ci    kLinear,    // interpolate between the two nearest levels
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci    kLast = kLinear,
27cb93a386Sopenharmony_ci};
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci/*
30cb93a386Sopenharmony_ci *  Specify B and C (each between 0...1) to create a shader that applies the corresponding
31cb93a386Sopenharmony_ci *  cubic reconstruction filter to the image.
32cb93a386Sopenharmony_ci *
33cb93a386Sopenharmony_ci *  Example values:
34cb93a386Sopenharmony_ci *      B = 1/3, C = 1/3        "Mitchell" filter
35cb93a386Sopenharmony_ci *      B = 0,   C = 1/2        "Catmull-Rom" filter
36cb93a386Sopenharmony_ci *
37cb93a386Sopenharmony_ci *  See "Reconstruction Filters in Computer Graphics"
38cb93a386Sopenharmony_ci *          Don P. Mitchell
39cb93a386Sopenharmony_ci *          Arun N. Netravali
40cb93a386Sopenharmony_ci *          1988
41cb93a386Sopenharmony_ci *  https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf
42cb93a386Sopenharmony_ci *
43cb93a386Sopenharmony_ci *  Desmos worksheet https://www.desmos.com/calculator/aghdpicrvr
44cb93a386Sopenharmony_ci *  Nice overview https://entropymine.com/imageworsener/bicubic/
45cb93a386Sopenharmony_ci */
46cb93a386Sopenharmony_cistruct SkCubicResampler {
47cb93a386Sopenharmony_ci    float B, C;
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci    // Historic default for kHigh_SkFilterQuality
50cb93a386Sopenharmony_ci    static constexpr SkCubicResampler Mitchell() { return {1/3.0f, 1/3.0f}; }
51cb93a386Sopenharmony_ci    static constexpr SkCubicResampler CatmullRom() { return {0.0f, 1/2.0f}; }
52cb93a386Sopenharmony_ci};
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_cistruct SK_API SkSamplingOptions {
55cb93a386Sopenharmony_ci    const bool             useCubic = false;
56cb93a386Sopenharmony_ci    const SkCubicResampler cubic    = {0, 0};
57cb93a386Sopenharmony_ci    const SkFilterMode     filter   = SkFilterMode::kNearest;
58cb93a386Sopenharmony_ci    const SkMipmapMode     mipmap   = SkMipmapMode::kNone;
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    SkSamplingOptions() = default;
61cb93a386Sopenharmony_ci    SkSamplingOptions(const SkSamplingOptions&) = default;
62cb93a386Sopenharmony_ci    SkSamplingOptions& operator=(const SkSamplingOptions& that) {
63cb93a386Sopenharmony_ci        this->~SkSamplingOptions();   // A pedantic no-op.
64cb93a386Sopenharmony_ci        new (this) SkSamplingOptions(that);
65cb93a386Sopenharmony_ci        return *this;
66cb93a386Sopenharmony_ci    }
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    SkSamplingOptions(SkFilterMode fm, SkMipmapMode mm)
69cb93a386Sopenharmony_ci        : useCubic(false)
70cb93a386Sopenharmony_ci        , filter(fm)
71cb93a386Sopenharmony_ci        , mipmap(mm) {}
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_ci    explicit SkSamplingOptions(SkFilterMode fm)
74cb93a386Sopenharmony_ci        : useCubic(false)
75cb93a386Sopenharmony_ci        , filter(fm)
76cb93a386Sopenharmony_ci        , mipmap(SkMipmapMode::kNone) {}
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ci    explicit SkSamplingOptions(const SkCubicResampler& c)
79cb93a386Sopenharmony_ci        : useCubic(true)
80cb93a386Sopenharmony_ci        , cubic(c) {}
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    bool operator==(const SkSamplingOptions& other) const {
83cb93a386Sopenharmony_ci        return useCubic == other.useCubic
84cb93a386Sopenharmony_ci            && cubic.B  == other.cubic.B
85cb93a386Sopenharmony_ci            && cubic.C  == other.cubic.C
86cb93a386Sopenharmony_ci            && filter   == other.filter
87cb93a386Sopenharmony_ci            && mipmap   == other.mipmap;
88cb93a386Sopenharmony_ci    }
89cb93a386Sopenharmony_ci    bool operator!=(const SkSamplingOptions& other) const { return !(*this == other); }
90cb93a386Sopenharmony_ci};
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci#endif
93