105 lines
2.4 KiB
C
105 lines
2.4 KiB
C
#include "cfg.h"
|
|
|
|
#ifdef G
|
|
#include "links.h"
|
|
|
|
#ifdef HAVE_AVIF
|
|
|
|
#include <avif/avif.h>
|
|
|
|
struct avif_decoder {
|
|
unsigned char *buffer;
|
|
int len;
|
|
};
|
|
|
|
void avif_start(struct cached_image *cimg)
|
|
{
|
|
struct avif_decoder *deco;
|
|
deco = mem_alloc(sizeof(struct avif_decoder));
|
|
deco->buffer = init_str();
|
|
deco->len = 0;
|
|
cimg->decoder = deco;
|
|
}
|
|
|
|
void avif_restart(struct cached_image *cimg, unsigned char *data, int length)
|
|
{
|
|
struct avif_decoder *deco = (struct avif_decoder *)cimg->decoder;
|
|
add_bytes_to_str(&deco->buffer, &deco->len, data, length);
|
|
}
|
|
|
|
void avif_finish(struct cached_image *cimg)
|
|
{
|
|
avifRGBImage ari;
|
|
struct avif_decoder *deco;
|
|
avifDecoder *decoder;
|
|
|
|
memset(&ari, 0, sizeof(avifRGBImage));
|
|
|
|
deco = (struct avif_decoder *)cimg->decoder;
|
|
decoder = avifDecoderCreate();
|
|
if (!decoder)
|
|
goto end;
|
|
#if AVIF_VERSION > 90001
|
|
decoder->strictFlags = AVIF_STRICT_DISABLED;
|
|
#endif
|
|
decoder->ignoreExif = 1;
|
|
decoder->ignoreXMP = 1;
|
|
if (avifDecoderSetIOMemory(decoder, deco->buffer, deco->len) != AVIF_RESULT_OK)
|
|
goto destroy_decoder;
|
|
if (avifDecoderParse(decoder) != AVIF_RESULT_OK)
|
|
goto destroy_decoder;
|
|
|
|
cimg->width = decoder->image->width;
|
|
cimg->height = decoder->image->height;
|
|
cimg->buffer_bytes_per_pixel = 4;
|
|
cimg->red_gamma = cimg->green_gamma = cimg->blue_gamma = (float)sRGB_gamma;
|
|
cimg->strip_optimized = 0;
|
|
|
|
if (avifDecoderNextImage(decoder) != AVIF_RESULT_OK)
|
|
goto destroy_decoder;
|
|
|
|
avifRGBImageSetDefaults(&ari, decoder->image);
|
|
ari.depth = 8;
|
|
ari.format = AVIF_RGB_FORMAT_RGBA;
|
|
|
|
if (header_dimensions_known(cimg))
|
|
goto destroy_decoder;
|
|
|
|
ari.pixels = cimg->buffer;
|
|
ari.rowBytes = (unsigned)cimg->width * 4;
|
|
|
|
if (avifImageYUVToRGB(decoder->image, &ari) != AVIF_RESULT_OK)
|
|
goto destroy_decoder;
|
|
|
|
destroy_decoder:
|
|
avifDecoderDestroy(decoder);
|
|
end:
|
|
img_end(cimg);
|
|
}
|
|
|
|
void avif_destroy_decoder(struct cached_image *cimg)
|
|
{
|
|
struct avif_decoder *deco = (struct avif_decoder *)cimg->decoder;
|
|
mem_free(deco->buffer);
|
|
}
|
|
|
|
void add_avif_version(unsigned char **s, int *l)
|
|
{
|
|
add_to_str(s, l, cast_uchar "AVIF (");
|
|
add_num_to_str(s, l, AVIF_VERSION_MAJOR);
|
|
add_chr_to_str(s, l, '.');
|
|
add_num_to_str(s, l, AVIF_VERSION_MINOR);
|
|
add_chr_to_str(s, l, '.');
|
|
add_num_to_str(s, l, AVIF_VERSION_PATCH);
|
|
#ifdef AVIF_VERSION_DEVEL
|
|
if (AVIF_VERSION_DEVEL) {
|
|
add_chr_to_str(s, l, '-');
|
|
add_num_to_str(s, l, AVIF_VERSION_DEVEL);
|
|
}
|
|
#endif
|
|
add_chr_to_str(s, l, ')');
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|