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)" ); } }
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." ); }
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); }
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" ); }
/// /// 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" ); }
/// /// 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" ); }
// // 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; } }
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 ); }
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." ); }
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); }
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" ); }
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 ); }
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 ); }
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" ); }
/// /// 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() ); }
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); }
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; }
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 ); }