diff options
author | David Walter Seikel | 2013-01-13 17:24:39 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:24:39 +1000 |
commit | 393b5cd1dc438872af89d334ef6e5fcc59f27d47 (patch) | |
tree | 6a14521219942a08a1b95cb2f5a923a9edd60f63 /libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp | |
parent | Add a note about rasters suggested start up code. (diff) | |
download | SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.zip SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.gz SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.bz2 SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.xz |
Added Irrlicht 1.8, but without all the Windows binaries.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp new file mode 100644 index 0000000..5f2549b --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderTGA.cpp | |||
@@ -0,0 +1,239 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "CImageLoaderTGA.h" | ||
6 | |||
7 | #ifdef _IRR_COMPILE_WITH_TGA_LOADER_ | ||
8 | |||
9 | #include "IReadFile.h" | ||
10 | #include "os.h" | ||
11 | #include "CColorConverter.h" | ||
12 | #include "CImage.h" | ||
13 | #include "irrString.h" | ||
14 | |||
15 | |||
16 | namespace irr | ||
17 | { | ||
18 | namespace video | ||
19 | { | ||
20 | |||
21 | |||
22 | //! returns true if the file maybe is able to be loaded by this class | ||
23 | //! based on the file extension (e.g. ".tga") | ||
24 | bool CImageLoaderTGA::isALoadableFileExtension(const io::path& filename) const | ||
25 | { | ||
26 | return core::hasFileExtension ( filename, "tga" ); | ||
27 | } | ||
28 | |||
29 | |||
30 | //! loads a compressed tga. | ||
31 | u8 *CImageLoaderTGA::loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const | ||
32 | { | ||
33 | // This was written and sent in by Jon Pry, thank you very much! | ||
34 | // I only changed the formatting a little bit. | ||
35 | |||
36 | s32 bytesPerPixel = header.PixelDepth/8; | ||
37 | s32 imageSize = header.ImageHeight * header.ImageWidth * bytesPerPixel; | ||
38 | u8* data = new u8[imageSize]; | ||
39 | s32 currentByte = 0; | ||
40 | |||
41 | while(currentByte < imageSize) | ||
42 | { | ||
43 | u8 chunkheader = 0; | ||
44 | file->read(&chunkheader, sizeof(u8)); // Read The Chunk's Header | ||
45 | |||
46 | if(chunkheader < 128) // If The Chunk Is A 'RAW' Chunk | ||
47 | { | ||
48 | chunkheader++; // Add 1 To The Value To Get Total Number Of Raw Pixels | ||
49 | |||
50 | file->read(&data[currentByte], bytesPerPixel * chunkheader); | ||
51 | currentByte += bytesPerPixel * chunkheader; | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | // thnx to neojzs for some fixes with this code | ||
56 | |||
57 | // If It's An RLE Header | ||
58 | chunkheader -= 127; // Subtract 127 To Get Rid Of The ID Bit | ||
59 | |||
60 | s32 dataOffset = currentByte; | ||
61 | file->read(&data[dataOffset], bytesPerPixel); | ||
62 | |||
63 | currentByte += bytesPerPixel; | ||
64 | |||
65 | for(s32 counter = 1; counter < chunkheader; counter++) | ||
66 | { | ||
67 | for(s32 elementCounter=0; elementCounter < bytesPerPixel; elementCounter++) | ||
68 | data[currentByte + elementCounter] = data[dataOffset + elementCounter]; | ||
69 | |||
70 | currentByte += bytesPerPixel; | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return data; | ||
76 | } | ||
77 | |||
78 | |||
79 | |||
80 | //! returns true if the file maybe is able to be loaded by this class | ||
81 | bool CImageLoaderTGA::isALoadableFileFormat(io::IReadFile* file) const | ||
82 | { | ||
83 | if (!file) | ||
84 | return false; | ||
85 | |||
86 | STGAFooter footer; | ||
87 | memset(&footer, 0, sizeof(STGAFooter)); | ||
88 | file->seek(file->getSize()-sizeof(STGAFooter)); | ||
89 | file->read(&footer, sizeof(STGAFooter)); | ||
90 | return (!strcmp(footer.Signature,"TRUEVISION-XFILE.")); // very old tgas are refused. | ||
91 | } | ||
92 | |||
93 | |||
94 | |||
95 | //! creates a surface from the file | ||
96 | IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const | ||
97 | { | ||
98 | STGAHeader header; | ||
99 | u32 *palette = 0; | ||
100 | |||
101 | file->read(&header, sizeof(STGAHeader)); | ||
102 | |||
103 | #ifdef __BIG_ENDIAN__ | ||
104 | header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength); | ||
105 | header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth); | ||
106 | header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight); | ||
107 | #endif | ||
108 | |||
109 | // skip image identification field | ||
110 | if (header.IdLength) | ||
111 | file->seek(header.IdLength, true); | ||
112 | |||
113 | if (header.ColorMapType) | ||
114 | { | ||
115 | // create 32 bit palette | ||
116 | palette = new u32[ header.ColorMapLength]; | ||
117 | |||
118 | // read color map | ||
119 | u8 * colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength]; | ||
120 | file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength); | ||
121 | |||
122 | // convert to 32-bit palette | ||
123 | switch ( header.ColorMapEntrySize ) | ||
124 | { | ||
125 | case 16: | ||
126 | CColorConverter::convert_A1R5G5B5toA8R8G8B8(colorMap, header.ColorMapLength, palette); | ||
127 | break; | ||
128 | case 24: | ||
129 | CColorConverter::convert_B8G8R8toA8R8G8B8(colorMap, header.ColorMapLength, palette); | ||
130 | break; | ||
131 | case 32: | ||
132 | CColorConverter::convert_B8G8R8A8toA8R8G8B8(colorMap, header.ColorMapLength, palette); | ||
133 | break; | ||
134 | } | ||
135 | delete [] colorMap; | ||
136 | } | ||
137 | |||
138 | // read image | ||
139 | |||
140 | u8* data = 0; | ||
141 | |||
142 | if ( header.ImageType == 1 || // Uncompressed, color-mapped images. | ||
143 | header.ImageType == 2 || // Uncompressed, RGB images | ||
144 | header.ImageType == 3 // Uncompressed, black and white images | ||
145 | ) | ||
146 | { | ||
147 | const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8; | ||
148 | data = new u8[imageSize]; | ||
149 | file->read(data, imageSize); | ||
150 | } | ||
151 | else | ||
152 | if(header.ImageType == 10) | ||
153 | { | ||
154 | // Runlength encoded RGB images | ||
155 | data = loadCompressedImage(file, header); | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR); | ||
160 | delete [] palette; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | IImage* image = 0; | ||
165 | |||
166 | switch(header.PixelDepth) | ||
167 | { | ||
168 | case 8: | ||
169 | { | ||
170 | if (header.ImageType==3) // grey image | ||
171 | { | ||
172 | image = new CImage(ECF_R8G8B8, | ||
173 | core::dimension2d<u32>(header.ImageWidth, header.ImageHeight)); | ||
174 | if (image) | ||
175 | CColorConverter::convert8BitTo24Bit((u8*)data, | ||
176 | (u8*)image->lock(), | ||
177 | header.ImageWidth,header.ImageHeight, | ||
178 | 0, 0, (header.ImageDescriptor&0x20)==0); | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | image = new CImage(ECF_A1R5G5B5, | ||
183 | core::dimension2d<u32>(header.ImageWidth, header.ImageHeight)); | ||
184 | if (image) | ||
185 | CColorConverter::convert8BitTo16Bit((u8*)data, | ||
186 | (s16*)image->lock(), | ||
187 | header.ImageWidth,header.ImageHeight, | ||
188 | (s32*) palette, 0, | ||
189 | (header.ImageDescriptor&0x20)==0); | ||
190 | } | ||
191 | } | ||
192 | break; | ||
193 | case 16: | ||
194 | image = new CImage(ECF_A1R5G5B5, | ||
195 | core::dimension2d<u32>(header.ImageWidth, header.ImageHeight)); | ||
196 | if (image) | ||
197 | CColorConverter::convert16BitTo16Bit((s16*)data, | ||
198 | (s16*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); | ||
199 | break; | ||
200 | case 24: | ||
201 | image = new CImage(ECF_R8G8B8, | ||
202 | core::dimension2d<u32>(header.ImageWidth, header.ImageHeight)); | ||
203 | if (image) | ||
204 | CColorConverter::convert24BitTo24Bit( | ||
205 | (u8*)data, (u8*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true); | ||
206 | break; | ||
207 | case 32: | ||
208 | image = new CImage(ECF_A8R8G8B8, | ||
209 | core::dimension2d<u32>(header.ImageWidth, header.ImageHeight)); | ||
210 | if (image) | ||
211 | CColorConverter::convert32BitTo32Bit((s32*)data, | ||
212 | (s32*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); | ||
213 | break; | ||
214 | default: | ||
215 | os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR); | ||
216 | break; | ||
217 | } | ||
218 | if (image) | ||
219 | image->unlock(); | ||
220 | |||
221 | delete [] data; | ||
222 | delete [] palette; | ||
223 | |||
224 | return image; | ||
225 | } | ||
226 | |||
227 | |||
228 | //! creates a loader which is able to load tgas | ||
229 | IImageLoader* createImageLoaderTGA() | ||
230 | { | ||
231 | return new CImageLoaderTGA(); | ||
232 | } | ||
233 | |||
234 | |||
235 | } // end namespace video | ||
236 | } // end namespace irr | ||
237 | |||
238 | #endif | ||
239 | |||