Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:58

0001 //
0002 // Copyright 2012 Olivier Tournaire, Christian Henning
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 #ifndef BOOST_GIL_EXTENSION_IO_RAW_DETAIL_READ_HPP
0009 #define BOOST_GIL_EXTENSION_IO_RAW_DETAIL_READ_HPP
0010 
0011 #include <boost/gil/extension/io/raw/tags.hpp>
0012 #include <boost/gil/extension/io/raw/detail/device.hpp>
0013 #include <boost/gil/extension/io/raw/detail/is_allowed.hpp>
0014 #include <boost/gil/extension/io/raw/detail/reader_backend.hpp>
0015 
0016 #include <boost/gil/io/detail/dynamic.hpp>
0017 #include <boost/gil/io/base.hpp>
0018 #include <boost/gil/io/bit_operations.hpp>
0019 #include <boost/gil/io/conversion_policies.hpp>
0020 #include <boost/gil/io/device.hpp>
0021 #include <boost/gil/io/reader_base.hpp>
0022 #include <boost/gil/io/row_buffer_helper.hpp>
0023 #include <boost/gil/io/typedefs.hpp>
0024 
0025 #include <cstdio>
0026 #include <sstream>
0027 #include <type_traits>
0028 #include <vector>
0029 
0030 namespace boost { namespace gil {
0031 
0032 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0033 #pragma warning(push)
0034 #pragma warning(disable:4512) //assignment operator could not be generated
0035 #endif
0036 
0037 #define BUILD_INTERLEAVED_VIEW(color_layout, bits_per_pixel) \
0038 { \
0039     color_layout##bits_per_pixel##_view_t build = boost::gil::interleaved_view(processed_image->width, \
0040                                                                              processed_image->height, \
0041                                                                              (color_layout##bits_per_pixel##_pixel_t*)processed_image->data, \
0042                                                                              processed_image->colors*processed_image->width*processed_image->bits/8); \
0043     this->_cc_policy.read( build.begin(), build.end(), dst_view.begin() ); \
0044 } \
0045 
0046 
0047 template< typename Device
0048         , typename ConversionPolicy
0049         >
0050 class reader< Device
0051             , raw_tag
0052             , ConversionPolicy
0053             >
0054     : public reader_base< raw_tag
0055                         , ConversionPolicy
0056                         >
0057     , public reader_backend< Device
0058                            , raw_tag
0059                            >
0060 {
0061 private:
0062 
0063     using this_t = reader<Device, raw_tag, ConversionPolicy>;
0064     using cc_t = typename ConversionPolicy::color_converter_type;
0065 
0066 public:
0067 
0068     using backend_t = reader_backend<Device, raw_tag>;
0069 
0070     //
0071     // Constructor
0072     //
0073     reader( const Device&                         io_dev
0074           , const image_read_settings< raw_tag >& settings
0075           )
0076     : backend_t( io_dev
0077                , settings
0078                )
0079     {}
0080 
0081     //
0082     // Constructor
0083     //
0084     reader( const Device&                         io_dev
0085           , const cc_t&                           cc
0086           , const image_read_settings< raw_tag >& settings
0087           )
0088     : reader_base< raw_tag
0089                  , ConversionPolicy
0090                  >( cc )
0091     , backend_t( io_dev
0092                , settings
0093                )
0094     {}
0095 
0096     template< typename View >
0097     void apply( const View& dst_view )
0098     {
0099         if( this->_info._valid == false )
0100         {
0101             io_error( "Image header was not read." );
0102         }
0103 
0104         using is_read_and_convert_t = typename std::is_same
0105             <
0106                 ConversionPolicy,
0107                 detail::read_and_no_convert
0108             >::type;
0109 
0110         io_error_if( !detail::is_allowed< View >( this->_info
0111                                                 , is_read_and_convert_t()
0112                                                 )
0113                    , "Image types aren't compatible."
0114                    );
0115 
0116         // TODO: better error handling based on return code
0117         int return_code = this->_io_dev.unpack();
0118         io_error_if( return_code != LIBRAW_SUCCESS, "Unable to unpack image" );
0119         this->_info._unpack_function_name = this->_io_dev.get_unpack_function_name();
0120 
0121         return_code = this->_io_dev.dcraw_process();
0122         io_error_if( return_code != LIBRAW_SUCCESS, "Unable to emulate dcraw behavior to process image" );
0123 
0124         libraw_processed_image_t* processed_image = this->_io_dev.dcraw_make_mem_image(&return_code);
0125         io_error_if( return_code != LIBRAW_SUCCESS, "Unable to dcraw_make_mem_image" );
0126 
0127         if(processed_image->colors!=1 && processed_image->colors!=3)
0128             io_error( "Image is neither gray nor RGB" );
0129 
0130         if(processed_image->bits!=8 && processed_image->bits!=16)
0131             io_error( "Image is neither 8bit nor 16bit" );
0132 
0133         // TODO Olivier Tournaire
0134         // Here, we should use a metafunction to reduce code size and avoid a (compile time) macro
0135         if(processed_image->bits==8)
0136         {
0137             if(processed_image->colors==1){ BUILD_INTERLEAVED_VIEW(gray, 8); }
0138             else                          { BUILD_INTERLEAVED_VIEW(rgb,  8); }
0139         }
0140         else if(processed_image->bits==16)
0141         {
0142             if(processed_image->colors==1){ BUILD_INTERLEAVED_VIEW(gray, 16); }
0143             else                          { BUILD_INTERLEAVED_VIEW(rgb,  16); }
0144         }
0145     }
0146 };
0147 
0148 namespace detail {
0149 
0150 struct raw_read_is_supported
0151 {
0152     template< typename View >
0153     struct apply : public is_read_supported< typename get_pixel_type< View >::type
0154                                            , raw_tag
0155                                            >
0156     {};
0157 };
0158 
0159 struct raw_type_format_checker
0160 {
0161     raw_type_format_checker( const image_read_info< raw_tag >& info )
0162     : _info( info )
0163     {}
0164 
0165     template< typename Image >
0166     bool apply()
0167     {
0168         using view_t = typename Image::view_t;
0169         return is_allowed<view_t>(_info, std::true_type{});
0170     }
0171 
0172 private:
0173     ///todo: do we need this here. Should be part of reader_backend
0174     const image_read_info< raw_tag >& _info;
0175 };
0176 
0177 } // namespace detail
0178 
0179 ///
0180 /// RAW Dynamic Reader
0181 ///
0182 template< typename Device >
0183 class dynamic_image_reader< Device
0184                           , raw_tag
0185                           >
0186     : public reader< Device
0187                    , raw_tag
0188                    , detail::read_and_no_convert
0189                    >
0190 {
0191     using parent_t = reader<Device, raw_tag, detail::read_and_no_convert>;
0192 
0193 public:
0194 
0195     dynamic_image_reader( const Device&                         io_dev
0196                         , const image_read_settings< raw_tag >& settings
0197                         )
0198     : parent_t( io_dev
0199               , settings
0200               )
0201     {}
0202 
0203     template< typename ...Images >
0204     void apply( any_image< Images... >& images )
0205     {
0206         detail::raw_type_format_checker format_checker( this->_info );
0207 
0208         if( !detail::construct_matched( images
0209                                , format_checker
0210                                ))
0211         {
0212             std::ostringstream error_message;
0213             error_message << "No matching image type between those of the given any_image and that of the file.\n";
0214             error_message << "Image type must be {gray||rgb}{8||16} unsigned for RAW image files.";
0215             io_error( error_message.str().c_str() );
0216         }
0217         else
0218         {
0219             if( !this->_info._valid )
0220           this->read_header();
0221             this->init_image(images, this->_settings);
0222 
0223             detail::dynamic_io_fnobj< detail::raw_read_is_supported
0224                                     , parent_t
0225                                     > op( this );
0226 
0227             variant2::visit( op
0228                             , view( images )
0229                             );
0230         }
0231     }
0232 };
0233 
0234 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0235 #pragma warning(pop)
0236 #endif
0237 
0238 } // gil
0239 } // boost
0240 
0241 #endif