diff options
author | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
---|---|---|
committer | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
commit | 5a422aba704c375a307a902bafe658342e209906 (patch) | |
tree | 5005011e086bb863d8fb587ad3319bbec59b2447 /src/im_dibxbitmap.cpp |
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/im_dibxbitmap.cpp')
-rw-r--r-- | src/im_dibxbitmap.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/im_dibxbitmap.cpp b/src/im_dibxbitmap.cpp new file mode 100644 index 0000000..8fabd4a --- /dev/null +++ b/src/im_dibxbitmap.cpp @@ -0,0 +1,181 @@ +/** \file + * \brief Conversion between imDib and imImage + * + * See Copyright Notice in im_lib.h + * $Id: im_dibxbitmap.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $ + */ + + +#include <windows.h> +#include <assert.h> + +#include "im.h" +#include "im_image.h" +#include "im_dib.h" +#include "im_util.h" + + +void imDibEncodeFromBitmap(imDib* dib, const unsigned char* data) +{ + int x, y; + BYTE* bits; + + assert(dib); + assert(dib->bmih->biBitCount > 16); + assert(data); + + if (dib->bmih->biHeight < 0) + bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */ + else + bits = dib->bits; + + for (y = 0; y < abs(dib->bmih->biHeight); y++) + { + for (x = 0; x < dib->bmih->biWidth; x++) + { + *bits++ = *(data+2); // R + *bits++ = *(data+1); // G + *bits++ = *(data+0); // B + + data += 3; + + if (dib->bmih->biBitCount == 32) + *bits++ = *data++; + } + + bits += dib->pad_size; + + if (dib->bmih->biHeight < 0) + bits -= 2*dib->line_size; + } +} + +void imDibDecodeToBitmap(const imDib* dib, unsigned char* data) +{ + int x, y, offset; + unsigned short color; + BYTE* bits; + unsigned int rmask = 0, gmask = 0, bmask = 0, + roff = 0, goff = 0, boff = 0; /* pixel bit mask control when reading 16 and 32 bpp images */ + + assert(dib); + assert(dib->bmih->biBitCount > 8); + assert(data); + + if (dib->bmih->biHeight < 0) + bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */ + else + bits = dib->bits; + + if (dib->bmih->biBitCount == 16) + offset = dib->line_size; /* do not increment for each pixel, jump line */ + else + offset = dib->pad_size; /* increment for each pixel, jump pad */ + + if (dib->bmih->biCompression == BI_BITFIELDS) + { + unsigned int Mask; + unsigned int* palette = (unsigned int*)dib->bmic; + + rmask = Mask = palette[0]; + while (!(Mask & 0x01)) + {Mask >>= 1; roff++;} + + gmask = Mask = palette[1]; + while (!(Mask & 0x01)) + {Mask >>= 1; goff++;} + + bmask = Mask = palette[2]; + while (!(Mask & 0x01)) + {Mask >>= 1; boff++;} + } + else if (dib->bmih->biBitCount == 16) + { + bmask = 0x001F; + gmask = 0x03E0; + rmask = 0x7C00; + boff = 0; + goff = 5; + roff = 10; + } + + for (y = 0; y < abs(dib->bmih->biHeight); y++) + { + for (x = 0; x < dib->bmih->biWidth; x++) + { + if (dib->bmih->biBitCount == 16) + { + color = ((unsigned short*)bits)[x]; + *data++ = (unsigned char)((((rmask & color) >> roff) * 255) / (rmask >> roff)); + *data++ = (unsigned char)((((gmask & color) >> goff) * 255) / (gmask >> goff)); + *data++ = (unsigned char)((((bmask & color) >> boff) * 255) / (bmask >> boff)); + } + else + { + *(data+2) = *bits++; // B + *(data+1) = *bits++; // G + *(data+0) = *bits++; // R + + data += 3; + + if (dib->bmih->biBitCount == 32) + *data++ = *bits++; + } + } + + bits += offset; + + if (dib->bmih->biHeight < 0) + bits -= 2*dib->line_size; + } +} + +imImage* imDibToImage(const imDib* dib) +{ + assert(dib); + + int color_space = IM_RGB; + if (dib->bmih->biBitCount <= 8) + color_space = IM_MAP; + + imImage* image = imImageCreate(dib->bmih->biWidth, abs(dib->bmih->biHeight), color_space, IM_BYTE); + if (!image) + return NULL; + + if (image->color_space == IM_MAP) + { + image->palette_count = dib->palette_count; + imDibDecodeToMap(dib, (imbyte*)image->data[0], image->palette); + } + else + { + imDibDecodeToRGBA(dib, (imbyte*)image->data[0], (imbyte*)image->data[1], (imbyte*)image->data[2], NULL); + } + + return image; +} + +imDib* imDibFromImage(const imImage* image) +{ + assert(image); + assert(imImageIsBitmap(image)); + + if (!imImageIsBitmap(image)) + return NULL; + + int bpp; + if (image->color_space != IM_RGB) + bpp = 8; + else + bpp = 24; + + imDib* dib = imDibCreate(image->width, image->height, bpp); + if (!dib) return NULL; + + if (image->color_space != IM_RGB) + imDibEncodeFromMap(dib, (const imbyte*)image->data[0], image->palette, image->palette_count); + else + imDibEncodeFromRGBA(dib, (const imbyte*)image->data[0], (const imbyte*)image->data[1], (const imbyte*)image->data[2], NULL); + + return dib; +} |