bitmap_reader.tpp
/*
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
*/
/**
* \file bitmap_reader.tpp
* \brief Template classes of the claw::graphic::bitmap::reader class.
* \author Julien Jorge
*/
#include <cassert>
#include <algorithm>
#include <claw/exception.hpp>
/*----------------------------------------------------------------------------*/
/**
* \brief Constructor.
* \param palette The color palette to convert the pixels.
* \param img The image we're filling.
*/
template< bool Coded4Bits >
claw::graphic::bitmap::reader::
rle_bitmap_output_buffer<Coded4Bits>::rle_bitmap_output_buffer
( const color_palette_type& palette, image& img )
: m_palette(palette), m_image(img), m_x(0), m_y(m_image.height() - 1)
{
} // bitmap::reader::rle_bitmap_output_buffer::rle_bitmap_output_buffer()
/*----------------------------------------------------------------------------*/
/**
* \brief Go to the begining of the next line to fill.
*/
template< bool Coded4Bits >
void claw::graphic::bitmap::reader::
rle_bitmap_output_buffer<Coded4Bits>::next_line()
{
assert( m_y > 0 );
m_x = 0;
--m_y;
} // bitmap::reader::rle_bitmap_output_buffer::next_line()
/*----------------------------------------------------------------------------*/
/**
* \brief Move the cursor horizontally and vertically.
* \param x Horizontal displacement.
* \param y Vertical displacement.
*/
template< bool Coded4Bits >
void claw::graphic::bitmap::reader::
rle_bitmap_output_buffer<Coded4Bits>::delta_move
(unsigned char x, unsigned char y)
{
assert( m_x + x < m_image.width() );
assert( m_y + y < m_image.height() );
m_x += x;
m_y += y;
} // bitmap::reader::rle_bitmap_output_buffer::delta_move()
//******************************************************************************
/*----------------------------------------------------------------------------*/
/**
* \brief Get the type of the following data in the input buffer, eventually
* apply the special codes.
* \param input The input stream (the bitmap file).
* \param output The output stream (the bitmap image).
*/
template< typename OutputBuffer >
void claw::graphic::bitmap::reader::rle_bitmap_decoder<OutputBuffer>::read_mode
( file_input_buffer& input, output_buffer_type& output)
{
this->m_mode = this->stop;
bool ok = true;
if ( input.remaining() < 2)
ok = input.read_more(2);
if (ok)
{
unsigned char key, pattern;
key = input.get_next();
pattern = input.get_next();
// compressed data, next byte is the pattern
if (key > 0)
{
this->m_mode = this->compressed;
this->m_count = key;
this->m_pattern = pattern;
}
else switch( pattern )
{
// end of line
case 0 : output.next_line(); read_mode(input, output); break;
// end of file
case 1 : this->m_mode = this->stop; break;
// delta move
case 2 :
{
if ( input.remaining() < 1 )
ok = input.read_more(1);
if (ok)
{
unsigned char x, y;
x = pattern;
y = input.get_next();
output.delta_move(x, y);
read_mode(input, output);
break;
}
}
// raw data
default: this->m_mode = this->raw; this->m_count = pattern; break;
}
}
} // bitmap::reader::rle_bitmap_decoder::read_mode()
/*----------------------------------------------------------------------------*/
/**
* \brief Load uncompressed data from the file.
* \param f The file from which we're loading the bitmap.
* \param buffer_size Number of bytes needed to store one line of pixels.
* \param palette Color palette.
* \param pixel_convert A method to convert one line of pixels from the file to
* a line of the current bitmap.
*
* \remark The Convert type method must take this four parameters in this order:
* # scanline& destination line,
* # const char* input buffer (contains one line of the bitmap),
* # const color_palette_type& palette The color palette of the file,
*/
template<typename Convert>
void claw::graphic::bitmap::reader::load_rgb_data
( std::istream& f, unsigned int buffer_size, const color_palette_type& palette,
const Convert& pixel_convert )
{
unsigned int line;
// lines are 4-bytes aligned, so adjust buffer's size.
if (buffer_size % 4 != 0)
buffer_size += 4 - buffer_size % 4;
char* buffer = new char[buffer_size];
for (line = m_image.height(); (line>0) && !f.eof(); )
{
--line;
f.read(buffer, buffer_size);
pixel_convert( m_image[line], buffer, palette );
}
delete[] buffer;
if ( f.rdstate() != std::ios_base::goodbit )
throw claw::bad_format("bitmap::reader::load_data");
} // bitmap::reader::load_data()