summaryrefslogtreecommitdiff
path: root/boost/gil/extension/io/targa/detail/scanline_read.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/extension/io/targa/detail/scanline_read.hpp')
-rw-r--r--boost/gil/extension/io/targa/detail/scanline_read.hpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/boost/gil/extension/io/targa/detail/scanline_read.hpp b/boost/gil/extension/io/targa/detail/scanline_read.hpp
new file mode 100644
index 0000000000..7fbd0b05b0
--- /dev/null
+++ b/boost/gil/extension/io/targa/detail/scanline_read.hpp
@@ -0,0 +1,167 @@
+/*
+ Copyright 2012 Kenneth Riddile and Christian Henning
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+*/
+
+/*************************************************************************************************/
+
+#ifndef BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
+#define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file
+/// \brief
+/// \author Kenneth Riddile and Christian Henning \n
+///
+/// \date 2012 \n
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <vector>
+
+#include <boost/gil/io/base.hpp>
+#include <boost/gil/io/bit_operations.hpp>
+#include <boost/gil/io/conversion_policies.hpp>
+#include <boost/gil/io/row_buffer_helper.hpp>
+#include <boost/gil/io/reader_base.hpp>
+#include <boost/gil/io/device.hpp>
+#include <boost/gil/io/scanline_read_iterator.hpp>
+#include <boost/gil/io/typedefs.hpp>
+
+#include <boost/gil/extension/io/targa/detail/reader_backend.hpp>
+#include <boost/gil/extension/io/targa/detail/is_allowed.hpp>
+
+namespace boost { namespace gil {
+
+///
+/// Targa Scanline Reader
+///
+template< typename Device >
+class scanline_reader< Device
+ , targa_tag
+ >
+ : public reader_backend< Device
+ , targa_tag
+ >
+{
+public:
+
+
+ typedef targa_tag tag_t;
+ typedef reader_backend < Device, tag_t > backend_t;
+ typedef scanline_reader< Device, tag_t > this_t;
+ typedef scanline_read_iterator< this_t > iterator_t;
+
+public:
+
+ //
+ // Constructor
+ //
+ scanline_reader( Device& device
+ , const image_read_settings< targa_tag >& settings
+ )
+ : backend_t( device
+ , settings
+ )
+ {
+ initialize();
+ }
+
+ /// Read part of image defined by View and return the data.
+ void read( byte_t* dst, int pos )
+ {
+ // jump to scanline
+ long offset = this->_info._offset
+ + ( this->_info._height - 1 - pos ) * static_cast< long >( this->_scanline_length );
+
+ this->_io_dev.seek( offset );
+
+
+ read_row( dst );
+ }
+
+ /// Skip over a scanline.
+ void skip( byte_t*, int )
+ {
+ this->_io_dev.seek( static_cast<long>( this->_scanline_length )
+ , SEEK_CUR
+ );
+ }
+
+ iterator_t begin() { return iterator_t( *this ); }
+ iterator_t end() { return iterator_t( *this, this->_info._height ); }
+
+private:
+
+ void initialize()
+ {
+ if( this->_info._color_map_type != targa_color_map_type::_rgb )
+ {
+ io_error( "scanline reader cannot read indexed targa files." );
+ }
+
+ if( this->_info._image_type != targa_image_type::_rgb )
+ {
+ io_error( "scanline reader cannot read this targa image type." );
+ }
+
+ switch( this->_info._image_type )
+ {
+ case targa_image_type::_rgb:
+ {
+ if( this->_info._color_map_type != targa_color_map_type::_rgb )
+ {
+ io_error( "Inconsistent color map type and image type in targa file." );
+ }
+
+ if( this->_info._color_map_length != 0 )
+ {
+ io_error( "Non-indexed targa files containing a palette are not supported." );
+ }
+
+ if( this->_info._screen_origin_bit )
+ {
+ io_error( "scanline reader cannot read targa files which have screen origin bit set." );
+ }
+
+ switch( this->_info._bits_per_pixel )
+ {
+ case 24:
+ case 32:
+ {
+ this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 );
+
+ // jump to first scanline
+ this->_io_dev.seek( static_cast< long >( this->_info._offset ));
+
+ break;
+ }
+ default:
+ {
+ io_error( "Unsupported bit depth in targa file." );
+ break;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ io_error( "Unsupported image type in targa file." );
+ break;
+ }
+ }
+ }
+
+ void read_row( byte_t* dst )
+ {
+ this->_io_dev.read( dst, this->_scanline_length );
+ }
+};
+
+} // namespace gil
+} // namespace boost
+
+#endif