aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp462
1 files changed, 231 insertions, 231 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp
index afa015b..60bc355 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderPCX.cpp
@@ -1,231 +1,231 @@
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 "CImageLoaderPCX.h" 5#include "CImageLoaderPCX.h"
6 6
7#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ 7#ifdef _IRR_COMPILE_WITH_PCX_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
16 16
17namespace irr 17namespace irr
18{ 18{
19namespace video 19namespace video
20{ 20{
21 21
22 22
23//! constructor 23//! constructor
24CImageLoaderPCX::CImageLoaderPCX() 24CImageLoaderPCX::CImageLoaderPCX()
25{ 25{
26 #ifdef _DEBUG 26 #ifdef _DEBUG
27 setDebugName("CImageLoaderPCX"); 27 setDebugName("CImageLoaderPCX");
28 #endif 28 #endif
29} 29}
30 30
31 31
32//! returns true if the file maybe is able to be loaded by this class 32//! returns true if the file maybe is able to be loaded by this class
33//! based on the file extension (e.g. ".tga") 33//! based on the file extension (e.g. ".tga")
34bool CImageLoaderPCX::isALoadableFileExtension(const io::path& filename) const 34bool CImageLoaderPCX::isALoadableFileExtension(const io::path& filename) const
35{ 35{
36 return core::hasFileExtension ( filename, "pcx" ); 36 return core::hasFileExtension ( filename, "pcx" );
37} 37}
38 38
39 39
40 40
41//! returns true if the file maybe is able to be loaded by this class 41//! returns true if the file maybe is able to be loaded by this class
42bool CImageLoaderPCX::isALoadableFileFormat(io::IReadFile* file) const 42bool CImageLoaderPCX::isALoadableFileFormat(io::IReadFile* file) const
43{ 43{
44 u8 headerID; 44 u8 headerID;
45 file->read(&headerID, sizeof(headerID)); 45 file->read(&headerID, sizeof(headerID));
46 return headerID == 0x0a; 46 return headerID == 0x0a;
47} 47}
48 48
49 49
50//! creates a image from the file 50//! creates a image from the file
51IImage* CImageLoaderPCX::loadImage(io::IReadFile* file) const 51IImage* CImageLoaderPCX::loadImage(io::IReadFile* file) const
52{ 52{
53 SPCXHeader header; 53 SPCXHeader header;
54 s32* paletteData = 0; 54 s32* paletteData = 0;
55 55
56 file->read(&header, sizeof(header)); 56 file->read(&header, sizeof(header));
57 #ifdef __BIG_ENDIAN__ 57 #ifdef __BIG_ENDIAN__
58 header.XMin = os::Byteswap::byteswap(header.XMin); 58 header.XMin = os::Byteswap::byteswap(header.XMin);
59 header.YMin = os::Byteswap::byteswap(header.YMin); 59 header.YMin = os::Byteswap::byteswap(header.YMin);
60 header.XMax = os::Byteswap::byteswap(header.XMax); 60 header.XMax = os::Byteswap::byteswap(header.XMax);
61 header.YMax = os::Byteswap::byteswap(header.YMax); 61 header.YMax = os::Byteswap::byteswap(header.YMax);
62 header.HorizDPI = os::Byteswap::byteswap(header.HorizDPI); 62 header.HorizDPI = os::Byteswap::byteswap(header.HorizDPI);
63 header.VertDPI = os::Byteswap::byteswap(header.VertDPI); 63 header.VertDPI = os::Byteswap::byteswap(header.VertDPI);
64 header.BytesPerLine = os::Byteswap::byteswap(header.BytesPerLine); 64 header.BytesPerLine = os::Byteswap::byteswap(header.BytesPerLine);
65 header.PaletteType = os::Byteswap::byteswap(header.PaletteType); 65 header.PaletteType = os::Byteswap::byteswap(header.PaletteType);
66 header.HScrSize = os::Byteswap::byteswap(header.HScrSize); 66 header.HScrSize = os::Byteswap::byteswap(header.HScrSize);
67 header.VScrSize = os::Byteswap::byteswap(header.VScrSize); 67 header.VScrSize = os::Byteswap::byteswap(header.VScrSize);
68 #endif 68 #endif
69 69
70 //! return if the header is wrong 70 //! return if the header is wrong
71 if (header.Manufacturer != 0x0a && header.Encoding != 0x01) 71 if (header.Manufacturer != 0x0a && header.Encoding != 0x01)
72 return 0; 72 return 0;
73 73
74 // return if this isn't a supported type 74 // return if this isn't a supported type
75 if ((header.BitsPerPixel != 8) && (header.BitsPerPixel != 4) && (header.BitsPerPixel != 1)) 75 if ((header.BitsPerPixel != 8) && (header.BitsPerPixel != 4) && (header.BitsPerPixel != 1))
76 { 76 {
77 os::Printer::log("Unsupported bits per pixel in PCX file.", 77 os::Printer::log("Unsupported bits per pixel in PCX file.",
78 file->getFileName(), irr::ELL_WARNING); 78 file->getFileName(), irr::ELL_WARNING);
79 return 0; 79 return 0;
80 } 80 }
81 81
82 // read palette 82 // read palette
83 if( (header.BitsPerPixel == 8) && (header.Planes == 1) ) 83 if( (header.BitsPerPixel == 8) && (header.Planes == 1) )
84 { 84 {
85 // the palette indicator (usually a 0x0c is found infront of the actual palette data) 85 // the palette indicator (usually a 0x0c is found infront of the actual palette data)
86 // is ignored because some exporters seem to forget to write it. This would result in 86 // is ignored because some exporters seem to forget to write it. This would result in
87 // no image loaded before, now only wrong colors will be set. 87 // no image loaded before, now only wrong colors will be set.
88 const long pos = file->getPos(); 88 const long pos = file->getPos();
89 file->seek( file->getSize()-256*3, false ); 89 file->seek( file->getSize()-256*3, false );
90 90
91 u8 *tempPalette = new u8[768]; 91 u8 *tempPalette = new u8[768];
92 paletteData = new s32[256]; 92 paletteData = new s32[256];
93 file->read( tempPalette, 768 ); 93 file->read( tempPalette, 768 );
94 94
95 for( s32 i=0; i<256; i++ ) 95 for( s32 i=0; i<256; i++ )
96 { 96 {
97 paletteData[i] = (0xff000000 | 97 paletteData[i] = (0xff000000 |
98 (tempPalette[i*3+0] << 16) | 98 (tempPalette[i*3+0] << 16) |
99 (tempPalette[i*3+1] << 8) | 99 (tempPalette[i*3+1] << 8) |
100 (tempPalette[i*3+2])); 100 (tempPalette[i*3+2]));
101 } 101 }
102 102
103 delete [] tempPalette; 103 delete [] tempPalette;
104 104
105 file->seek(pos); 105 file->seek(pos);
106 } 106 }
107 else if( header.BitsPerPixel == 4 ) 107 else if( header.BitsPerPixel == 4 )
108 { 108 {
109 paletteData = new s32[16]; 109 paletteData = new s32[16];
110 for( s32 i=0; i<16; i++ ) 110 for( s32 i=0; i<16; i++ )
111 { 111 {
112 paletteData[i] = (0xff000000 | 112 paletteData[i] = (0xff000000 |
113 (header.Palette[i*3+0] << 16) | 113 (header.Palette[i*3+0] << 16) |
114 (header.Palette[i*3+1] << 8) | 114 (header.Palette[i*3+1] << 8) |
115 (header.Palette[i*3+2])); 115 (header.Palette[i*3+2]));
116 } 116 }
117 } 117 }
118 118
119 // read image data 119 // read image data
120 const s32 width = header.XMax - header.XMin + 1; 120 const s32 width = header.XMax - header.XMin + 1;
121 const s32 height = header.YMax - header.YMin + 1; 121 const s32 height = header.YMax - header.YMin + 1;
122 const s32 imagebytes = header.BytesPerLine * header.Planes * header.BitsPerPixel * height / 8; 122 const s32 imagebytes = header.BytesPerLine * header.Planes * header.BitsPerPixel * height / 8;
123 u8* PCXData = new u8[imagebytes]; 123 u8* PCXData = new u8[imagebytes];
124 124
125 u8 cnt, value; 125 u8 cnt, value;
126 s32 lineoffset=0, linestart=0, nextmode=1; 126 s32 lineoffset=0, linestart=0, nextmode=1;
127 for(s32 offset = 0; offset < imagebytes; offset += cnt) 127 for(s32 offset = 0; offset < imagebytes; offset += cnt)
128 { 128 {
129 file->read(&cnt, 1); 129 file->read(&cnt, 1);
130 if( !((cnt & 0xc0) == 0xc0) ) 130 if( !((cnt & 0xc0) == 0xc0) )
131 { 131 {
132 value = cnt; 132 value = cnt;
133 cnt = 1; 133 cnt = 1;
134 } 134 }
135 else 135 else
136 { 136 {
137 cnt &= 0x3f; 137 cnt &= 0x3f;
138 file->read(&value, 1); 138 file->read(&value, 1);
139 } 139 }
140 if (header.Planes==1) 140 if (header.Planes==1)
141 memset(PCXData+offset, value, cnt); 141 memset(PCXData+offset, value, cnt);
142 else 142 else
143 { 143 {
144 for (u32 i=0; i<cnt; ++i) 144 for (u32 i=0; i<cnt; ++i)
145 { 145 {
146 PCXData[linestart+lineoffset]=value; 146 PCXData[linestart+lineoffset]=value;
147 lineoffset += 3; 147 lineoffset += 3;
148 if (lineoffset>=3*header.BytesPerLine) 148 if (lineoffset>=3*header.BytesPerLine)
149 { 149 {
150 lineoffset=nextmode; 150 lineoffset=nextmode;
151 if (++nextmode==3) 151 if (++nextmode==3)
152 nextmode=0; 152 nextmode=0;
153 if (lineoffset==0) 153 if (lineoffset==0)
154 linestart += 3*header.BytesPerLine; 154 linestart += 3*header.BytesPerLine;
155 } 155 }
156 } 156 }
157 } 157 }
158 } 158 }
159 159
160 // create image 160 // create image
161 video::IImage* image = 0; 161 video::IImage* image = 0;
162 s32 pad = (header.BytesPerLine - width * header.BitsPerPixel / 8) * header.Planes; 162 s32 pad = (header.BytesPerLine - width * header.BitsPerPixel / 8) * header.Planes;
163 163
164 if (pad < 0) 164 if (pad < 0)
165 pad = -pad; 165 pad = -pad;
166 166
167 if (header.BitsPerPixel==8) 167 if (header.BitsPerPixel==8)
168 { 168 {
169 switch(header.Planes) // TODO: Other formats 169 switch(header.Planes) // TODO: Other formats
170 { 170 {
171 case 1: 171 case 1:
172 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height)); 172 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height));
173 if (image) 173 if (image)
174 CColorConverter::convert8BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); 174 CColorConverter::convert8BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad);
175 break; 175 break;
176 case 3: 176 case 3:
177 image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(width, height)); 177 image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(width, height));
178 if (image) 178 if (image)
179 CColorConverter::convert24BitTo24Bit(PCXData, (u8*)image->lock(), width, height, pad); 179 CColorConverter::convert24BitTo24Bit(PCXData, (u8*)image->lock(), width, height, pad);
180 break; 180 break;
181 } 181 }
182 } 182 }
183 else if (header.BitsPerPixel==4) 183 else if (header.BitsPerPixel==4)
184 { 184 {
185 if (header.Planes==1) 185 if (header.Planes==1)
186 { 186 {
187 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height)); 187 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height));
188 if (image) 188 if (image)
189 CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); 189 CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad);
190 } 190 }
191 } 191 }
192 else if (header.BitsPerPixel==1) 192 else if (header.BitsPerPixel==1)
193 { 193 {
194 if (header.Planes==4) 194 if (header.Planes==4)
195 { 195 {
196 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height)); 196 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height));
197 if (image) 197 if (image)
198 CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); 198 CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad);
199 } 199 }
200 else if (header.Planes==1) 200 else if (header.Planes==1)
201 { 201 {
202 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height)); 202 image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(width, height));
203 if (image) 203 if (image)
204 CColorConverter::convert1BitTo16Bit(PCXData, (s16*)image->lock(), width, height, pad); 204 CColorConverter::convert1BitTo16Bit(PCXData, (s16*)image->lock(), width, height, pad);
205 } 205 }
206 } 206 }
207 if (image) 207 if (image)
208 image->unlock(); 208 image->unlock();
209 209
210 // clean up 210 // clean up
211 211
212 delete [] paletteData; 212 delete [] paletteData;
213 delete [] PCXData; 213 delete [] PCXData;
214 214
215 return image; 215 return image;
216} 216}
217 217
218 218
219//! creates a loader which is able to load pcx images 219//! creates a loader which is able to load pcx images
220IImageLoader* createImageLoaderPCX() 220IImageLoader* createImageLoaderPCX()
221{ 221{
222 return new CImageLoaderPCX(); 222 return new CImageLoaderPCX();
223} 223}
224 224
225 225
226 226
227} // end namespace video 227} // end namespace video
228} // end namespace irr 228} // end namespace irr
229 229
230#endif 230#endif
231 231