claw 1.9.0
 
Loading...
Searching...
No Matches
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@stuff-o-matic.com
24*/
30#include <claw/graphic/png.hpp>
31
32#include <claw/assert.hpp>
33#include <claw/exception.hpp>
34
42 png_bytep data,
43 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}
50
56{
58 = (claw::graphic::png::writer::target_manager*)png_get_io_ptr(png_ptr);
59
60 self->flush();
61}
62
68 : m_output(os)
69{
70 CLAW_PRECOND(!!os);
71}
72
79 png_size_t length)
80{
81 m_output.write((char*)data, length * sizeof(png_byte));
82}
83
88{
89 m_output.flush();
90}
91
99
106 compression_level compression_level_, interlace_type interlace_)
107 : compression(compression_level_)
108 , interlace(interlace_)
109{}
110
111const unsigned int claw::graphic::png::writer::s_rgba_pixel_size = 4;
112
118 : m_image(img)
119{}
120
127claw::graphic::png::writer::writer(const image& img, std::ostream& f,
128 const options& opt)
129 : m_image(img)
130{
131 save(f, opt);
132}
133
140 const options& opt) const
141{
142 CLAW_PRECOND(!!f);
143
144 target_manager outfile(f);
145 png_structp png_ptr;
146 png_infop info_ptr;
147
148 create_write_structures(png_ptr, info_ptr);
149
150 if(setjmp(png_jmpbuf(png_ptr)))
151 {
152 /* If we get here, we had a problem reading the file */
153 /* Free all of the memory associated with the png_ptr and info_ptr */
154 png_destroy_write_struct(&png_ptr, &info_ptr);
155 throw CLAW_EXCEPTION("Invalid PNG file.");
156 }
157
158 png_set_write_fn(png_ptr, (void*)&outfile,
161
162 set_options(png_ptr, info_ptr, opt);
163 save_image(png_ptr, info_ptr);
164
165 png_destroy_write_struct(&png_ptr, &info_ptr);
166}
167
174void claw::graphic::png::writer::set_options(png_structp png_ptr,
175 png_infop info_ptr,
176 const options& opt) const
177{
178 CLAW_PRECOND(png_ptr);
179 CLAW_PRECOND(info_ptr);
180
181 png_set_compression_level(png_ptr, opt.compression);
182
183 png_set_IHDR(png_ptr, info_ptr, m_image.width(), m_image.height(),
184 sizeof(pixel_type::component_type) * 8, /* 8 bits per byte */
185 PNG_COLOR_TYPE_RGB_ALPHA, opt.interlace,
186 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
187}
188
194void claw::graphic::png::writer::save_image(png_structp png_ptr,
195 png_infop info_ptr) const
196{
197 CLAW_PRECOND(png_ptr);
198 CLAW_PRECOND(info_ptr);
199
200 const unsigned int row_length = s_rgba_pixel_size * m_image.width();
201 png_bytepp data
202 = (png_bytepp)png_malloc(png_ptr, sizeof(png_bytep) * m_image.height());
203 unsigned int i = 0;
204
205 try
206 {
207 for(i = 0; i != m_image.height(); ++i)
208 {
209 data[i] = (png_bytep)png_malloc(png_ptr, row_length);
210
211 if(!data[i])
212 throw std::bad_alloc();
213
214 copy_pixel_line(data[i], i);
215 }
216
217 png_set_rows(png_ptr, info_ptr, data);
218 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
219 }
220 catch(...)
221 {
222 for(unsigned int j = 0; j != i; ++j)
223 png_free(png_ptr, data[j]);
224
225 png_free(png_ptr, data);
226 throw;
227 }
228
229 for(i = 0; i != m_image.height(); ++i)
230 png_free(png_ptr, data[i]);
231
232 png_free(png_ptr, data);
233}
234
241void claw::graphic::png::writer::copy_pixel_line(png_bytep data,
242 unsigned int y) const
243{
244 CLAW_PRECOND(data);
245 CLAW_PRECOND(y < m_image.height());
246
247 // four bytes for each pixel in the line
248 for(unsigned int x = 0; x != m_image.width(); ++x, data += s_rgba_pixel_size)
249 {
250 data[0] = m_image[y][x].components.red;
251 data[1] = m_image[y][x].components.green;
252 data[2] = m_image[y][x].components.blue;
253 data[3] = m_image[y][x].components.alpha;
254 }
255}
256
262void claw::graphic::png::writer::create_write_structures(
263 png_structp& png_ptr, png_infop& info_ptr) const
264{
265 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
266
267 if(png_ptr)
268 {
269 info_ptr = png_create_info_struct(png_ptr);
270
271 if(!info_ptr)
272 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
273 }
274
275 if(!png_ptr || !info_ptr)
276 throw CLAW_EXCEPTION("Can't create PNG write structures.");
277}
Some assert macros to strengthen you code.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
Definition assert.hpp:94
image()
Constructor. Creates an image without datas.
Definition image.cpp:95
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:92
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:119
compression_level compression
Compression level to use in the saved stream.
Definition png.hpp:148
interlace_type interlace
Interlace method to apply to the saved image.
Definition png.hpp:151
interlace_type
The algorithm to use to interlace the saved image.
Definition png.hpp:132
@ none
Saved image won't be interaced.
Definition png.hpp:134
compression_level
Compression level in the interlaced image.
Definition png.hpp:123
Target manager that allow us to write in a std::ostream.
Definition png.hpp:162
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