I have some code that uses libjpeg to decode jpeg images in memory, but it crashes sometimes when the input data is bad. I'm not particularly familiar with libjpeg - I just slightly modified some cut&paste code. :) So I'm wondering how I can get it to report and error or something instead of crashing, so that I can just skip the bad image and move on to the next one...
Here's my code:
I have one of these std::vector<unsigned char> m_jpegBuffer;
and this method:
const IplImage* JpegImageSerializer::getImage()
{
int offset, row_stride;
JSAMPROW rowptr[1];
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
memset(&cinfo, 0, sizeof(cinfo));
memset(&jerr, 0, sizeof(jerr));
// Initialize the JPEG decompression object with default error handling
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
#ifdef NEED_SIGNAL_CATCHER
enable_signal_catcher((j_common_ptr) &cinfo); // Now safe to enable signal catcher
#endif
jpeg_mem_src(&cinfo, &this->m_jpegBuffer[0], this->m_jpegBuffer.size()); // Specify data source for decompression
jpeg_read_header(&cinfo, TRUE); // Read file header, set default decompression parameters
jpeg_start_decompress(&cinfo); // Start decompressor
IplImage* pImage = cvCreateImage(cvSize(cinfo.image_width, cinfo.image_height),
IPL_DEPTH_8U, 3);
// Process data
offset = 0;
row_stride = cinfo.image_width * 3;
while(cinfo.output_scanline < cinfo.output_height)
{
rowptr[0] = (JSAMPROW) &pImage->imageData[offset * row_stride];
jpeg_read_scanlines(&cinfo, rowptr, 1);
++offset;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return pImage;
}
Here are some examples of the output when it crashes. These log messages are not from my code - libjpeg itself must be printing these.
Premature end of JPEG file
Premature end of JPEG file
Corrupt JPEG data: premature end of data segment
Unsupported marker type 0xaf
Premature end of JPEG file
Premature end of JPEG file
Premature end of JPEG file
Premature end of JPEG file
Premature end of JPEG file
Corrupt JPEG data: premature end of data segment
Invalid JPEG file structure: two SOI markers
Note that the Premature end of JPEG file
does not appear to cause a crash - I just get a resulting image that has a little artifact in the lower right corner... which is fine for what I'm doing. The last two lines, however, appear to occur only just before a crash.
By defaut libjpeg error handler exits the program (see
jerror.c
error_exit
function). The documentation indicates that:The library contains a sample code that explains how to do that: see
example.c
and please refer to theERROR HANDLING
section:Then refer to the
my_error_exit
function:The main decompression function (
GLOBAL(int) read_JPEG_file (char * filename)
) includes the code section that gets called when a fatal error occurs:So you need to override the default error handler in a similar fashion.