mirror of https://github.com/axmolengine/axmol.git
Merge pull request #1532 from wenbin1989/gles20
Add error handler when read image data using libjpeg.
This commit is contained in:
commit
3f3d09fabb
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue