Пример #1
0
    void read_header()
    {
        // read signature
        io_error_if( read_char() != 'P', "Invalid PNM signature" );

        _info._type = read_char() - '0';

		io_error_if( _info._type < pnm_image_type::mono_asc_t::value || _info._type > pnm_image_type::color_bin_t::value
		           , "Invalid PNM file (supports P1 to P6)"
		           );

        _info._width  = read_int();
        _info._height = read_int();

        if( _info._type == pnm_image_type::mono_asc_t::value || _info._type == pnm_image_type::mono_bin_t::value )
        {
            _info._max_value = 1;
        }
        else
        {
            _info._max_value = read_int();

		    io_error_if( _info._max_value > 255
		               , "Unsupported PNM format (supports maximum value 255)"
		               );
        }
    }
Пример #2
0
	void init()
	{
		char buf[PNG_BYTES_TO_CHECK];

		// read in some of the signature bytes
		io_error_if( fread( buf, 1, PNG_BYTES_TO_CHECK, get() ) != detail::PNG_BYTES_TO_CHECK,
			     "png_check_validity: fail to read file" );
		// compare the first PNG_BYTES_TO_CHECK bytes of the signature.
		io_error_if( png_sig_cmp( (png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK ) != 0,
			     "png_check_validity: invalid png file" );

		_png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
		io_error_if( _png_ptr == NULL, "png_get_file_size: fail to call png_create_write_struct()" );
		// allocate/initialize the image information data
		_info_ptr = png_create_info_struct( _png_ptr );
		if( _info_ptr == NULL )
		{
			png_destroy_read_struct( &_png_ptr, png_infopp_NULL, png_infopp_NULL );
			io_error( "png_get_file_size: fail to call png_create_info_struct()" );
		}
		if( setjmp( png_jmpbuf( _png_ptr ) ) )
		{
			//free all of the memory associated with the png_ptr and info_ptr
			png_destroy_read_struct( &_png_ptr, &_info_ptr, png_infopp_NULL );
			io_error( "png_get_file_size: fail to call setjmp()" );
		}
		png_init_io( _png_ptr, get() );
		png_set_sig_bytes( _png_ptr, PNG_BYTES_TO_CHECK );
		png_read_info( _png_ptr, _info_ptr );
		if( little_endian() && png_get_bit_depth( _png_ptr, _info_ptr ) > 8 )
			png_set_swap( _png_ptr );
	}
    void check_coordinates( const point_t& dim )
    {
       typedef point_t::value_type int_t;

       int_t width  = static_cast< int_t >( _info._width  );
       int_t height = static_cast< int_t >( _info._height );

       io_error_if( (  _settings._top_left.x < 0
                    || _settings._top_left.y < 0
                    || dim.x < 0
                    || dim.y < 0
                    )
                 , "User provided view has incorrect size." );


       io_error_if( (  ( width  ) <  _settings._top_left.x
                    && ( width  ) <= dim.x
                    && ( height ) <  _settings._top_left.y
                    && ( height ) <= dim.y  )
                 , "User provided view has incorrect size."       );

       io_error_if( (  ( _settings._top_left.x + dim.x ) > width
                    || ( _settings._top_left.y + dim.y ) > height
                   )
                 , "User provided view has incorrect size." );

    }
Пример #4
0
 void apply(const View& view) {
     jpeg_start_decompress(&_cinfo);    // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
     io_error_if(_cinfo.data_precision!=8,"jpeg_reader::apply(): this image file is not supported");
     io_error_if(_cinfo.out_color_space!=jpeg_read_support_private<typename channel_type<View>::type,
                                                                   typename color_space_type<View>::type>::color_type,
                 "jpeg_reader::apply(): input view type does not match the image file");
     io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader::apply(): input view dimensions do not match the image file");
     std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
     JSAMPLE* row_address=(JSAMPLE*)&row.front();
     for(int y=0;y<view.height();++y) {
         io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
                     "jpeg_reader::apply(): fail to read JPEG file");
         std::copy(row.begin(),row.end(),view.row_begin(y));
     }
     jpeg_finish_decompress(&_cinfo);
 }
