aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp654
1 files changed, 654 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp
new file mode 100644
index 0000000..4699dc0
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp
@@ -0,0 +1,654 @@
1//! Copyright (C) 2009-2012 Gary Conway
2//! This file is part of the "Irrlicht Engine".
3//! For conditions of distribution and use, see copyright notice in irrlicht.h
4
5/*
6 Author: Gary Conway (Viper) - co-author of the ZIP file format, Feb 1989,
7 see the story at http://www.idcnet.us/ziphistory.html
8 Website: http://idcnet.us
9 Email: codeslinger@vipergc.com
10 Created: March 1, 2009
11 Version: 1.0
12 Updated:
13
14 This module will load SGI .rgb files (along with the other extensions). The module complies
15 with version 1.0 of the SGI Image File Format by Paul Haeberli of Silicon Graphics Computer Systems
16 The module handles BW, RGB and RGBA images.
17
18 RGB images are stored with either 8 bits per COLOR VALUE, one each for red,green,blue (24bpp)
19 or 16 bits per COLOR VALUE, again one each for red,green,blue (48 bpp), not including the alpha channel
20
21
22 OPTIONS NOT SUPPORTED
23
24 1. 16 bit COLOR VALUES (48bpp modes)
25 2. COLORMAP = DITHERED mode
26
27
28
29For non- run length encoded files, this is the structure
30
31 The Header
32 The Image Data
33
34If the image is run length encoded, this is the structure:
35 The Header
36 The Offset Tables
37 The Image Data
38
39The Header consists of the following:
40
41 Size | Type | Name | Description
42
43 2 bytes | short | MAGIC | IRIS image file magic number
44 1 byte | char | STORAGE | Storage format
45 1 byte | char | BPC | Number of bytes per pixel channel
46 2 bytes | ushort | DIMENSION | Number of dimensions
47 2 bytes | ushort | XSIZE | X size in pixels
48 2 bytes | ushort | YSIZE | Y size in pixels
49 2 bytes | ushort | ZSIZE | Number of channels
50 4 bytes | long | PIXMIN | Minimum pixel value
51 4 bytes | long | PIXMAX | Maximum pixel value
52 4 bytes | char | DUMMY | Ignored
53 80 bytes | char | IMAGENAME | Image name
54 4 bytes | long | COLORMAP | Colormap ID
55 404 bytes | char | DUMMY | Ignored
56
57Here is a description of each field in the image file Header:
58
59MAGIC - This is the decimal value 474 saved as a short. This identifies the file as an SGI image file.
60
61STORAGE - specifies whether the image is stored using run length encoding (RLE) or not (VERBATIM).
62 If RLE is used, the value of this byte will be 1. Otherwise the value of this byte will
63 be 0. The only allowed values for this field are 0 or 1.
64
65BPC - describes the precision that is used to store each channel of an image. This is the number of
66 bytes per pixel component. The majority of SGI image files use 1 byte per pixel component,
67 giving 256 levels. Some SGI image files use 2 bytes per component. The only allowed values
68 for this field are 1 or 2.
69
70DIMENSION - described the number of dimensions in the data stored in the image file.
71 The only allowed values are 1, 2, or 3. If this value is 1, the image file
72 consists of only 1 channel and only 1 scanline (row). The length of this
73 scanline is given by the value of XSIZE below. If this value is 2, the file
74 consists of a single channel with a number of scanlines. The width and height
75 of the image are given by the values of XSIZE and YSIZE below.
76 If this value is 3, the file consists of a number of channels.
77 The width and height of the image are given by the values of XSIZE and YSIZE below.
78 The number of channels is given by the value of ZSIZE below.
79
80XSIZE - The width of the image in pixels
81
82YSIZE - The height of the image in pixels
83
84ZSIZE - The number of channels in the image. B/W (greyscale) images are stored as 2 dimensional
85 images with a ZSIZE of 1. RGB color images are stored as 3 dimensional images with a
86 ZSIZE of 3. An RGB image with an ALPHA channel is stored as a 3 dimensional image with
87 a ZSIZE of 4. There are no inherent limitations in the SGI image file format that would
88 preclude the creation of image files with more than 4 channels.
89
90PINMIN - The minimum pixel value in the image. The value of 0 may be used if no pixel has a value
91 that is smaller than 0.
92
93PINMAX - The maximum pixel value in the image. The value of 255 may be used if no pixel has a
94 value that is greater than 255. This is the value that is considered to be full
95 brightness in the image.
96
97DUMMY - This 4 bytes of data should be set to 0.
98
99IMAGENAME - An null terminated ascii string of up to 79 characters terminated by a null may be
100 included here. This is not commonly used.
101
102COLORMAP - This controls how the pixel values in the file should be interpreted. It can have one
103 of these four values:
104
1050: NORMAL - The data in the channels represent B/W values for images with 1 channel, RGB values
106 for images with 3 channels, and RGBA values for images with 4 channels. Almost all
107 the SGI image files are of this type.
108
1091: DITHERED - The image will have only 1 channel of data. For each pixel, RGB data is packed
110 into one 8 bit value. 3 bits are used for red and green, while blue uses 2 bits.
111 Red data is found in bits[2..0], green data in bits[5..3], and blue data in
112 bits[7..6]. This format is obsolete.
113
1142: SCREEN - The image will have only 1 channel of data. This format was used to store
115 color-indexed pixels. To convert the pixel values into RGB values a colormap
116 must be used. The appropriate color map varies from image to image. This format is obsolete.
117
1183: COLORMAP - The image is used to store a color map from an SGI machine. In this case the
119 image is not displayable in the conventional sense.
120
121DUMMY - This 404 bytes of data should be set to 0. This makes the Header exactly 512 bytes.
122*/
123
124#include "CImageLoaderRGB.h"
125
126#ifdef _IRR_COMPILE_WITH_RGB_LOADER_
127
128#include "IReadFile.h"
129#include "SColor.h"
130#include "CColorConverter.h"
131#include "CImage.h"
132#include "os.h"
133#include "irrString.h"
134
135
136namespace irr
137{
138namespace video
139{
140
141//! constructor
142CImageLoaderRGB::CImageLoaderRGB()
143{
144 #ifdef _DEBUG
145 setDebugName("CImageLoaderRGB");
146 #endif
147}
148
149
150//! returns true if the file maybe is able to be loaded by this class
151//! based on the file extensions listed here
152bool CImageLoaderRGB::isALoadableFileExtension(const io::path& filename) const
153{
154 return core::hasFileExtension( filename, "rgb", "rgba", "sgi" ) ||
155 core::hasFileExtension( filename, "int", "inta", "bw" );
156}
157
158
159//! returns true if the file maybe is able to be loaded by this class
160bool CImageLoaderRGB::isALoadableFileFormat(io::IReadFile* file) const
161{
162 rgbStruct rgb;
163 return checkFormat(file, rgb);
164}
165
166
167/** The main entry point, read and format the image file.
168\return Pointer to the image data on success
169 null pointer on fail */
170IImage* CImageLoaderRGB::loadImage(io::IReadFile* file) const
171{
172 IImage* image = 0;
173 s32* paletteData = 0;
174
175 rgbStruct rgb; // construct our structure for holding data
176
177 // read Header information
178 if (checkFormat(file, rgb))
179 {
180 // 16 bits per COLOR VALUE, not supported, this is 48bpp mode
181 if (rgb.Header.BPC != 1)
182 {
183 os::Printer::log("Only one byte per pixel RGB files are supported", file->getFileName(), ELL_ERROR);
184 }
185 else if (rgb.Header.Colormap != 0)
186 {
187 os::Printer::log("Dithered, Screen and Colormap RGB files are not supported", file->getFileName(), ELL_ERROR);
188 }
189 else if (rgb.Header.Storage == 1 && !readOffsetTables(file, rgb))
190 {
191 os::Printer::log("Failed to read RLE table in RGB file", file->getFileName(), ELL_ERROR);
192 }
193 else if (!rgb.allocateTemps())
194 {
195 os::Printer::log("Out of memory in RGB file loader", file->getFileName(), ELL_ERROR);
196 }
197 else
198 {
199 // read and process the file to rgbData
200 processFile(file, rgb);
201
202/*
203 ZSIZE Description
204 1 BW (grayscale) image
205 3 RGB image
206 4 RGBa image with one alpha channel
207
208 When the Alpha channel is present, I am not sure with RGB files if
209 it's a precomputed RGB color or it needs to be completely calculated. My guess
210 would be that it's not precomputed for two reasons.
211
212 1. the loss of precision when calculating the fraction, then storing the result as an int
213 2. the loss of the original color data when the image might be composited with another. Yes
214 the original color data could be computed, however, not without another loss in precision
215
216 Also, I don't know where to find the background color
217 Pixmin and Pixmax are apparently the min and max alpha blend values (0-100%)
218
219 Complete Alpha blending computation
220 The actual resulting merged color is computed this way:
221 (image color â—Š alpha) + (background color â—Š (100% - alpha)).
222
223 Using precomputed blending
224 (image color) + (background color â—Š (100% - alpha)).
225
226 Alternatively, the RGB files could use another blending technique entirely
227*/
228
229 switch (rgb.Header.Zsize)
230 {
231 case 1:
232 // BW (grayscale) image
233 paletteData = new s32[256];
234 for (int n=0; n<256; n++)
235 paletteData[n] = n;
236
237 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(rgb.Header.Xsize, rgb.Header.Ysize));
238 if (image)
239 CColorConverter::convert8BitTo16Bit(rgb.rgbData, (s16*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, paletteData, 0, true);
240 break;
241 case 3:
242 // RGB image
243 // one byte per COLOR VALUE, eg, 24bpp
244 image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(rgb.Header.Xsize, rgb.Header.Ysize));
245 if (image)
246 CColorConverter::convert24BitTo24Bit(rgb.rgbData, (u8*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, 0, true, false);
247 break;
248 case 4:
249 // RGBa image with one alpha channel (32bpp)
250 // image is stored in rgbData as RGBA
251
252 converttoARGB(reinterpret_cast<u32*>(rgb.rgbData), rgb.Header.Ysize * rgb.Header.Xsize);
253
254 image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(rgb.Header.Xsize, rgb.Header.Ysize));
255 if (image)
256 CColorConverter::convert32BitTo32Bit((s32*)rgb.rgbData, (s32*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, 0, true);
257
258 break;
259 default:
260 // Format unknown
261 os::Printer::log("Unsupported pixel format in RGB file", file->getFileName(), ELL_ERROR);
262 }
263
264 if (image)
265 image->unlock();
266 }
267 }
268
269 // and tidy up allocated memory
270 delete [] paletteData;
271
272 return image;
273}
274
275// returns true on success
276bool CImageLoaderRGB::readHeader(io::IReadFile* file, rgbStruct& rgb) const
277{
278 if ( file->read(&rgb.Header, sizeof(rgb.Header)) < s32(sizeof(rgb.Header)) )
279 return false;
280
281 // test for INTEL or BIG ENDIAN processor
282 // if INTEL, then swap the byte order on 16 bit INT's to make them BIG ENDIAN
283 // because that is the native format for the .rgb file
284#ifndef __BIG_ENDIAN__
285 rgb.Header.Magic = os::Byteswap::byteswap(rgb.Header.Magic);
286 rgb.Header.Storage = os::Byteswap::byteswap(rgb.Header.Storage);
287 rgb.Header.Dimension = os::Byteswap::byteswap(rgb.Header.Dimension);
288 rgb.Header.Xsize = os::Byteswap::byteswap(rgb.Header.Xsize);
289 rgb.Header.Ysize = os::Byteswap::byteswap(rgb.Header.Ysize);
290 rgb.Header.Zsize = os::Byteswap::byteswap(rgb.Header.Zsize);
291 rgb.Header.Pixmin = os::Byteswap::byteswap(rgb.Header.Pixmin);
292 rgb.Header.Pixmax = os::Byteswap::byteswap(rgb.Header.Pixmax);
293 rgb.Header.Colormap = os::Byteswap::byteswap(rgb.Header.Colormap);
294#endif
295
296 // calculate the size of the buffer needed: XSIZE * YSIZE * ZSIZE * BPC
297 rgb.ImageSize = (rgb.Header.Xsize)*(rgb.Header.Ysize)*(rgb.Header.Zsize)*(rgb.Header.BPC);
298
299 return true;
300}
301
302
303bool CImageLoaderRGB::checkFormat(io::IReadFile* file, rgbStruct& rgb) const
304{
305 if (!readHeader(file, rgb))
306 return false;
307
308 return (rgb.Header.Magic == 0x1DA);
309}
310
311/*
312If the image is stored using run length encoding, offset tables follow the Header that
313describe what the file offsets are to the RLE for each scanline. This information only
314applies if the value for STORAGE above is 1.
315
316 Size | Type | Name | Description
317
318 tablen longs | long | STARTTAB | Start table
319 tablen longs | long | LENGTHTAB | Length table
320
321One entry in each table is needed for each scanline of RLE data. The total number of scanlines in the image (tablen) is determined by the product of the YSIZE and ZSIZE. There are two tables of longs that are written. Each consists of tablen longs of data. The first table has the file offsets to the RLE data for each scanline in the image. In a file with more than 1 channel (ZSIZE > 1) this table first has all the offsets for the scanlines in the first channel, followed be offsets for the scanlines in the second channel, etc. The second table has the RLE data length for each scanline in the image. In a file with more than 1 channel (ZSIZE > 1) this table first has all the RLE data lengths for the scanlines in the first channel, followed be RLE data lengths for the scanlines in the second channel, etc.
322
323To find the the file offset, and the number of bytes in the RLE data for a particular scanline, these
324two arrays may be read in and indexed as follows:
325
326To read in the tables:
327
328 unsigned long *starttab, *lengthtab;
329
330 tablen = YSIZE*ZSIZE*sizeof(long);
331 starttab = (unsigned long *)mymalloc(tablen);
332 lengthtab = (unsigned long *)mymalloc(tablen);
333 fseek(rgb->inf,512,SEEK_SET);
334 readlongtab(rgb->inf,starttab);
335 readlongtab(rgb->inf,lengthtab);
336
337To find the file offset and RLE data length for a scanline:
338
339rowno is an integer in the range 0 to YSIZE-1 channo is an integer in the range 0 to ZSIZE-1
340
341 rleoffset = starttab[rowno+channo*YSIZE]
342 rlelength = lengthtab[rowno+channo*YSIZE]
343
344It is possible for two identical rows (scanlines) to share compressed data. A completely
345white image could be written as a single compressed row and having all table entries point
346to that row. Another little hack that should work is if you are writing out a RGB RLE file,
347and a particular scanline is achromatic (greyscale), you could just make the r, g and b rows
348point to the same data!!
349
350 RETURNS: on success true, else returns false
351*/
352
353bool CImageLoaderRGB::readOffsetTables(io::IReadFile* file, rgbStruct& rgb) const
354{
355 rgb.TableLen = rgb.Header.Ysize * rgb.Header.Zsize ; // calc size of tables
356
357 // return error if unable to allocate tables
358 rgb.StartTable = new u32[rgb.TableLen];
359 if (!rgb.StartTable)
360 return false;
361 rgb.LengthTable = new u32[rgb.TableLen];
362 if (!rgb.LengthTable)
363 return false;
364
365 file->seek(512);
366 file->read(rgb.StartTable, rgb.TableLen* sizeof(u32));
367 file->read(rgb.LengthTable, rgb.TableLen* sizeof(u32));
368
369 // if we are on an INTEL platform, swap the bytes
370#ifndef __BIG_ENDIAN__
371 const u32 length = rgb.TableLen;
372 for (u32 i=0; i<length; ++i)
373 {
374 rgb.StartTable[i] = os::Byteswap::byteswap(rgb.StartTable[i]);
375 rgb.LengthTable[i] = os::Byteswap::byteswap(rgb.LengthTable[i]);
376 }
377#endif
378
379 return true;
380}
381
382
383/*
384 The Header has already been read into rgb structure
385 The Tables have been read if necessary
386 Now process the actual data
387*/
388void CImageLoaderRGB::processFile(io::IReadFile* file, rgbStruct& rgb) const
389{
390 u16 *tempShort;
391
392 // calculate the size of the buffer needed: XSIZE * YSIZE * ZSIZE * BPC
393 rgb.rgbData = new u8 [(rgb.Header.Xsize)*(rgb.Header.Ysize)*(rgb.Header.Zsize)*(rgb.Header.BPC)];
394 u8 *ptr = rgb.rgbData;
395
396 // cycle through all scanlines
397
398#ifdef _IRR_RGB_FILE_INVERTED_IMAGE_
399 // preserve the image as stored, eg, inverted
400 for (u16 i = 0; i < rgb.Header.Ysize; ++i)
401#else
402 // invert the image to make it upright
403 for (s32 i = (s32)(rgb.Header.Ysize)-1; i>=0; --i)
404#endif
405 {
406 // check the number of channels and read a row of data
407 if (rgb.Header.Zsize >= 1)
408 readRGBrow( rgb.tmpR, i, 0, file, rgb);
409 if (rgb.Header.Zsize >= 2)
410 readRGBrow( rgb.tmpG, i, 1, file, rgb);
411 if (rgb.Header.Zsize >= 3)
412 readRGBrow( rgb.tmpB, i, 2, file, rgb);
413 if (rgb.Header.Zsize >= 4)
414 readRGBrow( rgb.tmpA, i, 3, file, rgb);
415
416 // cycle thru all values for this row
417 for (u16 j = 0; j < rgb.Header.Xsize; ++j)
418 {
419 if(rgb.Header.BPC == 1)
420 {
421 // ONE byte per color
422 if (rgb.Header.Zsize >= 1)
423 *ptr++ = rgb.tmpR[j];
424 if (rgb.Header.Zsize >= 2)
425 *ptr++ = rgb.tmpG[j];
426 if (rgb.Header.Zsize >= 3)
427 *ptr++ = rgb.tmpB[j];
428 if (rgb.Header.Zsize >= 4)
429 *ptr++ = rgb.tmpA[j];
430 }
431 else
432 {
433 // TWO bytes per color
434 if( rgb.Header.Zsize >= 1 )
435 {
436 // two bytes of color data
437 tempShort = (u16 *) (ptr);
438 *tempShort = *( (u16 *) (rgb.tmpR) + j);
439 tempShort++;
440 ptr = ( u8 *)(tempShort);
441 }
442 if( rgb.Header.Zsize >= 2 )
443 {
444 tempShort = ( u16 *) (ptr);
445 *tempShort = *( ( u16 *) (rgb.tmpG) + j);
446 tempShort++;
447 ptr = ( u8 *) (tempShort);
448 }
449 if( rgb.Header.Zsize >= 3 )
450 {
451 tempShort = ( u16 *) (ptr);
452 *tempShort = *( ( u16 *) (rgb.tmpB) + j);
453 tempShort++;
454 ptr = ( u8 *)(tempShort);
455 }
456 if( rgb.Header.Zsize >= 4 )
457 {
458 tempShort = ( u16 *) (ptr);
459 *tempShort = *( ( u16 *) (rgb.tmpA) + j);
460 tempShort++;
461 ptr = ( u8 *)(tempShort);
462 }
463 } // end if(rgb.Header.BPC == 1)
464 } // end for
465 } // end for
466}
467
468
469/*
470 This information only applies if the value for STORAGE is 1. If the image is
471 stored using run length encoding, the image data follows the offset/length tables.
472 The RLE data is not in any particular order. The offset tables are used to
473 locate the rle data for any scanline.
474
475 The RLE data must be read in from the file and expanded into pixel data in the following manner:
476
477 If BPC is 1, then there is one byte per pixel. In this case the RLE data should be
478 read into an array of chars. To expand data, the low order seven bits of the first
479 byte: bits[6..0] are used to form a count. If the high order bit of the first byte
480 is 1: bit[7], then the count is used to specify how many bytes to copy from the RLE
481 data buffer to the destination. Otherwise, if the high order bit of the first byte
482 is 0: bit[7], then the count is used to specify how many times to repeat the value
483 of the following byte, in the destination. This process continues until a count
484 of 0 is found. This should decompress exactly XSIZE pixels.
485
486
487 One entry in each table is needed for each scanline of RLE data. The total number of
488 scanlines in the image (tablen) is determined by the product of the YSIZE and ZSIZE.
489 There are two tables of longs that are written. Each consists of tablen longs of data.
490 The first table has the file offsets to the RLE data for each scanline in the image. In
491 a file with more than 1 channel (ZSIZE > 1) this table first has all the offsets for the
492 scanlines in the first channel, followed be offsets for the scanlines in the second
493 channel, etc. The second table has the RLE data length for each scanline in the image.
494 In a file with more than 1 channel (ZSIZE > 1) this table first has all the RLE data
495 lengths for the scanlines in the first channel, followed be RLE data lengths for the
496 scanlines in the second channel, etc.
497
498 Return a row of data, expanding RLE compression if necessary
499*/
500void CImageLoaderRGB::readRGBrow(u8 *buf, int y, int z, io::IReadFile* file, rgbStruct& rgb) const
501{
502 if (rgb.Header.Storage != 1)
503 {
504 // stored VERBATIM
505
506 file->seek(512+(y*rgb.Header.Xsize * rgb.Header.BPC)+(z* rgb.Header.Xsize * rgb.Header.Ysize * rgb.Header.BPC));
507 file->read(buf, rgb.Header.Xsize * rgb.Header.BPC);
508
509#ifndef __BIG_ENDIAN__
510 if (rgb.Header.BPC != 1)
511 {
512 u16* tmpbuf = reinterpret_cast<u16*>(buf);
513 for (u16 i=0; i<rgb.Header.Xsize; ++i)
514 tmpbuf[i] = os::Byteswap::byteswap(tmpbuf[i]);
515 }
516#endif
517 return;
518 }
519
520 // the file is stored as Run Length Encoding (RLE)
521 // each sequence is stored as 0x80 NumRepeats ByteToRepeat
522
523 // get the file offset from StartTable and SEEK
524 // then read the data
525
526 file->seek((long) rgb.StartTable[y+z * rgb.Header.Ysize]);
527 file->read(rgb.tmp, rgb.LengthTable[y+z * rgb.Header.Ysize]);
528
529 // rgb.tmp has the data
530
531 u16 pixel;
532 u16 *tempShort;
533 u8* iPtr = rgb.tmp;
534 u8* oPtr = buf;
535 while (true)
536 {
537 // if BPC = 1, then one byte per pixel
538 if (rgb.Header.BPC == 1)
539 {
540 pixel = *iPtr++;
541 }
542 else
543 {
544 // BPC = 2, so two bytes per pixel
545 tempShort = (u16 *) iPtr;
546 pixel = *tempShort;
547 tempShort++;
548 iPtr = (u8 *) tempShort;
549 }
550
551#ifndef __BIG_ENDIAN__
552 if (rgb.Header.BPC != 1)
553 pixel = os::Byteswap::byteswap(pixel);
554#endif
555
556 s32 count = (s32)(pixel & 0x7F);
557
558 // limit the count value to the remaining row size
559 if (oPtr + count*rgb.Header.BPC > buf + rgb.Header.Xsize * rgb.Header.BPC)
560 {
561 count = ( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;
562 }
563
564 if (count<=0)
565 break;
566 else if (pixel & 0x80)
567 {
568 // repeat the byte pointed to by iPtr, count times
569 while (count--)
570 {
571 if(rgb.Header.BPC == 1)
572 {
573 *oPtr++ = *iPtr++;
574 }
575 else
576 {
577 // write pixel from iPtr to oPtr, move both two bytes ahead
578 tempShort = (u16 *) (iPtr);
579 pixel = *tempShort;
580 tempShort++;
581 iPtr = (u8 *) (tempShort);
582#ifndef __BIG_ENDIAN__
583 pixel = os::Byteswap::byteswap(pixel);
584#endif
585 tempShort = (u16 *) (oPtr);
586 *tempShort = pixel;
587 tempShort++;
588 oPtr = (u8 *) (tempShort);
589 }
590 }
591 }
592 else
593 {
594 if (rgb.Header.BPC == 1)
595 {
596 pixel = *iPtr++;
597 }
598 else
599 {
600 tempShort = (u16 *) (iPtr);
601 pixel = *tempShort;
602 tempShort++;
603 iPtr = (u8 *) (tempShort);
604 }
605
606#ifndef __BIG_ENDIAN__
607 if (rgb.Header.BPC != 1)
608 pixel = os::Byteswap::byteswap(pixel);
609#endif
610
611 while (count--)
612 {
613 if(rgb.Header.BPC == 1)
614 {
615 *oPtr++ = (u8) pixel;
616 }
617 else
618 {
619 tempShort = (u16 *) (oPtr);
620 *tempShort = pixel;
621 tempShort++;
622 oPtr = (u8 *) (tempShort);
623 }
624 }
625 } // else if (pixel & 0x80)
626 } // while (true)
627}
628
629
630// we have 1 byte per COLOR VALUE, eg 24bpp and 1 alpha channel
631// color values are stored as RGBA, convert to ARGB
632// todo: replace with CColorConverter method
633void CImageLoaderRGB::converttoARGB(u32* in, const u32 size) const
634{
635 for (u32 x=0; x < size; ++x)
636 {
637 *in=(*in>>8)|(*in<<24);
638 ++in;
639 }
640}
641
642
643//! creates a loader which is able to load SGI RGB images
644IImageLoader* createImageLoaderRGB()
645{
646 return new CImageLoaderRGB;
647}
648
649
650} // end namespace video
651} // end namespace irr
652
653#endif
654