claw 1.9.0
 
Loading...
Searching...
No Matches
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@stuff-o-matic.com
24*/
30#include <claw/graphic/jpeg.hpp>
31
33
34#include <claw/assert.hpp>
35#include <claw/exception.hpp>
36
41METHODDEF(void)
43{
44 // nothing to do
45}
46
51METHODDEF(boolean)
53{
56
57 CLAW_PRECOND(&self->pub == cinfo->src);
58
59 return self->fill_input_buffer();
60}
61
67METHODDEF(void)
69 long num_bytes)
70{
73
74 CLAW_PRECOND(&self->pub == cinfo->src);
75
76 return self->skip_input_data(num_bytes);
77}
78
83METHODDEF(void)
85{
86 // nothing to do
87}
88
94 : m_input(is)
95 , m_buffer_size(1024)
96 , m_stream_position(0)
97{
98 std::istream::pos_type pos = is.tellg();
99
100 is.seekg(0, std::ios_base::end);
101 m_stream_size = is.tellg();
102
103 is.seekg(pos, std::ios_base::beg);
104
105 m_buffer = new JOCTET[m_buffer_size];
106 pub.bytes_in_buffer = 0;
107}
108
116
121{
122 unsigned int n = std::min(m_buffer_size, m_stream_size - m_stream_position);
123 m_input.read((char*)m_buffer, n);
124
125 pub.next_input_byte = m_buffer;
126 pub.bytes_in_buffer = n;
127
128 m_stream_position += n;
129
130 if(m_input)
131 return TRUE;
132 else
133 return FALSE;
134}
135
141 long num_bytes)
142{
143 CLAW_PRECOND(num_bytes >= 0);
144
145 if((size_t)num_bytes <= pub.bytes_in_buffer)
146 {
147 pub.next_input_byte += num_bytes;
148 pub.bytes_in_buffer -= num_bytes;
149 }
150 else
151 {
152 num_bytes -= pub.bytes_in_buffer;
153
154 long div = num_bytes / m_buffer_size;
155 long rest = num_bytes % m_buffer_size;
156
157 for(long i = 0; i != (div + 1); ++i)
159
160 pub.next_input_byte += rest;
161 pub.bytes_in_buffer -= rest;
162 }
163}
164
169claw::graphic::jpeg::reader::RGB_to_pixel32::operator()(
170 const JSAMPLE* pixel) const
171{
172 rgba_pixel_8 result;
173
174 result.components.alpha = 255;
175 result.components.red = pixel[0];
176 result.components.green = pixel[1];
177 result.components.blue = pixel[2];
178
179 return result;
180}
181
186claw::graphic::jpeg::reader::grayscale_to_pixel32::operator()(
187 const JSAMPLE* pixel) const
188{
189 rgba_pixel_8 result;
190
191 result.components.alpha = 255;
192 result.components.red = pixel[0];
193 result.components.green = pixel[0];
194 result.components.blue = pixel[0];
195
196 return result;
197}
198
204 : m_image(img)
205{}
206
214 : m_image(img)
215{
216 load(f);
217}
218
224{
225 CLAW_PRECOND(!!f);
226
227 std::istream::pos_type init_pos = f.tellg();
228
229 try
230 {
231 read_from_file(f);
232 }
233 catch(...)
234 {
235 f.clear();
236 f.seekg(init_pos, std::ios_base::beg);
237 throw;
238 }
239}
240
245void claw::graphic::jpeg::reader::read_from_file(std::istream& f)
246{
247 source_manager infile(f);
248 jpeg_decompress_struct cinfo;
249 error_manager jerr;
250
251 cinfo.err = jpeg_std_error(&jerr.pub);
252
253 if(setjmp(jerr.setjmp_buffer))
254 throw CLAW_EXCEPTION(jerr.error_string);
255
256 create_decompress_info(cinfo, infile);
257 jerr.pub.error_exit = jpeg__error_manager__error_exit;
258
259 try
260 {
261 decompress(f, cinfo);
262 jpeg_destroy_decompress(&cinfo);
263 }
264 catch(...)
265 {
266 jpeg_destroy_decompress(&cinfo);
267 throw;
268 }
269}
270
276void claw::graphic::jpeg::reader::decompress(std::istream& f,
277 jpeg_decompress_struct& cinfo)
278{
279 error_manager jerr;
280 jpeg_error_mgr* jerr_saved = cinfo.err;
281
282 cinfo.err = jpeg_std_error(&jerr.pub);
283 jerr.pub.error_exit = jpeg__error_manager__error_exit;
284
285 if(setjmp(jerr.setjmp_buffer))
286 {
287 jpeg_abort_decompress(&cinfo);
288 throw CLAW_EXCEPTION(jerr.error_string);
289 }
290
291 jpeg_read_header(&cinfo, TRUE);
292 jpeg_start_decompress(&cinfo);
293
294 try
295 {
296 m_image.set_size(cinfo.image_width, cinfo.image_height);
297
298 if(cinfo.out_color_components == 3)
299 read_data(cinfo, RGB_to_pixel32());
300 else if(cinfo.out_color_components == 1)
301 read_data(cinfo, grayscale_to_pixel32());
302 else
303 throw CLAW_EXCEPTION("invalid number of colors per channel");
304
305 jpeg_finish_decompress(&cinfo);
306 }
307 catch(...)
308 {
309 jpeg_abort_decompress(&cinfo);
310 throw;
311 }
312
313 cinfo.err = jerr_saved;
314}
315
321void claw::graphic::jpeg::reader::create_decompress_info(
322 jpeg_decompress_struct& cinfo, source_manager& infile) const
323{
324 jpeg_create_decompress(&cinfo);
325
326 cinfo.src = &infile.pub;
327 cinfo.client_data = &infile;
328
329 infile.pub.fill_input_buffer
331 infile.pub.skip_input_data
334 infile.pub.resync_to_restart = jpeg_resync_to_restart;
336}
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 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:92
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.
rgba_pixel rgba_pixel_8
A color with 8 bits per component and an alpha channel.
Definition pixel.hpp:126
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:88
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:98
component_type red
Red component.
Definition pixel.hpp:93
struct claw::graphic::rgba_pixel::@243011111317154221214371326113376113353054140240::@062221254366262347154034240363361326201063204322 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