123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- // Copyright (C) 2002-2012 Nikolaus Gebhardt
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- #include "CColorConverter.h"
- #include "SColor.h"
- #include "os.h"
- #include "irrString.h"
- namespace irr
- {
- namespace video
- {
- //! converts a monochrome bitmap to A1R5G5B5 data
- void CColorConverter::convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad, bool flip)
- {
- if (!in || !out)
- return;
- if (flip)
- out += width * height;
- for (s32 y=0; y<height; ++y)
- {
- s32 shift = 7;
- if (flip)
- out -= width;
- for (s32 x=0; x<width; ++x)
- {
- out[x] = *in>>shift & 0x01 ? (s16)0xffff : (s16)0x8000;
- if ((--shift)<0) // 8 pixel done
- {
- shift=7;
- ++in;
- }
- }
- if (shift != 7) // width did not fill last byte
- ++in;
- if (!flip)
- out += width;
- in += linepad;
- }
- }
- //! converts a 4 bit palettized image to A1R5G5B5
- void CColorConverter::convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip)
- {
- if (!in || !out || !palette)
- return;
- if (flip)
- out += width*height;
- for (s32 y=0; y<height; ++y)
- {
- s32 shift = 4;
- if (flip)
- out -= width;
- for (s32 x=0; x<width; ++x)
- {
- out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)((*in >> shift) & 0xf)]);
- if (shift==0)
- {
- shift = 4;
- ++in;
- }
- else
- shift = 0;
- }
- if (shift == 0) // odd width
- ++in;
- if (!flip)
- out += width;
- in += linepad;
- }
- }
- //! converts a 8 bit palettized image into A1R5G5B5
- void CColorConverter::convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip)
- {
- if (!in || !out || !palette)
- return;
- if (flip)
- out += width * height;
- for (s32 y=0; y<height; ++y)
- {
- if (flip)
- out -= width; // one line back
- for (s32 x=0; x<width; ++x)
- {
- out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)(*in)]);
- ++in;
- }
- if (!flip)
- out += width;
- in += linepad;
- }
- }
- //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
- void CColorConverter::convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)
- {
- if (!in || !out )
- return;
- const s32 lineWidth = 3 * width;
- if (flip)
- out += lineWidth * height;
- for (s32 y=0; y<height; ++y)
- {
- if (flip)
- out -= lineWidth; // one line back
- for (s32 x=0; x< lineWidth; x += 3)
- {
- if ( palette )
- {
- #ifdef __BIG_ENDIAN__
- out[x+0] = palette[ (in[0] << 2 ) + 0];
- out[x+1] = palette[ (in[0] << 2 ) + 1];
- out[x+2] = palette[ (in[0] << 2 ) + 2];
- #else
- out[x+0] = palette[ (in[0] << 2 ) + 2];
- out[x+1] = palette[ (in[0] << 2 ) + 1];
- out[x+2] = palette[ (in[0] << 2 ) + 0];
- #endif
- }
- else
- {
- out[x+0] = in[0];
- out[x+1] = in[0];
- out[x+2] = in[0];
- }
- ++in;
- }
- if (!flip)
- out += lineWidth;
- in += linepad;
- }
- }
- //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
- void CColorConverter::convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)
- {
- if (!in || !out )
- return;
- const u32 lineWidth = 4 * width;
- if (flip)
- out += lineWidth * height;
- u32 x;
- register u32 c;
- for (u32 y=0; y < (u32) height; ++y)
- {
- if (flip)
- out -= lineWidth; // one line back
- if ( palette )
- {
- for (x=0; x < (u32) width; x += 1)
- {
- c = in[x];
- ((u32*)out)[x] = ((u32*)palette)[ c ];
- }
- }
- else
- {
- for (x=0; x < (u32) width; x += 1)
- {
- c = in[x];
- #ifdef __BIG_ENDIAN__
- ((u32*)out)[x] = c << 24 | c << 16 | c << 8 | 0x000000FF;
- #else
- ((u32*)out)[x] = 0xFF000000 | c << 16 | c << 8 | c;
- #endif
- }
- }
- if (!flip)
- out += lineWidth;
- in += width + linepad;
- }
- }
- //! converts 16bit data to 16bit data
- void CColorConverter::convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad, bool flip)
- {
- if (!in || !out)
- return;
- if (flip)
- out += width * height;
- for (s32 y=0; y<height; ++y)
- {
- if (flip)
- out -= width;
- #ifdef __BIG_ENDIAN__
- for (s32 x=0; x<width; ++x)
- out[x]=os::Byteswap::byteswap(in[x]);
- #else
- memcpy(out, in, width*sizeof(s16));
- #endif
- if (!flip)
- out += width;
- in += width;
- in += linepad;
- }
- }
- //! copies R8G8B8 24bit data to 24bit data
- void CColorConverter::convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad, bool flip, bool bgr)
- {
- if (!in || !out)
- return;
- const s32 lineWidth = 3 * width;
- if (flip)
- out += lineWidth * height;
- for (s32 y=0; y<height; ++y)
- {
- if (flip)
- out -= lineWidth;
- if (bgr)
- {
- for (s32 x=0; x<lineWidth; x+=3)
- {
- out[x+0] = in[x+2];
- out[x+1] = in[x+1];
- out[x+2] = in[x+0];
- }
- }
- else
- {
- memcpy(out,in,lineWidth);
- }
- if (!flip)
- out += lineWidth;
- in += lineWidth;
- in += linepad;
- }
- }
- //! Resizes the surface to a new size and converts it at the same time
- //! to an A8R8G8B8 format, returning the pointer to the new buffer.
- void CColorConverter::convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight)
- {
- if (!newWidth || !newHeight)
- return;
- // note: this is very very slow. (i didn't want to write a fast version.
- // but hopefully, nobody wants to convert surfaces every frame.
- f32 sourceXStep = (f32)currentWidth / (f32)newWidth;
- f32 sourceYStep = (f32)currentHeight / (f32)newHeight;
- f32 sy;
- s32 t;
- for (s32 x=0; x<newWidth; ++x)
- {
- sy = 0.0f;
- for (s32 y=0; y<newHeight; ++y)
- {
- t = in[(s32)(((s32)sy)*currentWidth + x*sourceXStep)];
- t = (((t >> 15)&0x1)<<31) | (((t >> 10)&0x1F)<<19) |
- (((t >> 5)&0x1F)<<11) | (t&0x1F)<<3;
- out[(s32)(y*newWidth + x)] = t;
- sy+=sourceYStep;
- }
- }
- }
- //! copies X8R8G8B8 32 bit data
- void CColorConverter::convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip)
- {
- if (!in || !out)
- return;
- if (flip)
- out += width * height;
- for (s32 y=0; y<height; ++y)
- {
- if (flip)
- out -= width;
- #ifdef __BIG_ENDIAN__
- for (s32 x=0; x<width; ++x)
- out[x]=os::Byteswap::byteswap(in[x]);
- #else
- memcpy(out, in, width*sizeof(s32));
- #endif
- if (!flip)
- out += width;
- in += width;
- in += linepad;
- }
- }
- void CColorConverter::convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u8 * dB = (u8 *)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[2] = (*sB & 0x7c00) >> 7;
- dB[1] = (*sB & 0x03e0) >> 2;
- dB[0] = (*sB & 0x1f) << 3;
- sB += 1;
- dB += 3;
- }
- }
- void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u8 * dB = (u8 *)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[0] = (*sB & 0x7c00) >> 7;
- dB[1] = (*sB & 0x03e0) >> 2;
- dB[2] = (*sB & 0x1f) << 3;
- sB += 1;
- dB += 3;
- }
- }
- void CColorConverter::convert_A1R5G5B5toR5G5B5A1(const void* sP, s32 sN, void* dP)
- {
- const u16* sB = (const u16*)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- *dB = (*sB<<1)|(*sB>>15);
- ++sB; ++dB;
- }
- }
- void CColorConverter::convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- *dB++ = A1R5G5B5toA8R8G8B8(*sB++);
- }
- void CColorConverter::convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP)
- {
- memcpy(dP, sP, sN * 2);
- }
- void CColorConverter::convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- *dB++ = A1R5G5B5toR5G6B5(*sB++);
- }
- void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8*)sP;
- u8* dB = (u8*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- // sB[3] is alpha
- dB[0] = sB[2];
- dB[1] = sB[1];
- dB[2] = sB[0];
- sB += 4;
- dB += 3;
- }
- }
- void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8*)sP;
- u8* dB = (u8*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- // sB[3] is alpha
- dB[0] = sB[0];
- dB[1] = sB[1];
- dB[2] = sB[2];
- sB += 4;
- dB += 3;
- }
- }
- void CColorConverter::convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- memcpy(dP, sP, sN * 4);
- }
- void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP)
- {
- u32* sB = (u32*)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- *dB++ = A8R8G8B8toA1R5G5B5(*sB++);
- }
- void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)
- {
- u8 * sB = (u8 *)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- s32 r = sB[2] >> 3;
- s32 g = sB[1] >> 2;
- s32 b = sB[0] >> 3;
- dB[0] = (r << 11) | (g << 5) | (b);
- sB += 4;
- dB += 1;
- }
- }
- void CColorConverter::convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8*)sP;
- u8* dB = (u8*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- u8 r = sB[2] & 0xe0;
- u8 g = (sB[1] & 0xe0) >> 3;
- u8 b = (sB[0] & 0xc0) >> 6;
- dB[0] = (r | g | b);
- sB += 4;
- dB += 1;
- }
- }
- void CColorConverter::convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)
- {
- memcpy(dP, sP, sN * 3);
- }
- void CColorConverter::convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8* )sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- *dB = 0xff000000 | (sB[0]<<16) | (sB[1]<<8) | sB[2];
- sB += 3;
- ++dB;
- }
- }
- void CColorConverter::convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP)
- {
- u8 * sB = (u8 *)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- s32 r = sB[0] >> 3;
- s32 g = sB[1] >> 3;
- s32 b = sB[2] >> 3;
- dB[0] = (0x8000) | (r << 10) | (g << 5) | (b);
- sB += 3;
- dB += 1;
- }
- }
- void CColorConverter::convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8* )sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- *dB = 0xff000000 | (sB[2]<<16) | (sB[1]<<8) | sB[0];
- sB += 3;
- ++dB;
- }
- }
- void CColorConverter::convert_A8R8G8B8toR8G8B8A8(const void* sP, s32 sN, void* dP)
- {
- const u32* sB = (const u32*)sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- *dB++ = (*sB<<8) | (*sB>>24);
- ++sB;
- }
- }
- void CColorConverter::convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP)
- {
- const u32* sB = (const u32*)sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- *dB++ = (*sB&0xff00ff00)|((*sB&0x00ff0000)>>16)|((*sB&0x000000ff)<<16);
- ++sB;
- }
- }
- void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8*)sP;
- u8* dB = (u8*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[0] = sB[3];
- dB[1] = sB[2];
- dB[2] = sB[1];
- dB[3] = sB[0];
- sB += 4;
- dB += 4;
- }
- }
- void CColorConverter::convert_R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)
- {
- u8* sB = (u8*)sP;
- u8* dB = (u8*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[2] = sB[0];
- dB[1] = sB[1];
- dB[0] = sB[2];
- sB += 3;
- dB += 3;
- }
- }
- void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP)
- {
- u8 * sB = (u8 *)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- s32 r = sB[0] >> 3;
- s32 g = sB[1] >> 2;
- s32 b = sB[2] >> 3;
- dB[0] = (r << 11) | (g << 5) | (b);
- sB += 3;
- dB += 1;
- }
- }
- void CColorConverter::convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP)
- {
- memcpy(dP, sP, sN * 2);
- }
- void CColorConverter::convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u8 * dB = (u8 *)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[0] = (*sB & 0xf800) >> 8;
- dB[1] = (*sB & 0x07e0) >> 3;
- dB[2] = (*sB & 0x001f) << 3;
- sB += 1;
- dB += 3;
- }
- }
- void CColorConverter::convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u8 * dB = (u8 *)dP;
- for (s32 x = 0; x < sN; ++x)
- {
- dB[2] = (*sB & 0xf800) >> 8;
- dB[1] = (*sB & 0x07e0) >> 3;
- dB[0] = (*sB & 0x001f) << 3;
- sB += 1;
- dB += 3;
- }
- }
- void CColorConverter::convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u32* dB = (u32*)dP;
- for (s32 x = 0; x < sN; ++x)
- *dB++ = R5G6B5toA8R8G8B8(*sB++);
- }
- void CColorConverter::convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP)
- {
- u16* sB = (u16*)sP;
- u16* dB = (u16*)dP;
- for (s32 x = 0; x < sN; ++x)
- *dB++ = R5G6B5toA1R5G5B5(*sB++);
- }
- void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN,
- void* dP, ECOLOR_FORMAT dF)
- {
- switch (sF)
- {
- case ECF_A1R5G5B5:
- switch (dF)
- {
- case ECF_A1R5G5B5:
- convert_A1R5G5B5toA1R5G5B5(sP, sN, dP);
- break;
- case ECF_R5G6B5:
- convert_A1R5G5B5toR5G6B5(sP, sN, dP);
- break;
- case ECF_A8R8G8B8:
- convert_A1R5G5B5toA8R8G8B8(sP, sN, dP);
- break;
- case ECF_R8G8B8:
- convert_A1R5G5B5toR8G8B8(sP, sN, dP);
- break;
- #ifndef _DEBUG
- default:
- break;
- #endif
- }
- break;
- case ECF_R5G6B5:
- switch (dF)
- {
- case ECF_A1R5G5B5:
- convert_R5G6B5toA1R5G5B5(sP, sN, dP);
- break;
- case ECF_R5G6B5:
- convert_R5G6B5toR5G6B5(sP, sN, dP);
- break;
- case ECF_A8R8G8B8:
- convert_R5G6B5toA8R8G8B8(sP, sN, dP);
- break;
- case ECF_R8G8B8:
- convert_R5G6B5toR8G8B8(sP, sN, dP);
- break;
- #ifndef _DEBUG
- default:
- break;
- #endif
- }
- break;
- case ECF_A8R8G8B8:
- switch (dF)
- {
- case ECF_A1R5G5B5:
- convert_A8R8G8B8toA1R5G5B5(sP, sN, dP);
- break;
- case ECF_R5G6B5:
- convert_A8R8G8B8toR5G6B5(sP, sN, dP);
- break;
- case ECF_A8R8G8B8:
- convert_A8R8G8B8toA8R8G8B8(sP, sN, dP);
- break;
- case ECF_R8G8B8:
- convert_A8R8G8B8toR8G8B8(sP, sN, dP);
- break;
- #ifndef _DEBUG
- default:
- break;
- #endif
- }
- break;
- case ECF_R8G8B8:
- switch (dF)
- {
- case ECF_A1R5G5B5:
- convert_R8G8B8toA1R5G5B5(sP, sN, dP);
- break;
- case ECF_R5G6B5:
- convert_R8G8B8toR5G6B5(sP, sN, dP);
- break;
- case ECF_A8R8G8B8:
- convert_R8G8B8toA8R8G8B8(sP, sN, dP);
- break;
- case ECF_R8G8B8:
- convert_R8G8B8toR8G8B8(sP, sN, dP);
- break;
- #ifndef _DEBUG
- default:
- break;
- #endif
- }
- break;
- default:
- break;
- }
- }
- } // end namespace video
- } // end namespace irr
|