aboutsummaryrefslogtreecommitdiffstats
path: root/liblss16_encoder_init.c
blob: d94d4fac8818b4ed03d80774d8f3c185a3f00c98 (plain) (blame)
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
/* See LICENSE file for copyright and license details. */
#include "liblss16.h"
#include <string.h>

#if defined(__clang__)
# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif


int
liblss16_encoder_init(struct liblss16_encoder *encoder, const struct liblss16_header *header,
		      int rgb6, enum liblss16_encode_error *error_out)
{
	int i;

	memset(encoder, 0, sizeof(*encoder));
	memcpy(&encoder->header, header, sizeof(*header));

	if (!encoder->header.width || !encoder->header.height || encoder->header.height >> 15) {
		if (error_out)
			*error_out = LIBLSS16_ENCODE_BAD_IMAGE_SIZE;
		return -1;
	}

	if (rgb6) {
		uint8_t or = 0;
		for (i = 0; i < 16; i++) {
			or |= encoder->header.colour_map[i].r;
			or |= encoder->header.colour_map[i].g;
			or |= encoder->header.colour_map[i].b;
		}
		if (or & 0xC0) {
			if (error_out)
				*error_out = LIBLSS16_ENCODE_BAD_COLOUR;
			return -1;
		}
	} else {
		struct liblss16_colour *map = encoder->header.colour_map;
		for (i = 0; i < 16; i++) {
			map[i].r = (uint8_t)(((unsigned)map[i].r * 63U + 127U) / 255U);
			map[i].g = (uint8_t)(((unsigned)map[i].g * 63U + 127U) / 255U);
			map[i].b = (uint8_t)(((unsigned)map[i].b * 63U + 127U) / 255U);
		}
	}

	encoder->x_rem = encoder->header.width;
	encoder->y_rem = encoder->header.height;

	return 0;
}