image.cpp
Go to the documentation of this file.
/*
CLAW - a C++ Library Absolutely Wonderful
CLAW is a free library without any particular aim but being useful to
anyone.
Copyright (C) 2005-2011 Julien Jorge
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
contact: julien.jorge@gamned.org
*/
#include <claw/image.hpp>
#include <claw/exception.hpp>
#include <claw/bitmap.hpp>
#include <claw/gif.hpp>
#include <claw/pcx.hpp>
#include <claw/targa.hpp>
#include <claw/xbm.hpp>
#ifdef CLAW_PNG_SUPPORT
/* The png.h file must be included before any other file that includes setjmp.h
(as jpeg.hpp). */
#include <claw/png.hpp>
#endif // CLAW_PNG_SUPPORT
#ifdef CLAW_JPEG_SUPPORT
#include <claw/jpeg.hpp>
#endif // CLAW_JPEG_SUPPORT
#include <algorithm>
/*----------------------------------------------------------------------------*/
claw::graphic::image::scanline::iterator claw::graphic::image::scanline::begin()
{
return super::begin();
} // image::scanline::begin()
/*----------------------------------------------------------------------------*/
claw::graphic::image::scanline::iterator claw::graphic::image::scanline::end()
{
return super::end();
} // image::scanline::end()
/*----------------------------------------------------------------------------*/
claw::graphic::image::scanline::const_iterator
claw::graphic::image::scanline::begin() const
{
return super::begin();
} // image::scanline::begin()
/*----------------------------------------------------------------------------*/
claw::graphic::image::scanline::const_iterator
claw::graphic::image::scanline::end() const
{
return super::end();
} // image::scanline::end()
/*----------------------------------------------------------------------------*/
claw::graphic::image::scanline::size_type
claw::graphic::image::scanline::size() const
{
return super::size();
} // image::scanline::size()
/*----------------------------------------------------------------------------*/
claw::graphic::image::image()
{
} // image::image() [default constructor]
/*----------------------------------------------------------------------------*/
claw::graphic::image::image( std::istream& f )
{
load(f);
} // image::image() [constructor]
/*----------------------------------------------------------------------------*/
claw::graphic::image::image( unsigned int w, unsigned int h )
{
set_size(w, h);
} // image::image() [constructor]
/*----------------------------------------------------------------------------*/
void claw::graphic::image::swap( image& that )
{
std::swap(m_data, that.m_data);
} // image::swap()
/*----------------------------------------------------------------------------*/
unsigned int claw::graphic::image::width() const
{
if ( m_data.empty() )
return 0;
else
return m_data[0].size();
} // image::width()
/*----------------------------------------------------------------------------*/
unsigned int claw::graphic::image::height() const
{
return m_data.size();
} // image::height()
/*----------------------------------------------------------------------------*/
claw::graphic::image::iterator claw::graphic::image::begin()
{
return iterator(*this);
} // image::begin()
/*----------------------------------------------------------------------------*/
claw::graphic::image::iterator claw::graphic::image::end()
{
return iterator(*this, width(), height()-1);
} // image::end()
/*----------------------------------------------------------------------------*/
claw::graphic::image::const_iterator claw::graphic::image::begin() const
{
return const_iterator(*this);
} // image::begin()
/*----------------------------------------------------------------------------*/
claw::graphic::image::const_iterator claw::graphic::image::end() const
{
return const_iterator(*this, width(), height()-1);
} // image::end()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::merge( const image& that )
{
merge( that, math::coordinate_2d<int>(0, 0) );
} // image::merge()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::merge
( const image& that, const math::coordinate_2d<int>& pos )
{
math::rectangle<int> my_box(0, 0, width(), height());
math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
if ( my_box.intersects( his_box ) )
{
math::rectangle<int> intersection;
unsigned int that_y = pos.y < 0 ? -pos.y : 0;
unsigned int that_x = pos.x < 0 ? -pos.x : 0;
const double max_comp
( std::numeric_limits<rgba_pixel::component_type>::max() );
intersection = my_box.intersection( his_box );
for (int y=0; y!=intersection.height; ++y)
{
scanline::const_iterator first = that[y + that_y].begin() + that_x;
scanline::const_iterator last = first + intersection.width;
scanline::iterator dest = (*this)[y + intersection.position.y].begin()
+ intersection.position.x;
for( ; first!=last; ++first, ++dest )
{
const double src_alpha( first->components.alpha );
const double dest_alpha
( dest->components.alpha * (max_comp - src_alpha) );
const double red =
(double)first->components.red * src_alpha
+ (double)dest->components.red * dest_alpha;
const double green =
(double)first->components.green * src_alpha
+ (double)dest->components.green * dest_alpha;
const double blue =
(double)first->components.blue * src_alpha
+ (double)dest->components.blue * dest_alpha;
const double alpha = src_alpha + dest_alpha;
dest->components.red = std::min(red, max_comp);
dest->components.green = std::min(green, max_comp);
dest->components.blue = std::min(blue, max_comp);
dest->components.alpha = std::min(alpha, max_comp);
}
}
}
} // image::merge()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::partial_copy
(const image& that, const math::coordinate_2d<int>& pos )
{
math::rectangle<int> my_box(0, 0, width(), height());
math::rectangle<int> his_box(pos.x, pos.y, that.width(), that.height());
if ( my_box.intersects( his_box ) )
{
math::rectangle<int> intersection;
unsigned int that_y = pos.y < 0 ? -pos.y : 0;
unsigned int that_x = pos.x < 0 ? -pos.x : 0;
intersection = my_box.intersection( his_box );
for (int y=0; y!=intersection.height; ++y)
{
scanline::const_iterator first = that[y + that_y].begin() + that_x;
scanline::const_iterator last = first + intersection.width;
scanline::iterator dest = (*this)[y + intersection.position.y].begin()
+ intersection.position.x;
std::copy( first, last, dest );
}
}
} // image::partial_copy()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::flip()
{
for (unsigned int y=0; y!=height()/2; ++y)
std::swap( m_data[y], m_data[height()-y-1] );
} // image::flip()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::fill
( const math::rectangle<int> r, const pixel_type& c )
{
math::rectangle<int> my_box(0, 0, width(), height());
if ( my_box.intersects( r ) )
{
const math::rectangle<int> intersection( my_box.intersection( r ) );
const double max_comp
( std::numeric_limits<rgba_pixel::component_type>::max() );
for (int y=0; y!=intersection.height; ++y)
{
scanline::iterator first =
(*this)[intersection.position.y + y].begin()
+ intersection.position.x;
const scanline::iterator last = first + intersection.width;
for( ; first!=last; ++first )
{
const double src_alpha(c.components.alpha);
double red =
(double)first->components.red
+ src_alpha * (double)c.components.red / max_comp;
double green =
(double)first->components.green
+ src_alpha * (double)c.components.green / max_comp;
double blue =
(double)first->components.blue
+ src_alpha * (double)c.components.blue / max_comp;
double alpha = (double)first->components.alpha
+ (max_comp - src_alpha) / max_comp;
first->components.red = std::min(red, max_comp);
first->components.green = std::min(green, max_comp);
first->components.blue = std::min(blue, max_comp);
first->components.alpha = std::min(alpha, max_comp);
}
}
}
} // image::fill()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::set_size( unsigned int w, unsigned int h )
{
if (w == 0)
m_data.clear();
else
{
m_data.resize(h);
for (unsigned int y=0; y!=height(); ++y)
m_data[y].resize(w);
}
} // image::set_size()
/*----------------------------------------------------------------------------*/
void claw::graphic::image::load( std::istream& f )
{
bool ok = false;
#ifdef CLAW_JPEG_SUPPORT
if (!ok)
try { jpeg::reader( *this, f ); ok = true; }
catch( ... ) { }
#endif // CLAW_JPEG_SUPPORT
#ifdef CLAW_PNG_SUPPORT
if (!ok)
try { png::reader( *this, f ); ok = true; }
catch( ... ) { }
#endif // CLAW_PNG_SUPPORT
if (!ok)
try { bitmap::reader( *this, f ); ok = true; }
catch( ... ) { }
if (!ok)
try { targa::reader( *this, f ); ok = true; }
catch( ... ) { }
if (!ok)
try { gif::reader( *this, f ); ok = true; }
catch( ... ) { }
if (!ok)
try { pcx::reader( *this, f ); ok = true; }
catch( ... ) { }
if (!ok)
try { xbm::reader( *this, f ); ok = true; }
catch( ... ) { }
if (!ok)
throw claw::bad_format( "image::load: file format isn't supported." );
} // image::load()
/*----------------------------------------------------------------------------*/
void std::swap( claw::graphic::image& a, claw::graphic::image& b )
{
a.swap(b);
} // swap()
claw::graphic::pcx::reader
This class read data from a pcx file and store it in an image.
Definition: pcx.hpp:158
claw::graphic::png::reader
This class read data from a png file and store it in an image.
Definition: png.hpp:56
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::math::rectangle::position
coordinate_2d< value_type > position
value_typeop left coordinates.
Definition: rectangle.hpp:108
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::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
jpeg.hpp
A class for jpeg pictures.
claw::graphic::image::scanline::const_iterator
super::const_iterator const_iterator
Const iterator in the line.
Definition: image.hpp:81
claw::graphic::image::end
iterator end()
Get an iterator pointing just past the last pixel.
Definition: image.cpp:177
claw::graphic::image::scanline::size
size_type size() const
Get the length of the line.
Definition: image.cpp:93
claw::graphic::image::height
unsigned int height() const
Gets image&#39;s height.
Definition: image.cpp:159
claw::graphic::rgba_pixel::components
struct claw::graphic::rgba_pixel::@15::@17 components
Component by component representation.
claw::graphic::targa::reader
This class read data from a targa file and store it in an image.
Definition: targa.hpp:216
claw::graphic::rgba_pixel
RGBA pixel.
Definition: pixel.hpp:79
claw::math::coordinate_2d< int >
claw::graphic::image::scanline::size_type
super::size_type size_type
An unsigned integral type.
Definition: image.hpp:84
claw::graphic::image::flip
void flip()
Set the image upside down.
Definition: image.cpp:301
claw::graphic::image::swap
void swap(image &that)
Swap the content of two images.
Definition: image.cpp:138
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::first
Fuction object to get the first element of a std::pair.
Definition: functional.hpp:44
png.hpp
A class for png pictures.
claw::graphic::image::base_iterator
Base class for iterators on an image.
Definition: image.hpp:106
claw::graphic::image::scanline::end
iterator end()
Get en iterator past the last pixel.
Definition: image.cpp:63
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
bitmap.hpp
A class for bitmap pictures.
claw::graphic::xbm::reader
This class read data from a xbm file and store it in an image.
Definition: xbm.hpp:53
gif.hpp
Image class for gif files.
claw::math::rectangle::height
value_type height
Height.
Definition: rectangle.hpp:114
claw::graphic::jpeg::reader
This class read data from a jpeg file and store it in an image.
Definition: jpeg.hpp:80
claw::graphic::image::image
image()
Constructor. Creates an image without datas.
Definition: image.cpp:106
std::swap
void swap(claw::tween::tweener &a, claw::tween::tweener &b)
Swap two tweeners.
Definition: tweener.cpp:138
claw::math::coordinate_2d::y
value_type y
Y-coordinate.
Definition: coordinate_2d.hpp:85
claw::graphic::image::scanline::iterator
super::iterator iterator
Iterator in the line.
Definition: image.hpp:78
pcx.hpp
A class for pcx pictures.
claw::graphic::image::width
unsigned int width() const
Gets image&#39;s width.
Definition: image.cpp:147
exception.hpp
A simple class to use as exception with string message.
claw::graphic::image::merge
void merge(const image &that)
Merge an image on the current image.
Definition: image.cpp:205
claw::graphic::image::scanline::begin
iterator begin()
Get an iterator on the first pixel.
Definition: image.cpp:54
claw::graphic::image::begin
iterator begin()
Get an iterator pointing on the first pixel.
Definition: image.cpp:168
claw::graphic::image
A class to deal with images.
Definition: image.hpp:49
targa.hpp
A class for targa pictures.
xbm.hpp
A class for xbm pictures.
claw::math::rectangle::width
value_type width
Width.
Definition: rectangle.hpp:111
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::math::coordinate_2d::x
value_type x
X-coordinate.
Definition: coordinate_2d.hpp:82
image.hpp
A class to deal with images.