Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ The changes are relative to the previous release, unless the baseline is specifi
a cICP chunk and other color information chunks, such as iCCP (ICC profile),
the other chunks are ignored as per the PNG Specification Third Edition
Section 4.3.
* Support reading Sample-Transform-based 16-bit AVIF files when
avifDecoder::imageContentToDecode & AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS is
not zero.
* Support Sample Transform derived image items with grid input image items.
* Add --sato flag to avifdec to enable Sample Transforms support at decoding.
* Add --grid option to avifgainmaputil.

### Changed since 1.3.0

* Set avifDecoder::image->depth to the same value after avifDecoderParse() as
after avifDecoderNextImage() when AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM is
enabled and when the file to decode contains a 'sato' derived image item.
after avifDecoderNextImage() when the file to decode contains a 'sato' derived
image item.
* avifdec only enables Sample Transform decoding when --depth is set to 16.
* Update dav1d.cmd/dav1d_android.sh/LocalDav1d.cmake: 1.5.3
* Update googletest.cmd/LocalGTest.cmake: v1.17.0
* Update libjpeg.cmd/LocalJpeg.cmake: 3.1.3
Expand Down
8 changes: 7 additions & 1 deletion apps/avifdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static void syntax(void)
printf(" -j,--jobs J : Number of jobs (worker threads), or 'all' to potentially use as many cores as possible. (Default: all)\n");
printf(" -c,--codec C : Codec to use (choose from versions list below)\n");
printf(" -d,--depth D : Output depth, either 8 or 16. (PNG only; For y4m, depth is retained, and JPEG is always 8bpc)\n");
printf(" --sato : Enable Sample Transforms decoding (e.g. 16-bit AVIF)\n");
printf(" -q,--quality Q : Output quality in 0..100. (JPEG only, default: %d)\n", DEFAULT_JPEG_QUALITY);
printf(" --png-compress L : PNG compression level in 0..9 (PNG only; 0=none, 9=max). Defaults to libpng's builtin default\n");
printf(" -u,--upsampling U : Chroma upsampling (for 420/422). One of 'automatic' (default), 'fastest', 'best', 'nearest', or 'bilinear'\n");
Expand Down Expand Up @@ -88,6 +89,7 @@ int main(int argc, char * argv[])
const char * inputFilename = NULL;
const char * outputFilename = NULL;
int requestedDepth = 0;
avifBool enableSampleTransforms = AVIF_FALSE;
int jobs = -1;
int jpegQuality = DEFAULT_JPEG_QUALITY;
int pngCompressionLevel = -1; // -1 is a sentinel to avifPNGWrite() to skip calling png_set_compression_level()
Expand Down Expand Up @@ -168,6 +170,8 @@ int main(int argc, char * argv[])
fprintf(stderr, "ERROR: invalid depth: %s\n", arg);
return 1;
}
} else if (!strcmp(arg, "--sato")) {
enableSampleTransforms = AVIF_TRUE;
} else if (!strcmp(arg, "-q") || !strcmp(arg, "--quality")) {
NEXTARG();
jpegQuality = atoi(arg);
Expand Down Expand Up @@ -312,7 +316,9 @@ int main(int argc, char * argv[])
decoder->strictFlags = strictFlags;
decoder->allowProgressive = allowProgressive;
if (infoOnly) {
decoder->imageContentToDecode = AVIF_IMAGE_CONTENT_ALL;
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP | AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
} else if (enableSampleTransforms) {
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
}

avifResult result = avifDecoderSetIOFile(decoder, inputFilename);
Expand Down
5 changes: 5 additions & 0 deletions include/avif/avif.h
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,11 @@ typedef enum avifImageContentTypeFlag
AVIF_IMAGE_CONTENT_GAIN_MAP = (1 << 2),
AVIF_IMAGE_CONTENT_ALL = AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP,

// Mostly used for bit depth extensions to go beyond the underlying codec capability
// (e.g. 16-bit AVIF). Not part of AVIF_IMAGE_CONTENT_ALL as this is a rare use case.
// Has no effect without AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA.
AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS = (1 << 3),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two comments on this.

  1. It may be better to control this with a new boolean field in the avifDecoder struct. Since sample transforms also produce color and alpha, sample transforms are not a new content type.
  2. It may be better to restrict this control to bit depth extensions only rather than all sample transforms, if we can determine the output bit depth without applying the sample transforms. (Maryla also said this in her review comment.) I think we can get the bit depth from the 'pixi' box of the 'sato' derived image item, right?

In summary, please consider exposing this control as a new avifBool enableExtendedBitDepths field in the avifDecoder struct

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review.

  1. I disagree. Gain maps complement the primary color image but adding color information. Bit depth extensions, and thus Sample Transforms, also extend the color information in a similar way. The dimension is just bit depth instead of brightness, if I may say so.
    Also avifImageContentTypeFlags is a bit mask rather than an enum, meaning the different avifImageContentTypeFlag values are more orthogonal concepts that can each be toggled on or off than distinct types.
    Each avifImageContentTypeFlag maps to a separate image item in AVIFv1 (primary color item, aux alpha, derived gain map, derived sample transform).
  2. As of today, libavif applies any Sample Transform formula with at most 2 input items. Also, there could be plenty of different formulas for extending the bit depth, not only the few that are available at encoding right now. I do not think it is easy to precisely detect whether the decoded formula is a bit depth extension, and only that.
    Maryla's comment "Tying sample transforms decoding to bit depth" was specifically about avifdec's --depth flag. I am not sure this is what you meant.

Copy link
Copy Markdown
Collaborator

@wantehchang wantehchang Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am commenting on the change to the public header include/avif/avif.h.

If a 'sato' derived image item has one 8-bit AV1 image item and adds the constant 0 to the input image item, the 'sato' derived image item should have a 'pixi' box that indicates bit depth 8. Current clients of libavif can handle this output image. This is why we only need to disable by default the 'sato' derived image items whose 'pixi' box indicates a bit depth other than 8, 10, 12.

Since the outut image is still represented with the avifImage struct, it seems that the only field in avifImage that may catch existing clients by surprise is the depth field. Are there other kinds of 'sato' derived image items that produce an output avifImage that current clients of libavif cannot handle?

Copy link
Copy Markdown
Contributor Author

@y-guyon y-guyon Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current clients of libavif can handle this output image.

Yes. The question is: should it still be applied?
With this specific example (noop 0 addition), it is obviously better NOT to enable Sample Transforms, as it would just make decoding slower for the same result.

Are there other kinds of 'sato' derived image items that produce an output avifImage that current clients of libavif cannot handle?

I do not think so. But it does not mean it is beneficial to do so.
libavif only supports Sample Transform derived image items that are NOT the primary item, and in the same altr group as the primary item. So there is always an alternative, and the primary item should be the default output of libavif in my opinion.
Advanced users can enable Sample Transform decoding to extract more information when needed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the only concern was breaking the clients unprepared to handle new bit depths. I did not realize the cost incurred by applying sample transforms was also a concern.

We need to provide guidance on whether libavif clients should enable sample transforms. Besides the two concerns mentioned above, are there other concerns?

I think we should constrain the new bit depths that libavif supports and document what they are. My code analysis shows that libavif malfunctions if decoder->data->meta->sampleTransformDepth > 16, so we need to at least disallow bit depths > 16.


Note: You can ignore the rest of this comment.

Re: AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS vs. enableSampleTransforms: In your interpretation of avifImageContentTypeFlags based on the image item type, AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS makes sense. I have a different interpretation of avifImageContentTypeFlags based on the output destination:

  • AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA: the output goes to decoder->image
  • AVIF_IMAGE_CONTENT_GAIN_MAP: the output goes to decoder->image->gainMap->image

When sample transforms are enabled, the output still goes to decoder->image. Therefore sample transforms, unlike gain maps, do not behave like a new image content type.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more thing: avifDecoderSampleTransformItemValidateProperties() performs the following check:

    for (uint8_t i = 0; i < pixiProp->u.pixi.planeCount; ++i) {
        if (pixiProp->u.pixi.planeDepths[i] != pixiProp->u.pixi.planeDepths[0]) {
            avifDiagnosticsPrintf(diag,
                                  "Item ID %u of type '%.4s' has different depths specified by pixi property [%u, %u], this is not supported",
                                  item->id,
                                  (const char *)item->type,
                                  pixiProp->u.pixi.planeDepths[0],
                                  pixiProp->u.pixi.planeDepths[i]);
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }
    }

This check is redundant because avifParsePixelInformationProperty() already performs the same check.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote:

Possible solution: We can change avifDecoderSampleTransformItemValidateProperties() to disallow pixiProp->u.pixi.planeDepths[0] > 16.

Your PR #3038 disallows bit depths > 16 in avifParsePixelInformationProperty(). That is stricter and also works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is redundant because avifParsePixelInformationProperty() already performs the same check.

Done in #3040

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bypasses the bit depth check in avifImageCreate() that you mentioned.

Not really, because it goes through:

libavif/src/read.c

Lines 6846 to 6855 in 0812f44

static avifResult avifDecoderApplySampleTransform(const avifDecoder * decoder, avifImage * dstImage)
{
if (dstImage->depth != decoder->data->meta->sampleTransformDepth) {
AVIF_ASSERT_OR_RETURN(dstImage->yuvPlanes[0] != NULL);
AVIF_ASSERT_OR_RETURN(dstImage->imageOwnsYUVPlanes);
// Use a temporary buffer because dstImage may point to decoder->image, which could be an input image.
avifImage * dstImageWithCorrectDepth =
avifImageCreate(dstImage->width, dstImage->height, decoder->data->meta->sampleTransformDepth, dstImage->yuvFormat);
AVIF_CHECKERR(dstImageWithCorrectDepth != NULL, AVIF_RESULT_OUT_OF_MEMORY);

dstImage->depth is likely 8 or 12 because it contains the primary coded image item. decoder->data->meta->sampleTransformDepth is 16 (or higher). So the condition is true, and avifImageCreate() is called with sampleTransformDepth bits. For sampleTransformDepth>16, avifImageCreate() returns null and avifDecoderApplySampleTransform() returns the wrong AVIF_RESULT_OUT_OF_MEMORY error code.

If I understand correctly, the only way to bypass this would be for the user to explicitly set avifDecoder::image::depth to exactly sampleTransformDepth after parsing/decoding the primary item but before avifDecoderApplySampleTransform() is called.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your PR #3038 disallows bit depths > 16 in avifParsePixelInformationProperty(). That is stricter and also works.

I consider this thread resolved.


AVIF_IMAGE_CONTENT_DECODE_DEFAULT = AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
} avifImageContentTypeFlag;
typedef uint32_t avifImageContentTypeFlags;
Expand Down
12 changes: 7 additions & 5 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -6242,7 +6242,8 @@ avifResult avifDecoderReset(avifDecoder * decoder)

// AVIF_ITEM_SAMPLE_TRANSFORM (not used through mainItems because not a coded item (well grids are not coded items either but it's different)).
avifDecoderItem * const sampleTransformItem = avifDecoderDataFindSampleTransformImageItem(data);
if (sampleTransformItem != NULL) {
if ((decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) &&
(decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS) && sampleTransformItem != NULL) {
AVIF_ASSERT_OR_RETURN(data->sampleTransformNumInputImageItems == 0);

for (uint32_t i = 0; i < data->meta->items.count; ++i) {
Expand Down Expand Up @@ -6367,12 +6368,14 @@ avifResult avifDecoderReset(avifDecoder * decoder)

AVIF_CHECKRES(avifDecoderAdoptGridTileCodecTypeIfNeeded(decoder, mainItems[c], &data->tileInfos[c]));

if (c == AVIF_ITEM_COLOR || c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR ||
c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_1_COLOR || c == AVIF_ITEM_ALPHA ||
c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_ALPHA || c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_1_ALPHA) {
if (c == AVIF_ITEM_COLOR || c == AVIF_ITEM_ALPHA) {
if (!(decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA)) {
continue;
}
} else if (c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR || c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_1_COLOR ||
c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_ALPHA || c == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_1_ALPHA) {
AVIF_ASSERT_OR_RETURN((decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) &&
(decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS));
} else {
AVIF_ASSERT_OR_RETURN(c == AVIF_ITEM_GAIN_MAP);
if (!(decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_GAIN_MAP)) {
Expand Down Expand Up @@ -6942,7 +6945,6 @@ avifResult avifDecoderNextImage(avifDecoder * decoder)
// decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA was equal to 0.
// Only apply Sample Transforms if there is a color item to apply it onto.
if (decoder->data->tileInfos[AVIF_ITEM_COLOR].tileCount != 0 && decoder->data->meta->sampleTransformExpression.count > 0) {
// TODO(yguyon): Add a field in avifDecoder and only perform sample transformations upon request.
AVIF_CHECKRES(avifDecoderApplySampleTransform(decoder, decoder->image));
}

Expand Down
25 changes: 20 additions & 5 deletions tests/gtest/avif16bittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,15 @@ TEST_P(SampleTransformTest, Avif16bit) {
}
ASSERT_EQ(avifEncoderFinish(encoder.get(), &encoded), AVIF_RESULT_OK);

const ImagePtr decoded = testutil::Decode(encoded.data, encoded.size);
ImagePtr decoded(avifImageCreateEmpty());
ASSERT_NE(decoded, nullptr);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
decoder->imageContentToDecode =
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
encoded.size),
AVIF_RESULT_OK);

ASSERT_EQ(image->depth, decoded->depth);
ASSERT_EQ(image->width, decoded->width);
Expand All @@ -100,8 +107,14 @@ TEST_P(SampleTransformTest, Avif16bit) {
std::memcpy(&encoded.data[i], "zzzz", 4);
}
}
const ImagePtr decoded_no_sato = testutil::Decode(encoded.data, encoded.size);
ImagePtr decoded_no_sato(avifImageCreateEmpty());
ASSERT_NE(decoded_no_sato, nullptr);
DecoderPtr decoder_no_sato(avifDecoderCreate());
ASSERT_NE(decoder_no_sato, nullptr);
decoder_no_sato->imageContentToDecode = decoder->imageContentToDecode;
ASSERT_EQ(avifDecoderReadMemory(decoder_no_sato.get(), decoded_no_sato.get(),
encoded.data, encoded.size),
AVIF_RESULT_OK);
// Only the most significant bits of each sample can be retrieved.
// They should be encoded losslessly no matter the quantizer settings.
ImagePtr image_no_sato = testutil::CreateImage(
Expand Down Expand Up @@ -297,12 +310,13 @@ TEST_P(GainmapSampleTransformTest, ImageContentToDecode) {
ASSERT_NE(decoded, nullptr);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
decoder->imageContentToDecode = content_to_decode;
decoder->imageContentToDecode =
content_to_decode | AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
ASSERT_EQ(avifDecoderReadMemory(decoder.get(), decoded.get(), encoded.data,
encoded.size),
content_to_decode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA ||
(content_to_decode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) ||
(create_gainmap &&
content_to_decode & AVIF_IMAGE_CONTENT_GAIN_MAP)
(content_to_decode & AVIF_IMAGE_CONTENT_GAIN_MAP))
? AVIF_RESULT_OK
: AVIF_RESULT_NO_CONTENT);

Expand Down Expand Up @@ -331,6 +345,7 @@ INSTANTIATE_TEST_SUITE_P(
// Gain maps are not supported in the same file as 'sato' items.
/*create_gainmap=*/testing::Values(false),
/*use_grid=*/testing::Values(true),
// AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS is always set in this test.
testing::Values(AVIF_IMAGE_CONTENT_NONE,
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
AVIF_IMAGE_CONTENT_GAIN_MAP, AVIF_IMAGE_CONTENT_ALL)));
Expand Down
3 changes: 2 additions & 1 deletion tests/gtest/avif_fuzztest_dec_incr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ FUZZ_TEST(DecodeAvifFuzzTest, DecodeIncr)
/*give_size_hint=*/Arbitrary<bool>(),
fuzztest::BitFlagCombinationOf<avifImageContentTypeFlags>(
{AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
AVIF_IMAGE_CONTENT_GAIN_MAP}),
AVIF_IMAGE_CONTENT_GAIN_MAP,
AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS}),
/*use_nth_image_api=*/Arbitrary<bool>());

//------------------------------------------------------------------------------
Expand Down
6 changes: 5 additions & 1 deletion tests/gtest/avif_fuzztest_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,11 @@ inline auto ArbitraryAvifDecoderWithGainMapOptions() {
AddGainMapOptionsToDecoder, ArbitraryBaseAvifDecoder(),
fuzztest::ElementOf<avifImageContentTypeFlags>(
{AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA,
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP}));
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP,
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA |
AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS,
AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA | AVIF_IMAGE_CONTENT_GAIN_MAP |
AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS}));
}

