From b9ab64d8dbee2db829e59357d335c151680f44f0 Mon Sep 17 00:00:00 2001 From: DRC Date: Thu, 11 May 2017 21:02:29 -0500 Subject: [PATCH] TurboJPEG: Thread-safe error message retrieval Introduce a new C API function (tjGetErrorStr2()) that can be used to retrieve compression/decompression/transform error messages in a thread-safe (i.e. instance-specific) manner. Retrieving error messages from global functions is still thread-unsafe. Addresses a concern expressed in #151. --- BUILDING.md | 4 +- CMakeLists.txt | 2 +- ChangeLog.md | 9 +++ doc/html/annotated.html | 2 +- doc/html/classes.html | 2 +- doc/html/functions.html | 2 +- doc/html/functions_vars.html | 2 +- doc/html/group___turbo_j_p_e_g.html | 56 ++++++++++--------- doc/html/index.html | 2 +- doc/html/modules.html | 2 +- doc/html/search/all_74.js | 2 +- doc/html/search/functions_74.js | 2 +- doc/html/structtjregion.html | 2 +- doc/html/structtjscalingfactor.html | 2 +- doc/html/structtjtransform.html | 2 +- doxygen.config | 2 +- turbojpeg-jni.c | 4 +- turbojpeg-mapfile | 6 ++ turbojpeg-mapfile.jni | 6 ++ turbojpeg.c | 87 +++++++++++++++++++---------- turbojpeg.h | 45 ++++++++------- 21 files changed, 152 insertions(+), 91 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 6894a16..c9f6468 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -138,8 +138,8 @@ Import library for the libjpeg API **libturbojpeg.a**
Static link library for the TurboJPEG API -**libturbojpeg.so.0.1.0** (Linux, Unix)
-**libturbojpeg.0.1.0.dylib** (Mac)
+**libturbojpeg.so.0.2.0** (Linux, Unix)
+**libturbojpeg.0.2.0.dylib** (Mac)
**cygturbojpeg-0.dll** (Cygwin)
Shared library for the TurboJPEG API diff --git a/CMakeLists.txt b/CMakeLists.txt index c772c01..ee83835 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,7 +286,7 @@ message(STATUS "libjpeg API shared library version = ${SO_MAJOR_VERSION}.${SO_AG # minor SO versions don't change. However, we increase the middle number (the # SO "age") whenever functions are added to the API. set(TURBOJPEG_SO_MAJOR_VERSION 0) -set(TURBOJPEG_SO_VERSION 0.1.0) +set(TURBOJPEG_SO_VERSION 0.2.0) ############################################################################### diff --git a/ChangeLog.md b/ChangeLog.md index ef74573..f96d5fc 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -40,6 +40,15 @@ embed ICC profile data in a JPEG file while compressing or transforming. This eliminates the need for downstream projects, such as color management libraries and browsers, to include their own glueware for accomplishing this. +4. Improved error handling in the TurboJPEG API library: + + - Introduced a new function (`tjGetErrorStr2()`) in the TurboJPEG C API +that allows compression/decompression/transform error messages to be retrieved +in a thread-safe manner. Retrieving error messages from global functions, such +as `tjInitCompress()` or `tjBufSize()`, is still thread-unsafe, but since those +functions will only throw errors if passed an invalid argument or if a memory +allocation failure occurs, thread safety is not as much of a concern. + 1.5.2 ===== diff --git a/doc/html/annotated.html b/doc/html/annotated.html index d0b0e1e..8172f55 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/classes.html b/doc/html/classes.html index 275e96d..bc23e51 100644 --- a/doc/html/classes.html +++ b/doc/html/classes.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/functions.html b/doc/html/functions.html index 31d78f5..570debd 100644 --- a/doc/html/functions.html +++ b/doc/html/functions.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html index 8373eac..7d45f87 100644 --- a/doc/html/functions_vars.html +++ b/doc/html/functions_vars.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index 4b8d306..fb5da8c 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
@@ -295,9 +295,9 @@ Functions DLLEXPORT void DLLCALL tjFree (unsigned char *buffer)  Free an image buffer previously allocated by TurboJPEG. More...
  -DLLEXPORT char *DLLCALL tjGetErrorStr (void) - Returns a descriptive error message explaining why the last command failed. More...
-  +DLLEXPORT char *DLLCALL tjGetErrorStr2 (tjhandle handle) + Returns a descriptive error message explaining why the last command failed. More...
+  @@ -1018,7 +1018,7 @@ If you choose option 1, *jpegSize should be set to the size of your

Variables

-
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1115,7 +1115,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1212,7 +1212,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1305,7 +1305,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1398,7 +1398,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1483,7 +1483,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1554,7 +1554,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1633,7 +1633,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1712,7 +1712,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1737,7 +1737,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1830,7 +1830,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1923,7 +1923,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
@@ -1953,21 +1953,27 @@ If you choose option 1, *jpegSize should be set to the size of your - +
- + - - + +
DLLEXPORT char* DLLCALL tjGetErrorStr DLLEXPORT char* DLLCALL tjGetErrorStr2 (void )tjhandle handle)

