diff options
author | David Walter Seikel | 2016-03-28 22:28:34 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-03-28 22:28:34 +1000 |
commit | 7028cbe09c688437910a25623098762bf0fa592d (patch) | |
tree | 10b5af58277d9880380c2251f109325542c4e6eb /src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp | |
parent | Move lemon to the src/others directory. (diff) | |
download | SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.zip SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.gz SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.bz2 SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.xz |
Move Irrlicht to src/others.
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp')
-rw-r--r-- | src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp new file mode 100644 index 0000000..3dbbe1c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp | |||
@@ -0,0 +1,290 @@ | |||
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 "CImageLoaderPNG.h" | ||
6 | |||
7 | #ifdef _IRR_COMPILE_WITH_PNG_LOADER_ | ||
8 | |||
9 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | ||
10 | #ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ | ||
11 | #include <png.h> // use system lib png | ||
12 | #else // _IRR_USE_NON_SYSTEM_LIB_PNG_ | ||
13 | #include "libpng/png.h" // use irrlicht included lib png | ||
14 | #endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ | ||
15 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | ||
16 | |||
17 | #include "CImage.h" | ||
18 | #include "CReadFile.h" | ||
19 | #include "os.h" | ||
20 | |||
21 | namespace irr | ||
22 | { | ||
23 | namespace video | ||
24 | { | ||
25 | |||
26 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | ||
27 | // PNG function for error handling | ||
28 | static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) | ||
29 | { | ||
30 | os::Printer::log("PNG fatal error", msg, ELL_ERROR); | ||
31 | longjmp(png_jmpbuf(png_ptr), 1); | ||
32 | } | ||
33 | |||
34 | // PNG function for warning handling | ||
35 | static void png_cpexcept_warn(png_structp png_ptr, png_const_charp msg) | ||
36 | { | ||
37 | os::Printer::log("PNG warning", msg, ELL_WARNING); | ||
38 | } | ||
39 | |||
40 | // PNG function for file reading | ||
41 | void PNGAPI user_read_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) | ||
42 | { | ||
43 | png_size_t check; | ||
44 | |||
45 | // changed by zola { | ||
46 | io::IReadFile* file=(io::IReadFile*)png_get_io_ptr(png_ptr); | ||
47 | check=(png_size_t) file->read((void*)data,(u32)length); | ||
48 | // } | ||
49 | |||
50 | if (check != length) | ||
51 | png_error(png_ptr, "Read Error"); | ||
52 | } | ||
53 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | ||
54 | |||
55 | |||
56 | //! returns true if the file maybe is able to be loaded by this class | ||
57 | //! based on the file extension (e.g. ".tga") | ||
58 | bool CImageLoaderPng::isALoadableFileExtension(const io::path& filename) const | ||
59 | { | ||
60 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | ||
61 | return core::hasFileExtension ( filename, "png" ); | ||
62 | #else | ||
63 | return false; | ||
64 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | ||
65 | } | ||
66 | |||
67 | |||
68 | //! returns true if the file maybe is able to be loaded by this class | ||
69 | bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const | ||
70 | { | ||
71 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | ||
72 | if (!file) | ||
73 | return false; | ||
74 | |||
75 | png_byte buffer[8]; | ||
76 | // Read the first few bytes of the PNG file | ||
77 | if (file->read(buffer, 8) != 8) | ||
78 | return false; | ||
79 | |||
80 | // Check if it really is a PNG file | ||
81 | return !png_sig_cmp(buffer, 0, 8); | ||
82 | #else | ||
83 | return false; | ||
84 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | ||
85 | } | ||
86 | |||
87 | |||
88 | // load in the image data | ||
89 | IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const | ||
90 | { | ||
91 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | ||
92 | if (!file) | ||
93 | return 0; | ||
94 | |||
95 | video::IImage* image = 0; | ||
96 | //Used to point to image rows | ||
97 | u8** RowPointers = 0; | ||
98 | |||
99 | png_byte buffer[8]; | ||
100 | // Read the first few bytes of the PNG file | ||
101 | if( file->read(buffer, 8) != 8 ) | ||
102 | { | ||
103 | os::Printer::log("LOAD PNG: can't read file\n", file->getFileName(), ELL_ERROR); | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | // Check if it really is a PNG file | ||
108 | if( png_sig_cmp(buffer, 0, 8) ) | ||
109 | { | ||
110 | os::Printer::log("LOAD PNG: not really a png\n", file->getFileName(), ELL_ERROR); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | // Allocate the png read struct | ||
115 | png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, | ||
116 | NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn); | ||
117 | if (!png_ptr) | ||
118 | { | ||
119 | os::Printer::log("LOAD PNG: Internal PNG create read struct failure\n", file->getFileName(), ELL_ERROR); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | // Allocate the png info struct | ||
124 | png_infop info_ptr = png_create_info_struct(png_ptr); | ||
125 | if (!info_ptr) | ||
126 | { | ||
127 | os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); | ||
128 | png_destroy_read_struct(&png_ptr, NULL, NULL); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | // for proper error handling | ||
133 | if (setjmp(png_jmpbuf(png_ptr))) | ||
134 | { | ||
135 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | ||
136 | if (RowPointers) | ||
137 | delete [] RowPointers; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | // changed by zola so we don't need to have public FILE pointers | ||
142 | png_set_read_fn(png_ptr, file, user_read_data_fcn); | ||
143 | |||
144 | png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature | ||
145 | |||
146 | png_read_info(png_ptr, info_ptr); // Read the info section of the png file | ||
147 | |||
148 | u32 Width; | ||
149 | u32 Height; | ||
150 | s32 BitDepth; | ||
151 | s32 ColorType; | ||
152 | { | ||
153 | // Use temporary variables to avoid passing casted pointers | ||
154 | png_uint_32 w,h; | ||
155 | // Extract info | ||
156 | png_get_IHDR(png_ptr, info_ptr, | ||
157 | &w, &h, | ||
158 | &BitDepth, &ColorType, NULL, NULL, NULL); | ||
159 | Width=w; | ||
160 | Height=h; | ||
161 | } | ||
162 | |||
163 | // Convert palette color to true color | ||
164 | if (ColorType==PNG_COLOR_TYPE_PALETTE) | ||
165 | png_set_palette_to_rgb(png_ptr); | ||
166 | |||
167 | // Convert low bit colors to 8 bit colors | ||
168 | if (BitDepth < 8) | ||
169 | { | ||
170 | if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) | ||
171 | png_set_expand_gray_1_2_4_to_8(png_ptr); | ||
172 | else | ||
173 | png_set_packing(png_ptr); | ||
174 | } | ||
175 | |||
176 | if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) | ||
177 | png_set_tRNS_to_alpha(png_ptr); | ||
178 | |||
179 | // Convert high bit colors to 8 bit colors | ||
180 | if (BitDepth == 16) | ||
181 | png_set_strip_16(png_ptr); | ||
182 | |||
183 | // Convert gray color to true color | ||
184 | if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) | ||
185 | png_set_gray_to_rgb(png_ptr); | ||
186 | |||
187 | int intent; | ||
188 | const double screen_gamma = 2.2; | ||
189 | |||
190 | if (png_get_sRGB(png_ptr, info_ptr, &intent)) | ||
191 | png_set_gamma(png_ptr, screen_gamma, 0.45455); | ||
192 | else | ||
193 | { | ||
194 | double image_gamma; | ||
195 | if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) | ||
196 | png_set_gamma(png_ptr, screen_gamma, image_gamma); | ||
197 | else | ||
198 | png_set_gamma(png_ptr, screen_gamma, 0.45455); | ||
199 | } | ||
200 | |||
201 | // Update the changes in between, as we need to get the new color type | ||
202 | // for proper processing of the RGBA type | ||
203 | png_read_update_info(png_ptr, info_ptr); | ||
204 | { | ||
205 | // Use temporary variables to avoid passing casted pointers | ||
206 | png_uint_32 w,h; | ||
207 | // Extract info | ||
208 | png_get_IHDR(png_ptr, info_ptr, | ||
209 | &w, &h, | ||
210 | &BitDepth, &ColorType, NULL, NULL, NULL); | ||
211 | Width=w; | ||
212 | Height=h; | ||
213 | } | ||
214 | |||
215 | // Convert RGBA to BGRA | ||
216 | if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) | ||
217 | { | ||
218 | #ifdef __BIG_ENDIAN__ | ||
219 | png_set_swap_alpha(png_ptr); | ||
220 | #else | ||
221 | png_set_bgr(png_ptr); | ||
222 | #endif | ||
223 | } | ||
224 | |||
225 | // Create the image structure to be filled by png data | ||
226 | if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) | ||
227 | image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(Width, Height)); | ||
228 | else | ||
229 | image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(Width, Height)); | ||
230 | if (!image) | ||
231 | { | ||
232 | os::Printer::log("LOAD PNG: Internal PNG create image struct failure\n", file->getFileName(), ELL_ERROR); | ||
233 | png_destroy_read_struct(&png_ptr, NULL, NULL); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | // Create array of pointers to rows in image data | ||
238 | RowPointers = new png_bytep[Height]; | ||
239 | if (!RowPointers) | ||
240 | { | ||
241 | os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); | ||
242 | png_destroy_read_struct(&png_ptr, NULL, NULL); | ||
243 | delete image; | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | // Fill array of pointers to rows in image data | ||
248 | unsigned char* data = (unsigned char*)image->lock(); | ||
249 | for (u32 i=0; i<Height; ++i) | ||
250 | { | ||
251 | RowPointers[i]=data; | ||
252 | data += image->getPitch(); | ||
253 | } | ||
254 | |||
255 | // for proper error handling | ||
256 | if (setjmp(png_jmpbuf(png_ptr))) | ||
257 | { | ||
258 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | ||
259 | delete [] RowPointers; | ||
260 | image->unlock(); | ||
261 | delete [] image; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | // Read data using the library function that handles all transformations including interlacing | ||
266 | png_read_image(png_ptr, RowPointers); | ||
267 | |||
268 | png_read_end(png_ptr, NULL); | ||
269 | delete [] RowPointers; | ||
270 | image->unlock(); | ||
271 | png_destroy_read_struct(&png_ptr,&info_ptr, 0); // Clean up memory | ||
272 | |||
273 | return image; | ||
274 | #else | ||
275 | return 0; | ||
276 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | ||
277 | } | ||
278 | |||
279 | |||
280 | IImageLoader* createImageLoaderPNG() | ||
281 | { | ||
282 | return new CImageLoaderPng(); | ||
283 | } | ||
284 | |||
285 | |||
286 | }// end namespace irr | ||
287 | }//end namespace video | ||
288 | |||
289 | #endif | ||
290 | |||