You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.0 KiB
C++
153 lines
4.0 KiB
C++
2 years ago
|
//
|
||
|
// Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
|
||
|
//
|
||
|
// Distributed under 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
|
||
|
|
||
|
|
||
|
#include <boost/gil/extension/io/jpeg/detail/base.hpp>
|
||
|
#include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
|
||
|
#include <boost/gil/extension/io/jpeg/detail/reader_backend.hpp>
|
||
|
|
||
|
#include <boost/gil/io/base.hpp>
|
||
|
#include <boost/gil/io/conversion_policies.hpp>
|
||
|
#include <boost/gil/io/device.hpp>
|
||
|
#include <boost/gil/io/reader_base.hpp>
|
||
|
#include <boost/gil/io/scanline_read_iterator.hpp>
|
||
|
#include <boost/gil/io/typedefs.hpp>
|
||
|
|
||
|
#include <csetjmp>
|
||
|
#include <vector>
|
||
|
|
||
|
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:
|
||
|
|
||
|
using tag_t = jpeg_tag;
|
||
|
using backend_t = reader_backend<Device, tag_t>;
|
||
|
using this_t = scanline_reader<Device, tag_t>;
|
||
|
using iterator_t = scanline_read_iterator<this_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
|