1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC
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#include "include/core/SkCanvas.h"
9cb93a386Sopenharmony_ci#include "include/core/SkSurface.h"
10cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h"
11cb93a386Sopenharmony_ci#include "src/core/SkSamplingPriv.h"
12cb93a386Sopenharmony_ci#include "tests/Test.h"
13cb93a386Sopenharmony_ci#include "tools/Resources.h"
14cb93a386Sopenharmony_ci#include "tools/ToolUtils.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci// In general, sampling under identity matrix should not affect the pixels. However,
17cb93a386Sopenharmony_ci// cubic resampling when B != 0 is expected to change pixels.
18cb93a386Sopenharmony_ci//
19cb93a386Sopenharmony_ciDEF_TEST(sampling_with_identity_matrix, r) {
20cb93a386Sopenharmony_ci    const char* names[] = {
21cb93a386Sopenharmony_ci        "images/mandrill_128.png", "images/color_wheel.jpg",
22cb93a386Sopenharmony_ci    };
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ci    SkRandom rand;
25cb93a386Sopenharmony_ci    for (auto name : names) {
26cb93a386Sopenharmony_ci        auto src = GetResourceAsImage(name);
27cb93a386Sopenharmony_ci        auto surf = SkSurface::MakeRasterN32Premul(src->width(), src->height());
28cb93a386Sopenharmony_ci        auto canvas = surf->getCanvas();
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ci        auto dotest = [&](const SkSamplingOptions& sampling, bool expect_same) {
31cb93a386Sopenharmony_ci            canvas->clear(0);
32cb93a386Sopenharmony_ci            canvas->drawImage(src.get(), 0, 0, sampling, nullptr);
33cb93a386Sopenharmony_ci            auto dst = surf->makeImageSnapshot();
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci            REPORTER_ASSERT(r, SkSamplingPriv::NoChangeWithIdentityMatrix(sampling) == expect_same);
36cb93a386Sopenharmony_ci            REPORTER_ASSERT(r, ToolUtils::equal_pixels(src.get(), dst.get()) == expect_same);
37cb93a386Sopenharmony_ci        };
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci        // Exercise all non-cubics -- expecting no changes
40cb93a386Sopenharmony_ci        for (auto m : {SkMipmapMode::kNone, SkMipmapMode::kNearest, SkMipmapMode::kLinear}) {
41cb93a386Sopenharmony_ci            for (auto f : {SkFilterMode::kNearest, SkFilterMode::kLinear}) {
42cb93a386Sopenharmony_ci                dotest(SkSamplingOptions(f, m), true);
43cb93a386Sopenharmony_ci            }
44cb93a386Sopenharmony_ci        }
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci        // Exercise cubic variants with B zero and non-zero
47cb93a386Sopenharmony_ci        constexpr int N = 30;   // try a bunch of random values
48cb93a386Sopenharmony_ci        for (int i = 0; i < N; ++i) {
49cb93a386Sopenharmony_ci            float C = rand.nextF();
50cb93a386Sopenharmony_ci            dotest(SkSamplingOptions({0, C}), true);
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci            float B = rand.nextF() * 0.9f + 0.05f;  // non-zero but still within (0,,,1]
53cb93a386Sopenharmony_ci            SkASSERT(B != 0);
54cb93a386Sopenharmony_ci            dotest(SkSamplingOptions({B, C}), false);
55cb93a386Sopenharmony_ci        }
56cb93a386Sopenharmony_ci    }
57cb93a386Sopenharmony_ci}
58