From: DRC Date: Mon, 1 Jun 2015 19:22:41 +0000 (+0000) Subject: If a warning (such as "Premature end of JPEG file") is triggered in the underlying... X-Git-Tag: 1.4.1~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1f79c7c8c8c5e993042ea816e1dd161fb69061a3;p=libjpeg-turbo 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 --- diff --git a/ChangeLog.txt b/ChangeLog.txt index 2cd7c92..e545606 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -47,6 +47,12 @@ used. shared libraries. This is accomplished by adding either -DENABLE_STATIC=0 or -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 ===== diff --git a/turbojpeg.c b/turbojpeg.c index e8b156a..ec03aff 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -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 * modification, are permitted provided that the following conditions are met: @@ -58,6 +58,8 @@ struct my_error_mgr { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; + void (*emit_message)(j_common_ptr, int); + boolean warning; }; 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); } +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. */ @@ -122,17 +131,20 @@ static const tjscalingfactor sf[NUMSF]={ j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ 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; \ j_compress_ptr cinfo=NULL; \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ return -1;} \ - cinfo=&this->cinfo; + cinfo=&this->cinfo; \ + this->jerr.warning=FALSE; #define getdinstance(handle) tjinstance *this=(tjinstance *)handle; \ j_decompress_ptr dinfo=NULL; \ if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ return -1;} \ - dinfo=&this->dinfo; + dinfo=&this->dinfo; \ + this->jerr.warning=FALSE; 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->jerr.pub.error_exit=my_error_exit; 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)) { @@ -787,6 +801,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, if(rgbBuf) free(rgbBuf); #endif if(row_pointer) free(row_pointer); + if(this->jerr.warning) retval=-1; return retval; } @@ -969,6 +984,7 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, unsigned char *srcBuf, if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); if(outbuf[i]!=NULL) free(outbuf[i]); } + if(this->jerr.warning) retval=-1; return retval; } @@ -1152,6 +1168,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, if(inbuf[i]) free(inbuf[i]); } if(_tmpbuf) free(_tmpbuf); + if(this->jerr.warning) retval=-1; return retval; } @@ -1202,6 +1219,8 @@ static tjhandle _tjInitDecompress(tjinstance *this) this->dinfo.err=jpeg_std_error(&this->jerr.pub); this->jerr.pub.error_exit=my_error_exit; 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)) { @@ -1277,6 +1296,7 @@ DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, _throw("tjDecompressHeader3(): Invalid data returned in header"); bailout: + if(this->jerr.warning) retval=-1; return retval; } @@ -1410,6 +1430,7 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, if(rgbBuf) free(rgbBuf); #endif if(row_pointer) free(row_pointer); + if(this->jerr.warning) retval=-1; return retval; } @@ -1635,6 +1656,7 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); if(inbuf[i]!=NULL) free(inbuf[i]); } + if(this->jerr.warning) retval=-1; return retval; } @@ -1844,6 +1866,7 @@ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, if(outbuf[i]) free(outbuf[i]); } if(_tmpbuf) free(_tmpbuf); + if(this->jerr.warning) retval=-1; 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(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); if(xinfo) free(xinfo); + if(this->jerr.warning) retval=-1; return retval; }