Пример #5
0
 explicit mapped_input_file_guard( char const * const file_name )
     :
     memory_mapped_source( map_read_only_file( file_name )      ),
     mutable_range_      ( memory_mapped_source::memory_range() )
 {
     io_error_if( memory_range().empty(), "File open failure" );
 }
Пример #6
0
 ///
 /// Constructor
 ///
 file_stream_device( std::string const& file_name
                   , read_tag   = read_tag()
                   )
 {
     io_error_if( _processor_ptr.get()->open_file( file_name.c_str() ) != LIBRAW_SUCCESS 
                , "file_stream_device: failed to open file"
                );
 }
Пример #7
0
 ///
 /// Constructor
 ///
 file_stream_device( const char* file_name
                   , read_tag   = read_tag()
                   )
 {
     io_error_if( _processor_ptr.get()->open_file( file_name ) != LIBRAW_SUCCESS 
                , "file_stream_device: failed to open file"
                );
 }
Пример #8
0
    //
    // Constructor
    //
    reader_backend( const Device&                          io_dev
                  , const image_read_settings< jpeg_tag >& settings
                  )
    : _io_dev( io_dev )
    , _settings( settings )
    , _info()

    , _scanline_length( 0 )
    {
        get()->err         = jpeg_std_error( &_jerr );
        get()->client_data = this;

        // Error exit handler: does not return to caller.
        _jerr.error_exit = &reader_backend::error_exit;

        if( setjmp( _mark ))
        {
            raise_error();
        }

        _src._jsrc.bytes_in_buffer   = 0;
        _src._jsrc.next_input_byte   = buffer;
        _src._jsrc.init_source       = reinterpret_cast< void(*)   ( j_decompress_ptr )>( &reader_backend< Device, jpeg_tag >::init_device );
        _src._jsrc.fill_input_buffer = reinterpret_cast< boolean(*)( j_decompress_ptr )>( &reader_backend< Device, jpeg_tag >::fill_buffer );
        _src._jsrc.skip_input_data   = reinterpret_cast< void(*)   ( j_decompress_ptr
                                                                   , long num_bytes
                                                                   ) >( &reader_backend< Device, jpeg_tag >::skip_input_data );
        _src._jsrc.term_source       = reinterpret_cast< void(*)   ( j_decompress_ptr ) >( &reader_backend< Device, jpeg_tag >::close_device );
        _src._jsrc.resync_to_restart = jpeg_resync_to_restart;
        _src._this = this;

        jpeg_create_decompress( get() );

        get()->src = &_src._jsrc;

        jpeg_read_header( get()
                        , TRUE
                        );

        io_error_if( get()->data_precision != 8
                   , "Image file is not supported."
                   );

        //
        read_header();

        //
        if( _settings._dim.x == 0 )
        {
            _settings._dim.x = _info._width;
        }

        if( _settings._dim.y == 0 )
        {
            _settings._dim.y = _info._height;
        }
    }
Пример #9
0
    file_stream_device( std::string const& file_name, write_tag )
    {
        TIFF* tiff;

        io_error_if( ( tiff = TIFFOpen( file_name.c_str(), "w" )) == NULL
                     , "file_stream_device: failed to open file" );

        _tiff_file = tiff_file_t( tiff, TIFFClose );
    }
Пример #10
0
 void read_scaline( Buffer&        buffer
                    , std::ptrdiff_t row
                    , tsample_t      plane   )
 {
     io_error_if( TIFFReadScanline( _tiff_file.get()
                                    , reinterpret_cast< tdata_t >( &buffer.front() )
                                    , (uint32) row
                                    , plane           ) == -1
                  , "Read error."
                );
 }
