AOMediaCodec / libavif

libavif - Library for encoding and decoding .avif files
Other
1.44k stars 187 forks source link

Fail to save large AVIF image #960

Open lishengkang opened 2 years ago

lishengkang commented 2 years ago

The raw TIFF image is 39717 x 49716 in RGB mode,I am trying to convert this TIFF image to AVIF format. Unfortunately, I got a RuntimeError. It appears that libavif has a limit of 16384x16384 (228 pixels), I would not be able to encode the image as AVIF. What can i do to convert this TIFF image to AVIF format?

y-guyon commented 2 years ago

Thanks for your report. Could you share a few details for the record (source image, command line or code snippet used, version of the library, use case)?

I did not try them but here are a few leads:

wantehchang commented 2 years ago

@lishengkang Hi,

The avifDecoder struct has an imageSizeLimit that is intended for configuring the image size limit at run time:

    // This represents the maximum size of a image (in pixel count) that libavif and the underlying
    // AV1 decoder should attempt to decode. It defaults to AVIF_DEFAULT_IMAGE_SIZE_LIMIT, and can be
    // set to a smaller value. The value 0 is reserved.
    // Note: Only some underlying AV1 codecs support a configurable size limit (such as dav1d).
    uint32_t imageSizeLimit;

But setting it to a value greater than AVIF_DEFAULT_IMAGE_SIZE_LIMIT is currently disallowed by the following check in libavif/src/read.c:

    // An imageSizeLimit greater than AVIF_DEFAULT_IMAGE_SIZE_LIMIT and the special value of 0 to
    // disable the limit are not yet implemented.
    if ((decoder->imageSizeLimit > AVIF_DEFAULT_IMAGE_SIZE_LIMIT) || (decoder->imageSizeLimit == 0)) {
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

There is no fundamental reason for this restriction. The reason for this restriction is simply that we have not audited our code to verify it is free of integer overflow bugs caused by a large image size. (We audit code that uses image width and height and buffer row bytes whenever we can, but I don't think we finished a systematic audit of all code.)

You can try removing the above check and building libavif in 64-bit mode (so that size_t is 64 bits). Please let us know if it works for you.

Note: You can also try Yannis's first suggestion, with one modification -- increase AVIF_DEFAULT_IMAGE_SIZE_LIMIT to UINT32_MAX instead of 65536 65536. (65536 65536 does not fit in uint32_t.)

jzern commented 2 years ago

Another option would be to encode the image as a grid (--grid in avifenc), though that may require that your image can be evenly split.