Claw 1.7.3
image.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/image.hpp>
31#include <claw/exception.hpp>
32#include <claw/bitmap.hpp>
33#include <claw/gif.hpp>
34#include <claw/pcx.hpp>
35#include <claw/targa.hpp>
36#include <claw/xbm.hpp>
37
38#ifdef CLAW_PNG_SUPPORT
39/* The png.h file must be included before any other file that includes setjmp.h
40 (as jpeg.hpp). */
41#include <claw/png.hpp>
42#endif // CLAW_PNG_SUPPORT
43
44#ifdef CLAW_JPEG_SUPPORT
45#include <claw/jpeg.hpp>
46#endif // CLAW_JPEG_SUPPORT
47
48#include <algorithm>
49
50/*----------------------------------------------------------------------------*/
55{
56 return super::begin();
57} // image::scanline::begin()
58
59/*----------------------------------------------------------------------------*/
64{
65 return super::end();
66} // image::scanline::end()
67
68/*----------------------------------------------------------------------------*/
74{
75 return super::begin();
76} // image::scanline::begin()
77
78/*----------------------------------------------------------------------------*/
84{
85 return super::end();
86} // image::scanline::end()
87
88/*----------------------------------------------------------------------------*/
94{
95 return super::size();
96} // image::scanline::size()
97
98
99
100
101/*----------------------------------------------------------------------------*/
107{
108
109} // image::image() [default constructor]
110
111/*----------------------------------------------------------------------------*/
117{
118 load(f);
119} // image::image() [constructor]
120
121/*----------------------------------------------------------------------------*/
128claw::graphic::image::image( unsigned int w, unsigned int h )
129{
130 set_size(w, h);
131} // image::image() [constructor]
132
133/*----------------------------------------------------------------------------*/
139{
140 std::swap(m_data, that.m_data);
141} // image::swap()
142
143/*----------------------------------------------------------------------------*/
147unsigned int claw::graphic::image::width() const
148{
149 if ( m_data.empty() )
150 return 0;
151 else
152 return m_data[0].size();
153} // image::width()
154
155/*----------------------------------------------------------------------------*/
160{
161 return m_data.size();
162} // image::height()
163
164/*----------------------------------------------------------------------------*/
169{
170 return iterator(*this);
171} // image::begin()
172
173/*----------------------------------------------------------------------------*/
178{
179 return iterator(*this, width(), height()-1);
180} // image::end()
181
182/*----------------------------------------------------------------------------*/
187{
188 return const_iterator(*this);
189} // image::begin()
190
191/*----------------------------------------------------------------------------*/
196{
197 return const_iterator(*this, width(), height()-1);
198} // image::end()
199
200/*----------------------------------------------------------------------------*/
206{
207 merge( that, math::coordinate_2d<int>(0, 0) );
208} // image::merge()
209
210/*----------------------------------------------------------------------------*/
217( const image& that, const math::coordinate_2d<int>& pos )
218{
219 math::rectangle<int> my_box(0, 0, width(), height());
220 math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
221
222 if ( my_box.intersects( his_box ) )
223 {
224 math::rectangle<int> intersection;
225 unsigned int that_y = pos.y < 0 ? -pos.y : 0;
226 unsigned int that_x = pos.x < 0 ? -pos.x : 0;
227 const double max_comp
228 ( std::numeric_limits<rgba_pixel::component_type>::max() );
229
230 intersection = my_box.intersection( his_box );
231
232 for (int y=0; y!=intersection.height; ++y)
233 {
234 scanline::const_iterator first = that[y + that_y].begin() + that_x;
235 scanline::const_iterator last = first + intersection.width;
236 scanline::iterator dest = (*this)[y + intersection.position.y].begin()
237 + intersection.position.x;
238
239 for( ; first!=last; ++first, ++dest )
240 {
241 const double src_alpha( first->components.alpha );
242 const double dest_alpha
243 ( dest->components.alpha * (max_comp - src_alpha) );
244
245 const double red =
246 (double)first->components.red * src_alpha
247 + (double)dest->components.red * dest_alpha;
248 const double green =
249 (double)first->components.green * src_alpha
250 + (double)dest->components.green * dest_alpha;
251 const double blue =
252 (double)first->components.blue * src_alpha
253 + (double)dest->components.blue * dest_alpha;
254 const double alpha = src_alpha + dest_alpha;
255
256 dest->components.red = std::min(red, max_comp);
257 dest->components.green = std::min(green, max_comp);
258 dest->components.blue = std::min(blue, max_comp);
259 dest->components.alpha = std::min(alpha, max_comp);
260 }
261 }
262 }
263} // image::merge()
264
265/*----------------------------------------------------------------------------*/
272(const image& that, const math::coordinate_2d<int>& pos )
273{
274 math::rectangle<int> my_box(0, 0, width(), height());
275 math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
276
277 if ( my_box.intersects( his_box ) )
278 {
279 math::rectangle<int> intersection;
280 unsigned int that_y = pos.y < 0 ? -pos.y : 0;
281 unsigned int that_x = pos.x < 0 ? -pos.x : 0;
282
283 intersection = my_box.intersection( his_box );
284
285 for (int y=0; y!=intersection.height; ++y)
286 {
287 scanline::const_iterator first = that[y + that_y].begin() + that_x;
288 scanline::const_iterator last = first + intersection.width;
289 scanline::iterator dest = (*this)[y + intersection.position.y].begin()
290 + intersection.position.x;
291
292 std::copy( first, last, dest );
293 }
294 }
295} // image::partial_copy()
296
297/*----------------------------------------------------------------------------*/
302{
303 for (unsigned int y=0; y!=height()/2; ++y)
304 std::swap( m_data[y], m_data[height()-y-1] );
305} // image::flip()
306
307/*----------------------------------------------------------------------------*/
314( const math::rectangle<int> r, const pixel_type& c )
315{
316 math::rectangle<int> my_box(0, 0, width(), height());
317
318 if ( my_box.intersects( r ) )
319 {
320 const math::rectangle<int> intersection( my_box.intersection( r ) );
321 const double max_comp
322 ( std::numeric_limits<rgba_pixel::component_type>::max() );
323
324 for (int y=0; y!=intersection.height; ++y)
325 {
327 (*this)[intersection.position.y + y].begin()
328 + intersection.position.x;
329 const scanline::iterator last = first + intersection.width;
330
331 for( ; first!=last; ++first )
332 {
333 const double src_alpha(c.components.alpha);
334
335 double red =
336 (double)first->components.red
337 + src_alpha * (double)c.components.red / max_comp;
338 double green =
339 (double)first->components.green
340 + src_alpha * (double)c.components.green / max_comp;
341 double blue =
342 (double)first->components.blue
343 + src_alpha * (double)c.components.blue / max_comp;
344 double alpha = (double)first->components.alpha
345 + (max_comp - src_alpha) / max_comp;
346
347 first->components.red = std::min(red, max_comp);
348 first->components.green = std::min(green, max_comp);
349 first->components.blue = std::min(blue, max_comp);
350 first->components.alpha = std::min(alpha, max_comp);
351 }
352 }
353 }
354} // image::fill()
355
356/*----------------------------------------------------------------------------*/
363void claw::graphic::image::set_size( unsigned int w, unsigned int h )
364{
365 if (w == 0)
366 m_data.clear();
367 else
368 {
369 m_data.resize(h);
370
371 for (unsigned int y=0; y!=height(); ++y)
372 m_data[y].resize(w);
373 }
374} // image::set_size()
375
376/*----------------------------------------------------------------------------*/
381void claw::graphic::image::load( std::istream& f )
382{
383 bool ok = false;
384
385#ifdef CLAW_JPEG_SUPPORT
386 if (!ok)
387 try { jpeg::reader( *this, f ); ok = true; }
388 catch( ... ) { }
389#endif // CLAW_JPEG_SUPPORT
390
391#ifdef CLAW_PNG_SUPPORT
392 if (!ok)
393 try { png::reader( *this, f ); ok = true; }
394 catch( ... ) { }
395#endif // CLAW_PNG_SUPPORT
396
397 if (!ok)
398 try { bitmap::reader( *this, f ); ok = true; }
399 catch( ... ) { }
400
401 if (!ok)
402 try { targa::reader( *this, f ); ok = true; }
403 catch( ... ) { }
404
405 if (!ok)
406 try { gif::reader( *this, f ); ok = true; }
407 catch( ... ) { }
408
409 if (!ok)
410 try { pcx::reader( *this, f ); ok = true; }
411 catch( ... ) { }
412
413 if (!ok)
414 try { xbm::reader( *this, f ); ok = true; }
415 catch( ... ) { }
416
417 if (!ok)
418 throw claw::bad_format( "image::load: file format isn't supported." );
419} // image::load()
420
421
422
423
424/*----------------------------------------------------------------------------*/
431{
432 a.swap(b);
433} // swap()
A class for bitmap pictures.
Exception thrown when accessing bad formated data.
Definition exception.hpp:72
Fuction object to get the first element of a std::pair.
This class read data from a bitmap file and store it in an image.
Definition bitmap.hpp:135
This class reads data from a gif file. The image is resized to the size of the screen (as defined in ...
Definition gif.hpp:280
Base class for iterators on an image.
Definition image.hpp:108
super::iterator iterator
Iterator in the line.
Definition image.hpp:78
super::const_iterator const_iterator
Const iterator in the line.
Definition image.hpp:81
iterator begin()
Get an iterator on the first pixel.
Definition image.cpp:54
iterator end()
Get en iterator past the last pixel.
Definition image.cpp:63
super::size_type size_type
An unsigned integral type.
Definition image.hpp:84
size_type size() const
Get the length of the line.
Definition image.cpp:93
A class to deal with images.
Definition image.hpp:50
void flip()
Set the image upside down.
Definition image.cpp:301
void partial_copy(const image &that, const math::coordinate_2d< int > &pos)
Copy an image on the current image.
Definition image.cpp:272
base_iterator< const image, const pixel_type > const_iterator
The type of the iterator to access constant pixels.
Definition image.hpp:203
unsigned int height() const
Gets image's height.
Definition image.cpp:159
base_iterator< image, pixel_type > iterator
The type of the iterator on the pixels of the image.
Definition image.hpp:195
void set_size(unsigned int w, unsigned int h)
Set a new size to the image.
Definition image.cpp:363
unsigned int width() const
Gets image's width.
Definition image.cpp:147
void merge(const image &that)
Merge an image on the current image.
Definition image.cpp:205
void fill(const math::rectangle< int > r, const pixel_type &c)
Fill an area of the image with a given color.
Definition image.cpp:314
iterator end()
Get an iterator pointing just past the last pixel.
Definition image.cpp:177
void swap(image &that)
Swap the content of two images.
Definition image.cpp:138
image()
Constructor. Creates an image without datas.
Definition image.cpp:106
void load(std::istream &f)
Read the image from a stream.
Definition image.cpp:381
iterator begin()
Get an iterator pointing on the first pixel.
Definition image.cpp:168
This class read data from a jpeg file and store it in an image.
Definition jpeg.hpp:81
This class read data from a pcx file and store it in an image.
Definition pcx.hpp:159
This class read data from a png file and store it in an image.
Definition png.hpp:57
This class read data from a targa file and store it in an image.
Definition targa.hpp:217
This class read data from a xbm file and store it in an image.
Definition xbm.hpp:54
Coordinates in a two dimensional space.
value_type x
X-coordinate.
value_type y
Y-coordinate.
A class representing a rectangle by his x,y coordinates, width and height.
Definition rectangle.hpp:52
value_type width
Width.
coordinate_2d< value_type > position
value_typeop left coordinates.
value_type height
Height.
A simple class to use as exception with string message.
Image class for gif files.
void swap(claw::graphic::gif &a, claw::graphic::gif &b)
Swap the content of two gifs.
Definition gif.cpp:235
A class to deal with images.
A class for jpeg pictures.
A class for pcx pictures.
A class for png pictures.
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
A class for targa pictures.
A class for xbm pictures.