Returns a descriptive error message explaining why the last command failed.

+
Parameters
+ + +
handlea handle to a TurboJPEG compressor, decompressor, or transformer instance, or NULL if the error was generated by a global function (but note that retrieving the error message for a global function is not thread-safe.)
+
+
Returns
a descriptive error message explaining why the last command failed.
@@ -1993,7 +1999,7 @@ If you choose option 1, *jpegSize should be set to the size of your -
Returns
a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see tjGetErrorStr().)
+
Returns
a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see tjGetErrorStr2().)
@@ -2012,7 +2018,7 @@ If you choose option 1, *jpegSize should be set to the size of your

Create a TurboJPEG compressor instance.

-
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr().)
+
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr2().)
@@ -2031,7 +2037,7 @@ If you choose option 1, *jpegSize should be set to the size of your

Create a TurboJPEG decompressor instance.

-
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr().)
+
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr2().)
@@ -2050,7 +2056,7 @@ If you choose option 1, *jpegSize should be set to the size of your

Create a new TurboJPEG transformer instance.

-
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr().)
+
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tjGetErrorStr2().)
@@ -2279,7 +2285,7 @@ If you choose option 1, dstSizes[i] should be set to the size of yo -
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2().)
diff --git a/doc/html/index.html b/doc/html/index.html index 3cc1b3e..6b27f31 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/modules.html b/doc/html/modules.html index 8e6f815..8b38151 100644 --- a/doc/html/modules.html +++ b/doc/html/modules.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/search/all_74.js b/doc/html/search/all_74.js index 444aaef..eec0aee 100644 --- a/doc/html/search/all_74.js +++ b/doc/html/search/all_74.js @@ -32,7 +32,7 @@ var searchData= ['tjflag_5ffastupsample',['TJFLAG_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ga4ee4506c81177a06f77e2504a22efd2d',1,'turbojpeg.h']]], ['tjflag_5fnorealloc',['TJFLAG_NOREALLOC',['../group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963',1,'turbojpeg.h']]], ['tjfree',['tjFree',['../group___turbo_j_p_e_g.html#ga8c4a1231dc06a450514c835f6471f137',1,'turbojpeg.h']]], - ['tjgeterrorstr',['tjGetErrorStr',['../group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf',1,'turbojpeg.h']]], + ['tjgeterrorstr2',['tjGetErrorStr2',['../group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c',1,'turbojpeg.h']]], ['tjgetscalingfactors',['tjGetScalingFactors',['../group___turbo_j_p_e_g.html#ga6449044b9af402999ccf52f401333be8',1,'turbojpeg.h']]], ['tjgreenoffset',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]], ['tjhandle',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]], diff --git a/doc/html/search/functions_74.js b/doc/html/search/functions_74.js index 69410b0..f284a2c 100644 --- a/doc/html/search/functions_74.js +++ b/doc/html/search/functions_74.js @@ -16,7 +16,7 @@ var searchData= ['tjencodeyuv3',['tjEncodeYUV3',['../group___turbo_j_p_e_g.html#gaabe05acd734990053ad1294b5ef239aa',1,'turbojpeg.h']]], ['tjencodeyuvplanes',['tjEncodeYUVPlanes',['../group___turbo_j_p_e_g.html#ga8a65ed3bd12df57c219d46afbc9008f1',1,'turbojpeg.h']]], ['tjfree',['tjFree',['../group___turbo_j_p_e_g.html#ga8c4a1231dc06a450514c835f6471f137',1,'turbojpeg.h']]], - ['tjgeterrorstr',['tjGetErrorStr',['../group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf',1,'turbojpeg.h']]], + ['tjgeterrorstr2',['tjGetErrorStr2',['../group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c',1,'turbojpeg.h']]], ['tjgetscalingfactors',['tjGetScalingFactors',['../group___turbo_j_p_e_g.html#ga6449044b9af402999ccf52f401333be8',1,'turbojpeg.h']]], ['tjinitcompress',['tjInitCompress',['../group___turbo_j_p_e_g.html#ga3d10c47fbe4a2489a2b30c931551d01a',1,'turbojpeg.h']]], ['tjinitdecompress',['tjInitDecompress',['../group___turbo_j_p_e_g.html#gae5408179d041e2a2f7199c8283cf649e',1,'turbojpeg.h']]], diff --git a/doc/html/structtjregion.html b/doc/html/structtjregion.html index af2a473..36c0afa 100644 --- a/doc/html/structtjregion.html +++ b/doc/html/structtjregion.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/structtjscalingfactor.html b/doc/html/structtjscalingfactor.html index 3bb50f5..2f54900 100644 --- a/doc/html/structtjscalingfactor.html +++ b/doc/html/structtjscalingfactor.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doc/html/structtjtransform.html b/doc/html/structtjtransform.html index 9fd97f7..d9536a3 100644 --- a/doc/html/structtjtransform.html +++ b/doc/html/structtjtransform.html @@ -24,7 +24,7 @@
TurboJPEG -  1.5 +  1.6
diff --git a/doxygen.config b/doxygen.config index 1723123..2f2ab66 100644 --- a/doxygen.config +++ b/doxygen.config @@ -1,5 +1,5 @@ PROJECT_NAME = TurboJPEG -PROJECT_NUMBER = 1.5 +PROJECT_NUMBER = 1.6 OUTPUT_DIRECTORY = doc/ USE_WINDOWS_ENCODING = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c index eaba670..b53a8b9 100644 --- a/turbojpeg-jni.c +++ b/turbojpeg-jni.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2016 D. R. Commander. All Rights Reserved. + * Copyright (C)2011-2017 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: @@ -46,7 +46,7 @@ goto bailout; \ } -#define _throwtj() _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException") +#define _throwtj() _throw(tjGetErrorStr2(handle), "org/libjpegturbo/turbojpeg/TJException") #define _throwarg(msg) _throw(msg, "java/lang/IllegalArgumentException") diff --git a/turbojpeg-mapfile b/turbojpeg-mapfile index 35d55ae..8c389aa 100755 --- a/turbojpeg-mapfile +++ b/turbojpeg-mapfile @@ -54,3 +54,9 @@ TURBOJPEG_1.4 tjPlaneSizeYUV; tjPlaneWidth; } TURBOJPEG_1.2; + +TURBOJPEG_1.6 +{ + global: + tjGetErrorStr2; +} TURBOJPEG_1.4; diff --git a/turbojpeg-mapfile.jni b/turbojpeg-mapfile.jni index 9c1d25b..7aa0144 100755 --- a/turbojpeg-mapfile.jni +++ b/turbojpeg-mapfile.jni @@ -90,3 +90,9 @@ TURBOJPEG_1.4 Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII; Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III; } TURBOJPEG_1.3; + +TURBOJPEG_1.6 +{ + global: + tjGetErrorStr2; +} TURBOJPEG_1.4; diff --git a/turbojpeg.c b/turbojpeg.c index f3c9922..8b77100 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -96,6 +96,8 @@ typedef struct _tjinstance struct jpeg_decompress_struct dinfo; struct my_error_mgr jerr; int init, headerRead; + char errStr[JMSG_LENGTH_MAX]; + boolean isInstanceError; } tjinstance; static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3, 3}; @@ -126,26 +128,31 @@ static const tjscalingfactor sf[NUMSF]={ {1, 8} }; -#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ +#define _throwg(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ retval=-1; goto bailout;} +#define _throw(m) {snprintf(this->errStr, JMSG_LENGTH_MAX, "%s", m); \ + this->isInstanceError=TRUE; _throwg(m);} #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ 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; \ - this->jerr.warning=FALSE; + this->jerr.warning=FALSE; \ + this->isInstanceError=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; \ - this->jerr.warning=FALSE; + this->jerr.warning=FALSE; \ + this->isInstanceError=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; \ - this->jerr.warning=FALSE; + this->jerr.warning=FALSE; \ + this->isInstanceError=FALSE; static int getPixelFormat(int pixelSize, int flags) { @@ -272,37 +279,36 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo, return retval; } -static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, - int pixelFormat, int flags) +static int setDecompDefaults(tjinstance *this, int pixelFormat, int flags) { int retval=0; switch(pixelFormat) { case TJPF_GRAY: - dinfo->out_color_space=JCS_GRAYSCALE; break; + this->dinfo.out_color_space=JCS_GRAYSCALE; break; #if JCS_EXTENSIONS==1 case TJPF_RGB: - dinfo->out_color_space=JCS_EXT_RGB; break; + this->dinfo.out_color_space=JCS_EXT_RGB; break; case TJPF_BGR: - dinfo->out_color_space=JCS_EXT_BGR; break; + this->dinfo.out_color_space=JCS_EXT_BGR; break; case TJPF_RGBX: - dinfo->out_color_space=JCS_EXT_RGBX; break; + this->dinfo.out_color_space=JCS_EXT_RGBX; break; case TJPF_BGRX: - dinfo->out_color_space=JCS_EXT_BGRX; break; + this->dinfo.out_color_space=JCS_EXT_BGRX; break; case TJPF_XRGB: - dinfo->out_color_space=JCS_EXT_XRGB; break; + this->dinfo.out_color_space=JCS_EXT_XRGB; break; case TJPF_XBGR: - dinfo->out_color_space=JCS_EXT_XBGR; break; + this->dinfo.out_color_space=JCS_EXT_XBGR; break; #if JCS_ALPHA_EXTENSIONS==1 case TJPF_RGBA: - dinfo->out_color_space=JCS_EXT_RGBA; break; + this->dinfo.out_color_space=JCS_EXT_RGBA; break; case TJPF_BGRA: - dinfo->out_color_space=JCS_EXT_BGRA; break; + this->dinfo.out_color_space=JCS_EXT_BGRA; break; case TJPF_ARGB: - dinfo->out_color_space=JCS_EXT_ARGB; break; + this->dinfo.out_color_space=JCS_EXT_ARGB; break; case TJPF_ABGR: - dinfo->out_color_space=JCS_EXT_ABGR; break; + this->dinfo.out_color_space=JCS_EXT_ABGR; break; #endif #else case TJPF_RGB: @@ -315,15 +321,15 @@ static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, case TJPF_BGRA: case TJPF_ARGB: case TJPF_ABGR: - dinfo->out_color_space=JCS_RGB; break; + this->dinfo.out_color_space=JCS_RGB; break; #endif case TJPF_CMYK: - dinfo->out_color_space=JCS_CMYK; break; + this->dinfo.out_color_space=JCS_CMYK; break; default: _throw("Unsupported pixel format"); } - if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; + if(flags&TJFLAG_FASTDCT) this->dinfo.dct_method=JDCT_FASTEST; bailout: return retval; @@ -542,6 +548,18 @@ static void fromRGB(unsigned char *src, unsigned char *dst, int width, /* General API functions */ +DLLEXPORT char* DLLCALL tjGetErrorStr2(tjhandle handle) +{ + tjinstance *this=(tjinstance *)handle; + if(this && this->isInstanceError) + { + this->isInstanceError=FALSE; + return this->errStr; + } + else return errStr; +} + + DLLEXPORT char* DLLCALL tjGetErrorStr(void) { return errStr; @@ -615,6 +633,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void) return NULL; } MEMZERO(this, sizeof(tjinstance)); + snprintf(this->errStr, JMSG_LENGTH_MAX, "No error"); return _tjInitCompress(this); } @@ -624,7 +643,7 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, { unsigned long retval=0; int mcuw, mcuh, chromasf; if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) - _throw("tjBufSize(): Invalid argument"); + _throwg("tjBufSize(): Invalid argument"); /* This allows for rare corner cases in which a JPEG image can actually be larger than the uncompressed input (we wouldn't mention it if it hadn't @@ -642,7 +661,7 @@ DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) { unsigned long retval=0; if(width<1 || height<1) - _throw("TJBUFSIZE(): Invalid argument"); + _throwg("TJBUFSIZE(): Invalid argument"); /* This allows for rare corner cases in which a JPEG image can actually be larger than the uncompressed input (we wouldn't mention it if it hadn't @@ -660,7 +679,7 @@ DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, int retval=0, nc, i; if(subsamp<0 || subsamp>=NUMSUBOPT) - _throw("tjBufSizeYUV2(): Invalid argument"); + _throwg("tjBufSizeYUV2(): Invalid argument"); nc=(subsamp==TJSAMP_GRAY? 1:3); for(i=0; i=TJ_NUMSAMP) - _throw("tjPlaneWidth(): Invalid argument"); + _throwg("tjPlaneWidth(): Invalid argument"); nc=(subsamp==TJSAMP_GRAY? 1:3); if(componentID<0 || componentID>=nc) - _throw("tjPlaneWidth(): Invalid argument"); + _throwg("tjPlaneWidth(): Invalid argument"); pw=PAD(width, tjMCUWidth[subsamp]/8); if(componentID==0) @@ -715,10 +734,10 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) int ph, nc, retval=0; if(height<1 || subsamp<0 || subsamp>=TJ_NUMSAMP) - _throw("tjPlaneHeight(): Invalid argument"); + _throwg("tjPlaneHeight(): Invalid argument"); nc=(subsamp==TJSAMP_GRAY? 1:3); if(componentID<0 || componentID>=nc) - _throw("tjPlaneHeight(): Invalid argument"); + _throwg("tjPlaneHeight(): Invalid argument"); ph=PAD(height, tjMCUHeight[subsamp]/8); if(componentID==0) @@ -738,7 +757,7 @@ DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, int pw, ph; if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) - _throw("tjPlaneSizeYUV(): Invalid argument"); + _throwg("tjPlaneSizeYUV(): Invalid argument"); pw=tjPlaneWidth(componentID, width, subsamp); ph=tjPlaneHeight(componentID, height, subsamp); @@ -1032,6 +1051,8 @@ DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, unsigned char *dstPlanes[3]; int pw0, ph0, strides[3], retval=-1; + getcinstance(handle); + if(width<=0 || height<=0 || dstBuf==NULL || pad<0 || !isPow2(pad) || subsamp<0 || subsamp>=NUMSUBOPT) _throw("tjEncodeYUV3(): Invalid argument"); @@ -1224,6 +1245,8 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, const unsigned char *srcPlanes[3]; int pw0, ph0, strides[3], retval=-1; + getcinstance(handle); + if(srcBuf==NULL || width<=0 || pad<1 || height<=0 || subsamp<0 || subsamp>=NUMSUBOPT) _throw("tjCompressFromYUV(): Invalid argument"); @@ -1292,6 +1315,7 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void) return NULL; } MEMZERO(this, sizeof(tjinstance)); + snprintf(this->errStr, JMSG_LENGTH_MAX, "No error"); return _tjInitDecompress(this); } @@ -1410,7 +1434,7 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); jpeg_read_header(dinfo, TRUE); - if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) + if(setDecompDefaults(this, pixelFormat, flags)==-1) { retval=-1; goto bailout; } @@ -1616,7 +1640,7 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, dinfo->marker->read_markers=old_read_markers; dinfo->marker->reset_marker_reader=old_reset_marker_reader; - if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) + if(setDecompDefaults(this, pixelFormat, flags)==-1) { retval=-1; goto bailout; } @@ -1728,6 +1752,8 @@ DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, const unsigned char *srcPlanes[3]; int pw0, ph0, strides[3], retval=-1; + getdinstance(handle); + if(srcBuf==NULL || pad<0 || !isPow2(pad) || subsamp<0 || subsamp>=NUMSUBOPT || width<=0 || height<=0) _throw("tjDecodeYUV(): Invalid argument"); @@ -2025,6 +2051,7 @@ DLLEXPORT tjhandle DLLCALL tjInitTransform(void) return NULL; } MEMZERO(this, sizeof(tjinstance)); + snprintf(this->errStr, JMSG_LENGTH_MAX, "No error"); handle=_tjInitCompress(this); if(!handle) return NULL; handle=_tjInitDecompress(this); diff --git a/turbojpeg.h b/turbojpeg.h index 583029f..7475fb3 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2015 D. R. Commander. All Rights Reserved. + * Copyright (C)2009-2015, 2017 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: @@ -608,7 +608,7 @@ extern "C" { * Create a TurboJPEG compressor instance. * * @return a handle to the newly-created instance, or NULL if an error - * occurred (see #tjGetErrorStr().) + * occurred (see #tjGetErrorStr2().) */ DLLEXPORT tjhandle DLLCALL tjInitCompress(void); @@ -670,7 +670,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void); * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, @@ -734,7 +734,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, const unsigned char *srcBuf, int width, int pad, int height, int subsamp, @@ -804,7 +804,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, const unsigned char **srcPlanes, int width, const int *strides, int height, @@ -964,7 +964,7 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp); * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, @@ -1022,7 +1022,7 @@ DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, @@ -1034,7 +1034,7 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, * Create a TurboJPEG decompressor instance. * * @return a handle to the newly-created instance, or NULL if an error - * occurred (see #tjGetErrorStr().) + * occurred (see #tjGetErrorStr2().) */ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); @@ -1062,7 +1062,7 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); * of the JPEG colorspace constants, indicating the colorspace of the JPEG * image (see @ref TJCS "JPEG colorspaces".) * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int *width, @@ -1077,7 +1077,7 @@ DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, * the number of elements in the list * * @return a pointer to a list of fractional scaling factors, or NULL if an - * error is encountered (see #tjGetErrorStr().) + * error is encountered (see #tjGetErrorStr2().) */ DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors); @@ -1129,7 +1129,7 @@ DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors); * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, @@ -1179,7 +1179,7 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, @@ -1235,7 +1235,7 @@ DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, @@ -1287,7 +1287,7 @@ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, @@ -1344,7 +1344,7 @@ DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, const unsigned char **srcPlanes, const int *strides, int subsamp, @@ -1356,7 +1356,7 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, * Create a new TurboJPEG transformer instance. * * @return a handle to the newly-created instance, or NULL if an error - * occurred (see #tjGetErrorStr().) + * occurred (see #tjGetErrorStr2().) */ DLLEXPORT tjhandle DLLCALL tjInitTransform(void); @@ -1414,7 +1414,7 @@ DLLEXPORT tjhandle DLLCALL tjInitTransform(void); * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP * "flags" * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjTransform(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, @@ -1428,7 +1428,7 @@ DLLEXPORT int DLLCALL tjTransform(tjhandle handle, * @param handle a handle to a TurboJPEG compressor, decompressor or * transformer instance * - * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2().) */ DLLEXPORT int DLLCALL tjDestroy(tjhandle handle); @@ -1465,9 +1465,14 @@ DLLEXPORT void DLLCALL tjFree(unsigned char *buffer); /** * Returns a descriptive error message explaining why the last command failed. * + * @param handle a handle to a TurboJPEG compressor, decompressor, or + * transformer instance, or NULL if the error was generated by a global + * function (but note that retrieving the error message for a global function + * is not thread-safe.) + * * @return a descriptive error message explaining why the last command failed. */ -DLLEXPORT char* DLLCALL tjGetErrorStr(void); +DLLEXPORT char* DLLCALL tjGetErrorStr2(tjhandle handle); /* Deprecated functions and macros */ @@ -1530,6 +1535,8 @@ DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int flags); +DLLEXPORT char* DLLCALL tjGetErrorStr(void); + /** * @} -- 2.50.1