// Generator for an arbitrary DecoderPtr.
Expand Down
16 changes: 16 additions & 0 deletions tests/gtest/avifaltrtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ TEST(AltrTest, SampleTransformDepthEqualToInput) {

DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
ASSERT_EQ(avifDecoderSetIOMemory(decoder.get(), encoded.data, encoded.size),
AVIF_RESULT_OK);
ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK);
Expand All @@ -59,6 +60,7 @@ TEST(AltrTest, SampleTransformDepthParseNextEqual) {

DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
ASSERT_EQ(avifDecoderSetIOMemory(decoder.get(), encoded.data, encoded.size),
AVIF_RESULT_OK);

Expand All @@ -84,6 +86,20 @@ TEST(AltrTest, ZeroImageContentToDecode) {
AVIF_RESULT_NO_CONTENT);
}

TEST(AltrTest, OnlySampleTranformContentToDecode) {
const std::string file_path =
std::string(data_path) + "weld_sato_12B_8B_q0.avif";

DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
// Has no effect without AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA.
decoder->imageContentToDecode = AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
ImagePtr image(avifImageCreateEmpty());
ASSERT_NE(image, nullptr);
ASSERT_EQ(avifDecoderReadFile(decoder.get(), image.get(), file_path.c_str()),
AVIF_RESULT_NO_CONTENT);
}

