diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp | 444 |
1 files changed, 222 insertions, 222 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp index 6c6386e..fc868f9 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp | |||
@@ -1,222 +1,222 @@ | |||
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 "CImageWriterPNG.h" | 5 | #include "CImageWriterPNG.h" |
6 | 6 | ||
7 | #ifdef _IRR_COMPILE_WITH_PNG_WRITER_ | 7 | #ifdef _IRR_COMPILE_WITH_PNG_WRITER_ |
8 | 8 | ||
9 | #include "CImageLoaderPNG.h" | 9 | #include "CImageLoaderPNG.h" |
10 | #include "CColorConverter.h" | 10 | #include "CColorConverter.h" |
11 | #include "IWriteFile.h" | 11 | #include "IWriteFile.h" |
12 | #include "irrString.h" | 12 | #include "irrString.h" |
13 | #include "os.h" // for logging | 13 | #include "os.h" // for logging |
14 | 14 | ||
15 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | 15 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ |
16 | #ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ | 16 | #ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ |
17 | #include <png.h> // use system lib png | 17 | #include <png.h> // use system lib png |
18 | #else // _IRR_USE_NON_SYSTEM_LIB_PNG_ | 18 | #else // _IRR_USE_NON_SYSTEM_LIB_PNG_ |
19 | #include "libpng/png.h" // use irrlicht included lib png | 19 | #include "libpng/png.h" // use irrlicht included lib png |
20 | #endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ | 20 | #endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ |
21 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | 21 | #endif // _IRR_COMPILE_WITH_LIBPNG_ |
22 | 22 | ||
23 | namespace irr | 23 | namespace irr |
24 | { | 24 | { |
25 | namespace video | 25 | namespace video |
26 | { | 26 | { |
27 | 27 | ||
28 | IImageWriter* createImageWriterPNG() | 28 | IImageWriter* createImageWriterPNG() |
29 | { | 29 | { |
30 | return new CImageWriterPNG; | 30 | return new CImageWriterPNG; |
31 | } | 31 | } |
32 | 32 | ||
33 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | 33 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ |
34 | // PNG function for error handling | 34 | // PNG function for error handling |
35 | static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) | 35 | static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) |
36 | { | 36 | { |
37 | os::Printer::log("PNG fatal error", msg, ELL_ERROR); | 37 | os::Printer::log("PNG fatal error", msg, ELL_ERROR); |
38 | longjmp(png_jmpbuf(png_ptr), 1); | 38 | longjmp(png_jmpbuf(png_ptr), 1); |
39 | } | 39 | } |
40 | 40 | ||
41 | // PNG function for warning handling | 41 | // PNG function for warning handling |
42 | static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg) | 42 | static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg) |
43 | { | 43 | { |
44 | os::Printer::log("PNG warning", msg, ELL_WARNING); | 44 | os::Printer::log("PNG warning", msg, ELL_WARNING); |
45 | } | 45 | } |
46 | 46 | ||
47 | // PNG function for file writing | 47 | // PNG function for file writing |
48 | void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) | 48 | void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) |
49 | { | 49 | { |
50 | png_size_t check; | 50 | png_size_t check; |
51 | 51 | ||
52 | io::IWriteFile* file=(io::IWriteFile*)png_get_io_ptr(png_ptr); | 52 | io::IWriteFile* file=(io::IWriteFile*)png_get_io_ptr(png_ptr); |
53 | check=(png_size_t) file->write((const void*)data,(u32)length); | 53 | check=(png_size_t) file->write((const void*)data,(u32)length); |
54 | 54 | ||
55 | if (check != length) | 55 | if (check != length) |
56 | png_error(png_ptr, "Write Error"); | 56 | png_error(png_ptr, "Write Error"); |
57 | } | 57 | } |
58 | #endif // _IRR_COMPILE_WITH_LIBPNG_ | 58 | #endif // _IRR_COMPILE_WITH_LIBPNG_ |
59 | 59 | ||
60 | CImageWriterPNG::CImageWriterPNG() | 60 | CImageWriterPNG::CImageWriterPNG() |
61 | { | 61 | { |
62 | #ifdef _DEBUG | 62 | #ifdef _DEBUG |
63 | setDebugName("CImageWriterPNG"); | 63 | setDebugName("CImageWriterPNG"); |
64 | #endif | 64 | #endif |
65 | } | 65 | } |
66 | 66 | ||
67 | bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const | 67 | bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const |
68 | { | 68 | { |
69 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | 69 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ |
70 | return core::hasFileExtension ( filename, "png" ); | 70 | return core::hasFileExtension ( filename, "png" ); |
71 | #else | 71 | #else |
72 | return false; | 72 | return false; |
73 | #endif | 73 | #endif |
74 | } | 74 | } |
75 | 75 | ||
76 | bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const | 76 | bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const |
77 | { | 77 | { |
78 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ | 78 | #ifdef _IRR_COMPILE_WITH_LIBPNG_ |
79 | if (!file || !image) | 79 | if (!file || !image) |
80 | return false; | 80 | return false; |
81 | 81 | ||
82 | // Allocate the png write struct | 82 | // Allocate the png write struct |
83 | png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, | 83 | png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, |
84 | NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning); | 84 | NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning); |
85 | if (!png_ptr) | 85 | if (!png_ptr) |
86 | { | 86 | { |
87 | os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); | 87 | os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); |
88 | return false; | 88 | return false; |
89 | } | 89 | } |
90 | 90 | ||
91 | // Allocate the png info struct | 91 | // Allocate the png info struct |
92 | png_infop info_ptr = png_create_info_struct(png_ptr); | 92 | png_infop info_ptr = png_create_info_struct(png_ptr); |
93 | if (!info_ptr) | 93 | if (!info_ptr) |
94 | { | 94 | { |
95 | os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); | 95 | os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); |
96 | png_destroy_write_struct(&png_ptr, NULL); | 96 | png_destroy_write_struct(&png_ptr, NULL); |
97 | return false; | 97 | return false; |
98 | } | 98 | } |
99 | 99 | ||
100 | // for proper error handling | 100 | // for proper error handling |
101 | if (setjmp(png_jmpbuf(png_ptr))) | 101 | if (setjmp(png_jmpbuf(png_ptr))) |
102 | { | 102 | { |
103 | png_destroy_write_struct(&png_ptr, &info_ptr); | 103 | png_destroy_write_struct(&png_ptr, &info_ptr); |
104 | return false; | 104 | return false; |
105 | } | 105 | } |
106 | 106 | ||
107 | png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL); | 107 | png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL); |
108 | 108 | ||
109 | // Set info | 109 | // Set info |
110 | switch(image->getColorFormat()) | 110 | switch(image->getColorFormat()) |
111 | { | 111 | { |
112 | case ECF_A8R8G8B8: | 112 | case ECF_A8R8G8B8: |
113 | case ECF_A1R5G5B5: | 113 | case ECF_A1R5G5B5: |
114 | png_set_IHDR(png_ptr, info_ptr, | 114 | png_set_IHDR(png_ptr, info_ptr, |
115 | image->getDimension().Width, image->getDimension().Height, | 115 | image->getDimension().Width, image->getDimension().Height, |
116 | 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, | 116 | 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, |
117 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); | 117 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); |
118 | break; | 118 | break; |
119 | default: | 119 | default: |
120 | png_set_IHDR(png_ptr, info_ptr, | 120 | png_set_IHDR(png_ptr, info_ptr, |
121 | image->getDimension().Width, image->getDimension().Height, | 121 | image->getDimension().Width, image->getDimension().Height, |
122 | 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, | 122 | 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, |
123 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); | 123 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); |
124 | } | 124 | } |
125 | 125 | ||
126 | s32 lineWidth = image->getDimension().Width; | 126 | s32 lineWidth = image->getDimension().Width; |
127 | switch(image->getColorFormat()) | 127 | switch(image->getColorFormat()) |
128 | { | 128 | { |
129 | case ECF_R8G8B8: | 129 | case ECF_R8G8B8: |
130 | case ECF_R5G6B5: | 130 | case ECF_R5G6B5: |
131 | lineWidth*=3; | 131 | lineWidth*=3; |
132 | break; | 132 | break; |
133 | case ECF_A8R8G8B8: | 133 | case ECF_A8R8G8B8: |
134 | case ECF_A1R5G5B5: | 134 | case ECF_A1R5G5B5: |
135 | lineWidth*=4; | 135 | lineWidth*=4; |
136 | break; | 136 | break; |
137 | // TODO: Error handling in case of unsupported color format | 137 | // TODO: Error handling in case of unsupported color format |
138 | default: | 138 | default: |
139 | break; | 139 | break; |
140 | } | 140 | } |
141 | u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; | 141 | u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; |
142 | if (!tmpImage) | 142 | if (!tmpImage) |
143 | { | 143 | { |
144 | os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); | 144 | os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); |
145 | png_destroy_write_struct(&png_ptr, &info_ptr); | 145 | png_destroy_write_struct(&png_ptr, &info_ptr); |
146 | return false; | 146 | return false; |
147 | } | 147 | } |
148 | 148 | ||
149 | u8* data = (u8*)image->lock(); | 149 | u8* data = (u8*)image->lock(); |
150 | switch(image->getColorFormat()) | 150 | switch(image->getColorFormat()) |
151 | { | 151 | { |
152 | case ECF_R8G8B8: | 152 | case ECF_R8G8B8: |
153 | CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); | 153 | CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); |
154 | break; | 154 | break; |
155 | case ECF_A8R8G8B8: | 155 | case ECF_A8R8G8B8: |
156 | CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); | 156 | CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); |
157 | break; | 157 | break; |
158 | case ECF_R5G6B5: | 158 | case ECF_R5G6B5: |
159 | CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); | 159 | CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); |
160 | break; | 160 | break; |
161 | case ECF_A1R5G5B5: | 161 | case ECF_A1R5G5B5: |
162 | CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); | 162 | CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); |
163 | break; | 163 | break; |
164 | #ifndef _DEBUG | 164 | #ifndef _DEBUG |
165 | // TODO: Error handling in case of unsupported color format | 165 | // TODO: Error handling in case of unsupported color format |
166 | default: | 166 | default: |
167 | break; | 167 | break; |
168 | #endif | 168 | #endif |
169 | } | 169 | } |
170 | image->unlock(); | 170 | image->unlock(); |
171 | 171 | ||
172 | // Create array of pointers to rows in image data | 172 | // Create array of pointers to rows in image data |
173 | 173 | ||
174 | //Used to point to image rows | 174 | //Used to point to image rows |
175 | u8** RowPointers = new png_bytep[image->getDimension().Height]; | 175 | u8** RowPointers = new png_bytep[image->getDimension().Height]; |
176 | if (!RowPointers) | 176 | if (!RowPointers) |
177 | { | 177 | { |
178 | os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); | 178 | os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); |
179 | png_destroy_write_struct(&png_ptr, &info_ptr); | 179 | png_destroy_write_struct(&png_ptr, &info_ptr); |
180 | delete [] tmpImage; | 180 | delete [] tmpImage; |
181 | return false; | 181 | return false; |
182 | } | 182 | } |
183 | 183 | ||
184 | data=tmpImage; | 184 | data=tmpImage; |
185 | // Fill array of pointers to rows in image data | 185 | // Fill array of pointers to rows in image data |
186 | for (u32 i=0; i<image->getDimension().Height; ++i) | 186 | for (u32 i=0; i<image->getDimension().Height; ++i) |
187 | { | 187 | { |
188 | RowPointers[i]=data; | 188 | RowPointers[i]=data; |
189 | data += lineWidth; | 189 | data += lineWidth; |
190 | } | 190 | } |
191 | // for proper error handling | 191 | // for proper error handling |
192 | if (setjmp(png_jmpbuf(png_ptr))) | 192 | if (setjmp(png_jmpbuf(png_ptr))) |
193 | { | 193 | { |
194 | png_destroy_write_struct(&png_ptr, &info_ptr); | 194 | png_destroy_write_struct(&png_ptr, &info_ptr); |
195 | delete [] RowPointers; | 195 | delete [] RowPointers; |
196 | delete [] tmpImage; | 196 | delete [] tmpImage; |
197 | return false; | 197 | return false; |
198 | } | 198 | } |
199 | 199 | ||
200 | png_set_rows(png_ptr, info_ptr, RowPointers); | 200 | png_set_rows(png_ptr, info_ptr, RowPointers); |
201 | 201 | ||
202 | if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5) | 202 | if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5) |
203 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL); | 203 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL); |
204 | else | 204 | else |
205 | { | 205 | { |
206 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); | 206 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); |
207 | } | 207 | } |
208 | 208 | ||
209 | delete [] RowPointers; | 209 | delete [] RowPointers; |
210 | delete [] tmpImage; | 210 | delete [] tmpImage; |
211 | png_destroy_write_struct(&png_ptr, &info_ptr); | 211 | png_destroy_write_struct(&png_ptr, &info_ptr); |
212 | return true; | 212 | return true; |
213 | #else | 213 | #else |
214 | return false; | 214 | return false; |
215 | #endif | 215 | #endif |
216 | } | 216 | } |
217 | 217 | ||
218 | } // namespace video | 218 | } // namespace video |
219 | } // namespace irr | 219 | } // namespace irr |
220 | 220 | ||
221 | #endif | 221 | #endif |
222 | 222 | ||