If a warning (such as "Premature end of JPEG file") is triggered in the underlying libjpeg API, make sure that the TurboJPEG API function returns -1. Unlike errors, however, libjpeg warnings do not make the TurboJPEG functions abort.

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.4.x@1561 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC
2015-06-01 19:22:41 +00:00
parent bec45b162b
commit 1f79c7c8c8
2 changed files with 34 additions and 4 deletions

View File

@@ -47,6 +47,12 @@ used.
shared libraries. This is accomplished by adding either -DENABLE_STATIC=0 or shared libraries. This is accomplished by adding either -DENABLE_STATIC=0 or
-DENABLE_SHARED=0 to the CMake command line. -DENABLE_SHARED=0 to the CMake command line.
[9] TurboJPEG API functions will now return an error code if a warning is
triggered in the underlying libjpeg API. For instance, if a JPEG file is
corrupt, the TurboJPEG decompression functions will attempt to decompress
as much of the image as possible, but those functions will now return -1 to
indicate that the decompression was not entirely successful.
1.4.0 1.4.0
===== =====

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2009-2014 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2015 D. R. Commander. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -58,6 +58,8 @@ struct my_error_mgr
{ {
struct jpeg_error_mgr pub; struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer; jmp_buf setjmp_buffer;
void (*emit_message)(j_common_ptr, int);
boolean warning;
}; };
typedef struct my_error_mgr *my_error_ptr; typedef struct my_error_mgr *my_error_ptr;
@@ -75,6 +77,13 @@ static void my_output_message(j_common_ptr cinfo)
(*cinfo->err->format_message)(cinfo, errStr); (*cinfo->err->format_message)(cinfo, errStr);
} }
static void my_emit_message(j_common_ptr cinfo, int msg_level)
{
my_error_ptr myerr=(my_error_ptr)cinfo->err;
myerr->emit_message(cinfo, msg_level);
if(msg_level<0) myerr->warning=TRUE;
}
/* Global structures, macros, etc. */ /* Global structures, macros, etc. */
@@ -122,17 +131,20 @@ static const tjscalingfactor sf[NUMSF]={
j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \
if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \
return -1;} \ return -1;} \
cinfo=&this->cinfo; dinfo=&this->dinfo; cinfo=&this->cinfo; dinfo=&this->dinfo; \
this->jerr.warning=FALSE;
#define getcinstance(handle) tjinstance *this=(tjinstance *)handle; \ #define getcinstance(handle) tjinstance *this=(tjinstance *)handle; \
j_compress_ptr cinfo=NULL; \ j_compress_ptr cinfo=NULL; \
if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \
return -1;} \ return -1;} \
cinfo=&this->cinfo; cinfo=&this->cinfo; \
this->jerr.warning=FALSE;
#define getdinstance(handle) tjinstance *this=(tjinstance *)handle; \ #define getdinstance(handle) tjinstance *this=(tjinstance *)handle; \
j_decompress_ptr dinfo=NULL; \ j_decompress_ptr dinfo=NULL; \
if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \
return -1;} \ return -1;} \
dinfo=&this->dinfo; dinfo=&this->dinfo; \
this->jerr.warning=FALSE;
static int getPixelFormat(int pixelSize, int flags) static int getPixelFormat(int pixelSize, int flags)
{ {
@@ -550,6 +562,8 @@ static tjhandle _tjInitCompress(tjinstance *this)
this->cinfo.err=jpeg_std_error(&this->jerr.pub); this->cinfo.err=jpeg_std_error(&this->jerr.pub);
this->jerr.pub.error_exit=my_error_exit; this->jerr.pub.error_exit=my_error_exit;
this->jerr.pub.output_message=my_output_message; this->jerr.pub.output_message=my_output_message;
this->jerr.emit_message=this->jerr.pub.emit_message;
this->jerr.pub.emit_message=my_emit_message;
if(setjmp(this->jerr.setjmp_buffer)) if(setjmp(this->jerr.setjmp_buffer))
{ {
@@ -787,6 +801,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
if(rgbBuf) free(rgbBuf); if(rgbBuf) free(rgbBuf);
#endif #endif
if(row_pointer) free(row_pointer); if(row_pointer) free(row_pointer);
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -969,6 +984,7 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, unsigned char *srcBuf,
if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]);
if(outbuf[i]!=NULL) free(outbuf[i]); if(outbuf[i]!=NULL) free(outbuf[i]);
} }
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -1152,6 +1168,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle,
if(inbuf[i]) free(inbuf[i]); if(inbuf[i]) free(inbuf[i]);
} }
if(_tmpbuf) free(_tmpbuf); if(_tmpbuf) free(_tmpbuf);
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -1202,6 +1219,8 @@ static tjhandle _tjInitDecompress(tjinstance *this)
this->dinfo.err=jpeg_std_error(&this->jerr.pub); this->dinfo.err=jpeg_std_error(&this->jerr.pub);
this->jerr.pub.error_exit=my_error_exit; this->jerr.pub.error_exit=my_error_exit;
this->jerr.pub.output_message=my_output_message; this->jerr.pub.output_message=my_output_message;
this->jerr.emit_message=this->jerr.pub.emit_message;
this->jerr.pub.emit_message=my_emit_message;
if(setjmp(this->jerr.setjmp_buffer)) if(setjmp(this->jerr.setjmp_buffer))
{ {
@@ -1277,6 +1296,7 @@ DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle,
_throw("tjDecompressHeader3(): Invalid data returned in header"); _throw("tjDecompressHeader3(): Invalid data returned in header");
bailout: bailout:
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -1410,6 +1430,7 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
if(rgbBuf) free(rgbBuf); if(rgbBuf) free(rgbBuf);
#endif #endif
if(row_pointer) free(row_pointer); if(row_pointer) free(row_pointer);
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -1635,6 +1656,7 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle,
if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]);
if(inbuf[i]!=NULL) free(inbuf[i]); if(inbuf[i]!=NULL) free(inbuf[i]);
} }
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -1844,6 +1866,7 @@ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle,
if(outbuf[i]) free(outbuf[i]); if(outbuf[i]) free(outbuf[i]);
} }
if(_tmpbuf) free(_tmpbuf); if(_tmpbuf) free(_tmpbuf);
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }
@@ -2085,5 +2108,6 @@ DLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf,
if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
if(xinfo) free(xinfo); if(xinfo) free(xinfo);
if(this->jerr.warning) retval=-1;
return retval; return retval;
} }