summaryrefslogtreecommitdiff
path: root/boost/gil/extension/io/jpeg/detail/scanline_read.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/extension/io/jpeg/detail/scanline_read.hpp')
-rw-r--r--boost/gil/extension/io/jpeg/detail/scanline_read.hpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/boost/gil/extension/io/jpeg/detail/scanline_read.hpp b/boost/gil/extension/io/jpeg/detail/scanline_read.hpp
new file mode 100644
index 0000000000..ee33154c61
--- /dev/null
+++ b/boost/gil/extension/io/jpeg/detail/scanline_read.hpp
@@ -0,0 +1,163 @@
+/*
+ Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
+ 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_JPEG_DETAIL_SCANLINE_READ_HPP
+#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file
+/// \brief
+/// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n
+///
+/// \date 2007-2012 \n
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <csetjmp>
+#include <vector>
+
+#include <boost/gil/io/base.hpp>
+#include <boost/gil/io/conversion_policies.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/jpeg/detail/reader_backend.hpp>
+#include <boost/gil/extension/io/jpeg/detail/base.hpp>
+#include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
+
+namespace boost { namespace gil {
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(push)
+#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable
+#endif
+
+///
+/// JPEG Scanline Reader
+///
+template< typename Device >
+class scanline_reader< Device
+ , jpeg_tag
+ >
+ : public reader_backend< Device
+ , jpeg_tag
+ >
+{
+public:
+
+ typedef jpeg_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:
+ scanline_reader( Device& device
+ , const image_read_settings< jpeg_tag >& settings
+ )
+ : reader_backend< Device
+ , jpeg_tag
+ >( device
+ , settings
+ )
+ {
+ initialize();
+ }
+
+ void read( byte_t* dst
+ , int
+ )
+ {
+ // Fire exception in case of error.
+ if( setjmp( this->_mark )) { this->raise_error(); }
+
+ // read data
+ read_scanline( dst );
+ }
+
+ /// Skip over a scanline.
+ void skip( byte_t* dst, int )
+ {
+ // Fire exception in case of error.
+ if( setjmp( this->_mark )) { this->raise_error(); }
+
+ // read data
+ read_scanline( dst );
+ }
+
+ iterator_t begin() { return iterator_t( *this ); }
+ iterator_t end() { return iterator_t( *this, this->_info._height ); }
+
+private:
+
+ void initialize()
+ {
+ this->get()->dct_method = this->_settings._dct_method;
+
+ io_error_if( jpeg_start_decompress( this->get() ) == false
+ , "Cannot start decompression." );
+
+ switch( this->_info._color_space )
+ {
+ case JCS_GRAYSCALE:
+ {
+ this->_scanline_length = this->_info._width;
+
+ break;
+ }
+
+ case JCS_RGB:
+ //!\todo add Y'CbCr? We loose image quality when reading JCS_YCbCr as JCS_RGB
+ case JCS_YCbCr:
+ {
+ this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
+
+ break;
+ }
+
+
+ case JCS_CMYK:
+ //!\todo add Y'CbCrK? We loose image quality when reading JCS_YCCK as JCS_CMYK
+ case JCS_YCCK:
+ {
+ this->get()->out_color_space = JCS_CMYK;
+ this->_scanline_length = this->_info._width * num_channels< cmyk8_view_t >::value;
+
+ break;
+ }
+
+ default: { io_error( "Unsupported jpeg color space." ); }
+ }
+ }
+
+ void read_scanline( byte_t* dst )
+ {
+ JSAMPLE *row_adr = reinterpret_cast< JSAMPLE* >( dst );
+
+ // Read data.
+ io_error_if( jpeg_read_scanlines( this->get()
+ , &row_adr
+ , 1
+ ) != 1
+ , "jpeg_read_scanlines: fail to read JPEG file"
+ );
+
+ }
+};
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(pop)
+#endif
+
+} // namespace gil
+} // namespace boost
+
+#endif