aboutsummaryrefslogtreecommitdiffstats
path: root/srgb-gamma.h
blob: 33884977b92bbf53a67a03759acfa80b1c6e1b22 (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
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* See LICENSE file for copyright and license details. */

static inline long double
gamma_ullf(long double t)
{
	return GAMMA(long double, powl);
}

static inline double
gamma_ulf(double t)
{
	return GAMMA(double, pow);
}

static inline float
gamma_uf(float t)
{
	return GAMMA(float, powf);
}

static inline long double
gamma_llf(long double t)
{
	return t >= 0 ? gamma_ullf(t) : -gamma_ullf(-t);
}

static inline double
gamma_lf(double t)
{
	return t >= 0 ? gamma_ulf(t) : -gamma_ulf(-t);
}

static inline float
gamma_f(float t)
{
	return t >= 0 ? gamma_uf(t) : -gamma_uf(-t);
}

static inline uint64_t
gamma_u64(uint64_t t)
{
	return (uint64_t)(gamma_ullf((long double)t / UINT64_MAX) * UINT64_MAX);
}

static inline uint32_t
gamma_u32(uint32_t t)
{
	return (uint32_t)(gamma_ulf((double)t / UINT32_MAX) * UINT32_MAX);
}

static inline uint16_t
gamma_u16(uint32_t t)
{
	return (uint16_t)(gamma_ulf((double)t / UINT16_MAX) * UINT16_MAX);
}

void
FUNCTION_NAME(struct libskrift_image *image, size_t x, size_t y, size_t width, size_t height)
{
	struct format_settings settings;
	uint8_t *img = image->image;
	size_t linesize, psize;

	settings = libskrift_format_settings[image->format];
	psize    = settings.spsize * (size_t)(4 - (settings.apos <= -2));
	linesize = (size_t)image->width * psize;
	img     += y * linesize + x * psize;
	width   *= psize;

	switch (settings.float_type) {
	case 0:
		switch (settings.spsize) {
		case 1:
			for (y = 0; y < height; y++, img += linesize) {
				for (x = 0; x < width; x += psize) {
					((uint8_t *)&img[x])[settings.rpos] = gamma_u8[((uint8_t *)&img[x])[settings.rpos]];
					((uint8_t *)&img[x])[settings.gpos] = gamma_u8[((uint8_t *)&img[x])[settings.gpos]];
					((uint8_t *)&img[x])[settings.bpos] = gamma_u8[((uint8_t *)&img[x])[settings.bpos]];
				}
			}
			break;

		case 2:
			for (y = 0; y < height; y++, img += linesize) {
				for (x = 0; x < width; x += psize) {
					((uint16_t *)&img[x])[settings.rpos] = gamma_u16(((uint16_t *)&img[x])[settings.rpos]);
					((uint16_t *)&img[x])[settings.gpos] = gamma_u16(((uint16_t *)&img[x])[settings.gpos]);
					((uint16_t *)&img[x])[settings.bpos] = gamma_u16(((uint16_t *)&img[x])[settings.bpos]);
				}
			}
			break;

		case 4:
			for (y = 0; y < height; y++, img += linesize) {
				for (x = 0; x < width; x += psize) {
					((uint32_t *)&img[x])[settings.rpos] = gamma_u32(((uint32_t *)&img[x])[settings.rpos]);
					((uint32_t *)&img[x])[settings.gpos] = gamma_u32(((uint32_t *)&img[x])[settings.gpos]);
					((uint32_t *)&img[x])[settings.bpos] = gamma_u32(((uint32_t *)&img[x])[settings.bpos]);
				}
			}
			break;

		default:
			for (y = 0; y < height; y++, img += linesize) {
				for (x = 0; x < width; x += psize) {
					((uint64_t *)&img[x])[settings.rpos] = gamma_u64(((uint64_t *)&img[x])[settings.rpos]);
					((uint64_t *)&img[x])[settings.gpos] = gamma_u64(((uint64_t *)&img[x])[settings.gpos]);
					((uint64_t *)&img[x])[settings.bpos] = gamma_u64(((uint64_t *)&img[x])[settings.bpos]);
				}
			}
			break;
		}
		break;

	case 1:
		for (y = 0; y < height; y++, img += linesize) {
			for (x = 0; x < width; x += psize) {
				((float *)&img[x])[settings.rpos] = gamma_f(((float *)&img[x])[settings.rpos]);
				((float *)&img[x])[settings.gpos] = gamma_f(((float *)&img[x])[settings.gpos]);
				((float *)&img[x])[settings.bpos] = gamma_f(((float *)&img[x])[settings.bpos]);
			}
		}
		break;

	case 2:
		for (y = 0; y < height; y++, img += linesize) {
			for (x = 0; x < width; x += psize) {
				((double *)&img[x])[settings.rpos] = gamma_lf(((double *)&img[x])[settings.rpos]);
				((double *)&img[x])[settings.gpos] = gamma_lf(((double *)&img[x])[settings.gpos]);
				((double *)&img[x])[settings.bpos] = gamma_lf(((double *)&img[x])[settings.bpos]);
			}
		}
		break;

	default:
		for (y = 0; y < height; y++, img += linesize) {
			for (x = 0; x < width; x += psize) {
				((long double *)&img[x])[settings.rpos] = gamma_llf(((long double *)&img[x])[settings.rpos]);
				((long double *)&img[x])[settings.gpos] = gamma_llf(((long double *)&img[x])[settings.gpos]);
				((long double *)&img[x])[settings.bpos] = gamma_llf(((long double *)&img[x])[settings.bpos]);
			}
		}
		break;
	}
}