Пример #11
0
 void apply(const View& view) {
     jpeg_start_decompress(&_cinfo);    // lbourdev: Can this return an error? You need to check and throw. Check all other library methods that can return an error state...
     io_error_if(_cinfo.data_precision!=8,"jpeg_reader_color_covert::apply(): this image file is not supported");
     io_error_if(view.dimensions() != get_dimensions(), "jpeg_reader_color_covert::apply(): input view dimensions don't match the image file");
     switch (_cinfo.out_color_space) {
     case JCS_GRAYSCALE: {
         std::vector<gray8_pixel_t> row(view.width());
         JSAMPLE* row_address=(JSAMPLE*)&row.front();
         for(int y=0;y<view.height();++y) {
             io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
                         "jpeg_reader_color_covert::apply(): fail to read JPEG file");
             std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t, typename View::value_type,CC>(_cc));
         }
         break;
     }
     case JCS_RGB: {
         std::vector<rgb8_pixel_t> row(view.width());
         JSAMPLE* row_address=(JSAMPLE*)&row.front();
         for(int y=0;y<view.height();++y) {
             io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
                         "jpeg_reader_color_covert::apply(): fail to read JPEG file");
             std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t, typename View::value_type,CC>(_cc));
         }
         break;
     }
     case JCS_CMYK: {
         std::vector<cmyk8_pixel_t> row(view.width());
         JSAMPLE* row_address=(JSAMPLE*)&row.front();
         for(int y=0;y<view.height();++y) {
             io_error_if(jpeg_read_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1)!=1,
                         "jpeg_reader_color_covert::apply(): fail to read JPEG file");
             std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<cmyk8_ref_t, typename View::value_type,CC>(_cc));
         }
         break;
     }
     default:
         io_error("jpeg_reader_color_covert::apply(): unknown color type");
     }
     jpeg_finish_decompress(&_cinfo);
 }    
Пример #12
0
    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"
                    );

    }
Пример #13
0
    istream_device( std::istream & in )
            : _in( in )
    {
        TIFF* tiff;

        io_error_if( ( tiff = TIFFStreamOpen( ""
                                              , &_in
                                            )
                     ) == NULL
                     , "istream_device: failed to stream"
                   );

        _tiff_file = tiff_file_t( tiff, TIFFClose );
    }
Пример #14
0
    ostream_device( std::ostream & out )
            : _out( out )
    {
        TIFF* tiff;

        io_error_if( ( tiff = TIFFStreamOpen( ""
                                              , &_out
                                            )
                     ) == NULL
                     , "ostream_device: failed to stream"
                   );

        _tiff_file = tiff_file_t( tiff, TIFFClose );
    }
Пример #15
0
 inline
 void write_scaline( Buffer&     buffer
                     , uint32      row
                     , tsample_t   plane
                   )
 {
     io_error_if( TIFFWriteScanline( _tiff_file.get()
                                     , &buffer.front()
                                     , row
                                     , plane
                                   ) == -1
                  , "Write error"
                );
 }
Пример #16
0
    ///
    /// Constructor
    ///
    writer_backend( const Device&                      io_dev
                  , const image_write_info< png_tag >& info
                  )
    : png_struct_info_wrapper( false )
    , _io_dev( io_dev )
    , _info( info )
    {
        // Create and initialize the png_struct with the desired error handler
        // functions.  If you want to use the default stderr and longjump method,
        // you can supply NULL for the last three parameters.  We also check that
        // the library version is compatible with the one used at compile time,
        // in case we are using dynamically linked libraries.  REQUIRED.
        get()->_struct = png_create_write_struct( PNG_LIBPNG_VER_STRING
                                                , nullptr  // user_error_ptr
                                                , nullptr  // user_error_fn
                                                , nullptr  // user_warning_fn
                                                );

        io_error_if( get_struct() == nullptr
                   , "png_writer: fail to call png_create_write_struct()"
                   );

        // Allocate/initialize the image information data.  REQUIRED
        get()->_info = png_create_info_struct( get_struct() );

        if( get_info() == nullptr )
        {
            png_destroy_write_struct( &get()->_struct
                                    , nullptr
                                    );

            io_error( "png_writer: fail to call png_create_info_struct()" );
        }

        // Set error handling.  REQUIRED if you aren't supplying your own
        // error handling functions in the png_create_write_struct() call.
        if( setjmp( png_jmpbuf( get_struct() )))
        {
            //free all of the memory associated with the png_ptr and info_ptr
            png_destroy_write_struct( &get()->_struct
                                    , &get()->_info
                                    );

            io_error( "png_writer: fail to call setjmp()" );
        }

        init_io( get_struct() );
    }
