aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp612
1 files changed, 306 insertions, 306 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp
index 8fc5222..877a4d7 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageLoaderJPG.cpp
@@ -1,306 +1,306 @@
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 "CImageLoaderJPG.h" 5#include "CImageLoaderJPG.h"
6 6
7#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ 7#ifdef _IRR_COMPILE_WITH_JPG_LOADER_
8 8
9#include "IReadFile.h" 9#include "IReadFile.h"
10#include "CImage.h" 10#include "CImage.h"
11#include "os.h" 11#include "os.h"
12#include "irrString.h" 12#include "irrString.h"
13 13
14namespace irr 14namespace irr
15{ 15{
16namespace video 16namespace video
17{ 17{
18 18
19// Static members 19// Static members
20io::path CImageLoaderJPG::Filename; 20io::path CImageLoaderJPG::Filename;
21 21
22//! constructor 22//! constructor
23CImageLoaderJPG::CImageLoaderJPG() 23CImageLoaderJPG::CImageLoaderJPG()
24{ 24{
25 #ifdef _DEBUG 25 #ifdef _DEBUG
26 setDebugName("CImageLoaderJPG"); 26 setDebugName("CImageLoaderJPG");
27 #endif 27 #endif
28} 28}
29 29
30 30
31 31
32//! destructor 32//! destructor
33CImageLoaderJPG::~CImageLoaderJPG() 33CImageLoaderJPG::~CImageLoaderJPG()
34{ 34{
35} 35}
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
40//! based on the file extension (e.g. ".tga") 40//! based on the file extension (e.g. ".tga")
41bool CImageLoaderJPG::isALoadableFileExtension(const io::path& filename) const 41bool CImageLoaderJPG::isALoadableFileExtension(const io::path& filename) const
42{ 42{
43 return core::hasFileExtension ( filename, "jpg", "jpeg" ); 43 return core::hasFileExtension ( filename, "jpg", "jpeg" );
44} 44}
45 45
46 46
47#ifdef _IRR_COMPILE_WITH_LIBJPEG_ 47#ifdef _IRR_COMPILE_WITH_LIBJPEG_
48 48
49 // struct for handling jpeg errors 49 // struct for handling jpeg errors
50 struct irr_jpeg_error_mgr 50 struct irr_jpeg_error_mgr
51 { 51 {
52 // public jpeg error fields 52 // public jpeg error fields
53 struct jpeg_error_mgr pub; 53 struct jpeg_error_mgr pub;
54 54
55 // for longjmp, to return to caller on a fatal error 55 // for longjmp, to return to caller on a fatal error
56 jmp_buf setjmp_buffer; 56 jmp_buf setjmp_buffer;
57 }; 57 };
58 58
59void CImageLoaderJPG::init_source (j_decompress_ptr cinfo) 59void CImageLoaderJPG::init_source (j_decompress_ptr cinfo)
60{ 60{
61 // DO NOTHING 61 // DO NOTHING
62} 62}
63 63
64 64
65 65
66boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo) 66boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo)
67{ 67{
68 // DO NOTHING 68 // DO NOTHING
69 return 1; 69 return 1;
70} 70}
71 71
72 72
73 73
74void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count) 74void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count)
75{ 75{
76 jpeg_source_mgr * src = cinfo->src; 76 jpeg_source_mgr * src = cinfo->src;
77 if(count > 0) 77 if(count > 0)
78 { 78 {
79 src->bytes_in_buffer -= count; 79 src->bytes_in_buffer -= count;
80 src->next_input_byte += count; 80 src->next_input_byte += count;
81 } 81 }
82} 82}
83 83
84 84
85 85
86void CImageLoaderJPG::term_source (j_decompress_ptr cinfo) 86void CImageLoaderJPG::term_source (j_decompress_ptr cinfo)
87{ 87{
88 // DO NOTHING 88 // DO NOTHING
89} 89}
90 90
91 91
92void CImageLoaderJPG::error_exit (j_common_ptr cinfo) 92void CImageLoaderJPG::error_exit (j_common_ptr cinfo)
93{ 93{
94 // unfortunately we need to use a goto rather than throwing an exception 94 // unfortunately we need to use a goto rather than throwing an exception
95 // as gcc crashes under linux crashes when using throw from within 95 // as gcc crashes under linux crashes when using throw from within
96 // extern c code 96 // extern c code
97 97
98 // Always display the message 98 // Always display the message
99 (*cinfo->err->output_message) (cinfo); 99 (*cinfo->err->output_message) (cinfo);
100 100
101 // cinfo->err really points to a irr_error_mgr struct 101 // cinfo->err really points to a irr_error_mgr struct
102 irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err; 102 irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err;
103 103
104 longjmp(myerr->setjmp_buffer, 1); 104 longjmp(myerr->setjmp_buffer, 1);
105} 105}
106 106
107 107
108void CImageLoaderJPG::output_message(j_common_ptr cinfo) 108void CImageLoaderJPG::output_message(j_common_ptr cinfo)
109{ 109{
110 // display the error message. 110 // display the error message.
111 c8 temp1[JMSG_LENGTH_MAX]; 111 c8 temp1[JMSG_LENGTH_MAX];
112 (*cinfo->err->format_message)(cinfo, temp1); 112 (*cinfo->err->format_message)(cinfo, temp1);
113 core::stringc errMsg("JPEG FATAL ERROR in "); 113 core::stringc errMsg("JPEG FATAL ERROR in ");
114 errMsg += core::stringc(Filename); 114 errMsg += core::stringc(Filename);
115 os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR); 115 os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR);
116} 116}
117#endif // _IRR_COMPILE_WITH_LIBJPEG_ 117#endif // _IRR_COMPILE_WITH_LIBJPEG_
118 118
119//! returns true if the file maybe is able to be loaded by this class 119//! returns true if the file maybe is able to be loaded by this class
120bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const 120bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
121{ 121{
122 #ifndef _IRR_COMPILE_WITH_LIBJPEG_ 122 #ifndef _IRR_COMPILE_WITH_LIBJPEG_
123 return false; 123 return false;
124 #else 124 #else
125 125
126 if (!file) 126 if (!file)
127 return false; 127 return false;
128 128
129 s32 jfif = 0; 129 s32 jfif = 0;
130 file->seek(6); 130 file->seek(6);
131 file->read(&jfif, sizeof(s32)); 131 file->read(&jfif, sizeof(s32));
132 return (jfif == 0x4a464946 || jfif == 0x4649464a); 132 return (jfif == 0x4a464946 || jfif == 0x4649464a);
133 133
134 #endif 134 #endif
135} 135}
136 136
137//! creates a surface from the file 137//! creates a surface from the file
138IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const 138IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
139{ 139{
140 #ifndef _IRR_COMPILE_WITH_LIBJPEG_ 140 #ifndef _IRR_COMPILE_WITH_LIBJPEG_
141 os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG); 141 os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG);
142 return 0; 142 return 0;
143 #else 143 #else
144 144
145 if (!file) 145 if (!file)
146 return 0; 146 return 0;
147 147
148 Filename = file->getFileName(); 148 Filename = file->getFileName();
149 149
150 u8 **rowPtr=0; 150 u8 **rowPtr=0;
151 u8* input = new u8[file->getSize()]; 151 u8* input = new u8[file->getSize()];
152 file->read(input, file->getSize()); 152 file->read(input, file->getSize());
153 153
154 // allocate and initialize JPEG decompression object 154 // allocate and initialize JPEG decompression object
155 struct jpeg_decompress_struct cinfo; 155 struct jpeg_decompress_struct cinfo;
156 struct irr_jpeg_error_mgr jerr; 156 struct irr_jpeg_error_mgr jerr;
157 157
158 //We have to set up the error handler first, in case the initialization 158 //We have to set up the error handler first, in case the initialization
159 //step fails. (Unlikely, but it could happen if you are out of memory.) 159 //step fails. (Unlikely, but it could happen if you are out of memory.)
160 //This routine fills in the contents of struct jerr, and returns jerr's 160 //This routine fills in the contents of struct jerr, and returns jerr's
161 //address which we place into the link field in cinfo. 161 //address which we place into the link field in cinfo.
162 162
163 cinfo.err = jpeg_std_error(&jerr.pub); 163 cinfo.err = jpeg_std_error(&jerr.pub);
164 cinfo.err->error_exit = error_exit; 164 cinfo.err->error_exit = error_exit;
165 cinfo.err->output_message = output_message; 165 cinfo.err->output_message = output_message;
166 166
167 // compatibility fudge: 167 // compatibility fudge:
168 // we need to use setjmp/longjmp for error handling as gcc-linux 168 // we need to use setjmp/longjmp for error handling as gcc-linux
169 // crashes when throwing within external c code 169 // crashes when throwing within external c code
170 if (setjmp(jerr.setjmp_buffer)) 170 if (setjmp(jerr.setjmp_buffer))
171 { 171 {
172 // If we get here, the JPEG code has signaled an error. 172 // If we get here, the JPEG code has signaled an error.
173 // We need to clean up the JPEG object and return. 173 // We need to clean up the JPEG object and return.
174 174
175 jpeg_destroy_decompress(&cinfo); 175 jpeg_destroy_decompress(&cinfo);
176 176
177 delete [] input; 177 delete [] input;
178 // if the row pointer was created, we delete it. 178 // if the row pointer was created, we delete it.
179 if (rowPtr) 179 if (rowPtr)
180 delete [] rowPtr; 180 delete [] rowPtr;
181 181
182 // return null pointer 182 // return null pointer
183 return 0; 183 return 0;
184 } 184 }
185 185
186 // Now we can initialize the JPEG decompression object. 186 // Now we can initialize the JPEG decompression object.
187 jpeg_create_decompress(&cinfo); 187 jpeg_create_decompress(&cinfo);
188 188
189 // specify data source 189 // specify data source
190 jpeg_source_mgr jsrc; 190 jpeg_source_mgr jsrc;
191 191
192 // Set up data pointer 192 // Set up data pointer
193 jsrc.bytes_in_buffer = file->getSize(); 193 jsrc.bytes_in_buffer = file->getSize();
194 jsrc.next_input_byte = (JOCTET*)input; 194 jsrc.next_input_byte = (JOCTET*)input;
195 cinfo.src = &jsrc; 195 cinfo.src = &jsrc;
196 196
197 jsrc.init_source = init_source; 197 jsrc.init_source = init_source;
198 jsrc.fill_input_buffer = fill_input_buffer; 198 jsrc.fill_input_buffer = fill_input_buffer;
199 jsrc.skip_input_data = skip_input_data; 199 jsrc.skip_input_data = skip_input_data;
200 jsrc.resync_to_restart = jpeg_resync_to_restart; 200 jsrc.resync_to_restart = jpeg_resync_to_restart;
201 jsrc.term_source = term_source; 201 jsrc.term_source = term_source;
202 202
203 // Decodes JPG input from whatever source 203 // Decodes JPG input from whatever source
204 // Does everything AFTER jpeg_create_decompress 204 // Does everything AFTER jpeg_create_decompress
205 // and BEFORE jpeg_destroy_decompress 205 // and BEFORE jpeg_destroy_decompress
206 // Caller is responsible for arranging these + setting up cinfo 206 // Caller is responsible for arranging these + setting up cinfo
207 207
208 // read file parameters with jpeg_read_header() 208 // read file parameters with jpeg_read_header()
209 jpeg_read_header(&cinfo, TRUE); 209 jpeg_read_header(&cinfo, TRUE);
210 210
211 bool useCMYK=false; 211 bool useCMYK=false;
212 if (cinfo.jpeg_color_space==JCS_CMYK) 212 if (cinfo.jpeg_color_space==JCS_CMYK)
213 { 213 {
214 cinfo.out_color_space=JCS_CMYK; 214 cinfo.out_color_space=JCS_CMYK;
215 cinfo.out_color_components=4; 215 cinfo.out_color_components=4;
216 useCMYK=true; 216 useCMYK=true;
217 } 217 }
218 else 218 else
219 { 219 {
220 cinfo.out_color_space=JCS_RGB; 220 cinfo.out_color_space=JCS_RGB;
221 cinfo.out_color_components=3; 221 cinfo.out_color_components=3;
222 } 222 }
223 cinfo.output_gamma=2.2; 223 cinfo.output_gamma=2.2;
224 cinfo.do_fancy_upsampling=FALSE; 224 cinfo.do_fancy_upsampling=FALSE;
225 225
226 // Start decompressor 226 // Start decompressor
227 jpeg_start_decompress(&cinfo); 227 jpeg_start_decompress(&cinfo);
228 228
229 // Get image data 229 // Get image data
230 u16 rowspan = cinfo.image_width * cinfo.out_color_components; 230 u16 rowspan = cinfo.image_width * cinfo.out_color_components;
231 u32 width = cinfo.image_width; 231 u32 width = cinfo.image_width;
232 u32 height = cinfo.image_height; 232 u32 height = cinfo.image_height;
233 233
234 // Allocate memory for buffer 234 // Allocate memory for buffer
235 u8* output = new u8[rowspan * height]; 235 u8* output = new u8[rowspan * height];
236 236
237 // Here we use the library's state variable cinfo.output_scanline as the 237 // Here we use the library's state variable cinfo.output_scanline as the
238 // loop counter, so that we don't have to keep track ourselves. 238 // loop counter, so that we don't have to keep track ourselves.
239 // Create array of row pointers for lib 239 // Create array of row pointers for lib
240 rowPtr = new u8* [height]; 240 rowPtr = new u8* [height];
241 241
242 for( u32 i = 0; i < height; i++ ) 242 for( u32 i = 0; i < height; i++ )
243 rowPtr[i] = &output[ i * rowspan ]; 243 rowPtr[i] = &output[ i * rowspan ];
244 244
245 u32 rowsRead = 0; 245 u32 rowsRead = 0;
246 246
247 while( cinfo.output_scanline < cinfo.output_height ) 247 while( cinfo.output_scanline < cinfo.output_height )
248 rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead ); 248 rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead );
249 249
250 delete [] rowPtr; 250 delete [] rowPtr;
251 // Finish decompression 251 // Finish decompression
252 252
253 jpeg_finish_decompress(&cinfo); 253 jpeg_finish_decompress(&cinfo);
254 254
255 // Release JPEG decompression object 255 // Release JPEG decompression object
256 // This is an important step since it will release a good deal of memory. 256 // This is an important step since it will release a good deal of memory.
257 jpeg_destroy_decompress(&cinfo); 257 jpeg_destroy_decompress(&cinfo);
258 258
259 // convert image 259 // convert image
260 IImage* image = 0; 260 IImage* image = 0;
261 if (useCMYK) 261 if (useCMYK)
262 { 262 {
263 image = new CImage(ECF_R8G8B8, 263 image = new CImage(ECF_R8G8B8,
264 core::dimension2d<u32>(width, height)); 264 core::dimension2d<u32>(width, height));
265 const u32 size = 3*width*height; 265 const u32 size = 3*width*height;
266 u8* data = (u8*)image->lock(); 266 u8* data = (u8*)image->lock();
267 if (data) 267 if (data)
268 { 268 {
269 for (u32 i=0,j=0; i<size; i+=3, j+=4) 269 for (u32 i=0,j=0; i<size; i+=3, j+=4)
270 { 270 {
271 // Also works without K, but has more contrast with K multiplied in 271 // Also works without K, but has more contrast with K multiplied in
272// data[i+0] = output[j+2]; 272// data[i+0] = output[j+2];
273// data[i+1] = output[j+1]; 273// data[i+1] = output[j+1];
274// data[i+2] = output[j+0]; 274// data[i+2] = output[j+0];
275 data[i+0] = (char)(output[j+2]*(output[j+3]/255.f)); 275 data[i+0] = (char)(output[j+2]*(output[j+3]/255.f));
276 data[i+1] = (char)(output[j+1]*(output[j+3]/255.f)); 276 data[i+1] = (char)(output[j+1]*(output[j+3]/255.f));
277 data[i+2] = (char)(output[j+0]*(output[j+3]/255.f)); 277 data[i+2] = (char)(output[j+0]*(output[j+3]/255.f));
278 } 278 }
279 } 279 }
280 image->unlock(); 280 image->unlock();
281 delete [] output; 281 delete [] output;
282 } 282 }
283 else 283 else
284 image = new CImage(ECF_R8G8B8, 284 image = new CImage(ECF_R8G8B8,
285 core::dimension2d<u32>(width, height), output); 285 core::dimension2d<u32>(width, height), output);
286 286
287 delete [] input; 287 delete [] input;
288 288
289 return image; 289 return image;
290 290
291 #endif 291 #endif
292} 292}
293 293
294 294
295 295
296//! creates a loader which is able to load jpeg images 296//! creates a loader which is able to load jpeg images
297IImageLoader* createImageLoaderJPG() 297IImageLoader* createImageLoaderJPG()
298{ 298{
299 return new CImageLoaderJPG(); 299 return new CImageLoaderJPG();
300} 300}
301 301
302} // end namespace video 302} // end namespace video
303} // end namespace irr 303} // end namespace irr
304 304
305#endif 305#endif
306 306