1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#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
|