//------------------------------------------------------------------------------

} // namespace
Expand Down
35 changes: 22 additions & 13 deletions tests/gtest/avifdecodetest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,28 @@ TEST(AvifDecodeTest, ImageContentToDecodeNone) {
for (const std::string file_name :
{"paris_icc_exif_xmp.avif", "draw_points_idat.avif",
"sofa_grid1x5_420.avif", "color_grid_alpha_nogrid.avif",
"seine_sdr_gainmap_srgb.avif", "draw_points_idat_progressive.avif"}) {
SCOPED_TRACE(file_name);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
// Do not decode anything.
decoder->imageContentToDecode = AVIF_IMAGE_CONTENT_NONE;
ASSERT_EQ(avifDecoderSetIOFile(
decoder.get(), (std::string(data_path) + file_name).c_str()),
AVIF_RESULT_OK);
ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK)
<< decoder->diag.error;
EXPECT_EQ(decoder->imageSequenceTrackPresent, AVIF_FALSE);
EXPECT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_NO_CONTENT);
"seine_sdr_gainmap_srgb.avif", "draw_points_idat_progressive.avif",
"weld_sato_12B_8B_q0.avif"}) {
for (
avifImageContentTypeFlag image_content_to_decode : {
AVIF_IMAGE_CONTENT_NONE,
AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS // Equivalent to NONE without
// AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA.
}) {
SCOPED_TRACE(file_name);
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
// Do not decode anything.
decoder->imageContentToDecode = image_content_to_decode;
ASSERT_EQ(
avifDecoderSetIOFile(decoder.get(),
(std::string(data_path) + file_name).c_str()),
AVIF_RESULT_OK);
ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK)
<< decoder->diag.error;
EXPECT_EQ(decoder->imageSequenceTrackPresent, AVIF_FALSE);
EXPECT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_NO_CONTENT);
}
}
}

Expand Down
Loading