]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CColorConverter.cpp
Use swap_control from MESA and EXT before SGI
[irrlicht.git] / source / Irrlicht / CColorConverter.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #include "CColorConverter.h"\r
6 #include "SColor.h"\r
7 #include "os.h"\r
8 #include "irrString.h"\r
9 \r
10 namespace irr\r
11 {\r
12 namespace video\r
13 {\r
14 \r
15 //! converts a monochrome bitmap to A1R5G5B5 data\r
16 void CColorConverter::convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad, bool flip)\r
17 {\r
18         if (!in || !out)\r
19                 return;\r
20 \r
21         if (flip)\r
22                 out += width * height;\r
23 \r
24         for (s32 y=0; y<height; ++y)\r
25         {\r
26                 s32 shift = 7;\r
27                 if (flip)\r
28                         out -= width;\r
29 \r
30                 for (s32 x=0; x<width; ++x)\r
31                 {\r
32                         out[x] = *in>>shift & 0x01 ? (s16)0xffff : (s16)0x8000;\r
33 \r
34                         if ((--shift)<0) // 8 pixel done\r
35                         {\r
36                                 shift=7;\r
37                                 ++in;\r
38                         }\r
39                 }\r
40 \r
41                 if (shift != 7) // width did not fill last byte\r
42                         ++in;\r
43 \r
44                 if (!flip)\r
45                         out += width;\r
46                 in += linepad;\r
47         }\r
48 }\r
49 \r
50 \r
51 \r
52 //! converts a 4 bit palettized image to A1R5G5B5\r
53 void CColorConverter::convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip)\r
54 {\r
55         if (!in || !out || !palette)\r
56                 return;\r
57 \r
58         if (flip)\r
59                 out += width*height;\r
60 \r
61         for (s32 y=0; y<height; ++y)\r
62         {\r
63                 s32 shift = 4;\r
64                 if (flip)\r
65                         out -= width;\r
66 \r
67                 for (s32 x=0; x<width; ++x)\r
68                 {\r
69                         out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)((*in >> shift) & 0xf)]);\r
70 \r
71                         if (shift==0)\r
72                         {\r
73                                 shift = 4;\r
74                                 ++in;\r
75                         }\r
76                         else\r
77                                 shift = 0;\r
78                 }\r
79 \r
80                 if (shift == 0) // odd width\r
81                         ++in;\r
82 \r
83                 if (!flip)\r
84                         out += width;\r
85                 in += linepad;\r
86         }\r
87 }\r
88 \r
89 \r
90 \r
91 //! converts a 8 bit palettized image into A1R5G5B5\r
92 void CColorConverter::convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip)\r
93 {\r
94         if (!in || !out || !palette)\r
95                 return;\r
96 \r
97         if (flip)\r
98                 out += width * height;\r
99 \r
100         for (s32 y=0; y<height; ++y)\r
101         {\r
102                 if (flip)\r
103                         out -= width; // one line back\r
104                 for (s32 x=0; x<width; ++x)\r
105                 {\r
106                         out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)(*in)]);\r
107                         ++in;\r
108                 }\r
109                 if (!flip)\r
110                         out += width;\r
111                 in += linepad;\r
112         }\r
113 }\r
114 \r
115 //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8\r
116 void CColorConverter::convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)\r
117 {\r
118         if (!in || !out )\r
119                 return;\r
120 \r
121         const s32 lineWidth = 3 * width;\r
122         if (flip)\r
123                 out += lineWidth * height;\r
124 \r
125         for (s32 y=0; y<height; ++y)\r
126         {\r
127                 if (flip)\r
128                         out -= lineWidth; // one line back\r
129                 for (s32 x=0; x< lineWidth; x += 3)\r
130                 {\r
131                         if ( palette )\r
132                         {\r
133 #ifdef __BIG_ENDIAN__\r
134                                 out[x+0] = palette[ (in[0] << 2 ) + 0];\r
135                                 out[x+1] = palette[ (in[0] << 2 ) + 1];\r
136                                 out[x+2] = palette[ (in[0] << 2 ) + 2];\r
137 #else\r
138                                 out[x+0] = palette[ (in[0] << 2 ) + 2];\r
139                                 out[x+1] = palette[ (in[0] << 2 ) + 1];\r
140                                 out[x+2] = palette[ (in[0] << 2 ) + 0];\r
141 #endif\r
142                         }\r
143                         else\r
144                         {\r
145                                 out[x+0] = in[0];\r
146                                 out[x+1] = in[0];\r
147                                 out[x+2] = in[0];\r
148                         }\r
149                         ++in;\r
150                 }\r
151                 if (!flip)\r
152                         out += lineWidth;\r
153                 in += linepad;\r
154         }\r
155 }\r
156 \r
157 //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8\r
158 void CColorConverter::convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)\r
159 {\r
160         if (!in || !out )\r
161                 return;\r
162 \r
163         const u32 lineWidth = 4 * width;\r
164         if (flip)\r
165                 out += lineWidth * height;\r
166 \r
167         u32 x;\r
168         u32 c;\r
169         for (u32 y=0; y < (u32) height; ++y)\r
170         {\r
171                 if (flip)\r
172                         out -= lineWidth; // one line back\r
173 \r
174                 if ( palette )\r
175                 {\r
176                         for (x=0; x < (u32) width; x += 1)\r
177                         {\r
178                                 c = in[x];\r
179                                 ((u32*)out)[x] = ((u32*)palette)[ c ];\r
180                         }\r
181                 }\r
182                 else\r
183                 {\r
184                         for (x=0; x < (u32) width; x += 1)\r
185                         {\r
186                                 c = in[x];\r
187 #ifdef __BIG_ENDIAN__\r
188                                 ((u32*)out)[x] = c << 24 | c << 16 | c << 8 | 0x000000FF;\r
189 #else\r
190                                 ((u32*)out)[x] = 0xFF000000 | c << 16 | c << 8 | c;\r
191 #endif\r
192                         }\r
193 \r
194                 }\r
195 \r
196                 if (!flip)\r
197                         out += lineWidth;\r
198                 in += width + linepad;\r
199         }\r
200 }\r
201 \r
202 \r
203 \r
204 //! converts 16bit data to 16bit data\r
205 void CColorConverter::convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad, bool flip)\r
206 {\r
207         if (!in || !out)\r
208                 return;\r
209 \r
210         if (flip)\r
211                 out += width * height;\r
212 \r
213         for (s32 y=0; y<height; ++y)\r
214         {\r
215                 if (flip)\r
216                         out -= width;\r
217 #ifdef __BIG_ENDIAN__\r
218                 for (s32 x=0; x<width; ++x)\r
219                         out[x]=os::Byteswap::byteswap(in[x]);\r
220 #else\r
221                 memcpy(out, in, width*sizeof(s16));\r
222 #endif\r
223                 if (!flip)\r
224                         out += width;\r
225                 in += width;\r
226                 in += linepad;\r
227         }\r
228 }\r
229 \r
230 \r
231 \r
232 //! copies R8G8B8 24bit data to 24bit data\r
233 void CColorConverter::convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad, bool flip, bool bgr)\r
234 {\r
235         if (!in || !out)\r
236                 return;\r
237 \r
238         const s32 lineWidth = 3 * width;\r
239         if (flip)\r
240                 out += lineWidth * height;\r
241 \r
242         for (s32 y=0; y<height; ++y)\r
243         {\r
244                 if (flip)\r
245                         out -= lineWidth;\r
246                 if (bgr)\r
247                 {\r
248                         for (s32 x=0; x<lineWidth; x+=3)\r
249                         {\r
250                                 out[x+0] = in[x+2];\r
251                                 out[x+1] = in[x+1];\r
252                                 out[x+2] = in[x+0];\r
253                         }\r
254                 }\r
255                 else\r
256                 {\r
257                         memcpy(out,in,lineWidth);\r
258                 }\r
259                 if (!flip)\r
260                         out += lineWidth;\r
261                 in += lineWidth;\r
262                 in += linepad;\r
263         }\r
264 }\r
265 \r
266 \r
267 \r
268 //! Resizes the surface to a new size and converts it at the same time\r
269 //! to an A8R8G8B8 format, returning the pointer to the new buffer.\r
270 void CColorConverter::convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight)\r
271 {\r
272         if (!newWidth || !newHeight)\r
273                 return;\r
274 \r
275         // note: this is very very slow. (i didn't want to write a fast version.\r
276         // but hopefully, nobody wants to convert surfaces every frame.\r
277 \r
278         f32 sourceXStep = (f32)currentWidth / (f32)newWidth;\r
279         f32 sourceYStep = (f32)currentHeight / (f32)newHeight;\r
280         f32 sy;\r
281         s32 t;\r
282 \r
283         for (s32 x=0; x<newWidth; ++x)\r
284         {\r
285                 sy = 0.0f;\r
286 \r
287                 for (s32 y=0; y<newHeight; ++y)\r
288                 {\r
289                         t = in[(s32)(((s32)sy)*currentWidth + x*sourceXStep)];\r
290                         t = (((t >> 15)&0x1)<<31) |     (((t >> 10)&0x1F)<<19) |\r
291                                 (((t >> 5)&0x1F)<<11) | (t&0x1F)<<3;\r
292                         out[(s32)(y*newWidth + x)] = t;\r
293 \r
294                         sy+=sourceYStep;\r
295                 }\r
296         }\r
297 }\r
298 \r
299 \r
300 \r
301 //! copies X8R8G8B8 32 bit data\r
302 void CColorConverter::convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip)\r
303 {\r
304         if (!in || !out)\r
305                 return;\r
306 \r
307         if (flip)\r
308                 out += width * height;\r
309 \r
310         for (s32 y=0; y<height; ++y)\r
311         {\r
312                 if (flip)\r
313                         out -= width;\r
314 #ifdef __BIG_ENDIAN__\r
315                 for (s32 x=0; x<width; ++x)\r
316                         out[x]=os::Byteswap::byteswap(in[x]);\r
317 #else\r
318                 memcpy(out, in, width*sizeof(s32));\r
319 #endif\r
320                 if (!flip)\r
321                         out += width;\r
322                 in += width;\r
323                 in += linepad;\r
324         }\r
325 }\r
326 \r
327 \r
328 \r
329 void CColorConverter::convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP)\r
330 {\r
331         u16* sB = (u16*)sP;\r
332         u8 * dB = (u8 *)dP;\r
333 \r
334         for (s32 x = 0; x < sN; ++x)\r
335         {\r
336                 dB[2] = (*sB & 0x7c00) >> 7;\r
337                 dB[1] = (*sB & 0x03e0) >> 2;\r
338                 dB[0] = (*sB & 0x1f) << 3;\r
339 \r
340                 sB += 1;\r
341                 dB += 3;\r
342         }\r
343 }\r
344 \r
345 void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP)\r
346 {\r
347         u16* sB = (u16*)sP;\r
348         u8 * dB = (u8 *)dP;\r
349 \r
350         for (s32 x = 0; x < sN; ++x)\r
351         {\r
352                 dB[0] = (*sB & 0x7c00) >> 7;\r
353                 dB[1] = (*sB & 0x03e0) >> 2;\r
354                 dB[2] = (*sB & 0x1f) << 3;\r
355 \r
356                 sB += 1;\r
357                 dB += 3;\r
358         }\r
359 }\r
360 \r
361 void CColorConverter::convert_A1R5G5B5toR5G5B5A1(const void* sP, s32 sN, void* dP)\r
362 {\r
363         const u16* sB = (const u16*)sP;\r
364         u16* dB = (u16*)dP;\r
365 \r
366         for (s32 x = 0; x < sN; ++x)\r
367         {\r
368                 *dB = (*sB<<1)|(*sB>>15);\r
369                 ++sB; ++dB;\r
370         }\r
371 }\r
372 \r
373 void CColorConverter::convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
374 {\r
375         u16* sB = (u16*)sP;\r
376         u32* dB = (u32*)dP;\r
377 \r
378         for (s32 x = 0; x < sN; ++x)\r
379                 *dB++ = A1R5G5B5toA8R8G8B8(*sB++);\r
380 }\r
381 \r
382 void CColorConverter::convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP)\r
383 {\r
384         memcpy(dP, sP, sN * 2);\r
385 }\r
386 \r
387 void CColorConverter::convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP)\r
388 {\r
389         u16* sB = (u16*)sP;\r
390         u16* dB = (u16*)dP;\r
391 \r
392         for (s32 x = 0; x < sN; ++x)\r
393                 *dB++ = A1R5G5B5toR5G6B5(*sB++);\r
394 }\r
395 \r
396 void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)\r
397 {\r
398         u8* sB = (u8*)sP;\r
399         u8* dB = (u8*)dP;\r
400 \r
401         for (s32 x = 0; x < sN; ++x)\r
402         {\r
403                 // sB[3] is alpha\r
404                 dB[0] = sB[2];\r
405                 dB[1] = sB[1];\r
406                 dB[2] = sB[0];\r
407 \r
408                 sB += 4;\r
409                 dB += 3;\r
410         }\r
411 }\r
412 \r
413 void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)\r
414 {\r
415         u8* sB = (u8*)sP;\r
416         u8* dB = (u8*)dP;\r
417 \r
418         for (s32 x = 0; x < sN; ++x)\r
419         {\r
420                 // sB[3] is alpha\r
421                 dB[0] = sB[0];\r
422                 dB[1] = sB[1];\r
423                 dB[2] = sB[2];\r
424 \r
425                 sB += 4;\r
426                 dB += 3;\r
427         }\r
428 }\r
429 \r
430 void CColorConverter::convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
431 {\r
432         memcpy(dP, sP, sN * 4);\r
433 }\r
434 \r
435 void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP)\r
436 {\r
437         u32* sB = (u32*)sP;\r
438         u16* dB = (u16*)dP;\r
439 \r
440         for (s32 x = 0; x < sN; ++x)\r
441                 *dB++ = A8R8G8B8toA1R5G5B5(*sB++);\r
442 }\r
443 \r
444 void CColorConverter::convert_A8R8G8B8toA1B5G5R5(const void* sP, s32 sN, void* dP)\r
445 {\r
446         u8 * sB = (u8 *)sP;\r
447         u16* dB = (u16*)dP;\r
448 \r
449         for (s32 x = 0; x < sN; ++x)\r
450         {\r
451                 s32 r = sB[0] >> 3;\r
452                 s32 g = sB[1] >> 3;\r
453                 s32 b = sB[2] >> 3;\r
454                 s32 a = sB[3] >> 3;\r
455 \r
456                 dB[0] = (a << 15) | (r << 10) | (g << 5) | (b);\r
457 \r
458                 sB += 4;\r
459                 dB += 1;\r
460         }\r
461 }\r
462 \r
463 void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)\r
464 {\r
465         u8 * sB = (u8 *)sP;\r
466         u16* dB = (u16*)dP;\r
467 \r
468         for (s32 x = 0; x < sN; ++x)\r
469         {\r
470                 s32 r = sB[2] >> 3;\r
471                 s32 g = sB[1] >> 2;\r
472                 s32 b = sB[0] >> 3;\r
473 \r
474                 dB[0] = (r << 11) | (g << 5) | (b);\r
475 \r
476                 sB += 4;\r
477                 dB += 1;\r
478         }\r
479 }\r
480 \r
481 void CColorConverter::convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP)\r
482 {\r
483         u8* sB = (u8*)sP;\r
484         u8* dB = (u8*)dP;\r
485 \r
486         for (s32 x = 0; x < sN; ++x)\r
487         {\r
488                 u8 r = sB[2] & 0xe0;\r
489                 u8 g = (sB[1] & 0xe0) >> 3;\r
490                 u8 b = (sB[0] & 0xc0) >> 6;\r
491 \r
492                 dB[0] = (r | g | b);\r
493 \r
494                 sB += 4;\r
495                 dB += 1;\r
496         }\r
497 }\r
498 \r
499 void CColorConverter::convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)\r
500 {\r
501         memcpy(dP, sP, sN * 3);\r
502 }\r
503 \r
504 void CColorConverter::convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
505 {\r
506         u8*  sB = (u8* )sP;\r
507         u32* dB = (u32*)dP;\r
508 \r
509         for (s32 x = 0; x < sN; ++x)\r
510         {\r
511                 *dB = 0xff000000 | (sB[0]<<16) | (sB[1]<<8) | sB[2];\r
512 \r
513                 sB += 3;\r
514                 ++dB;\r
515         }\r
516 }\r
517 \r
518 void CColorConverter::convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP)\r
519 {\r
520         u8 * sB = (u8 *)sP;\r
521         u16* dB = (u16*)dP;\r
522 \r
523         for (s32 x = 0; x < sN; ++x)\r
524         {\r
525                 s32 r = sB[0] >> 3;\r
526                 s32 g = sB[1] >> 3;\r
527                 s32 b = sB[2] >> 3;\r
528 \r
529                 dB[0] = (0x8000) | (r << 10) | (g << 5) | (b);\r
530 \r
531                 sB += 3;\r
532                 dB += 1;\r
533         }\r
534 }\r
535 \r
536 void CColorConverter::convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
537 {\r
538         u8*  sB = (u8* )sP;\r
539         u32* dB = (u32*)dP;\r
540 \r
541         for (s32 x = 0; x < sN; ++x)\r
542         {\r
543                 *dB = 0xff000000 | (sB[2]<<16) | (sB[1]<<8) | sB[0];\r
544 \r
545                 sB += 3;\r
546                 ++dB;\r
547         }\r
548 }\r
549 \r
550 void CColorConverter::convert_A8R8G8B8toR8G8B8A8(const void* sP, s32 sN, void* dP)\r
551 {\r
552         const u32* sB = (const u32*)sP;\r
553         u32* dB = (u32*)dP;\r
554 \r
555         for (s32 x = 0; x < sN; ++x)\r
556         {\r
557                 *dB++ = (*sB<<8) | (*sB>>24);\r
558                 ++sB;\r
559         }\r
560 }\r
561 \r
562 void CColorConverter::convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP)\r
563 {\r
564         const u32* sB = (const u32*)sP;\r
565         u32* dB = (u32*)dP;\r
566 \r
567         for (s32 x = 0; x < sN; ++x)\r
568         {\r
569                 *dB++ = (*sB&0xff00ff00)|((*sB&0x00ff0000)>>16)|((*sB&0x000000ff)<<16);\r
570                 ++sB;\r
571         }\r
572 }\r
573 \r
574 void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
575 {\r
576         u8* sB = (u8*)sP;\r
577         u8* dB = (u8*)dP;\r
578 \r
579         for (s32 x = 0; x < sN; ++x)\r
580         {\r
581                 dB[0] = sB[3];\r
582                 dB[1] = sB[2];\r
583                 dB[2] = sB[1];\r
584                 dB[3] = sB[0];\r
585 \r
586                 sB += 4;\r
587                 dB += 4;\r
588         }\r
589 \r
590 }\r
591 \r
592 void CColorConverter::convert_R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)\r
593 {\r
594         u8* sB = (u8*)sP;\r
595         u8* dB = (u8*)dP;\r
596 \r
597         for (s32 x = 0; x < sN; ++x)\r
598         {\r
599                 dB[2] = sB[0];\r
600                 dB[1] = sB[1];\r
601                 dB[0] = sB[2];\r
602 \r
603                 sB += 3;\r
604                 dB += 3;\r
605         }\r
606 }\r
607 \r
608 void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)\r
609 {\r
610         u8 * sB = (u8 *)sP;\r
611         u16* dB = (u16*)dP;\r
612 \r
613         for (s32 x = 0; x < sN; ++x)\r
614         {\r
615                 s32 r = sB[0] >> 3;\r
616                 s32 g = sB[1] >> 2;\r
617                 s32 b = sB[2] >> 3;\r
618 \r
619                 dB[0] = (r << 11) | (g << 5) | (b);\r
620 \r
621                 sB += 3;\r
622                 dB += 1;\r
623         }\r
624 }\r
625 \r
626 void CColorConverter::convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP)\r
627 {\r
628         memcpy(dP, sP, sN * 2);\r
629 }\r
630 \r
631 void CColorConverter::convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP)\r
632 {\r
633         u16* sB = (u16*)sP;\r
634         u8 * dB = (u8 *)dP;\r
635 \r
636         for (s32 x = 0; x < sN; ++x)\r
637         {\r
638                 dB[0] = (*sB & 0xf800) >> 8;\r
639                 dB[1] = (*sB & 0x07e0) >> 3;\r
640                 dB[2] = (*sB & 0x001f) << 3;\r
641 \r
642                 sB += 1;\r
643                 dB += 3;\r
644         }\r
645 }\r
646 \r
647 void CColorConverter::convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP)\r
648 {\r
649         u16* sB = (u16*)sP;\r
650         u8 * dB = (u8 *)dP;\r
651 \r
652         for (s32 x = 0; x < sN; ++x)\r
653         {\r
654                 dB[2] = (*sB & 0xf800) >> 8;\r
655                 dB[1] = (*sB & 0x07e0) >> 3;\r
656                 dB[0] = (*sB & 0x001f) << 3;\r
657 \r
658                 sB += 1;\r
659                 dB += 3;\r
660         }\r
661 }\r
662 \r
663 void CColorConverter::convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP)\r
664 {\r
665         u16* sB = (u16*)sP;\r
666         u32* dB = (u32*)dP;\r
667 \r
668         for (s32 x = 0; x < sN; ++x)\r
669                 *dB++ = R5G6B5toA8R8G8B8(*sB++);\r
670 }\r
671 \r
672 void CColorConverter::convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP)\r
673 {\r
674         u16* sB = (u16*)sP;\r
675         u16* dB = (u16*)dP;\r
676 \r
677         for (s32 x = 0; x < sN; ++x)\r
678                 *dB++ = R5G6B5toA1R5G5B5(*sB++);\r
679 }\r
680 \r
681 bool CColorConverter::canConvertFormat(ECOLOR_FORMAT sourceFormat, ECOLOR_FORMAT destFormat)\r
682 {\r
683         switch (sourceFormat)\r
684         {\r
685                 case ECF_A1R5G5B5:\r
686                         switch (destFormat)\r
687                         {\r
688                                 case ECF_A1R5G5B5:\r
689                                 case ECF_R5G6B5:\r
690                                 case ECF_A8R8G8B8:\r
691                                 case ECF_R8G8B8:\r
692                                         return true;\r
693                                 default:\r
694                                         break;\r
695                         }\r
696                 break;\r
697                 case ECF_R5G6B5:\r
698                         switch (destFormat)\r
699                         {\r
700                                 case ECF_A1R5G5B5:\r
701                                 case ECF_R5G6B5:\r
702                                 case ECF_A8R8G8B8:\r
703                                 case ECF_R8G8B8:\r
704                                         return true;\r
705                                 default:\r
706                                         break;\r
707                         }\r
708                 break;\r
709                 case ECF_A8R8G8B8:\r
710                         switch (destFormat)\r
711                         {\r
712                                 case ECF_A1R5G5B5:\r
713                                 case ECF_R5G6B5:\r
714                                 case ECF_A8R8G8B8:\r
715                                 case ECF_R8G8B8:\r
716                                         return true;\r
717                                 default:\r
718                                         break;\r
719                         }\r
720                 break;\r
721                 case ECF_R8G8B8:\r
722                         switch (destFormat)\r
723                         {\r
724                                 case ECF_A1R5G5B5:\r
725                                 case ECF_R5G6B5:\r
726                                 case ECF_A8R8G8B8:\r
727                                 case ECF_R8G8B8:\r
728                                         return true;\r
729                                 default:\r
730                                         break;\r
731                         }\r
732                 break;\r
733                 default:\r
734                         break;\r
735         }\r
736         return false;\r
737 }\r
738 \r
739 void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN,\r
740                                 void* dP, ECOLOR_FORMAT dF)\r
741 {\r
742         // please also update can_convert_viaFormat when adding new conversions\r
743         switch (sF)\r
744         {\r
745                 case ECF_A1R5G5B5:\r
746                         switch (dF)\r
747                         {\r
748                                 case ECF_A1R5G5B5:\r
749                                         convert_A1R5G5B5toA1R5G5B5(sP, sN, dP);\r
750                                 break;\r
751                                 case ECF_R5G6B5:\r
752                                         convert_A1R5G5B5toR5G6B5(sP, sN, dP);\r
753                                 break;\r
754                                 case ECF_A8R8G8B8:\r
755                                         convert_A1R5G5B5toA8R8G8B8(sP, sN, dP);\r
756                                 break;\r
757                                 case ECF_R8G8B8:\r
758                                         convert_A1R5G5B5toR8G8B8(sP, sN, dP);\r
759                                 break;\r
760                                 IRR_CASE_IIMAGE_COMPRESSED_FORMAT\r
761                                         os::Printer::log("CColorConverter::convert_viaFormat method doesn't support compressed images.", ELL_WARNING);\r
762                                 break;\r
763 \r
764                                 default:\r
765                                         break;\r
766                         }\r
767                 break;\r
768                 case ECF_R5G6B5:\r
769                         switch (dF)\r
770                         {\r
771                                 case ECF_A1R5G5B5:\r
772                                         convert_R5G6B5toA1R5G5B5(sP, sN, dP);\r
773                                 break;\r
774                                 case ECF_R5G6B5:\r
775                                         convert_R5G6B5toR5G6B5(sP, sN, dP);\r
776                                 break;\r
777                                 case ECF_A8R8G8B8:\r
778                                         convert_R5G6B5toA8R8G8B8(sP, sN, dP);\r
779                                 break;\r
780                                 case ECF_R8G8B8:\r
781                                         convert_R5G6B5toR8G8B8(sP, sN, dP);\r
782                                 break;\r
783                                 IRR_CASE_IIMAGE_COMPRESSED_FORMAT\r
784                                         os::Printer::log("CColorConverter::convert_viaFormat method doesn't support compressed images.", ELL_WARNING);\r
785                                 break;\r
786 \r
787                                 default:\r
788                                         break;\r
789                         }\r
790                 break;\r
791                 case ECF_A8R8G8B8:\r
792                         switch (dF)\r
793                         {\r
794                                 case ECF_A1R5G5B5:\r
795                                         convert_A8R8G8B8toA1R5G5B5(sP, sN, dP);\r
796                                 break;\r
797                                 case ECF_R5G6B5:\r
798                                         convert_A8R8G8B8toR5G6B5(sP, sN, dP);\r
799                                 break;\r
800                                 case ECF_A8R8G8B8:\r
801                                         convert_A8R8G8B8toA8R8G8B8(sP, sN, dP);\r
802                                 break;\r
803                                 case ECF_R8G8B8:\r
804                                         convert_A8R8G8B8toR8G8B8(sP, sN, dP);\r
805                                 break;\r
806                                 IRR_CASE_IIMAGE_COMPRESSED_FORMAT\r
807                                         os::Printer::log("CColorConverter::convert_viaFormat method doesn't support compressed images.", ELL_WARNING);\r
808                                 break;\r
809 \r
810                                 default:\r
811                                         break;\r
812                         }\r
813                 break;\r
814                 case ECF_R8G8B8:\r
815                         switch (dF)\r
816                         {\r
817                                 case ECF_A1R5G5B5:\r
818                                         convert_R8G8B8toA1R5G5B5(sP, sN, dP);\r
819                                 break;\r
820                                 case ECF_R5G6B5:\r
821                                         convert_R8G8B8toR5G6B5(sP, sN, dP);\r
822                                 break;\r
823                                 case ECF_A8R8G8B8:\r
824                                         convert_R8G8B8toA8R8G8B8(sP, sN, dP);\r
825                                 break;\r
826                                 case ECF_R8G8B8:\r
827                                         convert_R8G8B8toR8G8B8(sP, sN, dP);\r
828                                 break;\r
829                                 IRR_CASE_IIMAGE_COMPRESSED_FORMAT\r
830                                         os::Printer::log("CColorConverter::convert_viaFormat method doesn't support compressed images.", ELL_WARNING);\r
831                                 break;\r
832 \r
833                                 default:\r
834                                         break;\r
835                         }\r
836                 break;\r
837                 IRR_CASE_IIMAGE_COMPRESSED_FORMAT\r
838                         os::Printer::log("CColorConverter::convert_viaFormat method doesn't support compressed images.", ELL_WARNING);\r
839                         break;\r
840 \r
841                 default:\r
842                         break;\r
843         }\r
844 }\r
845 \r
846 \r
847 } // end namespace video\r
848 } // end namespace irr\r