Coverage Report

Created: 2026-06-10 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/tests/gtest/avif_fuzztest_read_image.cc
Line
Count
Source
1
// Copyright 2023 Google LLC
2
// SPDX-License-Identifier: BSD-2-Clause
3
//
4
// Tests the jpeg/png/y4m reading code from avifenc.
5
6
#include <fstream>
7
#include <iostream>
8
#include <string>
9
#include <vector>
10
11
#include "avif/avif.h"
12
#include "avif_fuzztest_helpers.h"
13
#include "aviftest_helpers.h"
14
#include "avifutil.h"
15
#include "fuzztest/fuzztest.h"
16
#include "gtest/gtest.h"
17
18
using ::fuzztest::Arbitrary;
19
using ::fuzztest::ElementOf;
20
21
namespace avif {
22
namespace testutil {
23
namespace {
24
25
//------------------------------------------------------------------------------
26
27
0
std::string FileFormatToString(avifAppFileFormat file_format) {
28
0
  switch (file_format) {
29
0
    case AVIF_APP_FILE_FORMAT_UNKNOWN:
30
0
      return "unknown";
31
0
    case AVIF_APP_FILE_FORMAT_AVIF:
32
0
      return "AVIF";
33
0
    case AVIF_APP_FILE_FORMAT_PNG:
34
0
      return "PNG";
35
0
    case AVIF_APP_FILE_FORMAT_JPEG:
36
0
      return "JPEG";
37
0
    case AVIF_APP_FILE_FORMAT_Y4M:
38
0
      return "Y4M";
39
0
    default:
40
0
      assert(false);
41
0
      return "unknown";
42
0
  }
43
0
}
44
45
void ReadImageFile(const std::string& arbitrary_bytes,
46
                   avifPixelFormat requested_format, int requested_depth,
47
                   avifChromaDownsampling chroma_downsampling,
48
                   bool ignore_color_profile, bool ignore_exif, bool ignore_xmp,
49
                   bool ignore_gain_map,
50
0
                   avifMatrixCoefficients matrix_coefficients) {
51
0
  ASSERT_FALSE(GetSeedDataDirs().empty());  // Make sure seeds are available.
52
53
  // Write the byte stream to a temp file since avifReadImage() takes a file
54
  // path as input.
55
0
  const std::string file_path = testing::TempDir() + "inputimage";
56
0
  std::ofstream out(file_path);
57
0
  out << arbitrary_bytes;
58
0
  out.close();
59
60
0
  uint32_t out_depth;
61
0
  avifAppSourceTiming timing;
62
0
  ImagePtr avif_image(avifImageCreateEmpty());
63
0
  avif_image->matrixCoefficients = matrix_coefficients;
64
65
  // OSS-Fuzz limits the allocated memory to 2560 MB.
66
0
  constexpr uint32_t kMaxMem = 2560u * 1024 * 1024;
67
  // Consider at most four planes of 16-bit samples.
68
0
  constexpr uint32_t kMaxImageSize =
69
0
      kMaxMem / (AVIF_PLANE_COUNT_YUV + 1) / sizeof(uint16_t);
70
  // Reduce the limit further to include pixel buffer copies and other memory
71
  // allocations.
72
0
  constexpr uint32_t kImageSizeLimit = kMaxImageSize / 4;
73
  // SharpYUV is computationally expensive. Avoid timeouts.
74
0
  const uint32_t imageSizeLimit =
75
0
      (chroma_downsampling == AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV &&
76
0
       requested_format == AVIF_PIXEL_FORMAT_YUV420)
77
0
          ? kImageSizeLimit / 8
78
0
          : kImageSizeLimit;
79
80
0
  const avifAppFileFormat file_format = avifReadImage(
81
0
      file_path.c_str(), AVIF_APP_FILE_FORMAT_UNKNOWN /* guess format */,
82
0
      requested_format, requested_depth, chroma_downsampling,
83
0
      ignore_color_profile, ignore_exif, ignore_xmp, /*ignoreAlpha=*/false,
84
0
      ignore_gain_map, imageSizeLimit, avif_image.get(), &out_depth, &timing,
85
0
      /*frameIter=*/nullptr);
86
87
0
  if (file_format != AVIF_APP_FILE_FORMAT_UNKNOWN) {
88
0
    EXPECT_GT(avif_image->width, 0);
89
0
    EXPECT_GT(avif_image->height, 0);
90
91
0
    if (requested_depth != 0 && file_format != AVIF_APP_FILE_FORMAT_Y4M) {
92
0
      EXPECT_EQ(avif_image->depth, requested_depth);
93
0
    }
94
0
    if (file_format != AVIF_APP_FILE_FORMAT_Y4M) {
95
0
      EXPECT_EQ(avif_image->yuvFormat, requested_format);
96
0
    }
97
0
    if (ignore_color_profile) {
98
0
      EXPECT_EQ(avif_image->icc.size, 0);
99
0
    }
100
0
    if (ignore_exif) {
101
0
      EXPECT_EQ(avif_image->exif.size, 0);
102
0
    }
103
0
    if (ignore_xmp) {
104
0
      EXPECT_EQ(avif_image->xmp.size, 0);
105
0
    }
106
0
    std::cout << "Decode successful (" << FileFormatToString(file_format)
107
0
              << ")\n";
108
0
  }
109
0
}
110
111
FUZZ_TEST(ReadImageFuzzTest, ReadImageFile)
112
    .WithDomains(ArbitraryImageWithSeeds({AVIF_APP_FILE_FORMAT_JPEG,
113
                                          AVIF_APP_FILE_FORMAT_PNG,
114
                                          AVIF_APP_FILE_FORMAT_Y4M}),
115
                 ArbitraryPixelFormat(),
116
                 /*requested_depth=*/ElementOf({0, 8, 10, 12}),
117
                 ElementOf({AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC,
118
                            AVIF_CHROMA_DOWNSAMPLING_FASTEST,
119
                            AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY,
120
                            AVIF_CHROMA_DOWNSAMPLING_AVERAGE,
121
                            AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV}),
122
                 /*ignore_color_profile=*/Arbitrary<bool>(),
123
                 /*ignore_exif=*/Arbitrary<bool>(),
124
                 /*ignore_xmp=*/Arbitrary<bool>(),
125
                 /*ignore_gain_map=*/Arbitrary<bool>(),
126
                 ElementOf({AVIF_MATRIX_COEFFICIENTS_IDENTITY,
127
                            AVIF_MATRIX_COEFFICIENTS_BT709,
128
                            AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED,
129
                            AVIF_MATRIX_COEFFICIENTS_FCC,
130
                            AVIF_MATRIX_COEFFICIENTS_BT470BG,
131
                            AVIF_MATRIX_COEFFICIENTS_BT601,
132
                            AVIF_MATRIX_COEFFICIENTS_SMPTE240,
133
                            AVIF_MATRIX_COEFFICIENTS_YCGCO,
134
                            AVIF_MATRIX_COEFFICIENTS_BT2020_NCL,
135
                            AVIF_MATRIX_COEFFICIENTS_BT2020_CL,
136
                            AVIF_MATRIX_COEFFICIENTS_SMPTE2085,
137
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL,
138
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL,
139
                            AVIF_MATRIX_COEFFICIENTS_ICTCP}));
140
141
//------------------------------------------------------------------------------
142
143
}  // namespace
144
}  // namespace testutil
145
}  // namespace avif