aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CImageWriterPNG.cpp444
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
23namespace irr 23namespace irr
24{ 24{
25namespace video 25namespace video
26{ 26{
27 27
28IImageWriter* createImageWriterPNG() 28IImageWriter* 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
35static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) 35static 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
42static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg) 42static 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
48void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) 48void 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
60CImageWriterPNG::CImageWriterPNG() 60CImageWriterPNG::CImageWriterPNG()
61{ 61{
62#ifdef _DEBUG 62#ifdef _DEBUG
63 setDebugName("CImageWriterPNG"); 63 setDebugName("CImageWriterPNG");
64#endif 64#endif
65} 65}
66 66
67bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const 67bool 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
76bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const 76bool 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