Coverage Report

Created: 2026-06-13 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/tests/gtest/avif_fuzztest_enc_dec.cc
Line
Count
Source
1
// Copyright 2022 Google LLC
2
// SPDX-License-Identifier: BSD-2-Clause
3
4
#include <array>
5
#include <cstdint>
6
#include <cstring>
7
#include <memory>
8
#include <vector>
9
10
#include "avif/avif.h"
11
#include "avif_fuzztest_helpers.h"
12
#include "aviftest_helpers.h"
13
#include "fuzztest/fuzztest.h"
14
#include "gtest/gtest.h"
15
16
namespace avif {
17
namespace testutil {
18
namespace {
19
20
void CheckGainMapMetadataMatches(const avifGainMap& actual,
21
1.50k
                                 const avifGainMap& expected) {
22
1.50k
  EXPECT_EQ(actual.baseHdrHeadroom.n, expected.baseHdrHeadroom.n);
23
1.50k
  EXPECT_EQ(actual.baseHdrHeadroom.d, expected.baseHdrHeadroom.d);
24
1.50k
  EXPECT_EQ(actual.alternateHdrHeadroom.n, expected.alternateHdrHeadroom.n);
25
1.50k
  EXPECT_EQ(actual.alternateHdrHeadroom.d, expected.alternateHdrHeadroom.d);
26
6.00k
  for (int c = 0; c < 3; ++c) {
27
4.50k
    SCOPED_TRACE(c);
28
4.50k
    EXPECT_EQ(actual.baseOffset[c].n, expected.baseOffset[c].n);
29
4.50k
    EXPECT_EQ(actual.baseOffset[c].d, expected.baseOffset[c].d);
30
4.50k
    EXPECT_EQ(actual.alternateOffset[c].n, expected.alternateOffset[c].n);
31
4.50k
    EXPECT_EQ(actual.alternateOffset[c].d, expected.alternateOffset[c].d);
32
4.50k
    EXPECT_EQ(actual.gainMapGamma[c].n, expected.gainMapGamma[c].n);
33
4.50k
    EXPECT_EQ(actual.gainMapGamma[c].d, expected.gainMapGamma[c].d);
34
4.50k
    EXPECT_EQ(actual.gainMapMin[c].n, expected.gainMapMin[c].n);
35
4.50k
    EXPECT_EQ(actual.gainMapMin[c].d, expected.gainMapMin[c].d);
36
4.50k
    EXPECT_EQ(actual.gainMapMax[c].n, expected.gainMapMax[c].n);
37
4.50k
    EXPECT_EQ(actual.gainMapMax[c].d, expected.gainMapMax[c].d);
38
4.50k
  }
39
1.50k
}
40
41
13.6k
void EncodeDecodeValid(ImagePtr image, EncoderPtr encoder, DecoderPtr decoder) {
42
13.6k
  ImagePtr decoded_image(avifImageCreateEmpty());
43
13.6k
  ASSERT_NE(image.get(), nullptr);
44
13.6k
  ASSERT_NE(encoder.get(), nullptr);
45
13.6k
  ASSERT_NE(decoder.get(), nullptr);
46
13.6k
  ASSERT_NE(decoded_image.get(), nullptr);
47
48
13.6k
  AvifRwData encoded_data;
49
13.6k
  const avifResult encoder_result =
50
13.6k
      avifEncoderWrite(encoder.get(), image.get(), &encoded_data);
51
27.3k
  ASSERT_EQ(encoder_result, AVIF_RESULT_OK)
52
27.3k
      << avifResultToString(encoder_result) << ": " << encoder->diag.error;
53
54
13.6k
  const avifResult decoder_result = avifDecoderReadMemory(
55
13.6k
      decoder.get(), decoded_image.get(), encoded_data.data, encoded_data.size);
56
27.3k
  ASSERT_EQ(decoder_result, AVIF_RESULT_OK)
57
27.3k
      << avifResultToString(decoder_result) << ": " << decoder->diag.error;
58
59
13.6k
  EXPECT_EQ(decoded_image->width, image->width);
60
13.6k
  EXPECT_EQ(decoded_image->height, image->height);
61
13.6k
  EXPECT_EQ(decoded_image->depth, image->depth);
62
13.6k
  EXPECT_EQ(decoded_image->yuvFormat, image->yuvFormat);
63
64
13.6k
  EXPECT_EQ(decoded_image->gainMap != nullptr, image->gainMap != nullptr);
65
13.6k
  if (decoded_image->gainMap != nullptr &&
66
2.17k
      (decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_GAIN_MAP)) {
67
1.50k
    ASSERT_NE(decoded_image->gainMap->image, nullptr);
68
1.50k
    EXPECT_EQ(decoded_image->gainMap->image->width,
69
1.50k
              image->gainMap->image->width);
70
1.50k
    EXPECT_EQ(decoded_image->gainMap->image->height,
71
1.50k
              image->gainMap->image->height);
72
1.50k
    EXPECT_EQ(decoded_image->gainMap->image->depth,
73
1.50k
              image->gainMap->image->depth);
74
1.50k
    EXPECT_EQ(decoded_image->gainMap->image->yuvFormat,
75
1.50k
              image->gainMap->image->yuvFormat);
76
1.50k
    EXPECT_EQ(image->gainMap->image->gainMap, nullptr);
77
1.50k
    EXPECT_EQ(decoded_image->gainMap->image->alphaPlane, nullptr);
78
79
1.50k
    CheckGainMapMetadataMatches(*decoded_image->gainMap, *image->gainMap);
80
1.50k
  }
81
82
  // Verify that an opaque input leads to an opaque output.
83
13.6k
  if (avifImageIsOpaque(image.get())) {
84
9.47k
    EXPECT_TRUE(avifImageIsOpaque(decoded_image.get()));
85
9.47k
  }
86
  // A transparent image may be heavily compressed to an opaque image. This is
87
  // hard to verify so do not check it.
88
13.6k
}
89
90
FUZZ_TEST(EncodeDecodeAvifFuzzTest, EncodeDecodeValid)
91
    .WithDomains(fuzztest::OneOf(ArbitraryAvifImage(),
92
                                 ArbitraryAvifImageWithGainMap()),
93
                 ArbitraryAvifEncoder(), ArbitraryAvifDecoder());
94
95
}  // namespace
96
}  // namespace testutil
97
}  // namespace avif