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