Coverage Report

Created: 2026-08-31 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/tests/fuzzer/sharpyuv_fuzzer.cc
Line
Count
Source
1
// Copyright 2026 Google Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
////////////////////////////////////////////////////////////////////////////////
16
17
#include <cstddef>
18
#include <cstdint>
19
#include <vector>
20
21
#include "./fuzz_utils.h"
22
#include "gtest/gtest.h"
23
#include "sharpyuv/sharpyuv.h"
24
#include "sharpyuv/sharpyuv_csp.h"
25
26
namespace {
27
28
void SharpYuvConvertFuzz(int width, int height, int rgb_bit_depth,
29
                         int yuv_bit_depth,
30
                         const std::vector<uint16_t>& r_samples,
31
                         const std::vector<uint16_t>& g_samples,
32
                         const std::vector<uint16_t>& b_samples,
33
1.07k
                         int matrix_type_int, int transfer_type_int) {
34
1.07k
  const size_t num_pixels = static_cast<size_t>(width) * height;
35
1.07k
  ASSERT_LE(num_pixels, r_samples.size());
36
1.07k
  ASSERT_LE(num_pixels, g_samples.size());
37
1.07k
  ASSERT_LE(num_pixels, b_samples.size());
38
39
1.07k
  const SharpYuvMatrixType matrix_type =
40
1.07k
      static_cast<SharpYuvMatrixType>(matrix_type_int);
41
1.07k
  const SharpYuvTransferFunctionType transfer_type =
42
1.07k
      static_cast<SharpYuvTransferFunctionType>(transfer_type_int);
43
44
1.07k
  const SharpYuvConversionMatrix* matrix =
45
1.07k
      SharpYuvGetConversionMatrix(matrix_type);
46
1.07k
  ASSERT_NE(matrix, nullptr);
47
48
1.07k
  SharpYuvOptions options;
49
1.07k
  ASSERT_TRUE(SharpYuvOptionsInit(matrix, &options));
50
1.07k
  options.transfer_type = transfer_type;
51
52
1.07k
  const int yuv_bytes = (yuv_bit_depth > 8) ? 2 : 1;
53
1.07k
  const int y_stride = width * yuv_bytes;
54
1.07k
  const int uv_stride = ((width + 1) / 2) * yuv_bytes;
55
56
1.07k
  std::vector<uint8_t> y_dst(y_stride * height);
57
1.07k
  std::vector<uint8_t> u_dst(uv_stride * ((height + 1) / 2));
58
1.07k
  std::vector<uint8_t> v_dst(uv_stride * ((height + 1) / 2));
59
60
1.07k
  if (rgb_bit_depth == 8) {
61
234
    std::vector<uint8_t> r8(num_pixels), g8(num_pixels), b8(num_pixels);
62
101k
    for (size_t i = 0; i < num_pixels; ++i) {
63
101k
      r8[i] = static_cast<uint8_t>(r_samples[i]);
64
101k
      g8[i] = static_cast<uint8_t>(g_samples[i]);
65
101k
      b8[i] = static_cast<uint8_t>(b_samples[i]);
66
101k
    }
67
234
    EXPECT_TRUE(SharpYuvConvertWithOptions(
68
234
        r8.data(), g8.data(), b8.data(), 1, width, rgb_bit_depth, y_dst.data(),
69
234
        y_stride, u_dst.data(), uv_stride, v_dst.data(), uv_stride,
70
234
        yuv_bit_depth, width, height, &options));
71
837
  } else {
72
837
    EXPECT_TRUE(SharpYuvConvertWithOptions(
73
837
        r_samples.data(), g_samples.data(), b_samples.data(), 2, width * 2,
74
837
        rgb_bit_depth, y_dst.data(), y_stride, u_dst.data(), uv_stride,
75
837
        v_dst.data(), uv_stride, yuv_bit_depth, width, height, &options));
76
837
  }
77
1.07k
}
78
79
3.95k
auto AnyTransferFunction() {
80
3.95k
  return fuzztest::ElementOf<int>({
81
3.95k
      kSharpYuvTransferFunctionBt709,
82
3.95k
      kSharpYuvTransferFunctionBt470M,
83
3.95k
      kSharpYuvTransferFunctionBt470Bg,
84
3.95k
      kSharpYuvTransferFunctionBt601,
85
3.95k
      kSharpYuvTransferFunctionSmpte240,
86
3.95k
      kSharpYuvTransferFunctionLinear,
87
3.95k
      kSharpYuvTransferFunctionLog100,
88
3.95k
      kSharpYuvTransferFunctionLog100_Sqrt10,
89
3.95k
      kSharpYuvTransferFunctionIec61966,
90
3.95k
      kSharpYuvTransferFunctionBt1361,
91
3.95k
      kSharpYuvTransferFunctionSrgb,
92
3.95k
      kSharpYuvTransferFunctionBt2020_10Bit,
93
3.95k
      kSharpYuvTransferFunctionBt2020_12Bit,
94
3.95k
      kSharpYuvTransferFunctionSmpte2084,
95
3.95k
      kSharpYuvTransferFunctionSmpte428,
96
3.95k
      kSharpYuvTransferFunctionHlg,
97
3.95k
  });
98
3.95k
}
99
100
2
auto SharpYuvDomain() {
101
2
  return fuzztest::FlatMap(
102
3.95k
      [](int w, int h, int rgb_bd, int yuv_bd) {
103
        // Create input/output buffers of the right size.
104
3.95k
        const size_t n = static_cast<size_t>(w * h);
105
3.95k
        return fuzztest::TupleOf(
106
3.95k
            fuzztest::Just(w), fuzztest::Just(h), fuzztest::Just(rgb_bd),
107
3.95k
            fuzztest::Just(yuv_bd),
108
3.95k
            fuzztest::VectorOf(fuzztest::Arbitrary<uint16_t>()).WithSize(n),
109
3.95k
            fuzztest::VectorOf(fuzztest::Arbitrary<uint16_t>()).WithSize(n),
110
3.95k
            fuzztest::VectorOf(fuzztest::Arbitrary<uint16_t>()).WithSize(n),
111
3.95k
            fuzztest::InRange(0, static_cast<int>(kSharpYuvMatrixNum) - 1),
112
3.95k
            AnyTransferFunction());
113
3.95k
      },
114
2
      /*width=*/fuzztest::InRange(1, 128),
115
2
      /*height=*/fuzztest::InRange(1, 128),
116
2
      /*rgb_bit_depth=*/fuzztest::ElementOf({8, 10, 12, 16}),
117
2
      /*yuv_bit_depth=*/fuzztest::ElementOf({8, 10, 12}));
118
2
}
119
120
void SharpYuvConvertFuzzWrapped(
121
    const std::tuple<int, int, int, int, std::vector<uint16_t>,
122
                     std::vector<uint16_t>, std::vector<uint16_t>, int, int>&
123
1.07k
        args) {
124
1.07k
  std::apply(SharpYuvConvertFuzz, args);
125
1.07k
}
126
127
FUZZ_TEST(SharpYuvFuzz, SharpYuvConvertFuzzWrapped)
128
    .WithDomains(SharpYuvDomain());
129
130
}  // namespace