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