File: avif.c

package info (click to toggle)
links2 2.29-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 27,852 kB
  • sloc: ansic: 181,859; sh: 2,585; cpp: 1,450; makefile: 84; awk: 49; perl: 34
file content (105 lines) | stat: -rw-r--r-- 2,422 bytes parent folder | download
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