Пример #17
0
 void apply(const View& view,int quality=100) {
     _cinfo.image_width  = (JDIMENSION)view.width();
     _cinfo.image_height = (JDIMENSION)view.height();
     _cinfo.input_components=num_channels<View>::value;
     _cinfo.in_color_space = jpeg_write_support_private<typename channel_type<View>::type,
                                                        typename color_space_type<View>::type>::color_type;
     jpeg_set_defaults(&_cinfo);
     jpeg_set_quality(&_cinfo, quality, TRUE);
     jpeg_start_compress(&_cinfo, TRUE);
     std::vector<pixel<bits8,layout<typename color_space_type<View>::type> > > row(view.width());
     JSAMPLE* row_address=(JSAMPLE*)&row.front();
     for (int y=0;y<view.height(); ++y) {
         std::copy(view.row_begin(y),view.row_end(y),row.begin());
         io_error_if(jpeg_write_scanlines(&_cinfo,(JSAMPARRAY)&row_address,1) != 1,
                     "jpeg_writer::apply(): fail to write file");
     }
     jpeg_finish_compress(&_cinfo);
 }
Пример #18
0
    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 apply( const View& dst_view )
    {
        if( !_info._valid )
        {
            get_info();
        }

        typedef typename is_same< ConversionPolicy
                                , read_and_no_convert
                                >::type is_read_and_convert_t;

        io_error_if( !is_allowed< View >( this->_info
                                        , is_read_and_convert_t()
                                        )
                   , "Image types aren't compatible."
                   );

        // the row pitch must be multiple 4 bytes
        int pitch;

        if( _info._bits_per_pixel < 8 )
        {
            pitch = (( this->_info._width * this->_info._bits_per_pixel ) + 7 ) >> 3;
        }
Пример #20
0
    void initialize()
    {
        // Now it's time for some transformations.

        if( little_endian() )
        {
            if( this->_info._bit_depth == 16 )
            {
                // Swap bytes of 16 bit files to least significant byte first.
                png_set_swap( this->get()->_struct );
            }

            if( this->_info._bit_depth < 8 )
            {
                // swap bits of 1, 2, 4 bit packed pixel formats
                png_set_packswap( this->get()->_struct );
            }
        }

        if( this->_info._color_type == PNG_COLOR_TYPE_PALETTE )
        {
            png_set_palette_to_rgb( this->get()->_struct );
        }

        if( this->_info._num_trans > 0 )
        {
            png_set_tRNS_to_alpha( this->get()->_struct );
        }

        // Tell libpng to handle the gamma conversion for you.  The final call
        // is a good guess for PC generated images, but it should be configurable
        // by the user at run time by the user.  It is strongly suggested that
        // your application support gamma correction.
        if( this->_settings._apply_screen_gamma )
        {
            // png_set_gamma will change the image data!

#ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
        png_set_gamma( this->get()->_struct
                     , this->_settings._screen_gamma
                     , this->_info._file_gamma
                     );
#else
        png_set_gamma( this->get()->_struct
                     , this->_settings._screen_gamma
                     , this->_info._file_gamma
                     );
#endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
        }

        // Interlaced images are not supported.
        this->_number_passes = png_set_interlace_handling( this->get()->_struct );
        io_error_if( this->_number_passes != 1
                   , "scanline_read_iterator cannot read interlaced png images."
                   );


        // The above transformation might have changed the bit_depth and color type.
        png_read_update_info( this->get()->_struct
                            , this->get()->_info
                            );

        this->_info._bit_depth = png_get_bit_depth( this->get()->_struct
                                                  , this->get()->_info
                                                  );

        this->_info._num_channels = png_get_channels( this->get()->_struct
                                                    , this->get()->_info
                                                    );

        this->_info._color_type = png_get_color_type( this->get()->_struct
                                                    , this->get()->_info
                                                    );

        this->_scanline_length = png_get_rowbytes( this->get()->_struct
                                                 , this->get()->_info
                                                 );
    }