claw  1.9.0
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@stuff-o-matic.com
24 */
30 #include <claw/graphic/image.hpp>
31 
32 #include <claw/exception.hpp>
33 #include <claw/graphic/bitmap.hpp>
34 #include <claw/graphic/gif.hpp>
35 #include <claw/graphic/pcx.hpp>
36 #include <claw/graphic/targa.hpp>
37 #include <claw/graphic/xbm.hpp>
38 
39 /* The png.h file must be included before any other file that includes setjmp.h
40  (as jpeg.hpp). */
41 #include <claw/graphic/png.hpp>
42 
43 #include <claw/graphic/jpeg.hpp>
44 
45 #include <algorithm>
46 
52 {
53  return super::begin();
54 }
55 
60 {
61  return super::end();
62 }
63 
69 {
70  return super::begin();
71 }
72 
78 {
79  return super::end();
80 }
81 
87 {
88  return super::size();
89 }
90 
96 {}
97 
103 {
104  load(f);
105 }
106 
113 claw::graphic::image::image(unsigned int w, unsigned int h)
114 {
115  set_size(w, h);
116 }
117 
123 {
124  std::swap(m_data, that.m_data);
125 }
126 
130 unsigned int claw::graphic::image::width() const
131 {
132  if(m_data.empty())
133  return 0;
134  else
135  return m_data[0].size();
136 }
137 
141 unsigned int claw::graphic::image::height() const
142 {
143  return m_data.size();
144 }
145 
150 {
151  return iterator(*this);
152 }
153 
158 {
159  return iterator(*this, width(), height() - 1);
160 }
161 
166 {
167  return const_iterator(*this);
168 }
169 
174 {
175  return const_iterator(*this, width(), height() - 1);
176 }
177 
183 {
184  merge(that, math::coordinate_2d<int>(0, 0));
185 }
186 
193  const math::coordinate_2d<int>& pos)
194 {
195  math::rectangle<int> my_box(0, 0, width(), height());
196  math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
197 
198  if(my_box.intersects(his_box))
199  {
200  math::rectangle<int> intersection;
201  unsigned int that_y = pos.y < 0 ? -pos.y : 0;
202  unsigned int that_x = pos.x < 0 ? -pos.x : 0;
203  const double max_comp(
204  std::numeric_limits<rgba_pixel::component_type>::max());
205 
206  intersection = my_box.intersection(his_box);
207 
208  for(int y = 0; y != intersection.height; ++y)
209  {
210  scanline::const_iterator first = that[y + that_y].begin() + that_x;
211  scanline::const_iterator last = first + intersection.width;
212  scanline::iterator dest
213  = (*this)[y + intersection.position.y].begin()
214  + intersection.position.x;
215 
216  for(; first != last; ++first, ++dest)
217  {
218  const double src_alpha(first->components.alpha);
219  const double dest_alpha(dest->components.alpha
220  * (max_comp - src_alpha));
221 
222  const double red = (double)first->components.red * src_alpha
223  + (double)dest->components.red * dest_alpha;
224  const double green
225  = (double)first->components.green * src_alpha
226  + (double)dest->components.green * dest_alpha;
227  const double blue = (double)first->components.blue * src_alpha
228  + (double)dest->components.blue * dest_alpha;
229  const double alpha = src_alpha + dest_alpha;
230 
231  dest->components.red = std::min(red, max_comp);
232  dest->components.green = std::min(green, max_comp);
233  dest->components.blue = std::min(blue, max_comp);
234  dest->components.alpha = std::min(alpha, max_comp);
235  }
236  }
237  }
238 }
239 
246  const math::coordinate_2d<int>& pos)
247 {
248  math::rectangle<int> my_box(0, 0, width(), height());
249  math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
250 
251  if(my_box.intersects(his_box))
252  {
253  math::rectangle<int> intersection;
254  unsigned int that_y = pos.y < 0 ? -pos.y : 0;
255  unsigned int that_x = pos.x < 0 ? -pos.x : 0;
256 
257  intersection = my_box.intersection(his_box);
258 
259  for(int y = 0; y != intersection.height; ++y)
260  {
261  scanline::const_iterator first = that[y + that_y].begin() + that_x;
262  scanline::const_iterator last = first + intersection.width;
263  scanline::iterator dest
264  = (*this)[y + intersection.position.y].begin()
265  + intersection.position.x;
266 
267  std::copy(first, last, dest);
268  }
269  }
270 }
271 
276 {
277  for(unsigned int y = 0; y != height() / 2; ++y)
278  std::swap(m_data[y], m_data[height() - y - 1]);
279 }
280 
287  const pixel_type& c)
288 {
289  math::rectangle<int> my_box(0, 0, width(), height());
290 
291  if(my_box.intersects(r))
292  {
293  const math::rectangle<int> intersection(my_box.intersection(r));
294  const double max_comp(
295  std::numeric_limits<rgba_pixel::component_type>::max());
296 
297  for(int y = 0; y != intersection.height; ++y)
298  {
300  = (*this)[intersection.position.y + y].begin()
301  + intersection.position.x;
302  const scanline::iterator last = first + intersection.width;
303 
304  for(; first != last; ++first)
305  {
306  const double src_alpha(c.components.alpha);
307 
308  double red = (double)first->components.red
309  + src_alpha * (double)c.components.red / max_comp;
310  double green
311  = (double)first->components.green
312  + src_alpha * (double)c.components.green / max_comp;
313  double blue = (double)first->components.blue
314  + src_alpha * (double)c.components.blue / max_comp;
315  double alpha = (double)first->components.alpha
316  + (max_comp - src_alpha) / max_comp;
317 
318  first->components.red = std::min(red, max_comp);
319  first->components.green = std::min(green, max_comp);
320  first->components.blue = std::min(blue, max_comp);
321  first->components.alpha = std::min(alpha, max_comp);
322  }
323  }
324  }
325 }
326 
333 void claw::graphic::image::set_size(unsigned int w, unsigned int h)
334 {
335  if(w == 0)
336  m_data.clear();
337  else
338  {
339  m_data.resize(h);
340 
341  for(unsigned int y = 0; y != height(); ++y)
342  m_data[y].resize(w);
343  }
344 }
345 
350 void claw::graphic::image::load(std::istream& f)
351 {
352  bool ok = false;
353 
354  if(!ok)
355  try
356  {
357  jpeg::reader(*this, f);
358  ok = true;
359  }
360  catch(...)
361  {}
362 
363  if(!ok)
364  try
365  {
366  png::reader(*this, f);
367  ok = true;
368  }
369  catch(...)
370  {}
371 
372  if(!ok)
373  try
374  {
375  bitmap::reader(*this, f);
376  ok = true;
377  }
378  catch(...)
379  {}
380 
381  if(!ok)
382  try
383  {
384  targa::reader(*this, f);
385  ok = true;
386  }
387  catch(...)
388  {}
389 
390  if(!ok)
391  try
392  {
393  gif::reader(*this, f);
394  ok = true;
395  }
396  catch(...)
397  {}
398 
399  if(!ok)
400  try
401  {
402  pcx::reader(*this, f);
403  ok = true;
404  }
405  catch(...)
406  {}
407 
408  if(!ok)
409  try
410  {
411  xbm::reader(*this, f);
412  ok = true;
413  }
414  catch(...)
415  {}
416 
417  if(!ok)
418  throw claw::bad_format("image::load: file format isn't supported.");
419 }
420 
427 {
428  a.swap(b);
429 }
This class read data from a pcx file and store it in an image.
Definition: pcx.hpp:155
This class read data from a png file and store it in an image.
Definition: png.hpp:56
This class reads data from a gif file. The image is resized to the size of the screen (as defined in ...
Definition: gif.hpp:276
coordinate_2d< value_type > position
value_typeop left coordinates.
Definition: rectangle.hpp:108
This class read data from a bitmap file and store it in an image.
Definition: bitmap.hpp:135
void partial_copy(const image &that, const math::coordinate_2d< int > &pos)
Copy an image on the current image.
Definition: image.cpp:245
A class for jpeg pictures.
super::const_iterator const_iterator
Const iterator in the line.
Definition: image.hpp:82
iterator end()
Get an iterator pointing just past the last pixel.
Definition: image.cpp:157
size_type size() const
Get the length of the line.
Definition: image.cpp:86
unsigned int height() const
Gets image&#39;s height.
Definition: image.cpp:141
base_iterator< image, pixel_type > iterator
The type of the iterator on the pixels of the image.
Definition: image.hpp:195
struct claw::graphic::rgba_pixel::@15::@17 components
Component by component representation.
This class read data from a targa file and store it in an image.
Definition: targa.hpp:205
super::size_type size_type
An unsigned integral type.
Definition: image.hpp:85
void flip()
Set the image upside down.
Definition: image.cpp:275
void swap(image &that)
Swap the content of two images.
Definition: image.cpp:122
void fill(const math::rectangle< int > r, const pixel_type &c)
Fill an area of the image with a given color.
Definition: image.cpp:286
Fuction object to get the first element of a std::pair.
Definition: functional.hpp:42
A class for png pictures.
Base class for iterators on an image.
Definition: image.hpp:107
iterator end()
Get en iterator past the last pixel.
Definition: image.cpp:59
void load(std::istream &f)
Read the image from a stream.
Definition: image.cpp:350
A class representing a rectangle by his x,y coordinates, width and height.
Definition: box_2d.hpp:40
A class for bitmap pictures.
This class read data from a xbm file and store it in an image.
Definition: xbm.hpp:53
Image class for gif files.
value_type height
Height.
Definition: rectangle.hpp:114
This class read data from a jpeg file and store it in an image.
Definition: jpeg.hpp:79
image()
Constructor. Creates an image without datas.
Definition: image.cpp:95
void swap(claw::tween::tweener &a, claw::tween::tweener &b)
Swap two tweeners.
Definition: tweener.cpp:122
value_type y
Y-coordinate.
super::iterator iterator
Iterator in the line.
Definition: image.hpp:79
A class for pcx pictures.
unsigned int width() const
Gets image&#39;s width.
Definition: image.cpp:130
A simple class to use as exception with string message.
void merge(const image &that)
Merge an image on the current image.
Definition: image.cpp:182
iterator begin()
Get an iterator on the first pixel.
Definition: image.cpp:51
base_iterator< const image, const pixel_type > const_iterator
The type of the iterator to access constant pixels.
Definition: image.hpp:203
iterator begin()
Get an iterator pointing on the first pixel.
Definition: image.cpp:149
A class to deal with images.
Definition: image.hpp:50
A class for targa pictures.
A class for xbm pictures.
value_type width
Width.
Definition: rectangle.hpp:111
void set_size(unsigned int w, unsigned int h)
Set a new size to the image.
Definition: image.cpp:333
Exception thrown when accessing bad formated data.
Definition: exception.hpp:73
value_type x
X-coordinate.
A class to deal with images.