Claw 1.7.3
jpeg_reader.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__source_manager__init_source()
46
47/*----------------------------------------------------------------------------*/
52METHODDEF(boolean)
54{
57
58 CLAW_PRECOND( &self->pub == cinfo->src );
59
60 return self->fill_input_buffer();
61} // claw__graphic__jpeg__source_manager__fill_input_buffer()
62
63/*----------------------------------------------------------------------------*/
69METHODDEF(void)
71 long num_bytes)
72{
75
76 CLAW_PRECOND( &self->pub == cinfo->src );
77
78 return self->skip_input_data(num_bytes);
79} // claw__graphic__jpeg__source_manager__skip_input_data()
80
81/*----------------------------------------------------------------------------*/
86METHODDEF(void)
88{
89 // nothing to do
90} // claw__graphic__jpeg__source_manager__term_source()
91
92/*----------------------------------------------------------------------------*/
98 : m_input(is), m_buffer_size(1024), m_stream_position(0)
99{
100 std::istream::pos_type pos = is.tellg();
101
102 is.seekg( 0 , std::ios_base::end );
103 m_stream_size = is.tellg() ;
104
105 is.seekg( pos, std::ios_base::beg ) ;
106
107 m_buffer = new JOCTET[m_buffer_size];
108 pub.bytes_in_buffer = 0;
109} // jpeg::reader::source_manager::source_manager()
110
111/*----------------------------------------------------------------------------*/
116{
117 delete[] m_buffer;
118} // jpeg::reader::source_manager::~source_manager()
119
120/*----------------------------------------------------------------------------*/
124boolean
126{
127 unsigned int n = std::min( m_buffer_size, m_stream_size - m_stream_position );
128 m_input.read( (char*)m_buffer, n );
129
130 pub.next_input_byte = m_buffer;
131 pub.bytes_in_buffer = n;
132
133 m_stream_position += n;
134
135 if (m_input)
136 return TRUE;
137 else
138 return FALSE;
139} // jpeg::reader::source_manager::fill_input_buffer()
140
141/*----------------------------------------------------------------------------*/
146void
148{
149 CLAW_PRECOND(num_bytes >=0);
150
151 if ( (size_t)num_bytes <= pub.bytes_in_buffer )
152 {
153 pub.next_input_byte += num_bytes;
154 pub.bytes_in_buffer -= num_bytes;
155 }
156 else
157 {
158 num_bytes -= pub.bytes_in_buffer;
159
160 long div = num_bytes / m_buffer_size;
161 long rest = num_bytes % m_buffer_size;
162
163 for (long i=0; i!=(div+1); ++i)
164 fill_input_buffer();
165
166 pub.next_input_byte += rest;
167 pub.bytes_in_buffer -= rest;
168 }
169} // jpeg::reader::source_manager::skip_input_data()
170
171
172
173
174/*----------------------------------------------------------------------------*/
179claw::graphic::jpeg::reader::RGB_to_pixel32::operator()
180 ( const JSAMPLE* pixel ) const
181{
182 rgba_pixel_8 result;
183
184 result.components.alpha = 255;
185 result.components.red = pixel[0];
186 result.components.green = pixel[1];
187 result.components.blue = pixel[2];
188
189 return result;
190} // jpeg::reader::RGB_to_pixel32::operator()()
191
192/*----------------------------------------------------------------------------*/
197claw::graphic::jpeg::reader::grayscale_to_pixel32::operator()
198 ( const JSAMPLE* pixel ) const
199{
200 rgba_pixel_8 result;
201
202 result.components.alpha = 255;
203 result.components.red = pixel[0];
204 result.components.green = pixel[0];
205 result.components.blue = pixel[0];
206
207 return result;
208} // jpeg::reader::grayscale_to_pixel32::operator()()
209
210
211
212
213/*----------------------------------------------------------------------------*/
219 : m_image( img )
220{
221
222} // jpeg::reader::reader()
223
224/*----------------------------------------------------------------------------*/
232 : m_image( img )
233{
234 load(f);
235} // jpeg::reader::reader()
236
237/*----------------------------------------------------------------------------*/
243{
244 CLAW_PRECOND( !!f );
245
246 std::istream::pos_type init_pos = f.tellg();
247
248 try
249 {
250 read_from_file(f);
251 }
252 catch(...)
253 {
254 f.clear();
255 f.seekg( init_pos, std::ios_base::beg );
256 throw;
257 }
258} // jpeg::reader::load()
259
260/*----------------------------------------------------------------------------*/
265void claw::graphic::jpeg::reader::read_from_file( std::istream& f )
266{
267 source_manager infile(f);
268 jpeg_decompress_struct cinfo;
269 error_manager jerr;
270
271 cinfo.err = jpeg_std_error(&jerr.pub);
272
273 if ( setjmp(jerr.setjmp_buffer) )
274 throw CLAW_EXCEPTION(jerr.error_string);
275
276 create_decompress_info( cinfo, infile );
277 jerr.pub.error_exit = jpeg__error_manager__error_exit;
278
279 try
280 {
281 decompress(f, cinfo);
282 jpeg_destroy_decompress(&cinfo);
283 }
284 catch(...)
285 {
286 jpeg_destroy_decompress(&cinfo);
287 throw;
288 }
289} // jpeg::reader::read_from_file()
290
291/*----------------------------------------------------------------------------*/
297void claw::graphic::jpeg::reader::decompress
298( std::istream& f, jpeg_decompress_struct& cinfo )
299{
300 error_manager jerr;
301 jpeg_error_mgr* jerr_saved = cinfo.err;
302
303 cinfo.err = jpeg_std_error(&jerr.pub);
304 jerr.pub.error_exit = jpeg__error_manager__error_exit;
305
306 if ( setjmp(jerr.setjmp_buffer) )
307 {
308 jpeg_abort_decompress(&cinfo);
309 throw CLAW_EXCEPTION(jerr.error_string);
310 }
311
312 jpeg_read_header(&cinfo, TRUE);
313 jpeg_start_decompress( &cinfo );
314
315 try
316 {
317 m_image.set_size( cinfo.image_width, cinfo.image_height );
318
319 if ( cinfo.out_color_components == 3 )
320 read_data( cinfo, RGB_to_pixel32() );
321 else if ( cinfo.out_color_components == 1 )
322 read_data( cinfo, grayscale_to_pixel32() );
323 else
324 throw CLAW_EXCEPTION( "invalid number of colors per channel" );
325
326 jpeg_finish_decompress(&cinfo);
327 }
328 catch(...)
329 {
330 jpeg_abort_decompress(&cinfo);
331 throw;
332 }
333
334 cinfo.err = jerr_saved;
335} // jpeg::reader::decompress()
336
337/*----------------------------------------------------------------------------*/
343void claw::graphic::jpeg::reader::create_decompress_info
344( jpeg_decompress_struct& cinfo, source_manager& infile ) const
345{
346 jpeg_create_decompress(&cinfo);
347
348 cinfo.src = &infile.pub;
349 cinfo.client_data = &infile;
350
351 infile.pub.fill_input_buffer =
353 infile.pub.skip_input_data =
356 infile.pub.resync_to_restart = jpeg_resync_to_restart;
358} // jpeg::reader::create_decompress_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 load(std::istream &f)
Load an image from a jpeg file.
reader(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__source_manager__init_source(j_decompress_ptr cinfo)
Initialize the input stream.
claw__graphic__jpeg__source_manager__term_source(j_decompress_ptr cinfo)
Close the input stream.
claw__graphic__jpeg__source_manager__fill_input_buffer(j_decompress_ptr cinfo)
Fill the input buffer with new data.
claw__graphic__jpeg__source_manager__skip_input_data(j_decompress_ptr cinfo, long num_bytes)
Skip some bytes in the input buffer.
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
Source manager that allow us to read from a std::istream.
Definition jpeg.hpp:90
void skip_input_data(long num_bytes)
Skip some bytes in the input buffer.
boolean fill_input_buffer()
Fill the input buffer with new data.
source_manager(std::istream &is)
Constructor.
struct jpeg_source_mgr pub
"public" fields, needed by the jpeg library.
Definition jpeg.hpp:100
component_type red
Red component.
Definition pixel.hpp:93
struct claw::graphic::rgba_pixel::@15::@17 components
Component by component representation.
component_type alpha
Translucy.
Definition pixel.hpp:102
component_type green
Green component.
Definition pixel.hpp:96
component_type blue
Blue component.
Definition pixel.hpp:99