Claw 1.7.3
jpeg_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/jpeg.hpp>
32
33#include <claw/exception.hpp>
34#include <claw/assert.hpp>
35
36/*----------------------------------------------------------------------------*/
41METHODDEF(void)
43{
44 // nothing to do
45} // claw__graphic__jpeg__destination_manager__init_destination()
46
47/*----------------------------------------------------------------------------*/
52METHODDEF(boolean)
54(j_compress_ptr cinfo)
55{
58
59 CLAW_PRECOND( &self->pub == cinfo->dest );
60
61 self->flush();
62
63 return TRUE;
64} // claw__graphic__jpeg__destination_manager__empty_output_buffer()
65
66/*----------------------------------------------------------------------------*/
71METHODDEF(void)
73{
76
77 CLAW_PRECOND( &self->pub == cinfo->dest );
78
79 self->term();
80} // claw__graphic__jpeg__destination_manager__term_destination()
81
82
83
84
85/*----------------------------------------------------------------------------*/
91( std::ostream& os )
92 : m_output(os), m_buffer_size(1024)
93{
94 m_buffer = new JOCTET[m_buffer_size];
95 pub.next_output_byte = m_buffer;
96 pub.free_in_buffer = m_buffer_size;
97} // jpeg::writer::destination_manager::destination_manager()
98
99/*----------------------------------------------------------------------------*/
104{
105 delete[] m_buffer;
106} // jpeg::writer::destination_manager::~destination_manager()
107
108/*----------------------------------------------------------------------------*/
113{
114 m_output.write((char*)m_buffer, m_buffer_size);
115
116 pub.next_output_byte = m_buffer;
117 pub.free_in_buffer = m_buffer_size;
118} // jpeg::writer::destination_manager::fill_output_buffer()
119
120/*----------------------------------------------------------------------------*/
124void
126{
127 m_output.write((char*)m_buffer, m_buffer_size - pub.free_in_buffer);
128} // jpeg::writer::destination_manager::term()
129
130
131
132/*----------------------------------------------------------------------------*/
138 : quality(75), progressive(false)
139{
140
141} // jpeg::writer::options::options()
142
143/*----------------------------------------------------------------------------*/
151( unsigned char quality_, bool progressive_ )
152 : quality(quality_), progressive(progressive_)
153{
154
155} // jpeg::writer::options::options()
156
157
158
159
160/*----------------------------------------------------------------------------*/
161const unsigned int claw::graphic::jpeg::writer::s_rgb_pixel_size = 3;
162
163/*----------------------------------------------------------------------------*/
169 : m_image( img )
170{
171
172} // jpeg::writer::writer()
173
174/*----------------------------------------------------------------------------*/
182( const image& img, std::ostream& f, const options& opt )
183 : m_image( img )
184{
185 save(f, opt);
186} // jpeg::writer::writer()
187
188/*----------------------------------------------------------------------------*/
194void
195claw::graphic::jpeg::writer::save( std::ostream& f, const options& opt ) const
196{
197 CLAW_PRECOND( !!f );
198
199 destination_manager outfile(f);
200 jpeg_compress_struct cinfo;
201 error_manager jerr;
202
203 cinfo.err = jpeg_std_error(&jerr.pub);
204 jerr.pub.error_exit = jpeg__error_manager__error_exit;
205
206 if ( setjmp(jerr.setjmp_buffer) )
207 throw CLAW_EXCEPTION(jerr.error_string);
208
209 create_compress_info( cinfo, outfile );
210
211 try
212 {
213 set_options( cinfo, opt );
214 save_image( cinfo );
215 jpeg_destroy_compress(&cinfo);
216 }
217 catch(...)
218 {
219 jpeg_abort_compress(&cinfo);
220 jpeg_destroy_compress(&cinfo);
221 throw;
222 }
223} // jpeg::writer::save()
224
225/*----------------------------------------------------------------------------*/
231void claw::graphic::jpeg::writer::set_options
232( jpeg_compress_struct& cinfo, const options& opt ) const
233{
234 cinfo.image_width = m_image.width(); /* image width, in pixels */
235 cinfo.image_height = m_image.height(); /* image height, in pixels */
236 cinfo.input_components = s_rgb_pixel_size; /* # of components per pixel */
237 cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
238
239 jpeg_set_defaults(&cinfo);
240
241 if (opt.quality > 100)
242 jpeg_set_quality(&cinfo, 100, TRUE);
243 else
244 jpeg_set_quality(&cinfo, opt.quality, TRUE);
245
246 if (opt.progressive)
247 jpeg_simple_progression(&cinfo);
248} // jpeg::writer::set_options()
249
250/*----------------------------------------------------------------------------*/
255void
256claw::graphic::jpeg::writer::save_image( jpeg_compress_struct& cinfo ) const
257{
258 JSAMPLE* data = new JSAMPLE[ m_image.width() * s_rgb_pixel_size ];
259
260 error_manager jerr;
261 jpeg_error_mgr* jerr_saved = cinfo.err;
262
263 cinfo.err = jpeg_std_error(&jerr.pub);
264 jerr.pub.error_exit = jpeg__error_manager__error_exit;
265
266 if ( setjmp(jerr.setjmp_buffer) )
267 {
268 delete[] data;
269 jpeg_abort_compress(&cinfo);
270 throw CLAW_EXCEPTION(jerr.error_string);
271 }
272
273 jpeg_start_compress( &cinfo, TRUE );
274
275 while (cinfo.next_scanline < cinfo.image_height)
276 {
277 copy_pixel_line( data, cinfo.next_scanline );
278 jpeg_write_scanlines( &cinfo, &data, 1 );
279 }
280
281 delete[] data;
282 jpeg_finish_compress(&cinfo);
283
284 cinfo.err = jerr_saved;
285} // jpeg::writer::load()
286
287/*----------------------------------------------------------------------------*/
294void claw::graphic::jpeg::writer::copy_pixel_line
295( JSAMPLE* data, unsigned int y ) const
296{
297 CLAW_PRECOND( data );
298 CLAW_PRECOND( y < m_image.height() );
299
300 // three bytes for each pixel in the line
301 for (unsigned int x=0; x!=m_image.width(); ++x, data+=s_rgb_pixel_size)
302 {
303 data[0] = m_image[y][x].components.red;
304 data[1] = m_image[y][x].components.green;
305 data[2] = m_image[y][x].components.blue;
306 }
307} // jpeg::writer::copy_pixel_line()
308
309/*----------------------------------------------------------------------------*/
315void claw::graphic::jpeg::writer::create_compress_info
316( jpeg_compress_struct& cinfo, destination_manager& outfile ) const
317{
318 jpeg_create_compress(&cinfo);
319
320 cinfo.dest = &outfile.pub;
321 cinfo.client_data = &outfile;
322
323 outfile.pub.init_destination =
325 outfile.pub.empty_output_buffer =
327 outfile.pub.term_destination =
329} // jpeg::writer::create_compress_info()
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 an image in a jpeg 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 jpeg pictures.
Methods for the claw::graphic::jpeg::error_manager class.
claw__graphic__jpeg__destination_manager__empty_output_buffer(j_compress_ptr cinfo)
Write the content of the buffer in the file.
claw__graphic__jpeg__destination_manager__term_destination(j_compress_ptr cinfo)
Write the last pending bytes in the file.
claw__graphic__jpeg__destination_manager__init_destination(j_compress_ptr cinfo)
Initialize the output stream.
void jpeg__error_manager__error_exit(j_common_ptr cinfo)
Throw an exception when an error occurs in an internal jpeg processing.
Error handler that throw an exception instead of exiting the program.
Definition jpeg.hpp:63
std::string error_string
A comprehensive description of the error.
Definition jpeg.hpp:71
struct jpeg_error_mgr pub
"public" fields, needed by the jpeg library.
Definition jpeg.hpp:65
jmp_buf setjmp_buffer
For return to caller.
Definition jpeg.hpp:68
Destination manager that allow us to write in a std::ostream.
Definition jpeg.hpp:197
destination_manager(std::ostream &os)
Constructor.
void term()
Write the last pending bytes in the file.
struct jpeg_destination_mgr pub
"public" fields, needed by the jpeg library.
Definition jpeg.hpp:207
void flush()
Write the content of the buffer in the file.
Parameters of the writing algorithm.
Definition jpeg.hpp:175