1 #include "Draw.h"
2 
3 namespace Upp {
4 
sMaskPos16(dword mask)5 static int sMaskPos16(dword mask)
6 {
7 	if(mask > 0xffff)
8 		return 0;
9 	int pos = 0;
10 	while(((mask << pos) & 0x18000) != 0x8000)
11 		pos++;
12 	return pos;
13 }
14 
Set16le(dword _rmask,dword _gmask,dword _bmask)15 void RasterFormat::Set16le(dword _rmask, dword _gmask, dword _bmask)
16 {
17 	rpos = sMaskPos16(rmask = _rmask);
18 	gpos = sMaskPos16(gmask = _gmask);
19 	bpos = sMaskPos16(bmask = _bmask);
20 	type = RASTER_16;
21 }
22 
Set16be(dword _rmask,dword _gmask,dword _bmask)23 void RasterFormat::Set16be(dword _rmask, dword _gmask, dword _bmask)
24 {
25 	Set16le(_rmask, _gmask, _bmask);
26 	type = RASTER_16|RASTER_MSBFIRST;
27 }
28 
Set24le(dword rmask,dword gmask,dword bmask)29 void RasterFormat::Set24le(dword rmask, dword gmask, dword bmask)
30 {
31 	rpos = GetChMaskPos32(rmask);
32 	gpos = GetChMaskPos32(gmask);
33 	bpos = GetChMaskPos32(bmask);
34 	apos = 0;
35 	type = RASTER_24;
36 }
37 
Set32le(dword rmask,dword gmask,dword bmask,dword amask)38 void RasterFormat::Set32le(dword rmask, dword gmask, dword bmask, dword amask)
39 {
40 	Set24le(rmask, gmask, bmask);
41 	if(amask) {
42 		apos = GetChMaskPos32(amask);
43 		type = RASTER_32PREMULTIPLIED;
44 	}
45 	else
46 		type = RASTER_32;
47 }
48 
Set24be(dword rmask,dword gmask,dword bmask)49 void RasterFormat::Set24be(dword rmask, dword gmask, dword bmask)
50 {
51 	rpos = 2 - GetChMaskPos32(rmask);
52 	gpos = 2 - GetChMaskPos32(gmask);
53 	bpos = 2 - GetChMaskPos32(bmask);
54 	apos = 0;
55 	type = RASTER_24;
56 }
57 
Set32be(dword rmask,dword gmask,dword bmask,dword amask)58 void RasterFormat::Set32be(dword rmask, dword gmask, dword bmask, dword amask)
59 {
60 	rpos = 3 - GetChMaskPos32(rmask);
61 	gpos = 3 - GetChMaskPos32(gmask);
62 	bpos = 3 - GetChMaskPos32(bmask);
63 	if(amask) {
64 		apos = 3 - GetChMaskPos32(amask);
65 		type = RASTER_32PREMULTIPLIED;
66 	}
67 	else
68 		type = RASTER_32;
69 }
70 
Set32leStraight(dword rmask,dword gmask,dword bmask,dword amask)71 void RasterFormat::Set32leStraight(dword rmask, dword gmask, dword bmask, dword amask)
72 {
73 	Set32le(rmask, gmask, bmask, amask);
74 	type = RASTER_32ALPHA;
75 }
76 
Set32beStraight(dword rmask,dword gmask,dword bmask,dword amask)77 void RasterFormat::Set32beStraight(dword rmask, dword gmask, dword bmask, dword amask)
78 {
79 	Set32be(rmask, gmask, bmask, amask);
80 	type = RASTER_32ALPHA;
81 }
82 
SetRGBA()83 void RasterFormat::SetRGBA()
84 {
85 	type = RASTER_32PREMULTIPLIED;
86 	bpos = 0;
87 	gpos = 1;
88 	rpos = 2;
89 	apos = 3;
90 }
91 
SetRGBAStraight()92 void RasterFormat::SetRGBAStraight()
93 {
94 	type = RASTER_32ALPHA;
95 	bpos = 0;
96 	gpos = 1;
97 	rpos = 2;
98 	apos = 3;
99 }
100 
IsRGBA() const101 int RasterFormat::IsRGBA() const
102 {
103 	return (type & 31) == RASTER_32PREMULTIPLIED && bpos == 0 && gpos == 1 && rpos == 2 && apos == 3;
104 }
105 
106 static byte bits[16] = { 1, 2, 4, 8, 16, 16, 24, 32, 32, 32 };
107 
GetByteCount(int cx) const108 int RasterFormat::GetByteCount(int cx) const
109 {
110 	int b = bits[type & 15];
111 	return (cx * b + 7) >> 3;
112 }
113 
GetBpp() const114 int RasterFormat::GetBpp() const
115 {
116 	return bits[type & 15];
117 }
118 
HasAlpha() const119 bool RasterFormat::HasAlpha() const
120 {
121 	return (type & 15) == RASTER_32ALPHA;
122 }
123 
GetColorCount() const124 int RasterFormat::GetColorCount() const
125 {
126 	static int colors[16] = { 2, 4, 16, 256, 256, 65536, 256 * 256 * 256, 256 * 256 * 256, 256 * 256 * 256 };
127 	return colors[type & 15];
128 }
129 
GetPaletteCount() const130 int RasterFormat::GetPaletteCount() const
131 {
132 	static int colors[16] = { 2, 4, 16, 256 };
133 	return (type & 15) < 4 ? colors[type & 15] : 0;
134 }
135 
TailBits(RGBA * t,const byte * src,int cx,byte andm,byte shift,const RGBA * palette)136 void RasterFormat::TailBits(RGBA *t, const byte *src, int cx, byte andm, byte shift, const RGBA *palette)
137 {
138 	if(cx) {
139 		byte c = *src;
140 		while(cx > 0) {
141 			*t++ = palette[c & andm]; c >>= shift;
142 			cx--;
143 		}
144 	}
145 }
146 
TailBitsMSB1st(RGBA * t,const byte * src,int cx,byte shift1,byte andm,byte shift,const RGBA * palette)147 void RasterFormat::TailBitsMSB1st(RGBA *t, const byte *src, int cx, byte shift1, byte andm, byte shift, const RGBA *palette)
148 {
149 	if(cx) {
150 		byte c = *src;
151 		while(cx > 0) {
152 			*t++ = palette[(c >> shift1) & andm]; c <<= shift;
153 			cx--;
154 		}
155 	}
156 }
157 
Read(RGBA * t,const byte * s,int cx,const RGBA * palette) const158 void RasterFormat::Read(RGBA *t, const byte *s, int cx, const RGBA *palette) const
159 {
160 	switch(type) {
161 	case RASTER_1:
162 		{
163 			const byte *e = s + (cx >> 3);
164 			while(s < e) {
165 				byte c = *s++;
166 				t[0] = palette[(c >> 0) & 1];
167 				t[1] = palette[(c >> 1) & 1];
168 				t[2] = palette[(c >> 2) & 1];
169 				t[3] = palette[(c >> 3) & 1];
170 				t[4] = palette[(c >> 4) & 1];
171 				t[5] = palette[(c >> 5) & 1];
172 				t[6] = palette[(c >> 6) & 1];
173 				t[7] = palette[(c >> 7) & 1];
174 				t += 8;
175 			}
176 			TailBits(t, s, cx & 7, 1, 1, palette);
177 		}
178 		break;
179 	case RASTER_1|RASTER_MSBFIRST:
180 		{
181 			const byte *e = s + (cx >> 3);
182 			while(s < e) {
183 				byte c = *s++;
184 				t[7] = palette[(c >> 0) & 1];
185 				t[6] = palette[(c >> 1) & 1];
186 				t[5] = palette[(c >> 2) & 1];
187 				t[4] = palette[(c >> 3) & 1];
188 				t[3] = palette[(c >> 4) & 1];
189 				t[2] = palette[(c >> 5) & 1];
190 				t[1] = palette[(c >> 6) & 1];
191 				t[0] = palette[(c >> 7) & 1];
192 				t += 8;
193 			}
194 			TailBitsMSB1st(t, s, cx & 7, 7, 1, 1, palette);
195 		}
196 		break;
197 	case RASTER_2:
198 		{
199 			const byte *e = s + (cx >> 2);
200 			while(s < e) {
201 				byte c = *s++;
202 				t[0] = palette[(c >> 0) & 3];
203 				t[1] = palette[(c >> 2) & 3];
204 				t[2] = palette[(c >> 4) & 3];
205 				t[3] = palette[(c >> 6) & 3];
206 				t += 4;
207 			}
208 			TailBits(t, s, cx & 3, 3, 2, palette);
209 		}
210 		break;
211 	case RASTER_2|RASTER_MSBFIRST:
212 		{
213 			const byte *e = s + (cx >> 2);
214 			while(s < e) {
215 				byte c = *s++;
216 				t[3] = palette[(c >> 0) & 3];
217 				t[2] = palette[(c >> 2) & 3];
218 				t[1] = palette[(c >> 4) & 3];
219 				t[0] = palette[(c >> 6) & 3];
220 				t += 4;
221 			}
222 			TailBitsMSB1st(t, s, cx & 3, 6, 3, 2, palette);
223 		}
224 		break;
225 	case RASTER_4:
226 		{
227 			const byte *e = s + (cx >> 1);
228 			while(s < e) {
229 				byte c = *s++;
230 				t[0] = palette[(c >> 0) & 15];
231 				t[1] = palette[(c >> 4) & 15];
232 				t += 2;
233 			}
234 			TailBits(t, s, cx & 1, 15, 4, palette);
235 		}
236 		break;
237 	case RASTER_4|RASTER_MSBFIRST:
238 		{
239 			const byte *e = s + (cx >> 1);
240 			while(s < e) {
241 				byte c = *s++;
242 				t[1] = palette[(c >> 0) & 15];
243 				t[0] = palette[(c >> 4) & 15];
244 				t += 2;
245 			}
246 			TailBitsMSB1st(t, s, cx & 1, 4, 15, 4, palette);
247 		}
248 		break;
249 	case RASTER_8:
250 	case RASTER_8|RASTER_MSBFIRST:
251 		{
252 			RGBA *e = t + cx;
253 			while(t < e)
254 				*t++ = palette[*s++];
255 		}
256 		break;
257 	case RASTER_8ALPHA:
258 	case RASTER_8ALPHA|RASTER_MSBFIRST:
259 		{
260 			RGBA *e = t + cx;
261 			RGBA *b = t;
262 			while(t < e) {
263 				RGBA pal = palette[*s];
264 				pal.a = s[1];
265 				*t++ = pal;
266 				s += 2;
267 			}
268 			Premultiply(b, b, cx);
269 			break;
270 		}
271 	case RASTER_16:
272 		{
273 			RGBA *e = t + cx;
274 			while(t < e) {
275 				word w = Peek16le(s);
276 				t->a = 255;
277 				t->r = byte((w & rmask) << rpos >> 8);
278 				t->g = byte((w & gmask) << gpos >> 8);
279 				t->b = byte((w & bmask) << bpos >> 8);
280 				s += 2;
281 				t++;
282 			}
283 		}
284 		break;
285 	case RASTER_16|RASTER_MSBFIRST:
286 		{
287 			RGBA *e = t + cx;
288 			while(t < e) {
289 				word w = Peek16be(s);
290 				t->a = 255;
291 				t->r = byte((w & rmask) << rpos >> 8);
292 				t->g = byte((w & gmask) << gpos >> 8);
293 				t->b = byte((w & bmask) << bpos >> 8);
294 				s += 2;
295 				t++;
296 			}
297 		}
298 		break;
299 	case RASTER_24:
300 	case RASTER_24|RASTER_MSBFIRST:
301 		{
302 			RGBA *e = t + cx;
303 			while(t < e) {
304 				t->a = 255;
305 				t->r = s[rpos];
306 				t->g = s[gpos];
307 				t->b = s[bpos];
308 				s += 3;
309 				t++;
310 			}
311 		}
312 		break;
313 	case RASTER_32:
314 	case RASTER_32|RASTER_MSBFIRST:
315 		if(bpos == 0 && gpos == 1 && rpos == 2) {
316 			RGBA *e = t + cx;
317 			while(t < e) {
318 				*t = *(RGBA *)s;
319 				t->a = 255;
320 				s += 4;
321 				t++;
322 			}
323 		}
324 		else
325 		{
326 			RGBA *e = t + cx;
327 			while(t < e) {
328 				t->a = 255;
329 				t->r = s[rpos];
330 				t->g = s[gpos];
331 				t->b = s[bpos];
332 				s += 4;
333 				t++;
334 			}
335 		}
336 		break;
337 	case RASTER_32ALPHA:
338 	case RASTER_32ALPHA|RASTER_MSBFIRST: {
339 			RGBA *e = t + cx;
340 			while(t < e) {
341 				t->a = s[apos];
342 				int alpha = t->a + (t->a >> 7);
343 				t->r = (alpha * s[rpos]) >> 8;
344 				t->g = (alpha * s[gpos]) >> 8;
345 				t->b = (alpha * s[bpos]) >> 8;
346 				s += 4;
347 				t++;
348 			}
349 		}
350 		break;
351 	case RASTER_32PREMULTIPLIED:
352 	case RASTER_32PREMULTIPLIED|RASTER_MSBFIRST:
353 		if(bpos == 0 && gpos == 1 && rpos == 2 && apos == 3)
354 			memcpy(t, s, cx * sizeof(RGBA));
355 		else {
356 			RGBA *e = t + cx;
357 			while(t < e) {
358 				t->a = s[apos];
359 				t->r = s[rpos];
360 				t->g = s[gpos];
361 				t->b = s[bpos];
362 				s += 4;
363 				t++;
364 			}
365 		}
366 		break;
367 	}
368 }
369 
370 }
371