Coverage Report

Created: 2025-08-03 06:57

/src/libavif/tests/gtest/avif_fuzztest_read_image.cc
Line
Count
Source (jump to first uncovered line)
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
2.13k
std::string FileFormatToString(avifAppFileFormat file_format) {
28
2.13k
  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
33
    case AVIF_APP_FILE_FORMAT_PNG:
34
33
      return "PNG";
35
2.09k
    case AVIF_APP_FILE_FORMAT_JPEG:
36
2.09k
      return "JPEG";
37
7
    case AVIF_APP_FILE_FORMAT_Y4M:
38
7
      return "Y4M";
39
0
    default:
40
0
      assert(false);
41
0
      return "unknown";
42
2.13k
  }
43
2.13k
}
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 allow_changing_cicp, bool ignore_gain_map,
50
8.00k
                   avifMatrixCoefficients matrix_coefficients) {
51
8.00k
  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
8.00k
  const std::string file_path = testing::TempDir() + "inputimage";
56
8.00k
  std::ofstream out(file_path);
57
8.00k
  out << arbitrary_bytes;
58
8.00k
  out.close();
59
60
8.00k
  uint32_t out_depth;
61
8.00k
  avifAppSourceTiming timing;
62
8.00k
  ImagePtr avif_image(avifImageCreateEmpty());
63
8.00k
  avif_image->matrixCoefficients = matrix_coefficients;
64
65
  // OSS-Fuzz limits the allocated memory to 2560 MB.
66
8.00k
  constexpr uint32_t kMaxMem = 2560u * 1024 * 1024;
67
  // Consider at most four planes of 16-bit samples.
68
8.00k
  constexpr uint32_t kMaxImageSize =
69
8.00k
      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
8.00k
  constexpr uint32_t kImageSizeLimit = kMaxImageSize / 4;
73
  // SharpYUV is computationally expensive. Avoid timeouts.
74
8.00k
  const uint32_t imageSizeLimit =
75
8.00k
      (chroma_downsampling == AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV &&
76
8.00k
       requested_format == AVIF_PIXEL_FORMAT_YUV420)
77
8.00k
          ? kImageSizeLimit / 8
78
8.00k
          : kImageSizeLimit;
79
80
8.00k
  const avifAppFileFormat file_format = avifReadImage(
81
8.00k
      file_path.c_str(), AVIF_APP_FILE_FORMAT_UNKNOWN /* guess format */,
82
8.00k
      requested_format, requested_depth, chroma_downsampling,
83
8.00k
      ignore_color_profile, ignore_exif, ignore_xmp, allow_changing_cicp,
84
8.00k
      ignore_gain_map, imageSizeLimit, avif_image.get(), &out_depth, &timing,
85
8.00k
      /*frameIter=*/nullptr);
86
87
8.00k
  if (file_format != AVIF_APP_FILE_FORMAT_UNKNOWN) {
88
2.13k
    EXPECT_GT(avif_image->width, 0);
89
2.13k
    EXPECT_GT(avif_image->height, 0);
90
91
2.13k
    if (requested_depth != 0 && file_format != AVIF_APP_FILE_FORMAT_Y4M) {
92
1.54k
      EXPECT_EQ(avif_image->depth, requested_depth);
93
1.54k
    }
94
2.13k
    if (file_format != AVIF_APP_FILE_FORMAT_Y4M) {
95
2.13k
      EXPECT_EQ(avif_image->yuvFormat, requested_format);
96
2.13k
    }
97
2.13k
    if (ignore_color_profile) {
98
1.06k
      EXPECT_EQ(avif_image->icc.size, 0);
99
1.06k
    }
100
2.13k
    if (ignore_exif) {
101
1.05k
      EXPECT_EQ(avif_image->exif.size, 0);
102
1.05k
    }
103
2.13k
    if (ignore_xmp) {
104
1.03k
      EXPECT_EQ(avif_image->xmp.size, 0);
105
1.03k
    }
106
2.13k
    std::cout << "Decode successful (" << FileFormatToString(file_format)
107
2.13k
              << ")\n";
108
2.13k
  }
109
8.00k
}
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
                 /*allow_changing_cicp=*/Arbitrary<bool>(),
126
                 /*ignore_gain_map=*/Arbitrary<bool>(),
127
                 ElementOf({AVIF_MATRIX_COEFFICIENTS_IDENTITY,
128
                            AVIF_MATRIX_COEFFICIENTS_BT709,
129
                            AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED,
130
                            AVIF_MATRIX_COEFFICIENTS_FCC,
131
                            AVIF_MATRIX_COEFFICIENTS_BT470BG,
132
                            AVIF_MATRIX_COEFFICIENTS_BT601,
133
                            AVIF_MATRIX_COEFFICIENTS_SMPTE240,
134
                            AVIF_MATRIX_COEFFICIENTS_YCGCO,
135
                            AVIF_MATRIX_COEFFICIENTS_BT2020_NCL,
136
                            AVIF_MATRIX_COEFFICIENTS_BT2020_CL,
137
                            AVIF_MATRIX_COEFFICIENTS_SMPTE2085,
138
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL,
139
                            AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL,
140
                            AVIF_MATRIX_COEFFICIENTS_ICTCP}));
141
142
//------------------------------------------------------------------------------
143
144
}  // namespace
145
}  // namespace testutil
146
}  // namespace avif