Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
/* Unpack image samples and optionally pad pixels with opaque alpha */
4
 
5
#define get1(buf,x) ((buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 )
6
#define get2(buf,x) ((buf[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3 )
7
#define get4(buf,x) ((buf[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15 )
8
#define get8(buf,x) (buf[x])
9
#define get16(buf,x) (buf[x << 1])
10
 
11
static unsigned char get1_tab_1[256][8];
12
static unsigned char get1_tab_1p[256][16];
13
static unsigned char get1_tab_255[256][8];
14
static unsigned char get1_tab_255p[256][16];
15
 
16
static void
17
init_get1_tables(void)
18
{
19
	static int once = 0;
20
	unsigned char bits[1];
21
	int i, k, x;
22
 
23
	/* TODO: mutex lock here */
24
 
25
	if (once)
26
		return;
27
 
28
	for (i = 0; i < 256; i++)
29
	{
30
		bits[0] = i;
31
		for (k = 0; k < 8; k++)
32
		{
33
			x = get1(bits, k);
34
 
35
			get1_tab_1[i][k] = x;
36
			get1_tab_1p[i][k * 2] = x;
37
			get1_tab_1p[i][k * 2 + 1] = 255;
38
 
39
			get1_tab_255[i][k] = x * 255;
40
			get1_tab_255p[i][k * 2] = x * 255;
41
			get1_tab_255p[i][k * 2 + 1] = 255;
42
		}
43
	}
44
 
45
	once = 1;
46
}
47
 
48
void
49
fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale)
50
{
51
	int pad, x, y, k;
52
	int w = dst->w;
53
 
54
	pad = 0;
55
	if (dst->n > n)
56
		pad = 255;
57
 
58
	if (depth == 1)
59
		init_get1_tables();
60
 
61
	if (scale == 0)
62
	{
63
		switch (depth)
64
		{
65
		case 1: scale = 255; break;
66
		case 2: scale = 85; break;
67
		case 4: scale = 17; break;
68
		}
69
	}
70
 
71
	for (y = 0; y < dst->h; y++)
72
	{
73
		unsigned char *sp = src + y * stride;
74
		unsigned char *dp = dst->samples + y * (dst->w * dst->n);
75
 
76
		/* Specialized loops */
77
 
78
		if (n == 1 && depth == 1 && scale == 1 && !pad)
79
		{
80
			int w3 = w >> 3;
81
			for (x = 0; x < w3; x++)
82
			{
83
				memcpy(dp, get1_tab_1[*sp++], 8);
84
				dp += 8;
85
			}
86
			x = x << 3;
87
			if (x < w)
88
				memcpy(dp, get1_tab_1[*sp], w - x);
89
		}
90
 
91
		else if (n == 1 && depth == 1 && scale == 255 && !pad)
92
		{
93
			int w3 = w >> 3;
94
			for (x = 0; x < w3; x++)
95
			{
96
				memcpy(dp, get1_tab_255[*sp++], 8);
97
				dp += 8;
98
			}
99
			x = x << 3;
100
			if (x < w)
101
				memcpy(dp, get1_tab_255[*sp], w - x);
102
		}
103
 
104
		else if (n == 1 && depth == 1 && scale == 1 && pad)
105
		{
106
			int w3 = w >> 3;
107
			for (x = 0; x < w3; x++)
108
			{
109
				memcpy(dp, get1_tab_1p[*sp++], 16);
110
				dp += 16;
111
			}
112
			x = x << 3;
113
			if (x < w)
114
				memcpy(dp, get1_tab_1p[*sp], (w - x) << 1);
115
		}
116
 
117
		else if (n == 1 && depth == 1 && scale == 255 && pad)
118
		{
119
			int w3 = w >> 3;
120
			for (x = 0; x < w3; x++)
121
			{
122
				memcpy(dp, get1_tab_255p[*sp++], 16);
123
				dp += 16;
124
			}
125
			x = x << 3;
126
			if (x < w)
127
				memcpy(dp, get1_tab_255p[*sp], (w - x) << 1);
128
		}
129
 
130
		else if (depth == 8 && !pad)
131
		{
132
			int len = w * n;
133
			while (len--)
134
				*dp++ = *sp++;
135
		}
136
 
137
		else if (depth == 8 && pad)
138
		{
139
			for (x = 0; x < w; x++)
140
			{
141
				for (k = 0; k < n; k++)
142
					*dp++ = *sp++;
143
				*dp++ = 255;
144
			}
145
		}
146
 
147
		else
148
		{
149
			int b = 0;
150
			for (x = 0; x < w; x++)
151
			{
152
				for (k = 0; k < n; k++)
153
				{
154
					switch (depth)
155
					{
156
					case 1: *dp++ = get1(sp, b) * scale; break;
157
					case 2: *dp++ = get2(sp, b) * scale; break;
158
					case 4: *dp++ = get4(sp, b) * scale; break;
159
					case 8: *dp++ = get8(sp, b); break;
160
					case 16: *dp++ = get16(sp, b); break;
161
					}
162
					b++;
163
				}
164
				if (pad)
165
					*dp++ = 255;
166
			}
167
		}
168
	}
169
}
170
 
171
/* Apply decode array */
172
 
173
void
174
fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval)
175
{
176
	int add[FZ_MAX_COLORS];
177
	int mul[FZ_MAX_COLORS];
178
	unsigned char *p = pix->samples;
179
	int len = pix->w * pix->h;
180
	int n = pix->n - 1;
181
	int needed;
182
	int k;
183
 
184
	needed = 0;
185
	for (k = 0; k < n; k++)
186
	{
187
		int min = decode[k * 2] * 256;
188
		int max = decode[k * 2 + 1] * 256;
189
		add[k] = min;
190
		mul[k] = (max - min) / maxval;
191
		needed |= min != 0 || max != maxval * 256;
192
	}
193
 
194
	if (!needed)
195
		return;
196
 
197
	while (len--)
198
	{
199
		for (k = 0; k < n; k++)
200
			p[k] = (add[k] + (((p[k] << 8) * mul[k]) >> 8)) >> 8;
201
		p += n + 1;
202
	}
203
}
204
 
205
void
206
fz_decode_tile(fz_pixmap *pix, float *decode)
207
{
208
	int add[FZ_MAX_COLORS];
209
	int mul[FZ_MAX_COLORS];
210
	unsigned char *p = pix->samples;
211
	int len = pix->w * pix->h;
212
	int n = MAX(1, pix->n - 1);
213
	int needed;
214
	int k;
215
 
216
	needed = 0;
217
	for (k = 0; k < n; k++)
218
	{
219
		int min = decode[k * 2] * 255;
220
		int max = decode[k * 2 + 1] * 255;
221
		add[k] = min;
222
		mul[k] = max - min;
223
		needed |= min != 0 || max != 255;
224
	}
225
 
226
	if (!needed)
227
		return;
228
 
229
	while (len--)
230
	{
231
		for (k = 0; k < n; k++)
232
			p[k] = add[k] + fz_mul255(p[k], mul[k]);
233
		p += pix->n;
234
	}
235
}