void jpeg_loader::read_image(const unsigned char * buffer, size_t len) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; // Setup decompression structure cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); my_set_source_mgr(&cinfo, buffer, len); // read info from header. int r = jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); // ..<snip>.. // .. decompress the JPEG here as usual // ..<snip>.. height_ = cinfo.output_height; width_ = cinfo.output_width; output_components_ = cinfo.output_components; if (output_components_ != 1 && output_components_ != 3 && output_components_ != 4) { jpeg_destroy_decompress(&cinfo); std::ostringstream sout; sout << "jpeg_loader: Unsupported number of colors (" << output_components_ << ") in buffer "; throw image_load_error(sout.str()); } std::vector<unsigned char*> rows; rows.resize(height_); // size the image buffer data.resize(height_*width_*output_components_); // setup pointers to each row for (unsigned long i = 0; i < rows.size(); ++i) rows[i] = &data[i*width_*output_components_]; // read the data into the buffer while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &rows[cinfo.output_scanline], 100); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); }
void png_loader::read_image( const char* filename ) { ld_.reset(new LibpngData); if ( filename == NULL ) { throw image_load_error("png_loader: invalid filename, it is NULL"); } FILE *fp = fopen( filename, "rb" ); if ( !fp ) { throw image_load_error(std::string("png_loader: unable to open file ") + filename); } png_byte sig[8]; if (fread( sig, 1, 8, fp ) != 8) { fclose( fp ); throw image_load_error(std::string("png_loader: error reading file ") + filename); } if ( png_sig_cmp( sig, 0, 8 ) != 0 ) { fclose( fp ); throw image_load_error(std::string("png_loader: format error in file ") + filename); } ld_->png_ptr_ = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if ( ld_->png_ptr_ == NULL ) { fclose( fp ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } ld_->info_ptr_ = png_create_info_struct( ld_->png_ptr_ ); if ( ld_->info_ptr_ == NULL ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), ( png_infopp )NULL, ( png_infopp )NULL ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } ld_->end_info_ = png_create_info_struct( ld_->png_ptr_ ); if ( ld_->end_info_ == NULL ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), ( png_infopp )NULL ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } png_init_io( ld_->png_ptr_, fp ); png_set_sig_bytes( ld_->png_ptr_, 8 ); // flags force one byte per channel output png_read_png( ld_->png_ptr_, ld_->info_ptr_, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, NULL ); height_ = png_get_image_height( ld_->png_ptr_, ld_->info_ptr_ ); width_ = png_get_image_width( ld_->png_ptr_, ld_->info_ptr_ ); bit_depth_ = png_get_bit_depth( ld_->png_ptr_, ld_->info_ptr_ ); color_type_ = png_get_color_type( ld_->png_ptr_, ld_-> info_ptr_ ); if (color_type_ != PNG_COLOR_TYPE_GRAY && color_type_ != PNG_COLOR_TYPE_RGB && color_type_ != PNG_COLOR_TYPE_RGB_ALPHA ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) ); throw image_load_error(std::string("png_loader: unsupported color type in file ") + filename); } ld_->row_pointers_ = png_get_rows( ld_->png_ptr_, ld_->info_ptr_ ); // FIXME: the following call makes libpng crash. Why? //png_read_end( ld_->png_ptr_, ld_->end_info_ ); fclose( fp ); if ( ld_->row_pointers_ == NULL ) { throw image_load_error(std::string("png_loader: parse error in file ") + filename); } }
void jpeg_loader::read_image( const char* filename ) { if ( filename == NULL ) { throw image_load_error("jpeg_loader: invalid filename, it is NULL"); } FILE *fp = fopen( filename, "rb" ); if ( !fp ) { throw image_load_error(std::string("jpeg_loader: unable to open file ") + filename); } jpeg_decompress_struct cinfo; jpeg_loader_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_loader_error_exit; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress(&cinfo); fclose(fp); throw image_load_error(std::string("jpeg_loader: error while reading ") + filename); } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); height_ = cinfo.output_height; width_ = cinfo.output_width; output_components_ = cinfo.output_components; if (output_components_ != 1 && output_components_ != 3) { fclose( fp ); jpeg_destroy_decompress(&cinfo); std::ostringstream sout; sout << "jpeg_loader: Unsupported number of colors (" << output_components_ << ") in file " << filename; throw image_load_error(sout.str()); } std::vector<unsigned char*> rows; rows.resize(height_); // size the image buffer data.resize(height_*width_*output_components_); // setup pointers to each row for (unsigned long i = 0; i < rows.size(); ++i) rows[i] = &data[i*width_*output_components_]; // read the data into the buffer while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &rows[cinfo.output_scanline], 100); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose( fp ); }
void png_loader::read_image( const char* filename ) { ld_.reset(new LibpngData); if ( filename == NULL ) { throw image_load_error("png_loader: invalid filename, it is NULL"); } FILE *fp = fopen( filename, "rb" ); if ( !fp ) { throw image_load_error(std::string("png_loader: unable to open file ") + filename); } png_byte sig[8]; if (fread( sig, 1, 8, fp ) != 8) { fclose( fp ); throw image_load_error(std::string("png_loader: error reading file ") + filename); } if ( png_sig_cmp( sig, 0, 8 ) != 0 ) { fclose( fp ); throw image_load_error(std::string("png_loader: format error in file ") + filename); } ld_->png_ptr_ = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, &png_loader_user_error_fn_silent, &png_loader_user_warning_fn_silent ); if ( ld_->png_ptr_ == NULL ) { fclose( fp ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } ld_->info_ptr_ = png_create_info_struct( ld_->png_ptr_ ); if ( ld_->info_ptr_ == NULL ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), ( png_infopp )NULL, ( png_infopp )NULL ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } ld_->end_info_ = png_create_info_struct( ld_->png_ptr_ ); if ( ld_->end_info_ == NULL ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), ( png_infopp )NULL ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } if (setjmp(png_jmpbuf(ld_->png_ptr_))) { // If we get here, we had a problem writing the file fclose(fp); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } png_set_palette_to_rgb(ld_->png_ptr_); png_init_io( ld_->png_ptr_, fp ); png_set_sig_bytes( ld_->png_ptr_, 8 ); // flags force one byte per channel output byte_orderer bo; int png_transforms = PNG_TRANSFORM_PACKING; if (bo.host_is_little_endian()) png_transforms |= PNG_TRANSFORM_SWAP_ENDIAN; png_read_png( ld_->png_ptr_, ld_->info_ptr_, png_transforms, NULL ); height_ = png_get_image_height( ld_->png_ptr_, ld_->info_ptr_ ); width_ = png_get_image_width( ld_->png_ptr_, ld_->info_ptr_ ); bit_depth_ = png_get_bit_depth( ld_->png_ptr_, ld_->info_ptr_ ); color_type_ = png_get_color_type( ld_->png_ptr_, ld_-> info_ptr_ ); if (color_type_ != PNG_COLOR_TYPE_GRAY && color_type_ != PNG_COLOR_TYPE_RGB && color_type_ != PNG_COLOR_TYPE_RGB_ALPHA ) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) ); throw image_load_error(std::string("png_loader: unsupported color type in file ") + filename); } if (bit_depth_ != 8 && bit_depth_ != 16) { fclose( fp ); png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) ); throw image_load_error("png_loader: unsupported bit depth of " + cast_to_string(bit_depth_) + " in file " + std::string(filename)); } ld_->row_pointers_ = png_get_rows( ld_->png_ptr_, ld_->info_ptr_ ); fclose( fp ); if ( ld_->row_pointers_ == NULL ) { png_destroy_read_struct( &( ld_->png_ptr_ ), &( ld_->info_ptr_ ), &( ld_->end_info_ ) ); throw image_load_error(std::string("png_loader: parse error in file ") + filename); } }