Claw 1.7.3
png_writer.cpp
Go to the documentation of this file.
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
23 contact: julien.jorge@gamned.org
24*/
30#include <claw/png.hpp>
31
32#include <claw/exception.hpp>
33#include <claw/assert.hpp>
34
35/*----------------------------------------------------------------------------*/
43( png_structp png_ptr, png_bytep data, png_size_t length )
44{
46 (claw::graphic::png::writer::target_manager*)png_get_io_ptr(png_ptr);
47
48 self->write(data, length);
49} // claw__graphic__png__target_manager__write()
50
51/*----------------------------------------------------------------------------*/
57{
59 (claw::graphic::png::writer::target_manager*)png_get_io_ptr(png_ptr);
60
61 self->flush();
62} // claw__graphic__png__target_manager__write()
63
64
65
66
67/*----------------------------------------------------------------------------*/
73 : m_output(os)
74{
75 CLAW_PRECOND( !!os );
76} // png::writer::target_manager::target_manager()
77
78/*----------------------------------------------------------------------------*/
85( png_bytep data, png_size_t length )
86{
87 m_output.write( (char*)data, length * sizeof(png_byte) );
88} // png::writer::target_manager::write()
89
90/*----------------------------------------------------------------------------*/
95{
96 m_output.flush();
97} // png::writer::target_manager::flush()
98
99
100
101
102/*----------------------------------------------------------------------------*/
107 : compression(default_compression), interlace(none)
108{
109
110} // png::writer::options::options()
111
112/*----------------------------------------------------------------------------*/
119( compression_level compression_level_, interlace_type interlace_ )
120 : compression(compression_level_), interlace(interlace_)
121{
122
123} // png::writer::options::options()
124
125
126
127
128/*----------------------------------------------------------------------------*/
129const unsigned int claw::graphic::png::writer::s_rgba_pixel_size = 4;
130
131/*----------------------------------------------------------------------------*/
137 : m_image( img )
138{
139
140} // png::writer::writer()
141
142/*----------------------------------------------------------------------------*/
150( const image& img, std::ostream& f, const options& opt )
151 : m_image( img )
152{
153 save(f, opt);
154} // png::writer::writer()
155
156/*----------------------------------------------------------------------------*/
162void
163claw::graphic::png::writer::save( std::ostream& f, const options& opt ) const
164{
165 CLAW_PRECOND( !!f );
166
167 target_manager outfile(f);
168 png_structp png_ptr;
169 png_infop info_ptr;
170
171 create_write_structures(png_ptr, info_ptr);
172
173 if (setjmp(png_jmpbuf(png_ptr)))
174 {
175 /* If we get here, we had a problem reading the file */
176 /* Free all of the memory associated with the png_ptr and info_ptr */
177 png_destroy_write_struct(&png_ptr, &info_ptr);
178 throw CLAW_EXCEPTION("Invalid PNG file.");
179 }
180
181 png_set_write_fn( png_ptr, (void *)&outfile,
184
185 set_options( png_ptr, info_ptr, opt );
186 save_image( png_ptr, info_ptr );
187
188 png_destroy_write_struct(&png_ptr, &info_ptr);
189} // png::writer::save()
190
191/*----------------------------------------------------------------------------*/
198void claw::graphic::png::writer::set_options
199( png_structp png_ptr, png_infop info_ptr, const options& opt ) const
200{
201 CLAW_PRECOND( png_ptr );
202 CLAW_PRECOND( info_ptr );
203
204 png_set_compression_level( png_ptr, opt.compression );
205
206 png_set_IHDR( png_ptr, info_ptr, m_image.width(), m_image.height(),
207 sizeof(pixel_type::component_type) * 8, /* 8 bits per byte */
208 PNG_COLOR_TYPE_RGB_ALPHA,
209 opt.interlace, PNG_COMPRESSION_TYPE_DEFAULT,
210 PNG_FILTER_TYPE_DEFAULT );
211} // png::writer::set_options()
212
213/*----------------------------------------------------------------------------*/
219void claw::graphic::png::writer::save_image
220( png_structp png_ptr, png_infop info_ptr ) const
221{
222 CLAW_PRECOND( png_ptr );
223 CLAW_PRECOND( info_ptr );
224
225 const unsigned int row_length = s_rgba_pixel_size * m_image.width();
226 png_bytepp data =
227 (png_bytepp)png_malloc( png_ptr, sizeof(png_bytep) * m_image.height() );
228 unsigned int i=0;
229
230 try
231 {
232 for (i=0; i!=m_image.height(); ++i)
233 {
234 data[i] = (png_bytep)png_malloc( png_ptr, row_length );
235
236 if (!data[i])
237 throw std::bad_alloc();
238
239 copy_pixel_line( data[i], i );
240 }
241
242 png_set_rows(png_ptr, info_ptr, data);
243 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
244 }
245 catch(...)
246 {
247 for(unsigned int j=0; j!=i; ++j)
248 png_free(png_ptr, data[j]);
249
250 png_free(png_ptr, data);
251 throw;
252 }
253
254 for(i=0; i!=m_image.height(); ++i)
255 png_free(png_ptr, data[i]);
256
257 png_free(png_ptr, data);
258} // png::writer::save_image()
259
260/*----------------------------------------------------------------------------*/
267void claw::graphic::png::writer::copy_pixel_line
268( png_bytep data, unsigned int y ) const
269{
270 CLAW_PRECOND( data );
271 CLAW_PRECOND( y < m_image.height() );
272
273 // four bytes for each pixel in the line
274 for (unsigned int x=0; x!=m_image.width(); ++x, data+=s_rgba_pixel_size)
275 {
276 data[0] = m_image[y][x].components.red;
277 data[1] = m_image[y][x].components.green;
278 data[2] = m_image[y][x].components.blue;
279 data[3] = m_image[y][x].components.alpha;
280 }
281} // png::writer::copy_pixel_line()
282
283/*----------------------------------------------------------------------------*/
289void claw::graphic::png::writer::create_write_structures
290( png_structp& png_ptr, png_infop& info_ptr ) const
291{
292 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
293
294 if (png_ptr)
295 {
296 info_ptr = png_create_info_struct(png_ptr);
297
298 if (!info_ptr)
299 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
300 }
301
302 if (!png_ptr || !info_ptr)
303 throw CLAW_EXCEPTION("Can't create PNG write structures.");
304} // png::writer::create_write_structures()
Some assert macros to strengthen you code.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition assert.hpp:98
A class to deal with images.
Definition image.hpp:50
void save(std::ostream &f, const options &opt=options()) const
Save the image in a PNG file.
writer(const image &img)
Constructor.
A simple class to use as exception with string message.
#define CLAW_EXCEPTION(m)
Create an exception and add the name of the current function to the message.
Definition exception.hpp:90
A class for png pictures.
void claw__graphic__png__target_manager__write(png_structp png_ptr, png_bytep data, png_size_t length)
Write data in the ouput stream.
void claw__graphic__png__target_manager__flush(png_structp png_ptr)
Flush the output stream.
Parameters of the writing algorithm.
Definition png.hpp:122
interlace_type
The algorithm to use to interlace the saved image.
Definition png.hpp:135
compression_level
Compression level in the interlaced image.
Definition png.hpp:126
Target manager that allow us to write in a std::ostream.
Definition png.hpp:166
void flush()
Flush the output stream.
void write(png_bytep data, png_size_t length)
Write data in the ouput stream.
target_manager(std::ostream &os)
Constructor.
unsigned char component_type
The type of the components of the color.
Definition pixel.hpp:82