Merge pull request #1532 from wenbin1989/gles20

Add error handler when read image data using libjpeg.
This commit is contained in:
minggo 2012-11-06 20:10:21 -08:00
commit 3f3d09fabb
1 changed files with 76 additions and 8 deletions

View File

@ -197,11 +197,64 @@ bool CCImage::initWithImageData(void * pData,
return bRet;
}
/*
* ERROR HANDLING:
*
* The JPEG library's standard error handler (jerror.c) is divided into
* several "methods" which you can override individually. This lets you
* adjust the behavior without duplicating a lot of code, which you might
* have to update with each future release.
*
* We override the "error_exit" method so that control is returned to the
* library's caller when a fatal error occurs, rather than calling exit()
* as the standard error_exit method does.
*
* We use C's setjmp/longjmp facility to return control. This means that the
* routine which calls the JPEG library must first execute a setjmp() call to
* establish the return point. We want the replacement error_exit to do a
* longjmp(). But we need to make the setjmp buffer accessible to the
* error_exit routine. To do this, we make a private extension of the
* standard JPEG error handler object. (If we were using C++, we'd say we
* were making a subclass of the regular error handler.)
*
* Here's the extended error handler struct:
*/
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
/*
* Here's the routine that will replace the standard error_exit method:
*/
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
bool CCImage::_initWithJpgData(void * data, int nSize)
{
/* these are standard libjpeg structures for reading(decompression) */
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
/* libjpeg data structure for storing one row, that is, scanline of an image */
JSAMPROW row_pointer[1] = {0};
unsigned long location = 0;
@ -210,8 +263,18 @@ bool CCImage::_initWithJpgData(void * data, int nSize)
bool bRet = false;
do
{
/* here we set up the standard libjpeg error handler */
cinfo.err = jpeg_std_error( &jerr );
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_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.
*/
CCLog("%d", bRet);
jpeg_destroy_decompress(&cinfo);
break;
}
/* setup decompression process and source, then read JPEG header */
jpeg_create_decompress( &cinfo );
@ -238,8 +301,8 @@ bool CCImage::_initWithJpgData(void * data, int nSize)
jpeg_start_decompress( &cinfo );
/* init image info */
m_nWidth = (short)(cinfo.image_width);
m_nHeight = (short)(cinfo.image_height);
m_nWidth = (short)(cinfo.output_width);
m_nHeight = (short)(cinfo.output_height);
m_bHasAlpha = false;
m_bPreMulti = false;
m_nBitsPerComponent = 8;
@ -251,16 +314,21 @@ bool CCImage::_initWithJpgData(void * data, int nSize)
/* now actually read the jpeg into the raw buffer */
/* read one scan line at a time */
while( cinfo.output_scanline < cinfo.image_height )
while( cinfo.output_scanline < cinfo.output_height )
{
jpeg_read_scanlines( &cinfo, row_pointer, 1 );
for( i=0; i<cinfo.image_width*cinfo.output_components;i++)
for( i=0; i<cinfo.output_width*cinfo.output_components;i++)
{
m_pData[location++] = row_pointer[0][i];
}
}
jpeg_finish_decompress( &cinfo );
/* When read image file with broken data, jpeg_finish_decompress() may cause error.
* Besides, jpeg_destroy_decompress() shall deallocate and release all memory associated
* with the decompression object.
* So it doesn't need to call jpeg_finish_decompress().
*/
//jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
/* wrap up decompression, destroy objects, free pointers and close open files */
bRet = true;