SD + Bitmap
Dependencies: TS_DISCO_F746NG LCD_DISCO_F746NG BSP_DISCO_F746NG
bitmap.h@0:14e97aa401f3, 2019-05-21 (annotated)
- Committer:
- iut_cachan01
- Date:
- Tue May 21 10:24:03 2019 +0000
- Revision:
- 0:14e97aa401f3
SD + Bitmap
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
iut_cachan01 | 0:14e97aa401f3 | 1 | /* |
iut_cachan01 | 0:14e97aa401f3 | 2 | * Windows Bitmap File Loader |
iut_cachan01 | 0:14e97aa401f3 | 3 | * Version 1.2.5 (20120929) |
iut_cachan01 | 0:14e97aa401f3 | 4 | * |
iut_cachan01 | 0:14e97aa401f3 | 5 | * Supported Formats: 1, 4, 8, 16, 24, 32 Bit Images |
iut_cachan01 | 0:14e97aa401f3 | 6 | * Alpha Bitmaps are also supported. |
iut_cachan01 | 0:14e97aa401f3 | 7 | * Supported compression types: RLE 8, BITFIELDS |
iut_cachan01 | 0:14e97aa401f3 | 8 | * |
iut_cachan01 | 0:14e97aa401f3 | 9 | * Created by: Benjamin Kalytta, 2006 - 2012 |
iut_cachan01 | 0:14e97aa401f3 | 10 | * Thanks for bug fixes goes to: Chris Campbell |
iut_cachan01 | 0:14e97aa401f3 | 11 | * |
iut_cachan01 | 0:14e97aa401f3 | 12 | * Licence: Free to use, URL to my source and my name is required in your source code. |
iut_cachan01 | 0:14e97aa401f3 | 13 | * |
iut_cachan01 | 0:14e97aa401f3 | 14 | * Source can be found at http://www.kalytta.com/bitmap.h |
iut_cachan01 | 0:14e97aa401f3 | 15 | * |
iut_cachan01 | 0:14e97aa401f3 | 16 | * Warning: This code should not be used in unmodified form in a production environment. |
iut_cachan01 | 0:14e97aa401f3 | 17 | * It should only serve as a basis for your own development. |
iut_cachan01 | 0:14e97aa401f3 | 18 | * There is only a minimal error handling in this code. (Notice added 20111211) |
iut_cachan01 | 0:14e97aa401f3 | 19 | */ |
iut_cachan01 | 0:14e97aa401f3 | 20 | |
iut_cachan01 | 0:14e97aa401f3 | 21 | #ifndef BITMAP_H |
iut_cachan01 | 0:14e97aa401f3 | 22 | #define BITMAP_H |
iut_cachan01 | 0:14e97aa401f3 | 23 | |
iut_cachan01 | 0:14e97aa401f3 | 24 | #include <iostream> |
iut_cachan01 | 0:14e97aa401f3 | 25 | #include <fstream> |
iut_cachan01 | 0:14e97aa401f3 | 26 | #include <string> |
iut_cachan01 | 0:14e97aa401f3 | 27 | |
iut_cachan01 | 0:14e97aa401f3 | 28 | #ifndef __LITTLE_ENDIAN__ |
iut_cachan01 | 0:14e97aa401f3 | 29 | #ifndef __BIG_ENDIAN__ |
iut_cachan01 | 0:14e97aa401f3 | 30 | #define __LITTLE_ENDIAN__ |
iut_cachan01 | 0:14e97aa401f3 | 31 | #endif |
iut_cachan01 | 0:14e97aa401f3 | 32 | #endif |
iut_cachan01 | 0:14e97aa401f3 | 33 | |
iut_cachan01 | 0:14e97aa401f3 | 34 | #ifdef __LITTLE_ENDIAN__ |
iut_cachan01 | 0:14e97aa401f3 | 35 | #define BITMAP_SIGNATURE 0x4d42 |
iut_cachan01 | 0:14e97aa401f3 | 36 | #else |
iut_cachan01 | 0:14e97aa401f3 | 37 | #define BITMAP_SIGNATURE 0x424d |
iut_cachan01 | 0:14e97aa401f3 | 38 | #endif |
iut_cachan01 | 0:14e97aa401f3 | 39 | |
iut_cachan01 | 0:14e97aa401f3 | 40 | #if defined(_MSC_VER) || defined(__INTEL_COMPILER) |
iut_cachan01 | 0:14e97aa401f3 | 41 | typedef unsigned __int32 uint32_t; |
iut_cachan01 | 0:14e97aa401f3 | 42 | typedef unsigned __int16 uint16_t; |
iut_cachan01 | 0:14e97aa401f3 | 43 | typedef unsigned __int8 uint8_t; |
iut_cachan01 | 0:14e97aa401f3 | 44 | typedef __int32 int32_t; |
iut_cachan01 | 0:14e97aa401f3 | 45 | #elif defined(__GNUC__) || defined(__CYGWIN__) || defined(__MWERKS__) || defined(__WATCOMC__) || defined(__PGI) || defined(__LCC__) |
iut_cachan01 | 0:14e97aa401f3 | 46 | #include <stdint.h> |
iut_cachan01 | 0:14e97aa401f3 | 47 | #else |
iut_cachan01 | 0:14e97aa401f3 | 48 | typedef unsigned int uint32_t; |
iut_cachan01 | 0:14e97aa401f3 | 49 | typedef unsigned short int uint16_t; |
iut_cachan01 | 0:14e97aa401f3 | 50 | typedef unsigned char uint8_t; |
iut_cachan01 | 0:14e97aa401f3 | 51 | typedef int int32_t; |
iut_cachan01 | 0:14e97aa401f3 | 52 | #endif |
iut_cachan01 | 0:14e97aa401f3 | 53 | |
iut_cachan01 | 0:14e97aa401f3 | 54 | #pragma pack(push, 1) |
iut_cachan01 | 0:14e97aa401f3 | 55 | |
iut_cachan01 | 0:14e97aa401f3 | 56 | typedef struct _BITMAP_FILEHEADER { |
iut_cachan01 | 0:14e97aa401f3 | 57 | uint16_t Signature; |
iut_cachan01 | 0:14e97aa401f3 | 58 | uint32_t Size; |
iut_cachan01 | 0:14e97aa401f3 | 59 | uint32_t Reserved; |
iut_cachan01 | 0:14e97aa401f3 | 60 | uint32_t BitsOffset; |
iut_cachan01 | 0:14e97aa401f3 | 61 | } BITMAP_FILEHEADER; |
iut_cachan01 | 0:14e97aa401f3 | 62 | |
iut_cachan01 | 0:14e97aa401f3 | 63 | #define BITMAP_FILEHEADER_SIZE 14 |
iut_cachan01 | 0:14e97aa401f3 | 64 | |
iut_cachan01 | 0:14e97aa401f3 | 65 | typedef struct _BITMAP_HEADER { |
iut_cachan01 | 0:14e97aa401f3 | 66 | uint32_t HeaderSize; |
iut_cachan01 | 0:14e97aa401f3 | 67 | int32_t Width; |
iut_cachan01 | 0:14e97aa401f3 | 68 | int32_t Height; |
iut_cachan01 | 0:14e97aa401f3 | 69 | uint16_t Planes; |
iut_cachan01 | 0:14e97aa401f3 | 70 | uint16_t BitCount; |
iut_cachan01 | 0:14e97aa401f3 | 71 | uint32_t Compression; |
iut_cachan01 | 0:14e97aa401f3 | 72 | uint32_t SizeImage; |
iut_cachan01 | 0:14e97aa401f3 | 73 | int32_t PelsPerMeterX; |
iut_cachan01 | 0:14e97aa401f3 | 74 | int32_t PelsPerMeterY; |
iut_cachan01 | 0:14e97aa401f3 | 75 | uint32_t ClrUsed; |
iut_cachan01 | 0:14e97aa401f3 | 76 | uint32_t ClrImportant; |
iut_cachan01 | 0:14e97aa401f3 | 77 | uint32_t RedMask; |
iut_cachan01 | 0:14e97aa401f3 | 78 | uint32_t GreenMask; |
iut_cachan01 | 0:14e97aa401f3 | 79 | uint32_t BlueMask; |
iut_cachan01 | 0:14e97aa401f3 | 80 | uint32_t AlphaMask; |
iut_cachan01 | 0:14e97aa401f3 | 81 | uint32_t CsType; |
iut_cachan01 | 0:14e97aa401f3 | 82 | uint32_t Endpoints[9]; // see http://msdn2.microsoft.com/en-us/library/ms536569.aspx |
iut_cachan01 | 0:14e97aa401f3 | 83 | uint32_t GammaRed; |
iut_cachan01 | 0:14e97aa401f3 | 84 | uint32_t GammaGreen; |
iut_cachan01 | 0:14e97aa401f3 | 85 | uint32_t GammaBlue; |
iut_cachan01 | 0:14e97aa401f3 | 86 | } BITMAP_HEADER; |
iut_cachan01 | 0:14e97aa401f3 | 87 | |
iut_cachan01 | 0:14e97aa401f3 | 88 | typedef struct _RGBA { |
iut_cachan01 | 0:14e97aa401f3 | 89 | uint8_t Red; |
iut_cachan01 | 0:14e97aa401f3 | 90 | uint8_t Green; |
iut_cachan01 | 0:14e97aa401f3 | 91 | uint8_t Blue; |
iut_cachan01 | 0:14e97aa401f3 | 92 | uint8_t Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 93 | } RGBA; |
iut_cachan01 | 0:14e97aa401f3 | 94 | |
iut_cachan01 | 0:14e97aa401f3 | 95 | typedef struct _BGRA { |
iut_cachan01 | 0:14e97aa401f3 | 96 | uint8_t Blue; |
iut_cachan01 | 0:14e97aa401f3 | 97 | uint8_t Green; |
iut_cachan01 | 0:14e97aa401f3 | 98 | uint8_t Red; |
iut_cachan01 | 0:14e97aa401f3 | 99 | uint8_t Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 100 | } BGRA; |
iut_cachan01 | 0:14e97aa401f3 | 101 | |
iut_cachan01 | 0:14e97aa401f3 | 102 | #pragma pack(pop) |
iut_cachan01 | 0:14e97aa401f3 | 103 | |
iut_cachan01 | 0:14e97aa401f3 | 104 | class CBitmap { |
iut_cachan01 | 0:14e97aa401f3 | 105 | private: |
iut_cachan01 | 0:14e97aa401f3 | 106 | BITMAP_FILEHEADER m_BitmapFileHeader; |
iut_cachan01 | 0:14e97aa401f3 | 107 | BITMAP_HEADER m_BitmapHeader; |
iut_cachan01 | 0:14e97aa401f3 | 108 | BGRA *m_BitmapData; |
iut_cachan01 | 0:14e97aa401f3 | 109 | unsigned int m_BitmapSize; |
iut_cachan01 | 0:14e97aa401f3 | 110 | |
iut_cachan01 | 0:14e97aa401f3 | 111 | // Masks and bit counts shouldn't exceed 32 Bits |
iut_cachan01 | 0:14e97aa401f3 | 112 | public: |
iut_cachan01 | 0:14e97aa401f3 | 113 | class CColor { |
iut_cachan01 | 0:14e97aa401f3 | 114 | public: |
iut_cachan01 | 0:14e97aa401f3 | 115 | static inline unsigned int BitCountByMask(unsigned int Mask) { |
iut_cachan01 | 0:14e97aa401f3 | 116 | unsigned int BitCount = 0; |
iut_cachan01 | 0:14e97aa401f3 | 117 | while (Mask) { |
iut_cachan01 | 0:14e97aa401f3 | 118 | Mask &= Mask - 1; |
iut_cachan01 | 0:14e97aa401f3 | 119 | BitCount++; |
iut_cachan01 | 0:14e97aa401f3 | 120 | } |
iut_cachan01 | 0:14e97aa401f3 | 121 | return BitCount; |
iut_cachan01 | 0:14e97aa401f3 | 122 | } |
iut_cachan01 | 0:14e97aa401f3 | 123 | |
iut_cachan01 | 0:14e97aa401f3 | 124 | static inline unsigned int BitPositionByMask(unsigned int Mask) { |
iut_cachan01 | 0:14e97aa401f3 | 125 | return BitCountByMask((Mask & (~Mask + 1)) - 1); |
iut_cachan01 | 0:14e97aa401f3 | 126 | } |
iut_cachan01 | 0:14e97aa401f3 | 127 | |
iut_cachan01 | 0:14e97aa401f3 | 128 | static inline unsigned int ComponentByMask(unsigned int Color, unsigned int Mask) { |
iut_cachan01 | 0:14e97aa401f3 | 129 | unsigned int Component = Color & Mask; |
iut_cachan01 | 0:14e97aa401f3 | 130 | return Component >> BitPositionByMask(Mask); |
iut_cachan01 | 0:14e97aa401f3 | 131 | } |
iut_cachan01 | 0:14e97aa401f3 | 132 | |
iut_cachan01 | 0:14e97aa401f3 | 133 | static inline unsigned int BitCountToMask(unsigned int BitCount) { |
iut_cachan01 | 0:14e97aa401f3 | 134 | return (BitCount == 32) ? 0xFFFFFFFF : (1 << BitCount) - 1; |
iut_cachan01 | 0:14e97aa401f3 | 135 | } |
iut_cachan01 | 0:14e97aa401f3 | 136 | |
iut_cachan01 | 0:14e97aa401f3 | 137 | static unsigned int Convert(unsigned int Color, unsigned int FromBitCount, unsigned int ToBitCount) { |
iut_cachan01 | 0:14e97aa401f3 | 138 | if (ToBitCount < FromBitCount) { |
iut_cachan01 | 0:14e97aa401f3 | 139 | Color >>= (FromBitCount - ToBitCount); |
iut_cachan01 | 0:14e97aa401f3 | 140 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 141 | Color <<= (ToBitCount - FromBitCount); |
iut_cachan01 | 0:14e97aa401f3 | 142 | if (Color > 0) { |
iut_cachan01 | 0:14e97aa401f3 | 143 | Color |= BitCountToMask(ToBitCount - FromBitCount); |
iut_cachan01 | 0:14e97aa401f3 | 144 | } |
iut_cachan01 | 0:14e97aa401f3 | 145 | } |
iut_cachan01 | 0:14e97aa401f3 | 146 | return Color; |
iut_cachan01 | 0:14e97aa401f3 | 147 | } |
iut_cachan01 | 0:14e97aa401f3 | 148 | }; |
iut_cachan01 | 0:14e97aa401f3 | 149 | |
iut_cachan01 | 0:14e97aa401f3 | 150 | public: |
iut_cachan01 | 0:14e97aa401f3 | 151 | |
iut_cachan01 | 0:14e97aa401f3 | 152 | CBitmap() : m_BitmapData(0), m_BitmapSize(0) { |
iut_cachan01 | 0:14e97aa401f3 | 153 | Dispose(); |
iut_cachan01 | 0:14e97aa401f3 | 154 | } |
iut_cachan01 | 0:14e97aa401f3 | 155 | |
iut_cachan01 | 0:14e97aa401f3 | 156 | CBitmap(const char* Filename) : m_BitmapData(0), m_BitmapSize(0) { |
iut_cachan01 | 0:14e97aa401f3 | 157 | Load(Filename); |
iut_cachan01 | 0:14e97aa401f3 | 158 | } |
iut_cachan01 | 0:14e97aa401f3 | 159 | |
iut_cachan01 | 0:14e97aa401f3 | 160 | ~CBitmap() { |
iut_cachan01 | 0:14e97aa401f3 | 161 | Dispose(); |
iut_cachan01 | 0:14e97aa401f3 | 162 | } |
iut_cachan01 | 0:14e97aa401f3 | 163 | |
iut_cachan01 | 0:14e97aa401f3 | 164 | void Dispose() { |
iut_cachan01 | 0:14e97aa401f3 | 165 | if (m_BitmapData) { |
iut_cachan01 | 0:14e97aa401f3 | 166 | delete[] m_BitmapData; |
iut_cachan01 | 0:14e97aa401f3 | 167 | m_BitmapData = 0; |
iut_cachan01 | 0:14e97aa401f3 | 168 | } |
iut_cachan01 | 0:14e97aa401f3 | 169 | memset(&m_BitmapFileHeader, 0, sizeof(m_BitmapFileHeader)); |
iut_cachan01 | 0:14e97aa401f3 | 170 | memset(&m_BitmapHeader, 0, sizeof(m_BitmapHeader)); |
iut_cachan01 | 0:14e97aa401f3 | 171 | } |
iut_cachan01 | 0:14e97aa401f3 | 172 | |
iut_cachan01 | 0:14e97aa401f3 | 173 | /* Load specified Bitmap and stores it as RGBA in an internal buffer */ |
iut_cachan01 | 0:14e97aa401f3 | 174 | |
iut_cachan01 | 0:14e97aa401f3 | 175 | bool Load(const char *Filename) { |
iut_cachan01 | 0:14e97aa401f3 | 176 | std::ifstream file(Filename, std::ios::binary | std::ios::in); |
iut_cachan01 | 0:14e97aa401f3 | 177 | |
iut_cachan01 | 0:14e97aa401f3 | 178 | if (file.bad()) { |
iut_cachan01 | 0:14e97aa401f3 | 179 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 180 | } |
iut_cachan01 | 0:14e97aa401f3 | 181 | |
iut_cachan01 | 0:14e97aa401f3 | 182 | if (file.is_open() == false) { |
iut_cachan01 | 0:14e97aa401f3 | 183 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 184 | } |
iut_cachan01 | 0:14e97aa401f3 | 185 | |
iut_cachan01 | 0:14e97aa401f3 | 186 | Dispose(); |
iut_cachan01 | 0:14e97aa401f3 | 187 | |
iut_cachan01 | 0:14e97aa401f3 | 188 | file.read((char*) &m_BitmapFileHeader, BITMAP_FILEHEADER_SIZE); |
iut_cachan01 | 0:14e97aa401f3 | 189 | if (m_BitmapFileHeader.Signature != BITMAP_SIGNATURE) { |
iut_cachan01 | 0:14e97aa401f3 | 190 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 191 | } |
iut_cachan01 | 0:14e97aa401f3 | 192 | |
iut_cachan01 | 0:14e97aa401f3 | 193 | file.read((char*) &m_BitmapHeader, sizeof(BITMAP_HEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 194 | |
iut_cachan01 | 0:14e97aa401f3 | 195 | /* Load Color Table */ |
iut_cachan01 | 0:14e97aa401f3 | 196 | |
iut_cachan01 | 0:14e97aa401f3 | 197 | file.seekg(BITMAP_FILEHEADER_SIZE + m_BitmapHeader.HeaderSize, std::ios::beg); |
iut_cachan01 | 0:14e97aa401f3 | 198 | |
iut_cachan01 | 0:14e97aa401f3 | 199 | unsigned int ColorTableSize = 0; |
iut_cachan01 | 0:14e97aa401f3 | 200 | |
iut_cachan01 | 0:14e97aa401f3 | 201 | if (m_BitmapHeader.BitCount == 1) { |
iut_cachan01 | 0:14e97aa401f3 | 202 | ColorTableSize = 2; |
iut_cachan01 | 0:14e97aa401f3 | 203 | } else if (m_BitmapHeader.BitCount == 4) { |
iut_cachan01 | 0:14e97aa401f3 | 204 | ColorTableSize = 16; |
iut_cachan01 | 0:14e97aa401f3 | 205 | } else if (m_BitmapHeader.BitCount == 8) { |
iut_cachan01 | 0:14e97aa401f3 | 206 | ColorTableSize = 256; |
iut_cachan01 | 0:14e97aa401f3 | 207 | } |
iut_cachan01 | 0:14e97aa401f3 | 208 | |
iut_cachan01 | 0:14e97aa401f3 | 209 | // Always allocate full sized color table |
iut_cachan01 | 0:14e97aa401f3 | 210 | |
iut_cachan01 | 0:14e97aa401f3 | 211 | BGRA* ColorTable = new BGRA[ColorTableSize]; // std::bad_alloc exception should be thrown if memory is not available |
iut_cachan01 | 0:14e97aa401f3 | 212 | |
iut_cachan01 | 0:14e97aa401f3 | 213 | file.read((char*) ColorTable, sizeof(BGRA) * m_BitmapHeader.ClrUsed); |
iut_cachan01 | 0:14e97aa401f3 | 214 | |
iut_cachan01 | 0:14e97aa401f3 | 215 | /* ... Color Table for 16 bits images are not supported yet */ |
iut_cachan01 | 0:14e97aa401f3 | 216 | |
iut_cachan01 | 0:14e97aa401f3 | 217 | m_BitmapSize = GetWidth() * GetHeight(); |
iut_cachan01 | 0:14e97aa401f3 | 218 | m_BitmapData = new BGRA[m_BitmapSize]; |
iut_cachan01 | 0:14e97aa401f3 | 219 | |
iut_cachan01 | 0:14e97aa401f3 | 220 | unsigned int LineWidth = ((GetWidth() * GetBitCount() / 8) + 3) & ~3; |
iut_cachan01 | 0:14e97aa401f3 | 221 | uint8_t *Line = new uint8_t[LineWidth]; |
iut_cachan01 | 0:14e97aa401f3 | 222 | |
iut_cachan01 | 0:14e97aa401f3 | 223 | file.seekg(m_BitmapFileHeader.BitsOffset, std::ios::beg); |
iut_cachan01 | 0:14e97aa401f3 | 224 | |
iut_cachan01 | 0:14e97aa401f3 | 225 | int Index = 0; |
iut_cachan01 | 0:14e97aa401f3 | 226 | bool Result = true; |
iut_cachan01 | 0:14e97aa401f3 | 227 | |
iut_cachan01 | 0:14e97aa401f3 | 228 | if (m_BitmapHeader.Compression == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 229 | for (unsigned int i = 0; i < GetHeight(); i++) { |
iut_cachan01 | 0:14e97aa401f3 | 230 | file.read((char*) Line, LineWidth); |
iut_cachan01 | 0:14e97aa401f3 | 231 | |
iut_cachan01 | 0:14e97aa401f3 | 232 | uint8_t *LinePtr = Line; |
iut_cachan01 | 0:14e97aa401f3 | 233 | |
iut_cachan01 | 0:14e97aa401f3 | 234 | for (unsigned int j = 0; j < GetWidth(); j++) { |
iut_cachan01 | 0:14e97aa401f3 | 235 | if (m_BitmapHeader.BitCount == 1) { |
iut_cachan01 | 0:14e97aa401f3 | 236 | uint32_t Color = *((uint8_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 237 | for (int k = 0; k < 8; k++) { |
iut_cachan01 | 0:14e97aa401f3 | 238 | m_BitmapData[Index].Red = ColorTable[Color & 0x80 ? 1 : 0].Red; |
iut_cachan01 | 0:14e97aa401f3 | 239 | m_BitmapData[Index].Green = ColorTable[Color & 0x80 ? 1 : 0].Green; |
iut_cachan01 | 0:14e97aa401f3 | 240 | m_BitmapData[Index].Blue = ColorTable[Color & 0x80 ? 1 : 0].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 241 | m_BitmapData[Index].Alpha = ColorTable[Color & 0x80 ? 1 : 0].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 242 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 243 | Color <<= 1; |
iut_cachan01 | 0:14e97aa401f3 | 244 | } |
iut_cachan01 | 0:14e97aa401f3 | 245 | LinePtr++; |
iut_cachan01 | 0:14e97aa401f3 | 246 | j += 7; |
iut_cachan01 | 0:14e97aa401f3 | 247 | } else if (m_BitmapHeader.BitCount == 4) { |
iut_cachan01 | 0:14e97aa401f3 | 248 | uint32_t Color = *((uint8_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 249 | m_BitmapData[Index].Red = ColorTable[(Color >> 4) & 0x0f].Red; |
iut_cachan01 | 0:14e97aa401f3 | 250 | m_BitmapData[Index].Green = ColorTable[(Color >> 4) & 0x0f].Green; |
iut_cachan01 | 0:14e97aa401f3 | 251 | m_BitmapData[Index].Blue = ColorTable[(Color >> 4) & 0x0f].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 252 | m_BitmapData[Index].Alpha = ColorTable[(Color >> 4) & 0x0f].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 253 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 254 | m_BitmapData[Index].Red = ColorTable[Color & 0x0f].Red; |
iut_cachan01 | 0:14e97aa401f3 | 255 | m_BitmapData[Index].Green = ColorTable[Color & 0x0f].Green; |
iut_cachan01 | 0:14e97aa401f3 | 256 | m_BitmapData[Index].Blue = ColorTable[Color & 0x0f].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 257 | m_BitmapData[Index].Alpha = ColorTable[Color & 0x0f].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 258 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 259 | LinePtr++; |
iut_cachan01 | 0:14e97aa401f3 | 260 | j++; |
iut_cachan01 | 0:14e97aa401f3 | 261 | } else if (m_BitmapHeader.BitCount == 8) { |
iut_cachan01 | 0:14e97aa401f3 | 262 | uint32_t Color = *((uint8_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 263 | m_BitmapData[Index].Red = ColorTable[Color].Red; |
iut_cachan01 | 0:14e97aa401f3 | 264 | m_BitmapData[Index].Green = ColorTable[Color].Green; |
iut_cachan01 | 0:14e97aa401f3 | 265 | m_BitmapData[Index].Blue = ColorTable[Color].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 266 | m_BitmapData[Index].Alpha = ColorTable[Color].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 267 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 268 | LinePtr++; |
iut_cachan01 | 0:14e97aa401f3 | 269 | } else if (m_BitmapHeader.BitCount == 16) { |
iut_cachan01 | 0:14e97aa401f3 | 270 | uint32_t Color = *((uint16_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 271 | m_BitmapData[Index].Red = ((Color >> 10) & 0x1f) << 3; |
iut_cachan01 | 0:14e97aa401f3 | 272 | m_BitmapData[Index].Green = ((Color >> 5) & 0x1f) << 3; |
iut_cachan01 | 0:14e97aa401f3 | 273 | m_BitmapData[Index].Blue = (Color & 0x1f) << 3; |
iut_cachan01 | 0:14e97aa401f3 | 274 | m_BitmapData[Index].Alpha = 255; |
iut_cachan01 | 0:14e97aa401f3 | 275 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 276 | LinePtr += 2; |
iut_cachan01 | 0:14e97aa401f3 | 277 | } else if (m_BitmapHeader.BitCount == 24) { |
iut_cachan01 | 0:14e97aa401f3 | 278 | uint32_t Color = *((uint32_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 279 | m_BitmapData[Index].Blue = Color & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 280 | m_BitmapData[Index].Green = (Color >> 8) & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 281 | m_BitmapData[Index].Red = (Color >> 16) & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 282 | m_BitmapData[Index].Alpha = 255; |
iut_cachan01 | 0:14e97aa401f3 | 283 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 284 | LinePtr += 3; |
iut_cachan01 | 0:14e97aa401f3 | 285 | } else if (m_BitmapHeader.BitCount == 32) { |
iut_cachan01 | 0:14e97aa401f3 | 286 | uint32_t Color = *((uint32_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 287 | m_BitmapData[Index].Blue = Color & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 288 | m_BitmapData[Index].Green = (Color >> 8) & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 289 | m_BitmapData[Index].Red = (Color >> 16) & 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 290 | m_BitmapData[Index].Alpha = Color >> 24; |
iut_cachan01 | 0:14e97aa401f3 | 291 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 292 | LinePtr += 4; |
iut_cachan01 | 0:14e97aa401f3 | 293 | } |
iut_cachan01 | 0:14e97aa401f3 | 294 | } |
iut_cachan01 | 0:14e97aa401f3 | 295 | } |
iut_cachan01 | 0:14e97aa401f3 | 296 | } else if (m_BitmapHeader.Compression == 1) { // RLE 8 |
iut_cachan01 | 0:14e97aa401f3 | 297 | uint8_t Count = 0; |
iut_cachan01 | 0:14e97aa401f3 | 298 | uint8_t ColorIndex = 0; |
iut_cachan01 | 0:14e97aa401f3 | 299 | int x = 0, y = 0; |
iut_cachan01 | 0:14e97aa401f3 | 300 | |
iut_cachan01 | 0:14e97aa401f3 | 301 | while (file.eof() == false) { |
iut_cachan01 | 0:14e97aa401f3 | 302 | file.read((char*) &Count, sizeof(uint8_t)); |
iut_cachan01 | 0:14e97aa401f3 | 303 | file.read((char*) &ColorIndex, sizeof(uint8_t)); |
iut_cachan01 | 0:14e97aa401f3 | 304 | |
iut_cachan01 | 0:14e97aa401f3 | 305 | if (Count > 0) { |
iut_cachan01 | 0:14e97aa401f3 | 306 | Index = x + y * GetWidth(); |
iut_cachan01 | 0:14e97aa401f3 | 307 | for (int k = 0; k < Count; k++) { |
iut_cachan01 | 0:14e97aa401f3 | 308 | m_BitmapData[Index + k].Red = ColorTable[ColorIndex].Red; |
iut_cachan01 | 0:14e97aa401f3 | 309 | m_BitmapData[Index + k].Green = ColorTable[ColorIndex].Green; |
iut_cachan01 | 0:14e97aa401f3 | 310 | m_BitmapData[Index + k].Blue = ColorTable[ColorIndex].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 311 | m_BitmapData[Index + k].Alpha = ColorTable[ColorIndex].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 312 | } |
iut_cachan01 | 0:14e97aa401f3 | 313 | x += Count; |
iut_cachan01 | 0:14e97aa401f3 | 314 | } else if (Count == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 315 | int Flag = ColorIndex; |
iut_cachan01 | 0:14e97aa401f3 | 316 | if (Flag == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 317 | x = 0; |
iut_cachan01 | 0:14e97aa401f3 | 318 | y++; |
iut_cachan01 | 0:14e97aa401f3 | 319 | } else if (Flag == 1) { |
iut_cachan01 | 0:14e97aa401f3 | 320 | break; |
iut_cachan01 | 0:14e97aa401f3 | 321 | } else if (Flag == 2) { |
iut_cachan01 | 0:14e97aa401f3 | 322 | char rx = 0; |
iut_cachan01 | 0:14e97aa401f3 | 323 | char ry = 0; |
iut_cachan01 | 0:14e97aa401f3 | 324 | file.read((char*) &rx, sizeof(char)); |
iut_cachan01 | 0:14e97aa401f3 | 325 | file.read((char*) &ry, sizeof(char)); |
iut_cachan01 | 0:14e97aa401f3 | 326 | x += rx; |
iut_cachan01 | 0:14e97aa401f3 | 327 | y += ry; |
iut_cachan01 | 0:14e97aa401f3 | 328 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 329 | Count = Flag; |
iut_cachan01 | 0:14e97aa401f3 | 330 | Index = x + y * GetWidth(); |
iut_cachan01 | 0:14e97aa401f3 | 331 | for (int k = 0; k < Count; k++) { |
iut_cachan01 | 0:14e97aa401f3 | 332 | file.read((char*) &ColorIndex, sizeof(uint8_t)); |
iut_cachan01 | 0:14e97aa401f3 | 333 | m_BitmapData[Index + k].Red = ColorTable[ColorIndex].Red; |
iut_cachan01 | 0:14e97aa401f3 | 334 | m_BitmapData[Index + k].Green = ColorTable[ColorIndex].Green; |
iut_cachan01 | 0:14e97aa401f3 | 335 | m_BitmapData[Index + k].Blue = ColorTable[ColorIndex].Blue; |
iut_cachan01 | 0:14e97aa401f3 | 336 | m_BitmapData[Index + k].Alpha = ColorTable[ColorIndex].Alpha; |
iut_cachan01 | 0:14e97aa401f3 | 337 | } |
iut_cachan01 | 0:14e97aa401f3 | 338 | x += Count; |
iut_cachan01 | 0:14e97aa401f3 | 339 | // Attention: Current Microsoft STL implementation seems to be buggy, tellg() always returns 0. |
iut_cachan01 | 0:14e97aa401f3 | 340 | if (file.tellg() & 1) { |
iut_cachan01 | 0:14e97aa401f3 | 341 | file.seekg(1, std::ios::cur); |
iut_cachan01 | 0:14e97aa401f3 | 342 | } |
iut_cachan01 | 0:14e97aa401f3 | 343 | } |
iut_cachan01 | 0:14e97aa401f3 | 344 | } |
iut_cachan01 | 0:14e97aa401f3 | 345 | } |
iut_cachan01 | 0:14e97aa401f3 | 346 | } else if (m_BitmapHeader.Compression == 2) { // RLE 4 |
iut_cachan01 | 0:14e97aa401f3 | 347 | /* RLE 4 is not supported */ |
iut_cachan01 | 0:14e97aa401f3 | 348 | Result = false; |
iut_cachan01 | 0:14e97aa401f3 | 349 | } else if (m_BitmapHeader.Compression == 3) { // BITFIELDS |
iut_cachan01 | 0:14e97aa401f3 | 350 | |
iut_cachan01 | 0:14e97aa401f3 | 351 | /* We assumes that mask of each color component can be in any order */ |
iut_cachan01 | 0:14e97aa401f3 | 352 | |
iut_cachan01 | 0:14e97aa401f3 | 353 | uint32_t BitCountRed = CColor::BitCountByMask(m_BitmapHeader.RedMask); |
iut_cachan01 | 0:14e97aa401f3 | 354 | uint32_t BitCountGreen = CColor::BitCountByMask(m_BitmapHeader.GreenMask); |
iut_cachan01 | 0:14e97aa401f3 | 355 | uint32_t BitCountBlue = CColor::BitCountByMask(m_BitmapHeader.BlueMask); |
iut_cachan01 | 0:14e97aa401f3 | 356 | uint32_t BitCountAlpha = CColor::BitCountByMask(m_BitmapHeader.AlphaMask); |
iut_cachan01 | 0:14e97aa401f3 | 357 | |
iut_cachan01 | 0:14e97aa401f3 | 358 | for (unsigned int i = 0; i < GetHeight(); i++) { |
iut_cachan01 | 0:14e97aa401f3 | 359 | file.read((char*) Line, LineWidth); |
iut_cachan01 | 0:14e97aa401f3 | 360 | |
iut_cachan01 | 0:14e97aa401f3 | 361 | uint8_t *LinePtr = Line; |
iut_cachan01 | 0:14e97aa401f3 | 362 | |
iut_cachan01 | 0:14e97aa401f3 | 363 | for (unsigned int j = 0; j < GetWidth(); j++) { |
iut_cachan01 | 0:14e97aa401f3 | 364 | |
iut_cachan01 | 0:14e97aa401f3 | 365 | uint32_t Color = 0; |
iut_cachan01 | 0:14e97aa401f3 | 366 | |
iut_cachan01 | 0:14e97aa401f3 | 367 | if (m_BitmapHeader.BitCount == 16) { |
iut_cachan01 | 0:14e97aa401f3 | 368 | Color = *((uint16_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 369 | LinePtr += 2; |
iut_cachan01 | 0:14e97aa401f3 | 370 | } else if (m_BitmapHeader.BitCount == 32) { |
iut_cachan01 | 0:14e97aa401f3 | 371 | Color = *((uint32_t*) LinePtr); |
iut_cachan01 | 0:14e97aa401f3 | 372 | LinePtr += 4; |
iut_cachan01 | 0:14e97aa401f3 | 373 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 374 | // Other formats are not valid |
iut_cachan01 | 0:14e97aa401f3 | 375 | } |
iut_cachan01 | 0:14e97aa401f3 | 376 | m_BitmapData[Index].Red = CColor::Convert(CColor::ComponentByMask(Color, m_BitmapHeader.RedMask), BitCountRed, 8); |
iut_cachan01 | 0:14e97aa401f3 | 377 | m_BitmapData[Index].Green = CColor::Convert(CColor::ComponentByMask(Color, m_BitmapHeader.GreenMask), BitCountGreen, 8); |
iut_cachan01 | 0:14e97aa401f3 | 378 | m_BitmapData[Index].Blue = CColor::Convert(CColor::ComponentByMask(Color, m_BitmapHeader.BlueMask), BitCountBlue, 8); |
iut_cachan01 | 0:14e97aa401f3 | 379 | m_BitmapData[Index].Alpha = CColor::Convert(CColor::ComponentByMask(Color, m_BitmapHeader.AlphaMask), BitCountAlpha, 8); |
iut_cachan01 | 0:14e97aa401f3 | 380 | |
iut_cachan01 | 0:14e97aa401f3 | 381 | Index++; |
iut_cachan01 | 0:14e97aa401f3 | 382 | } |
iut_cachan01 | 0:14e97aa401f3 | 383 | } |
iut_cachan01 | 0:14e97aa401f3 | 384 | } |
iut_cachan01 | 0:14e97aa401f3 | 385 | |
iut_cachan01 | 0:14e97aa401f3 | 386 | delete [] ColorTable; |
iut_cachan01 | 0:14e97aa401f3 | 387 | delete [] Line; |
iut_cachan01 | 0:14e97aa401f3 | 388 | |
iut_cachan01 | 0:14e97aa401f3 | 389 | file.close(); |
iut_cachan01 | 0:14e97aa401f3 | 390 | return Result; |
iut_cachan01 | 0:14e97aa401f3 | 391 | } |
iut_cachan01 | 0:14e97aa401f3 | 392 | |
iut_cachan01 | 0:14e97aa401f3 | 393 | bool Save(const char* Filename, unsigned int BitCount = 32) { |
iut_cachan01 | 0:14e97aa401f3 | 394 | bool Result = true; |
iut_cachan01 | 0:14e97aa401f3 | 395 | |
iut_cachan01 | 0:14e97aa401f3 | 396 | std::ofstream file(Filename, std::ios::out | std::ios::binary); |
iut_cachan01 | 0:14e97aa401f3 | 397 | |
iut_cachan01 | 0:14e97aa401f3 | 398 | if (file.is_open() == false) { |
iut_cachan01 | 0:14e97aa401f3 | 399 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 400 | } |
iut_cachan01 | 0:14e97aa401f3 | 401 | |
iut_cachan01 | 0:14e97aa401f3 | 402 | BITMAP_FILEHEADER bfh; |
iut_cachan01 | 0:14e97aa401f3 | 403 | BITMAP_HEADER bh; |
iut_cachan01 | 0:14e97aa401f3 | 404 | memset(&bfh, 0, sizeof(bfh)); |
iut_cachan01 | 0:14e97aa401f3 | 405 | memset(&bh, 0, sizeof(bh)); |
iut_cachan01 | 0:14e97aa401f3 | 406 | |
iut_cachan01 | 0:14e97aa401f3 | 407 | bfh.Signature = BITMAP_SIGNATURE; |
iut_cachan01 | 0:14e97aa401f3 | 408 | bfh.BitsOffset = BITMAP_FILEHEADER_SIZE + sizeof(BITMAP_HEADER); |
iut_cachan01 | 0:14e97aa401f3 | 409 | bfh.Size = (GetWidth() * GetHeight() * BitCount) / 8 + bfh.BitsOffset; |
iut_cachan01 | 0:14e97aa401f3 | 410 | |
iut_cachan01 | 0:14e97aa401f3 | 411 | bh.HeaderSize = sizeof(BITMAP_HEADER); |
iut_cachan01 | 0:14e97aa401f3 | 412 | bh.BitCount = BitCount; |
iut_cachan01 | 0:14e97aa401f3 | 413 | |
iut_cachan01 | 0:14e97aa401f3 | 414 | if (BitCount == 32) { |
iut_cachan01 | 0:14e97aa401f3 | 415 | bh.Compression = 3; // BITFIELD |
iut_cachan01 | 0:14e97aa401f3 | 416 | bh.AlphaMask = 0xff000000; |
iut_cachan01 | 0:14e97aa401f3 | 417 | bh.BlueMask = 0x00ff0000; |
iut_cachan01 | 0:14e97aa401f3 | 418 | bh.GreenMask = 0x0000ff00; |
iut_cachan01 | 0:14e97aa401f3 | 419 | bh.RedMask = 0x000000ff; |
iut_cachan01 | 0:14e97aa401f3 | 420 | } else if (BitCount == 16) { |
iut_cachan01 | 0:14e97aa401f3 | 421 | bh.Compression = 3; // BITFIELD |
iut_cachan01 | 0:14e97aa401f3 | 422 | bh.AlphaMask = 0x00000000; |
iut_cachan01 | 0:14e97aa401f3 | 423 | bh.BlueMask = 0x0000001f; |
iut_cachan01 | 0:14e97aa401f3 | 424 | bh.GreenMask = 0x000007E0; |
iut_cachan01 | 0:14e97aa401f3 | 425 | bh.RedMask = 0x0000F800; |
iut_cachan01 | 0:14e97aa401f3 | 426 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 427 | bh.Compression = 0; // RGB |
iut_cachan01 | 0:14e97aa401f3 | 428 | } |
iut_cachan01 | 0:14e97aa401f3 | 429 | |
iut_cachan01 | 0:14e97aa401f3 | 430 | unsigned int LineWidth = (GetWidth() + 3) & ~3; |
iut_cachan01 | 0:14e97aa401f3 | 431 | |
iut_cachan01 | 0:14e97aa401f3 | 432 | bh.Planes = 1; |
iut_cachan01 | 0:14e97aa401f3 | 433 | bh.Height = GetHeight(); |
iut_cachan01 | 0:14e97aa401f3 | 434 | bh.Width = GetWidth(); |
iut_cachan01 | 0:14e97aa401f3 | 435 | bh.SizeImage = (LineWidth * BitCount * GetHeight()) / 8; |
iut_cachan01 | 0:14e97aa401f3 | 436 | bh.PelsPerMeterX = 3780; |
iut_cachan01 | 0:14e97aa401f3 | 437 | bh.PelsPerMeterY = 3780; |
iut_cachan01 | 0:14e97aa401f3 | 438 | |
iut_cachan01 | 0:14e97aa401f3 | 439 | if (BitCount == 32) { |
iut_cachan01 | 0:14e97aa401f3 | 440 | file.write((char*) &bfh, sizeof(BITMAP_FILEHEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 441 | file.write((char*) &bh, sizeof(BITMAP_HEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 442 | file.write((char*) m_BitmapData, bh.SizeImage); |
iut_cachan01 | 0:14e97aa401f3 | 443 | } else if (BitCount < 16) { |
iut_cachan01 | 0:14e97aa401f3 | 444 | uint8_t* Bitmap = new uint8_t[bh.SizeImage]; |
iut_cachan01 | 0:14e97aa401f3 | 445 | |
iut_cachan01 | 0:14e97aa401f3 | 446 | BGRA *Palette = 0; |
iut_cachan01 | 0:14e97aa401f3 | 447 | unsigned int PaletteSize = 0; |
iut_cachan01 | 0:14e97aa401f3 | 448 | |
iut_cachan01 | 0:14e97aa401f3 | 449 | if (GetBitsWithPalette(Bitmap, bh.SizeImage, BitCount, Palette, PaletteSize)) { |
iut_cachan01 | 0:14e97aa401f3 | 450 | bfh.BitsOffset += PaletteSize * sizeof(BGRA); |
iut_cachan01 | 0:14e97aa401f3 | 451 | |
iut_cachan01 | 0:14e97aa401f3 | 452 | file.write((char*) &bfh, BITMAP_FILEHEADER_SIZE); |
iut_cachan01 | 0:14e97aa401f3 | 453 | file.write((char*) &bh, sizeof(BITMAP_HEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 454 | file.write((char*) Palette, PaletteSize * sizeof(BGRA)); |
iut_cachan01 | 0:14e97aa401f3 | 455 | file.write((char*) Bitmap, bh.SizeImage); |
iut_cachan01 | 0:14e97aa401f3 | 456 | } |
iut_cachan01 | 0:14e97aa401f3 | 457 | delete [] Bitmap; |
iut_cachan01 | 0:14e97aa401f3 | 458 | delete [] Palette; |
iut_cachan01 | 0:14e97aa401f3 | 459 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 460 | uint32_t RedMask = 0; |
iut_cachan01 | 0:14e97aa401f3 | 461 | uint32_t GreenMask = 0; |
iut_cachan01 | 0:14e97aa401f3 | 462 | uint32_t BlueMask = 0; |
iut_cachan01 | 0:14e97aa401f3 | 463 | uint32_t AlphaMask = 0; |
iut_cachan01 | 0:14e97aa401f3 | 464 | |
iut_cachan01 | 0:14e97aa401f3 | 465 | if (BitCount == 16) { |
iut_cachan01 | 0:14e97aa401f3 | 466 | RedMask = 0x0000F800; |
iut_cachan01 | 0:14e97aa401f3 | 467 | GreenMask = 0x000007E0; |
iut_cachan01 | 0:14e97aa401f3 | 468 | BlueMask = 0x0000001F; |
iut_cachan01 | 0:14e97aa401f3 | 469 | AlphaMask = 0x00000000; |
iut_cachan01 | 0:14e97aa401f3 | 470 | } else if (BitCount == 24) { |
iut_cachan01 | 0:14e97aa401f3 | 471 | RedMask = 0x00FF0000; |
iut_cachan01 | 0:14e97aa401f3 | 472 | GreenMask = 0x0000FF00; |
iut_cachan01 | 0:14e97aa401f3 | 473 | BlueMask = 0x000000FF; |
iut_cachan01 | 0:14e97aa401f3 | 474 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 475 | // Other color formats are not valid |
iut_cachan01 | 0:14e97aa401f3 | 476 | Result = false; |
iut_cachan01 | 0:14e97aa401f3 | 477 | } |
iut_cachan01 | 0:14e97aa401f3 | 478 | |
iut_cachan01 | 0:14e97aa401f3 | 479 | if (Result) { |
iut_cachan01 | 0:14e97aa401f3 | 480 | if (GetBits(NULL, bh.SizeImage, RedMask, GreenMask, BlueMask, AlphaMask)) { |
iut_cachan01 | 0:14e97aa401f3 | 481 | uint8_t* Bitmap = new uint8_t[bh.SizeImage]; |
iut_cachan01 | 0:14e97aa401f3 | 482 | if (GetBits(Bitmap, bh.SizeImage, RedMask, GreenMask, BlueMask, AlphaMask)) { |
iut_cachan01 | 0:14e97aa401f3 | 483 | file.write((char*) &bfh, sizeof(BITMAP_FILEHEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 484 | file.write((char*) &bh, sizeof(BITMAP_HEADER)); |
iut_cachan01 | 0:14e97aa401f3 | 485 | file.write((char*) Bitmap, bh.SizeImage); |
iut_cachan01 | 0:14e97aa401f3 | 486 | } |
iut_cachan01 | 0:14e97aa401f3 | 487 | delete [] Bitmap; |
iut_cachan01 | 0:14e97aa401f3 | 488 | } |
iut_cachan01 | 0:14e97aa401f3 | 489 | } |
iut_cachan01 | 0:14e97aa401f3 | 490 | } |
iut_cachan01 | 0:14e97aa401f3 | 491 | |
iut_cachan01 | 0:14e97aa401f3 | 492 | file.close(); |
iut_cachan01 | 0:14e97aa401f3 | 493 | return Result; |
iut_cachan01 | 0:14e97aa401f3 | 494 | } |
iut_cachan01 | 0:14e97aa401f3 | 495 | |
iut_cachan01 | 0:14e97aa401f3 | 496 | unsigned int GetWidth() { |
iut_cachan01 | 0:14e97aa401f3 | 497 | /* Add plausibility test */ |
iut_cachan01 | 0:14e97aa401f3 | 498 | // if (abs(m_BitmapHeader.Width) > 8192) { |
iut_cachan01 | 0:14e97aa401f3 | 499 | // m_BitmapHeader.Width = 8192; |
iut_cachan01 | 0:14e97aa401f3 | 500 | // } |
iut_cachan01 | 0:14e97aa401f3 | 501 | return m_BitmapHeader.Width < 0 ? -m_BitmapHeader.Width : m_BitmapHeader.Width; |
iut_cachan01 | 0:14e97aa401f3 | 502 | } |
iut_cachan01 | 0:14e97aa401f3 | 503 | |
iut_cachan01 | 0:14e97aa401f3 | 504 | unsigned int GetHeight() { |
iut_cachan01 | 0:14e97aa401f3 | 505 | /* Add plausibility test */ |
iut_cachan01 | 0:14e97aa401f3 | 506 | // if (abs(m_BitmapHeader.Height) > 8192) { |
iut_cachan01 | 0:14e97aa401f3 | 507 | // m_BitmapHeader.Height = 8192; |
iut_cachan01 | 0:14e97aa401f3 | 508 | // } |
iut_cachan01 | 0:14e97aa401f3 | 509 | return m_BitmapHeader.Height < 0 ? -m_BitmapHeader.Height : m_BitmapHeader.Height; |
iut_cachan01 | 0:14e97aa401f3 | 510 | } |
iut_cachan01 | 0:14e97aa401f3 | 511 | |
iut_cachan01 | 0:14e97aa401f3 | 512 | unsigned int GetBitCount() { |
iut_cachan01 | 0:14e97aa401f3 | 513 | /* Add plausibility test */ |
iut_cachan01 | 0:14e97aa401f3 | 514 | // if (m_BitmapHeader.BitCount > 32) { |
iut_cachan01 | 0:14e97aa401f3 | 515 | // m_BitmapHeader.BitCount = 32; |
iut_cachan01 | 0:14e97aa401f3 | 516 | // } |
iut_cachan01 | 0:14e97aa401f3 | 517 | return m_BitmapHeader.BitCount; |
iut_cachan01 | 0:14e97aa401f3 | 518 | } |
iut_cachan01 | 0:14e97aa401f3 | 519 | |
iut_cachan01 | 0:14e97aa401f3 | 520 | /* Copies internal RGBA buffer to user specified buffer */ |
iut_cachan01 | 0:14e97aa401f3 | 521 | |
iut_cachan01 | 0:14e97aa401f3 | 522 | bool GetBits(void* Buffer, unsigned int &Size) { |
iut_cachan01 | 0:14e97aa401f3 | 523 | bool Result = false; |
iut_cachan01 | 0:14e97aa401f3 | 524 | if (Size == 0 || Buffer == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 525 | Size = m_BitmapSize * sizeof(RGBA); |
iut_cachan01 | 0:14e97aa401f3 | 526 | Result = m_BitmapSize != 0; |
iut_cachan01 | 0:14e97aa401f3 | 527 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 528 | memcpy(Buffer, m_BitmapData, Size); |
iut_cachan01 | 0:14e97aa401f3 | 529 | Result = true; |
iut_cachan01 | 0:14e97aa401f3 | 530 | } |
iut_cachan01 | 0:14e97aa401f3 | 531 | return Result; |
iut_cachan01 | 0:14e97aa401f3 | 532 | } |
iut_cachan01 | 0:14e97aa401f3 | 533 | |
iut_cachan01 | 0:14e97aa401f3 | 534 | /* Returns internal RGBA buffer */ |
iut_cachan01 | 0:14e97aa401f3 | 535 | |
iut_cachan01 | 0:14e97aa401f3 | 536 | void* GetBits() { |
iut_cachan01 | 0:14e97aa401f3 | 537 | return m_BitmapData; |
iut_cachan01 | 0:14e97aa401f3 | 538 | } |
iut_cachan01 | 0:14e97aa401f3 | 539 | |
iut_cachan01 | 0:14e97aa401f3 | 540 | /* Copies internal RGBA buffer to user specified buffer and converts it into destination |
iut_cachan01 | 0:14e97aa401f3 | 541 | * bit format specified by component masks. |
iut_cachan01 | 0:14e97aa401f3 | 542 | * |
iut_cachan01 | 0:14e97aa401f3 | 543 | * Typical Bitmap color formats (BGR/BGRA): |
iut_cachan01 | 0:14e97aa401f3 | 544 | * |
iut_cachan01 | 0:14e97aa401f3 | 545 | * Masks for 16 bit (5-5-5): ALPHA = 0x00000000, RED = 0x00007C00, GREEN = 0x000003E0, BLUE = 0x0000001F |
iut_cachan01 | 0:14e97aa401f3 | 546 | * Masks for 16 bit (5-6-5): ALPHA = 0x00000000, RED = 0x0000F800, GREEN = 0x000007E0, BLUE = 0x0000001F |
iut_cachan01 | 0:14e97aa401f3 | 547 | * Masks for 24 bit: ALPHA = 0x00000000, RED = 0x00FF0000, GREEN = 0x0000FF00, BLUE = 0x000000FF |
iut_cachan01 | 0:14e97aa401f3 | 548 | * Masks for 32 bit: ALPHA = 0xFF000000, RED = 0x00FF0000, GREEN = 0x0000FF00, BLUE = 0x000000FF |
iut_cachan01 | 0:14e97aa401f3 | 549 | * |
iut_cachan01 | 0:14e97aa401f3 | 550 | * Other color formats (RGB/RGBA): |
iut_cachan01 | 0:14e97aa401f3 | 551 | * |
iut_cachan01 | 0:14e97aa401f3 | 552 | * Masks for 32 bit (RGBA): ALPHA = 0xFF000000, RED = 0x000000FF, GREEN = 0x0000FF00, BLUE = 0x00FF0000 |
iut_cachan01 | 0:14e97aa401f3 | 553 | * |
iut_cachan01 | 0:14e97aa401f3 | 554 | * Bit count will be rounded to next 8 bit boundary. If IncludePadding is true, it will be ensured |
iut_cachan01 | 0:14e97aa401f3 | 555 | * that line width is a multiple of 4. padding bytes are included if necessary. |
iut_cachan01 | 0:14e97aa401f3 | 556 | * |
iut_cachan01 | 0:14e97aa401f3 | 557 | * NOTE: systems with big endian byte order may require masks in inversion order. |
iut_cachan01 | 0:14e97aa401f3 | 558 | */ |
iut_cachan01 | 0:14e97aa401f3 | 559 | |
iut_cachan01 | 0:14e97aa401f3 | 560 | bool GetBits(void* Buffer, unsigned int &Size, unsigned int RedMask, unsigned int GreenMask, unsigned int BlueMask, unsigned int AlphaMask, bool IncludePadding = true) { |
iut_cachan01 | 0:14e97aa401f3 | 561 | bool Result = false; |
iut_cachan01 | 0:14e97aa401f3 | 562 | |
iut_cachan01 | 0:14e97aa401f3 | 563 | uint32_t BitCountRed = CColor::BitCountByMask(RedMask); |
iut_cachan01 | 0:14e97aa401f3 | 564 | uint32_t BitCountGreen = CColor::BitCountByMask(GreenMask); |
iut_cachan01 | 0:14e97aa401f3 | 565 | uint32_t BitCountBlue = CColor::BitCountByMask(BlueMask); |
iut_cachan01 | 0:14e97aa401f3 | 566 | uint32_t BitCountAlpha = CColor::BitCountByMask(AlphaMask); |
iut_cachan01 | 0:14e97aa401f3 | 567 | |
iut_cachan01 | 0:14e97aa401f3 | 568 | unsigned int BitCount = (BitCountRed + BitCountGreen + BitCountBlue + BitCountAlpha + 7) & ~7; |
iut_cachan01 | 0:14e97aa401f3 | 569 | |
iut_cachan01 | 0:14e97aa401f3 | 570 | if (BitCount > 32) { |
iut_cachan01 | 0:14e97aa401f3 | 571 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 572 | } |
iut_cachan01 | 0:14e97aa401f3 | 573 | |
iut_cachan01 | 0:14e97aa401f3 | 574 | unsigned int w = GetWidth(); |
iut_cachan01 | 0:14e97aa401f3 | 575 | //unsigned int LineWidth = (w + 3) & ~3; |
iut_cachan01 | 0:14e97aa401f3 | 576 | unsigned int dataBytesPerLine = (w * BitCount + 7) / 8; |
iut_cachan01 | 0:14e97aa401f3 | 577 | unsigned int LineWidth = (dataBytesPerLine + 3) & ~3; |
iut_cachan01 | 0:14e97aa401f3 | 578 | |
iut_cachan01 | 0:14e97aa401f3 | 579 | if (Size == 0 || Buffer == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 580 | //Size = (LineWidth * GetHeight() * BitCount) / 8 + sizeof(unsigned int); |
iut_cachan01 | 0:14e97aa401f3 | 581 | Size = (GetWidth() * GetHeight() * BitCount) / 8 + sizeof(unsigned int); |
iut_cachan01 | 0:14e97aa401f3 | 582 | return true; |
iut_cachan01 | 0:14e97aa401f3 | 583 | } |
iut_cachan01 | 0:14e97aa401f3 | 584 | |
iut_cachan01 | 0:14e97aa401f3 | 585 | uint8_t* BufferPtr = (uint8_t*) Buffer; |
iut_cachan01 | 0:14e97aa401f3 | 586 | |
iut_cachan01 | 0:14e97aa401f3 | 587 | Result = true; |
iut_cachan01 | 0:14e97aa401f3 | 588 | |
iut_cachan01 | 0:14e97aa401f3 | 589 | uint32_t BitPosRed = CColor::BitPositionByMask(RedMask); |
iut_cachan01 | 0:14e97aa401f3 | 590 | uint32_t BitPosGreen = CColor::BitPositionByMask(GreenMask); |
iut_cachan01 | 0:14e97aa401f3 | 591 | uint32_t BitPosBlue = CColor::BitPositionByMask(BlueMask); |
iut_cachan01 | 0:14e97aa401f3 | 592 | uint32_t BitPosAlpha = CColor::BitPositionByMask(AlphaMask); |
iut_cachan01 | 0:14e97aa401f3 | 593 | |
iut_cachan01 | 0:14e97aa401f3 | 594 | unsigned int j = 0; |
iut_cachan01 | 0:14e97aa401f3 | 595 | |
iut_cachan01 | 0:14e97aa401f3 | 596 | for (unsigned int i = 0; i < m_BitmapSize; i++) { |
iut_cachan01 | 0:14e97aa401f3 | 597 | *(uint32_t*) BufferPtr = |
iut_cachan01 | 0:14e97aa401f3 | 598 | (CColor::Convert(m_BitmapData[i].Blue, 8, BitCountBlue) << BitPosBlue) | |
iut_cachan01 | 0:14e97aa401f3 | 599 | (CColor::Convert(m_BitmapData[i].Green, 8, BitCountGreen) << BitPosGreen) | |
iut_cachan01 | 0:14e97aa401f3 | 600 | (CColor::Convert(m_BitmapData[i].Red, 8, BitCountRed) << BitPosRed) | |
iut_cachan01 | 0:14e97aa401f3 | 601 | (CColor::Convert(m_BitmapData[i].Alpha, 8, BitCountAlpha) << BitPosAlpha); |
iut_cachan01 | 0:14e97aa401f3 | 602 | |
iut_cachan01 | 0:14e97aa401f3 | 603 | if (IncludePadding) { |
iut_cachan01 | 0:14e97aa401f3 | 604 | j++; |
iut_cachan01 | 0:14e97aa401f3 | 605 | if (j >= w) { |
iut_cachan01 | 0:14e97aa401f3 | 606 | for (unsigned int k = 0; k < LineWidth - dataBytesPerLine; k++) { |
iut_cachan01 | 0:14e97aa401f3 | 607 | BufferPtr += (BitCount >> 3); |
iut_cachan01 | 0:14e97aa401f3 | 608 | } |
iut_cachan01 | 0:14e97aa401f3 | 609 | j = 0; |
iut_cachan01 | 0:14e97aa401f3 | 610 | } |
iut_cachan01 | 0:14e97aa401f3 | 611 | } |
iut_cachan01 | 0:14e97aa401f3 | 612 | |
iut_cachan01 | 0:14e97aa401f3 | 613 | BufferPtr += (BitCount >> 3); |
iut_cachan01 | 0:14e97aa401f3 | 614 | } |
iut_cachan01 | 0:14e97aa401f3 | 615 | |
iut_cachan01 | 0:14e97aa401f3 | 616 | Size -= sizeof(unsigned int); |
iut_cachan01 | 0:14e97aa401f3 | 617 | |
iut_cachan01 | 0:14e97aa401f3 | 618 | return Result; |
iut_cachan01 | 0:14e97aa401f3 | 619 | } |
iut_cachan01 | 0:14e97aa401f3 | 620 | |
iut_cachan01 | 0:14e97aa401f3 | 621 | /* See GetBits(). |
iut_cachan01 | 0:14e97aa401f3 | 622 | * It creates a corresponding color table (palette) which have to be destroyed by the user after usage. |
iut_cachan01 | 0:14e97aa401f3 | 623 | * |
iut_cachan01 | 0:14e97aa401f3 | 624 | * Supported Bit depths are: 4, 8 |
iut_cachan01 | 0:14e97aa401f3 | 625 | * |
iut_cachan01 | 0:14e97aa401f3 | 626 | * Todo: Optimize, use optimized palette, do ditehring (see my dithering class), support padding for 4 bit bitmaps |
iut_cachan01 | 0:14e97aa401f3 | 627 | */ |
iut_cachan01 | 0:14e97aa401f3 | 628 | |
iut_cachan01 | 0:14e97aa401f3 | 629 | bool GetBitsWithPalette(void* Buffer, unsigned int &Size, unsigned int BitCount, BGRA* &Palette, unsigned int &PaletteSize, bool OptimalPalette = false, bool IncludePadding = true) { |
iut_cachan01 | 0:14e97aa401f3 | 630 | bool Result = false; |
iut_cachan01 | 0:14e97aa401f3 | 631 | |
iut_cachan01 | 0:14e97aa401f3 | 632 | if (BitCount > 16) { |
iut_cachan01 | 0:14e97aa401f3 | 633 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 634 | } |
iut_cachan01 | 0:14e97aa401f3 | 635 | |
iut_cachan01 | 0:14e97aa401f3 | 636 | unsigned int w = GetWidth(); |
iut_cachan01 | 0:14e97aa401f3 | 637 | unsigned int dataBytesPerLine = (w * BitCount + 7) / 8; |
iut_cachan01 | 0:14e97aa401f3 | 638 | unsigned int LineWidth = (dataBytesPerLine + 3) & ~3; |
iut_cachan01 | 0:14e97aa401f3 | 639 | |
iut_cachan01 | 0:14e97aa401f3 | 640 | if (Size == 0 || Buffer == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 641 | Size = (LineWidth * GetHeight() * BitCount) / 8; |
iut_cachan01 | 0:14e97aa401f3 | 642 | return true; |
iut_cachan01 | 0:14e97aa401f3 | 643 | } |
iut_cachan01 | 0:14e97aa401f3 | 644 | |
iut_cachan01 | 0:14e97aa401f3 | 645 | |
iut_cachan01 | 0:14e97aa401f3 | 646 | if (OptimalPalette) { |
iut_cachan01 | 0:14e97aa401f3 | 647 | PaletteSize = 0; |
iut_cachan01 | 0:14e97aa401f3 | 648 | // Not implemented |
iut_cachan01 | 0:14e97aa401f3 | 649 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 650 | if (BitCount == 1) { |
iut_cachan01 | 0:14e97aa401f3 | 651 | PaletteSize = 2; |
iut_cachan01 | 0:14e97aa401f3 | 652 | // Not implemented: Who need that? |
iut_cachan01 | 0:14e97aa401f3 | 653 | } else if (BitCount == 4) { // 2:2:1 |
iut_cachan01 | 0:14e97aa401f3 | 654 | PaletteSize = 16; |
iut_cachan01 | 0:14e97aa401f3 | 655 | Palette = new BGRA[PaletteSize]; |
iut_cachan01 | 0:14e97aa401f3 | 656 | for (int r = 0; r < 4; r++) { |
iut_cachan01 | 0:14e97aa401f3 | 657 | for (int g = 0; g < 2; g++) { |
iut_cachan01 | 0:14e97aa401f3 | 658 | for (int b = 0; b < 2; b++) { |
iut_cachan01 | 0:14e97aa401f3 | 659 | Palette[r | g << 2 | b << 3].Red = r ? (r << 6) | 0x3f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 660 | Palette[r | g << 2 | b << 3].Green = g ? (g << 7) | 0x7f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 661 | Palette[r | g << 2 | b << 3].Blue = b ? (b << 7) | 0x7f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 662 | Palette[r | g << 2 | b << 3].Alpha = 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 663 | } |
iut_cachan01 | 0:14e97aa401f3 | 664 | } |
iut_cachan01 | 0:14e97aa401f3 | 665 | } |
iut_cachan01 | 0:14e97aa401f3 | 666 | } else if (BitCount == 8) { // 3:3:2 |
iut_cachan01 | 0:14e97aa401f3 | 667 | PaletteSize = 256; |
iut_cachan01 | 0:14e97aa401f3 | 668 | Palette = new BGRA[PaletteSize]; |
iut_cachan01 | 0:14e97aa401f3 | 669 | for (int r = 0; r < 8; r++) { |
iut_cachan01 | 0:14e97aa401f3 | 670 | for (int g = 0; g < 8; g++) { |
iut_cachan01 | 0:14e97aa401f3 | 671 | for (int b = 0; b < 4; b++) { |
iut_cachan01 | 0:14e97aa401f3 | 672 | Palette[r | g << 3 | b << 6].Red = r ? (r << 5) | 0x1f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 673 | Palette[r | g << 3 | b << 6].Green = g ? (g << 5) | 0x1f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 674 | Palette[r | g << 3 | b << 6].Blue = b ? (b << 6) | 0x3f : 0; |
iut_cachan01 | 0:14e97aa401f3 | 675 | Palette[r | g << 3 | b << 6].Alpha = 0xff; |
iut_cachan01 | 0:14e97aa401f3 | 676 | } |
iut_cachan01 | 0:14e97aa401f3 | 677 | } |
iut_cachan01 | 0:14e97aa401f3 | 678 | } |
iut_cachan01 | 0:14e97aa401f3 | 679 | } else if (BitCount == 16) { // 5:5:5 |
iut_cachan01 | 0:14e97aa401f3 | 680 | // Not implemented |
iut_cachan01 | 0:14e97aa401f3 | 681 | } |
iut_cachan01 | 0:14e97aa401f3 | 682 | } |
iut_cachan01 | 0:14e97aa401f3 | 683 | |
iut_cachan01 | 0:14e97aa401f3 | 684 | unsigned int j = 0; |
iut_cachan01 | 0:14e97aa401f3 | 685 | uint8_t* BufferPtr = (uint8_t*) Buffer; |
iut_cachan01 | 0:14e97aa401f3 | 686 | |
iut_cachan01 | 0:14e97aa401f3 | 687 | for (unsigned int i = 0; i < m_BitmapSize; i++) { |
iut_cachan01 | 0:14e97aa401f3 | 688 | if (BitCount == 1) { |
iut_cachan01 | 0:14e97aa401f3 | 689 | // Not implemented: Who needs that? |
iut_cachan01 | 0:14e97aa401f3 | 690 | } else if (BitCount == 4) { |
iut_cachan01 | 0:14e97aa401f3 | 691 | *BufferPtr = ((m_BitmapData[i].Red >> 6) | (m_BitmapData[i].Green >> 7) << 2 | (m_BitmapData[i].Blue >> 7) << 3) << 4; |
iut_cachan01 | 0:14e97aa401f3 | 692 | i++; |
iut_cachan01 | 0:14e97aa401f3 | 693 | *BufferPtr |= (m_BitmapData[i].Red >> 6) | (m_BitmapData[i].Green >> 7) << 2 | (m_BitmapData[i].Blue >> 7) << 3; |
iut_cachan01 | 0:14e97aa401f3 | 694 | } else if (BitCount == 8) { |
iut_cachan01 | 0:14e97aa401f3 | 695 | *BufferPtr = (m_BitmapData[i].Red >> 5) | (m_BitmapData[i].Green >> 5) << 3 | (m_BitmapData[i].Blue >> 5) << 6; |
iut_cachan01 | 0:14e97aa401f3 | 696 | } else if (BitCount == 16) { |
iut_cachan01 | 0:14e97aa401f3 | 697 | // Not implemented |
iut_cachan01 | 0:14e97aa401f3 | 698 | } |
iut_cachan01 | 0:14e97aa401f3 | 699 | |
iut_cachan01 | 0:14e97aa401f3 | 700 | if (IncludePadding) { |
iut_cachan01 | 0:14e97aa401f3 | 701 | j++; |
iut_cachan01 | 0:14e97aa401f3 | 702 | if (j >= w) { |
iut_cachan01 | 0:14e97aa401f3 | 703 | for (unsigned int k = 0; k < (LineWidth - dataBytesPerLine); k++) { |
iut_cachan01 | 0:14e97aa401f3 | 704 | BufferPtr += BitCount / 8; |
iut_cachan01 | 0:14e97aa401f3 | 705 | } |
iut_cachan01 | 0:14e97aa401f3 | 706 | j = 0; |
iut_cachan01 | 0:14e97aa401f3 | 707 | } |
iut_cachan01 | 0:14e97aa401f3 | 708 | } |
iut_cachan01 | 0:14e97aa401f3 | 709 | |
iut_cachan01 | 0:14e97aa401f3 | 710 | BufferPtr++; |
iut_cachan01 | 0:14e97aa401f3 | 711 | } |
iut_cachan01 | 0:14e97aa401f3 | 712 | |
iut_cachan01 | 0:14e97aa401f3 | 713 | Result = true; |
iut_cachan01 | 0:14e97aa401f3 | 714 | |
iut_cachan01 | 0:14e97aa401f3 | 715 | return Result; |
iut_cachan01 | 0:14e97aa401f3 | 716 | } |
iut_cachan01 | 0:14e97aa401f3 | 717 | |
iut_cachan01 | 0:14e97aa401f3 | 718 | /* Set Bitmap Bits. Will be converted to RGBA internally */ |
iut_cachan01 | 0:14e97aa401f3 | 719 | |
iut_cachan01 | 0:14e97aa401f3 | 720 | bool SetBits(void* Buffer, unsigned int Width, unsigned int Height, unsigned int RedMask, unsigned int GreenMask, unsigned int BlueMask, unsigned int AlphaMask = 0) { |
iut_cachan01 | 0:14e97aa401f3 | 721 | if (Buffer == 0) { |
iut_cachan01 | 0:14e97aa401f3 | 722 | return false; |
iut_cachan01 | 0:14e97aa401f3 | 723 | } |
iut_cachan01 | 0:14e97aa401f3 | 724 | |
iut_cachan01 | 0:14e97aa401f3 | 725 | uint8_t *BufferPtr = (uint8_t*) Buffer; |
iut_cachan01 | 0:14e97aa401f3 | 726 | |
iut_cachan01 | 0:14e97aa401f3 | 727 | Dispose(); |
iut_cachan01 | 0:14e97aa401f3 | 728 | |
iut_cachan01 | 0:14e97aa401f3 | 729 | m_BitmapHeader.Width = Width; |
iut_cachan01 | 0:14e97aa401f3 | 730 | m_BitmapHeader.Height = Height; |
iut_cachan01 | 0:14e97aa401f3 | 731 | m_BitmapHeader.BitCount = 32; |
iut_cachan01 | 0:14e97aa401f3 | 732 | m_BitmapHeader.Compression = 3; |
iut_cachan01 | 0:14e97aa401f3 | 733 | |
iut_cachan01 | 0:14e97aa401f3 | 734 | m_BitmapSize = GetWidth() * GetHeight(); |
iut_cachan01 | 0:14e97aa401f3 | 735 | m_BitmapData = new BGRA[m_BitmapSize]; |
iut_cachan01 | 0:14e97aa401f3 | 736 | |
iut_cachan01 | 0:14e97aa401f3 | 737 | /* Find bit count by masks (rounded to next 8 bit boundary) */ |
iut_cachan01 | 0:14e97aa401f3 | 738 | |
iut_cachan01 | 0:14e97aa401f3 | 739 | unsigned int BitCount = (CColor::BitCountByMask(RedMask | GreenMask | BlueMask | AlphaMask) + 7) & ~7; |
iut_cachan01 | 0:14e97aa401f3 | 740 | |
iut_cachan01 | 0:14e97aa401f3 | 741 | uint32_t BitCountRed = CColor::BitCountByMask(RedMask); |
iut_cachan01 | 0:14e97aa401f3 | 742 | uint32_t BitCountGreen = CColor::BitCountByMask(GreenMask); |
iut_cachan01 | 0:14e97aa401f3 | 743 | uint32_t BitCountBlue = CColor::BitCountByMask(BlueMask); |
iut_cachan01 | 0:14e97aa401f3 | 744 | uint32_t BitCountAlpha = CColor::BitCountByMask(AlphaMask); |
iut_cachan01 | 0:14e97aa401f3 | 745 | |
iut_cachan01 | 0:14e97aa401f3 | 746 | for (unsigned int i = 0; i < m_BitmapSize; i++) { |
iut_cachan01 | 0:14e97aa401f3 | 747 | unsigned int Color = 0; |
iut_cachan01 | 0:14e97aa401f3 | 748 | if (BitCount <= 8) { |
iut_cachan01 | 0:14e97aa401f3 | 749 | Color = *((uint8_t*) BufferPtr); |
iut_cachan01 | 0:14e97aa401f3 | 750 | BufferPtr += 1; |
iut_cachan01 | 0:14e97aa401f3 | 751 | } else if (BitCount <= 16) { |
iut_cachan01 | 0:14e97aa401f3 | 752 | Color = *((uint16_t*) BufferPtr); |
iut_cachan01 | 0:14e97aa401f3 | 753 | BufferPtr += 2; |
iut_cachan01 | 0:14e97aa401f3 | 754 | } else if (BitCount <= 24) { |
iut_cachan01 | 0:14e97aa401f3 | 755 | Color = *((uint32_t*) BufferPtr); |
iut_cachan01 | 0:14e97aa401f3 | 756 | BufferPtr += 3; |
iut_cachan01 | 0:14e97aa401f3 | 757 | } else if (BitCount <= 32) { |
iut_cachan01 | 0:14e97aa401f3 | 758 | Color = *((uint32_t*) BufferPtr); |
iut_cachan01 | 0:14e97aa401f3 | 759 | BufferPtr += 4; |
iut_cachan01 | 0:14e97aa401f3 | 760 | } else { |
iut_cachan01 | 0:14e97aa401f3 | 761 | /* unsupported */ |
iut_cachan01 | 0:14e97aa401f3 | 762 | BufferPtr += 1; |
iut_cachan01 | 0:14e97aa401f3 | 763 | } |
iut_cachan01 | 0:14e97aa401f3 | 764 | m_BitmapData[i].Alpha = CColor::Convert(CColor::ComponentByMask(Color, AlphaMask), BitCountAlpha, 8); |
iut_cachan01 | 0:14e97aa401f3 | 765 | m_BitmapData[i].Red = CColor::Convert(CColor::ComponentByMask(Color, RedMask), BitCountRed, 8); |
iut_cachan01 | 0:14e97aa401f3 | 766 | m_BitmapData[i].Green = CColor::Convert(CColor::ComponentByMask(Color, GreenMask), BitCountGreen, 8); |
iut_cachan01 | 0:14e97aa401f3 | 767 | m_BitmapData[i].Blue = CColor::Convert(CColor::ComponentByMask(Color, BlueMask), BitCountBlue, 8); |
iut_cachan01 | 0:14e97aa401f3 | 768 | } |
iut_cachan01 | 0:14e97aa401f3 | 769 | |
iut_cachan01 | 0:14e97aa401f3 | 770 | return true; |
iut_cachan01 | 0:14e97aa401f3 | 771 | } |
iut_cachan01 | 0:14e97aa401f3 | 772 | }; |
iut_cachan01 | 0:14e97aa401f3 | 773 | |
iut_cachan01 | 0:14e97aa401f3 | 774 | #endif |