aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp744
1 files changed, 372 insertions, 372 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp
index 2ccb64c..93f1b04 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderBMP.cpp
@@ -1,372 +1,372 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "CImageLoaderBMP.h" 5#include "CImageLoaderBMP.h"
6 6
7#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ 7#ifdef _IRR_COMPILE_WITH_BMP_LOADER_
8 8
9#include "IReadFile.h" 9#include "IReadFile.h"
10#include "SColor.h" 10#include "SColor.h"
11#include "CColorConverter.h" 11#include "CColorConverter.h"
12#include "CImage.h" 12#include "CImage.h"
13#include "os.h" 13#include "os.h"
14#include "irrString.h" 14#include "irrString.h"
15 15
16namespace irr 16namespace irr
17{ 17{
18namespace video 18namespace video
19{ 19{
20 20
21 21
22//! constructor 22//! constructor
23CImageLoaderBMP::CImageLoaderBMP() 23CImageLoaderBMP::CImageLoaderBMP()
24{ 24{
25 #ifdef _DEBUG 25 #ifdef _DEBUG
26 setDebugName("CImageLoaderBMP"); 26 setDebugName("CImageLoaderBMP");
27 #endif 27 #endif
28} 28}
29 29
30 30
31//! returns true if the file maybe is able to be loaded by this class 31//! returns true if the file maybe is able to be loaded by this class
32//! based on the file extension (e.g. ".tga") 32//! based on the file extension (e.g. ".tga")
33bool CImageLoaderBMP::isALoadableFileExtension(const io::path& filename) const 33bool CImageLoaderBMP::isALoadableFileExtension(const io::path& filename) const
34{ 34{
35 return core::hasFileExtension ( filename, "bmp" ); 35 return core::hasFileExtension ( filename, "bmp" );
36} 36}
37 37
38 38
39//! returns true if the file maybe is able to be loaded by this class 39//! returns true if the file maybe is able to be loaded by this class
40bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const 40bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const
41{ 41{
42 u16 headerID; 42 u16 headerID;
43 file->read(&headerID, sizeof(u16)); 43 file->read(&headerID, sizeof(u16));
44#ifdef __BIG_ENDIAN__ 44#ifdef __BIG_ENDIAN__
45 headerID = os::Byteswap::byteswap(headerID); 45 headerID = os::Byteswap::byteswap(headerID);
46#endif 46#endif
47 return headerID == 0x4d42; 47 return headerID == 0x4d42;
48} 48}
49 49
50 50
51void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const 51void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
52{ 52{
53 u8* p = bmpData; 53 u8* p = bmpData;
54 u8* newBmp = new u8[(width+pitch)*height]; 54 u8* newBmp = new u8[(width+pitch)*height];
55 u8* d = newBmp; 55 u8* d = newBmp;
56 u8* destEnd = newBmp + (width+pitch)*height; 56 u8* destEnd = newBmp + (width+pitch)*height;
57 s32 line = 0; 57 s32 line = 0;
58 58
59 while (bmpData - p < size && d < destEnd) 59 while (bmpData - p < size && d < destEnd)
60 { 60 {
61 if (*p == 0) 61 if (*p == 0)
62 { 62 {
63 ++p; 63 ++p;
64 64
65 switch(*p) 65 switch(*p)
66 { 66 {
67 case 0: // end of line 67 case 0: // end of line
68 ++p; 68 ++p;
69 ++line; 69 ++line;
70 d = newBmp + (line*(width+pitch)); 70 d = newBmp + (line*(width+pitch));
71 break; 71 break;
72 case 1: // end of bmp 72 case 1: // end of bmp
73 delete [] bmpData; 73 delete [] bmpData;
74 bmpData = newBmp; 74 bmpData = newBmp;
75 return; 75 return;
76 case 2: 76 case 2:
77 ++p; d +=(u8)*p; // delta 77 ++p; d +=(u8)*p; // delta
78 ++p; d += ((u8)*p)*(width+pitch); 78 ++p; d += ((u8)*p)*(width+pitch);
79 ++p; 79 ++p;
80 break; 80 break;
81 default: 81 default:
82 { 82 {
83 // absolute mode 83 // absolute mode
84 s32 count = (u8)*p; ++p; 84 s32 count = (u8)*p; ++p;
85 s32 readAdditional = ((2-(count%2))%2); 85 s32 readAdditional = ((2-(count%2))%2);
86 s32 i; 86 s32 i;
87 87
88 for (i=0; i<count; ++i) 88 for (i=0; i<count; ++i)
89 { 89 {
90 *d = *p; 90 *d = *p;
91 ++p; 91 ++p;
92 ++d; 92 ++d;
93 } 93 }
94 94
95 for (i=0; i<readAdditional; ++i) 95 for (i=0; i<readAdditional; ++i)
96 ++p; 96 ++p;
97 } 97 }
98 } 98 }
99 } 99 }
100 else 100 else
101 { 101 {
102 s32 count = (u8)*p; ++p; 102 s32 count = (u8)*p; ++p;
103 u8 color = *p; ++p; 103 u8 color = *p; ++p;
104 for (s32 i=0; i<count; ++i) 104 for (s32 i=0; i<count; ++i)
105 { 105 {
106 *d = color; 106 *d = color;
107 ++d; 107 ++d;
108 } 108 }
109 } 109 }
110 } 110 }
111 111
112 delete [] bmpData; 112 delete [] bmpData;
113 bmpData = newBmp; 113 bmpData = newBmp;
114} 114}
115 115
116 116
117void CImageLoaderBMP::decompress4BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const 117void CImageLoaderBMP::decompress4BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
118{ 118{
119 s32 lineWidth = (width+1)/2+pitch; 119 s32 lineWidth = (width+1)/2+pitch;
120 u8* p = bmpData; 120 u8* p = bmpData;
121 u8* newBmp = new u8[lineWidth*height]; 121 u8* newBmp = new u8[lineWidth*height];
122 u8* d = newBmp; 122 u8* d = newBmp;
123 u8* destEnd = newBmp + lineWidth*height; 123 u8* destEnd = newBmp + lineWidth*height;
124 s32 line = 0; 124 s32 line = 0;
125 s32 shift = 4; 125 s32 shift = 4;
126 126
127 while (bmpData - p < size && d < destEnd) 127 while (bmpData - p < size && d < destEnd)
128 { 128 {
129 if (*p == 0) 129 if (*p == 0)
130 { 130 {
131 ++p; 131 ++p;
132 132
133 switch(*p) 133 switch(*p)
134 { 134 {
135 case 0: // end of line 135 case 0: // end of line
136 ++p; 136 ++p;
137 ++line; 137 ++line;
138 d = newBmp + (line*lineWidth); 138 d = newBmp + (line*lineWidth);
139 shift = 4; 139 shift = 4;
140 break; 140 break;
141 case 1: // end of bmp 141 case 1: // end of bmp
142 delete [] bmpData; 142 delete [] bmpData;
143 bmpData = newBmp; 143 bmpData = newBmp;
144 return; 144 return;
145 case 2: 145 case 2:
146 { 146 {
147 ++p; 147 ++p;
148 s32 x = (u8)*p; ++p; 148 s32 x = (u8)*p; ++p;
149 s32 y = (u8)*p; ++p; 149 s32 y = (u8)*p; ++p;
150 d += x/2 + y*lineWidth; 150 d += x/2 + y*lineWidth;
151 shift = x%2==0 ? 4 : 0; 151 shift = x%2==0 ? 4 : 0;
152 } 152 }
153 break; 153 break;
154 default: 154 default:
155 { 155 {
156 // absolute mode 156 // absolute mode
157 s32 count = (u8)*p; ++p; 157 s32 count = (u8)*p; ++p;
158 s32 readAdditional = ((2-((count)%2))%2); 158 s32 readAdditional = ((2-((count)%2))%2);
159 s32 readShift = 4; 159 s32 readShift = 4;
160 s32 i; 160 s32 i;
161 161
162 for (i=0; i<count; ++i) 162 for (i=0; i<count; ++i)
163 { 163 {
164 s32 color = (((u8)*p) >> readShift) & 0x0f; 164 s32 color = (((u8)*p) >> readShift) & 0x0f;
165 readShift -= 4; 165 readShift -= 4;
166 if (readShift < 0) 166 if (readShift < 0)
167 { 167 {
168 ++*p; 168 ++*p;
169 readShift = 4; 169 readShift = 4;
170 } 170 }
171 171
172 u8 mask = 0x0f << shift; 172 u8 mask = 0x0f << shift;
173 *d = (*d & (~mask)) | ((color << shift) & mask); 173 *d = (*d & (~mask)) | ((color << shift) & mask);
174 174
175 shift -= 4; 175 shift -= 4;
176 if (shift < 0) 176 if (shift < 0)
177 { 177 {
178 shift = 4; 178 shift = 4;
179 ++d; 179 ++d;
180 } 180 }
181 181
182 } 182 }
183 183
184 for (i=0; i<readAdditional; ++i) 184 for (i=0; i<readAdditional; ++i)
185 ++p; 185 ++p;
186 } 186 }
187 } 187 }
188 } 188 }
189 else 189 else
190 { 190 {
191 s32 count = (u8)*p; ++p; 191 s32 count = (u8)*p; ++p;
192 s32 color1 = (u8)*p; color1 = color1 & 0x0f; 192 s32 color1 = (u8)*p; color1 = color1 & 0x0f;
193 s32 color2 = (u8)*p; color2 = (color2 >> 4) & 0x0f; 193 s32 color2 = (u8)*p; color2 = (color2 >> 4) & 0x0f;
194 ++p; 194 ++p;
195 195
196 for (s32 i=0; i<count; ++i) 196 for (s32 i=0; i<count; ++i)
197 { 197 {
198 u8 mask = 0x0f << shift; 198 u8 mask = 0x0f << shift;
199 u8 toSet = (shift==0 ? color1 : color2) << shift; 199 u8 toSet = (shift==0 ? color1 : color2) << shift;
200 *d = (*d & (~mask)) | (toSet & mask); 200 *d = (*d & (~mask)) | (toSet & mask);
201 201
202 shift -= 4; 202 shift -= 4;
203 if (shift < 0) 203 if (shift < 0)
204 { 204 {
205 shift = 4; 205 shift = 4;
206 ++d; 206 ++d;
207 } 207 }
208 } 208 }
209 } 209 }
210 } 210 }
211 211
212 delete [] bmpData; 212 delete [] bmpData;
213 bmpData = newBmp; 213 bmpData = newBmp;
214} 214}
215 215
216 216
217 217
218//! creates a surface from the file 218//! creates a surface from the file
219IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const 219IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const
220{ 220{
221 SBMPHeader header; 221 SBMPHeader header;
222 222
223 file->read(&header, sizeof(header)); 223 file->read(&header, sizeof(header));
224 224
225#ifdef __BIG_ENDIAN__ 225#ifdef __BIG_ENDIAN__
226 header.Id = os::Byteswap::byteswap(header.Id); 226 header.Id = os::Byteswap::byteswap(header.Id);
227 header.FileSize = os::Byteswap::byteswap(header.FileSize); 227 header.FileSize = os::Byteswap::byteswap(header.FileSize);
228 header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset); 228 header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset);
229 header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize); 229 header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize);
230 header.Width = os::Byteswap::byteswap(header.Width); 230 header.Width = os::Byteswap::byteswap(header.Width);
231 header.Height = os::Byteswap::byteswap(header.Height); 231 header.Height = os::Byteswap::byteswap(header.Height);
232 header.Planes = os::Byteswap::byteswap(header.Planes); 232 header.Planes = os::Byteswap::byteswap(header.Planes);
233 header.BPP = os::Byteswap::byteswap(header.BPP); 233 header.BPP = os::Byteswap::byteswap(header.BPP);
234 header.Compression = os::Byteswap::byteswap(header.Compression); 234 header.Compression = os::Byteswap::byteswap(header.Compression);
235 header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize); 235 header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize);
236 header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX); 236 header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX);
237 header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY); 237 header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY);
238 header.Colors = os::Byteswap::byteswap(header.Colors); 238 header.Colors = os::Byteswap::byteswap(header.Colors);
239 header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors); 239 header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors);
240#endif 240#endif
241 241
242 s32 pitch = 0; 242 s32 pitch = 0;
243 243
244 //! return if the header is false 244 //! return if the header is false
245 245
246 if (header.Id != 0x4d42) 246 if (header.Id != 0x4d42)
247 return 0; 247 return 0;
248 248
249 if (header.Compression > 2) // we'll only handle RLE-Compression 249 if (header.Compression > 2) // we'll only handle RLE-Compression
250 { 250 {
251 os::Printer::log("Compression mode not supported.", ELL_ERROR); 251 os::Printer::log("Compression mode not supported.", ELL_ERROR);
252 return 0; 252 return 0;
253 } 253 }
254 254
255 // adjust bitmap data size to dword boundary 255 // adjust bitmap data size to dword boundary
256 header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4; 256 header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4;
257 257
258 // read palette 258 // read palette
259 259
260 long pos = file->getPos(); 260 long pos = file->getPos();
261 s32 paletteSize = (header.BitmapDataOffset - pos) / 4; 261 s32 paletteSize = (header.BitmapDataOffset - pos) / 4;
262 262
263 s32* paletteData = 0; 263 s32* paletteData = 0;
264 if (paletteSize) 264 if (paletteSize)
265 { 265 {
266 paletteData = new s32[paletteSize]; 266 paletteData = new s32[paletteSize];
267 file->read(paletteData, paletteSize * sizeof(s32)); 267 file->read(paletteData, paletteSize * sizeof(s32));
268#ifdef __BIG_ENDIAN__ 268#ifdef __BIG_ENDIAN__
269 for (s32 i=0; i<paletteSize; ++i) 269 for (s32 i=0; i<paletteSize; ++i)
270 paletteData[i] = os::Byteswap::byteswap(paletteData[i]); 270 paletteData[i] = os::Byteswap::byteswap(paletteData[i]);
271#endif 271#endif
272 } 272 }
273 273
274 // read image data 274 // read image data
275 275
276 if (!header.BitmapDataSize) 276 if (!header.BitmapDataSize)
277 { 277 {
278 // okay, lets guess the size 278 // okay, lets guess the size
279 // some tools simply don't set it 279 // some tools simply don't set it
280 header.BitmapDataSize = static_cast<u32>(file->getSize()) - header.BitmapDataOffset; 280 header.BitmapDataSize = static_cast<u32>(file->getSize()) - header.BitmapDataOffset;
281 } 281 }
282 282
283 file->seek(header.BitmapDataOffset); 283 file->seek(header.BitmapDataOffset);
284 284
285 f32 t = (header.Width) * (header.BPP / 8.0f); 285 f32 t = (header.Width) * (header.BPP / 8.0f);
286 s32 widthInBytes = (s32)t; 286 s32 widthInBytes = (s32)t;
287 t -= widthInBytes; 287 t -= widthInBytes;
288 if (t!=0.0f) 288 if (t!=0.0f)
289 ++widthInBytes; 289 ++widthInBytes;
290 290
291 s32 lineData = widthInBytes + ((4-(widthInBytes%4)))%4; 291 s32 lineData = widthInBytes + ((4-(widthInBytes%4)))%4;
292 pitch = lineData - widthInBytes; 292 pitch = lineData - widthInBytes;
293 293
294 u8* bmpData = new u8[header.BitmapDataSize]; 294 u8* bmpData = new u8[header.BitmapDataSize];
295 file->read(bmpData, header.BitmapDataSize); 295 file->read(bmpData, header.BitmapDataSize);
296 296
297 // decompress data if needed 297 // decompress data if needed
298 switch(header.Compression) 298 switch(header.Compression)
299 { 299 {
300 case 1: // 8 bit rle 300 case 1: // 8 bit rle
301 decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); 301 decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
302 break; 302 break;
303 case 2: // 4 bit rle 303 case 2: // 4 bit rle
304 decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); 304 decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
305 break; 305 break;
306 } 306 }
307 307
308 // create surface 308 // create surface
309 309
310 // no default constructor from packed area! ARM problem! 310 // no default constructor from packed area! ARM problem!
311 core::dimension2d<u32> dim; 311 core::dimension2d<u32> dim;
312 dim.Width = header.Width; 312 dim.Width = header.Width;
313 dim.Height = header.Height; 313 dim.Height = header.Height;
314 314
315 IImage* image = 0; 315 IImage* image = 0;
316 switch(header.BPP) 316 switch(header.BPP)
317 { 317 {
318 case 1: 318 case 1:
319 image = new CImage(ECF_A1R5G5B5, dim); 319 image = new CImage(ECF_A1R5G5B5, dim);
320 if (image) 320 if (image)
321 CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); 321 CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true);
322 break; 322 break;
323 case 4: 323 case 4:
324 image = new CImage(ECF_A1R5G5B5, dim); 324 image = new CImage(ECF_A1R5G5B5, dim);
325 if (image) 325 if (image)
326 CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); 326 CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true);
327 break; 327 break;
328 case 8: 328 case 8:
329 image = new CImage(ECF_A1R5G5B5, dim); 329 image = new CImage(ECF_A1R5G5B5, dim);
330 if (image) 330 if (image)
331 CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); 331 CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true);
332 break; 332 break;
333 case 16: 333 case 16:
334 image = new CImage(ECF_A1R5G5B5, dim); 334 image = new CImage(ECF_A1R5G5B5, dim);
335 if (image) 335 if (image)
336 CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); 336 CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true);
337 break; 337 break;
338 case 24: 338 case 24:
339 image = new CImage(ECF_R8G8B8, dim); 339 image = new CImage(ECF_R8G8B8, dim);
340 if (image) 340 if (image)
341 CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->lock(), header.Width, header.Height, pitch, true, true); 341 CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->lock(), header.Width, header.Height, pitch, true, true);
342 break; 342 break;
343 case 32: // thx to Reinhard Ostermeier 343 case 32: // thx to Reinhard Ostermeier
344 image = new CImage(ECF_A8R8G8B8, dim); 344 image = new CImage(ECF_A8R8G8B8, dim);
345 if (image) 345 if (image)
346 CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->lock(), header.Width, header.Height, pitch, true); 346 CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->lock(), header.Width, header.Height, pitch, true);
347 break; 347 break;
348 }; 348 };
349 if (image) 349 if (image)
350 image->unlock(); 350 image->unlock();
351 351
352 // clean up 352 // clean up
353 353
354 delete [] paletteData; 354 delete [] paletteData;
355 delete [] bmpData; 355 delete [] bmpData;
356 356
357 return image; 357 return image;
358} 358}
359 359
360 360
361//! creates a loader which is able to load windows bitmaps 361//! creates a loader which is able to load windows bitmaps
362IImageLoader* createImageLoaderBMP() 362IImageLoader* createImageLoaderBMP()
363{ 363{
364 return new CImageLoaderBMP; 364 return new CImageLoaderBMP;
365} 365}
366 366
367 367
368} // end namespace video 368} // end namespace video
369} // end namespace irr 369} // end namespace irr
370 370
371#endif 371#endif
372 372