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 /*----------------------------------------------------------------------------*/
116 claw::graphic::image::image( std::istream& f )
117 {
118  load(f);
119 } // image::image() [constructor]
120 
121 /*----------------------------------------------------------------------------*/
128 claw::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 /*----------------------------------------------------------------------------*/
147 unsigned 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 /*----------------------------------------------------------------------------*/
159 unsigned int claw::graphic::image::height() const
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 /*----------------------------------------------------------------------------*/
363 void 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 /*----------------------------------------------------------------------------*/
381 void 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()
claw::math::rectangle::position
coordinate_2d< value_type > position
value_typeop left coordinates.
Definition: rectangle.hpp:108
claw::graphic::image::merge
void merge(const image &that)
Merge an image on the current image.
Definition: image.cpp:205
claw::math::coordinate_2d::y
value_type y
Y-coordinate.
Definition: coordinate_2d.hpp:85
claw::first
Fuction object to get the first element of a std::pair.
Definition: functional.hpp:44
claw::graphic::rgba_pixel
RGBA pixel.
Definition: pixel.hpp:79
claw::graphic::image::iterator
base_iterator< image, pixel_type > iterator
The type of the iterator on the pixels of the image.
Definition: image.hpp:195
claw::graphic::pcx::reader
This class read data from a pcx file and store it in an image.
Definition: pcx.hpp:158
claw::math::rectangle::width
value_type width
Width.
Definition: rectangle.hpp:111
claw::graphic::image::scanline::end
iterator end()
Get en iterator past the last pixel.
Definition: image.cpp:63
claw::graphic::image::image
image()
Constructor. Creates an image without datas.
Definition: image.cpp:106
claw::graphic::png::reader
This class read data from a png file and store it in an image.
Definition: png.hpp:56
claw::graphic::image::load
void load(std::istream &f)
Read the image from a stream.
Definition: image.cpp:381
claw::math::rectangle
A class representing a rectangle by his x,y coordinates, width and height.
Definition: box_2d.hpp:39
claw::graphic::rgba_pixel::components
struct claw::graphic::rgba_pixel::@15::@17 components
Component by component representation.
claw::graphic::image::const_iterator
base_iterator< const image, const pixel_type > const_iterator
The type of the iterator to access constant pixels.
Definition: image.hpp:203
claw::graphic::image::scanline::begin
iterator begin()
Get an iterator on the first pixel.
Definition: image.cpp:54
claw::math::coordinate_2d< int >
png.hpp
A class for png pictures.
claw::graphic::targa::reader
This class read data from a targa file and store it in an image.
Definition: targa.hpp:216
claw::graphic::jpeg::reader
This class read data from a jpeg file and store it in an image.
Definition: jpeg.hpp:80
gif.hpp
Image class for gif files.
claw::graphic::bitmap::reader
This class read data from a bitmap file and store it in an image.
Definition: bitmap.hpp:134
claw::graphic::image::set_size
void set_size(unsigned int w, unsigned int h)
Set a new size to the image.
Definition: image.cpp:363
claw::bad_format
Exception thrown when accessing bad formated data.
Definition: exception.hpp:70
claw::graphic::image::end
iterator end()
Get an iterator pointing just past the last pixel.
Definition: image.cpp:177
claw::math::rectangle::height
value_type height
Height.
Definition: rectangle.hpp:114
pcx.hpp
A class for pcx pictures.
claw::graphic::image::scanline::iterator
super::iterator iterator
Iterator in the line.
Definition: image.hpp:78
jpeg.hpp
A class for jpeg pictures.
claw::graphic::image::fill
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
claw::graphic::image::swap
void swap(image &that)
Swap the content of two images.
Definition: image.cpp:138
claw::graphic::image::scanline::const_iterator
super::const_iterator const_iterator
Const iterator in the line.
Definition: image.hpp:81
image.hpp
A class to deal with images.
claw::graphic::image::partial_copy
void partial_copy(const image &that, const math::coordinate_2d< int > &pos)
Copy an image on the current image.
Definition: image.cpp:272
claw::graphic::xbm::reader
This class read data from a xbm file and store it in an image.
Definition: xbm.hpp:53
bitmap.hpp
A class for bitmap pictures.
claw::graphic::image::scanline::size
size_type size() const
Get the length of the line.
Definition: image.cpp:93
claw::graphic::image
A class to deal with images.
Definition: image.hpp:49
claw::math::coordinate_2d::x
value_type x
X-coordinate.
Definition: coordinate_2d.hpp:82
claw::graphic::gif::reader
This class reads data from a gif file. The image is resized to the size of the screen (as defined in ...
Definition: gif.hpp:279
claw::graphic::image::scanline::size_type
super::size_type size_type
An unsigned integral type.
Definition: image.hpp:84
exception.hpp
A simple class to use as exception with string message.
claw::graphic::image::flip
void flip()
Set the image upside down.
Definition: image.cpp:301
claw::graphic::image::width
unsigned int width() const
Gets image's width.
Definition: image.cpp:147
claw::graphic::image::base_iterator
Base class for iterators on an image.
Definition: image.hpp:106
xbm.hpp
A class for xbm pictures.
claw::graphic::image::height
unsigned int height() const
Gets image's height.
Definition: image.cpp:159
targa.hpp
A class for targa pictures.
std::swap
void swap(claw::tween::tweener &a, claw::tween::tweener &b)
Swap two tweeners.
Definition: tweener.cpp:138
claw::graphic::image::begin
iterator begin()
Get an iterator pointing on the first pixel.
Definition: image.cpp:168