refactor jpeg reader to close fd after read - refs #1783
This commit is contained in:
parent
6e29ceb55f
commit
16e2e8a06f
1 changed files with 47 additions and 22 deletions
|
@ -42,22 +42,34 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
class jpeg_reader : public image_reader
|
class jpeg_reader : public image_reader
|
||||||
{
|
{
|
||||||
struct file_closer
|
struct jpeg_file_guard
|
||||||
{
|
{
|
||||||
void operator() (FILE * file)
|
jpeg_file_guard(FILE * fd)
|
||||||
{
|
: fd_(fd) {}
|
||||||
if (file != 0) fclose(file);
|
|
||||||
}
|
~jpeg_file_guard()
|
||||||
|
{
|
||||||
|
if (fd_) fclose(fd_);
|
||||||
|
}
|
||||||
|
FILE * fd_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jpeg_info_guard
|
||||||
|
{
|
||||||
|
jpeg_info_guard(jpeg_decompress_struct * cinfo)
|
||||||
|
: i_(cinfo) {}
|
||||||
|
|
||||||
|
~jpeg_info_guard()
|
||||||
|
{
|
||||||
|
jpeg_destroy_decompress(i_);
|
||||||
|
}
|
||||||
|
jpeg_decompress_struct * i_;
|
||||||
};
|
};
|
||||||
typedef boost::shared_ptr<FILE> file_ptr;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string file_name_;
|
std::string file_name_;
|
||||||
unsigned width_;
|
unsigned width_;
|
||||||
unsigned height_;
|
unsigned height_;
|
||||||
jpeg_decompress_struct cinfo;
|
|
||||||
jpeg_error_mgr jerr;
|
|
||||||
file_ptr file_;
|
|
||||||
public:
|
public:
|
||||||
explicit jpeg_reader(std::string const& fileName);
|
explicit jpeg_reader(std::string const& fileName);
|
||||||
~jpeg_reader();
|
~jpeg_reader();
|
||||||
|
@ -83,21 +95,17 @@ const bool registered = register_image_reader("jpeg",create_jpeg_reader);
|
||||||
jpeg_reader::jpeg_reader(std::string const& fileName)
|
jpeg_reader::jpeg_reader(std::string const& fileName)
|
||||||
: file_name_(fileName),
|
: file_name_(fileName),
|
||||||
width_(0),
|
width_(0),
|
||||||
height_(0),
|
height_(0)
|
||||||
file_()
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
jpeg_reader::~jpeg_reader()
|
jpeg_reader::~jpeg_reader() {}
|
||||||
{
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void jpeg_reader::on_error(j_common_ptr cinfo)
|
void jpeg_reader::on_error(j_common_ptr cinfo)
|
||||||
{
|
{
|
||||||
(*cinfo->err->output_message)(cinfo);
|
//(*cinfo->err->output_message)(cinfo);
|
||||||
jpeg_destroy(cinfo);
|
//jpeg_destroy(cinfo);
|
||||||
throw image_reader_exception("JPEG Reader: libjpeg could not read image");
|
throw image_reader_exception("JPEG Reader: libjpeg could not read image");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,13 +118,17 @@ void jpeg_reader::init()
|
||||||
{
|
{
|
||||||
FILE * fp = fopen(file_name_.c_str(),"rb");
|
FILE * fp = fopen(file_name_.c_str(),"rb");
|
||||||
if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + file_name_);
|
if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + file_name_);
|
||||||
file_ = boost::shared_ptr<FILE>(fp,file_closer());
|
jpeg_file_guard guard(fp);
|
||||||
|
jpeg_decompress_struct cinfo;
|
||||||
|
jpeg_info_guard iguard(&cinfo);
|
||||||
|
jpeg_error_mgr jerr;
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
jerr.error_exit = on_error;
|
jerr.error_exit = on_error;
|
||||||
jerr.output_message = on_error_message;
|
jerr.output_message = on_error_message;
|
||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress(&cinfo);
|
||||||
jpeg_stdio_src(&cinfo, &*file_);
|
jpeg_stdio_src(&cinfo, fp);
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
int ret = jpeg_read_header(&cinfo, TRUE);
|
||||||
|
if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader: failed to read header in " + file_name_);
|
||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
width_ = cinfo.output_width;
|
width_ = cinfo.output_width;
|
||||||
height_ = cinfo.output_height;
|
height_ = cinfo.output_height;
|
||||||
|
@ -127,7 +139,6 @@ void jpeg_reader::init()
|
||||||
}
|
}
|
||||||
if (cinfo.output_width == 0 || cinfo.output_height == 0)
|
if (cinfo.output_width == 0 || cinfo.output_height == 0)
|
||||||
{
|
{
|
||||||
jpeg_destroy_decompress (&cinfo);
|
|
||||||
throw image_reader_exception("JPEG Reader: failed to read image size of " + file_name_);
|
throw image_reader_exception("JPEG Reader: failed to read image size of " + file_name_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +155,20 @@ unsigned jpeg_reader::height() const
|
||||||
|
|
||||||
void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image)
|
void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image)
|
||||||
{
|
{
|
||||||
|
FILE * fp = fopen(file_name_.c_str(),"rb");
|
||||||
|
if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + file_name_);
|
||||||
|
jpeg_file_guard guard(fp);
|
||||||
|
jpeg_decompress_struct cinfo;
|
||||||
|
jpeg_info_guard iguard(&cinfo);
|
||||||
|
jpeg_error_mgr jerr;
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
jerr.error_exit = on_error;
|
||||||
|
jerr.output_message = on_error_message;
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
jpeg_stdio_src(&cinfo, fp);
|
||||||
|
int ret = jpeg_read_header(&cinfo, TRUE);
|
||||||
|
if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader: failed to read header in " + file_name_);
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
JSAMPARRAY buffer;
|
JSAMPARRAY buffer;
|
||||||
int row_stride;
|
int row_stride;
|
||||||
unsigned char a,r,g,b;
|
unsigned char a,r,g,b;
|
||||||
|
@ -179,7 +204,7 @@ void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image)
|
||||||
}
|
}
|
||||||
++row;
|
++row;
|
||||||
}
|
}
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue