]> granicus.if.org Git - libjpeg-turbo/commitdiff
TurboJPEG: Thread-safe error message retrieval
authorDRC <information@libjpeg-turbo.org>
Fri, 12 May 2017 02:02:29 +0000 (21:02 -0500)
committerDRC <information@libjpeg-turbo.org>
Tue, 27 Jun 2017 15:58:36 +0000 (10:58 -0500)
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.

21 files changed:
BUILDING.md
CMakeLists.txt
ChangeLog.md
doc/html/annotated.html
doc/html/classes.html
doc/html/functions.html
doc/html/functions_vars.html
doc/html/group___turbo_j_p_e_g.html
doc/html/index.html
doc/html/modules.html
doc/html/search/all_74.js
doc/html/search/functions_74.js
doc/html/structtjregion.html
doc/html/structtjscalingfactor.html
doc/html/structtjtransform.html
doxygen.config
turbojpeg-jni.c
turbojpeg-mapfile
turbojpeg-mapfile.jni
turbojpeg.c
turbojpeg.h

index 6894a16211e8a007cf2fa16d6ffffea4bb8ec0bd..c9f646847f24e3249fd2c68e406d8f0864b304e5 100644 (file)
@@ -138,8 +138,8 @@ Import library for the libjpeg API
 **libturbojpeg.a**<br>
 Static link library for the TurboJPEG API
 
-**libturbojpeg.so.0.1.0** (Linux, Unix)<br>
-**libturbojpeg.0.1.0.dylib** (Mac)<br>
+**libturbojpeg.so.0.2.0** (Linux, Unix)<br>
+**libturbojpeg.0.2.0.dylib** (Mac)<br>
 **cygturbojpeg-0.dll** (Cygwin)<br>
 Shared library for the TurboJPEG API
 
index c772c01da59011673075af4b5d38f2a7fdd5ba78..ee838358992603ef1b5db898cdd824c5dc5b64ad 100644 (file)
@@ -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)
 
 
 ###############################################################################
index ef7457390d9289936cacaec223843056f3aa275b..f96d5fc7ae3cd9be3f9b70b6836cce7ffb0e47d3 100644 (file)
@@ -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
 =====
index d0b0e1eb176b3b4182d3560e9a36bebf27f68580..8172f55f13895ca0609f0ce5728ca827f5ccead2 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 275e96d6f30e6ae1b3ca1bda0d9aed351c0537e0..bc23e5175bbdfb28b9420ade9d7a9f5d0cd94453 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 31d78f567ca8e23b4fc0af156b3ac61d617bf5bb..570debd666d3c02c78fd83ad28b706d56fa28a0d 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 8373eace853ac7072e9c6c8965b5fb664a6165a4..7d45f87c15925ba0d72dfe26db43ea98f9d918f0 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 4b8d306e216e24d0f1de7e0525ce66241a3c39ee..fb5da8ca39569686bc4187d72d8a9867f166ce35 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
@@ -295,9 +295,9 @@ Functions</h2></td></tr>
 <tr class="memitem:ga8c4a1231dc06a450514c835f6471f137"><td class="memItemLeft" align="right" valign="top">DLLEXPORT void DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga8c4a1231dc06a450514c835f6471f137">tjFree</a> (unsigned char *buffer)</td></tr>
 <tr class="memdesc:ga8c4a1231dc06a450514c835f6471f137"><td class="mdescLeft">&#160;</td><td class="mdescRight">Free an image buffer previously allocated by TurboJPEG.  <a href="#ga8c4a1231dc06a450514c835f6471f137">More...</a><br/></td></tr>
 <tr class="separator:ga8c4a1231dc06a450514c835f6471f137"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga9af79c908ec131b1ae8d52fe40375abf"><td class="memItemLeft" align="right" valign="top">DLLEXPORT char *DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf">tjGetErrorStr</a> (void)</td></tr>
-<tr class="memdesc:ga9af79c908ec131b1ae8d52fe40375abf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a descriptive error message explaining why the last command failed.  <a href="#ga9af79c908ec131b1ae8d52fe40375abf">More...</a><br/></td></tr>
-<tr class="separator:ga9af79c908ec131b1ae8d52fe40375abf"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ga94a235bd4f1088f61ad87b4eadb64c9c"><td class="memItemLeft" align="right" valign="top">DLLEXPORT char *DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c">tjGetErrorStr2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle)</td></tr>
+<tr class="memdesc:ga94a235bd4f1088f61ad87b4eadb64c9c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a descriptive error message explaining why the last command failed.  <a href="#ga94a235bd4f1088f61ad87b4eadb64c9c">More...</a><br/></td></tr>
+<tr class="separator:ga94a235bd4f1088f61ad87b4eadb64c9c"><td class="memSeparator" colspan="2">&#160;</td></tr>
 </table><table class="memberdecls">
 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="var-members"></a>
 Variables</h2></td></tr>
@@ -1018,7 +1018,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1115,7 +1115,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1212,7 +1212,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1305,7 +1305,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1398,7 +1398,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1483,7 +1483,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1554,7 +1554,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1633,7 +1633,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1712,7 +1712,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1737,7 +1737,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1830,7 +1830,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1923,7 +1923,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -1953,21 +1953,27 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
 
 </div>
 </div>
-<a class="anchor" id="ga9af79c908ec131b1ae8d52fe40375abf"></a>
+<a class="anchor" id="ga94a235bd4f1088f61ad87b4eadb64c9c"></a>
 <div class="memitem">
 <div class="memproto">
       <table class="memname">
         <tr>
-          <td class="memname">DLLEXPORT char* DLLCALL tjGetErrorStr </td>
+          <td class="memname">DLLEXPORT char* DLLCALL tjGetErrorStr2 </td>
           <td>(</td>
-          <td class="paramtype">void&#160;</td>
-          <td class="paramname"></td><td>)</td>
+          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
+          <td class="paramname"><em>handle</em></td><td>)</td>
           <td></td>
         </tr>
       </table>
 </div><div class="memdoc">
 
 <p>Returns a descriptive error message explaining why the last command failed. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">handle</td><td>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.)</td></tr>
+  </table>
+  </dd>
+</dl>
 <dl class="section return"><dt>Returns</dt><dd>a descriptive error message explaining why the last command failed. </dd></dl>
 
 </div>
@@ -1993,7 +1999,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -2012,7 +2018,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
 </div><div class="memdoc">
 
 <p>Create a TurboJPEG compressor instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -2031,7 +2037,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
 </div><div class="memdoc">
 
 <p>Create a TurboJPEG decompressor instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -2050,7 +2056,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
 </div><div class="memdoc">
 
 <p>Create a new TurboJPEG transformer instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
@@ -2279,7 +2285,7 @@ If you choose option 1, <code>dstSizes[i]</code> should be set to the size of yo
   </table>
   </dd>
 </dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga9af79c908ec131b1ae8d52fe40375abf" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr()</a>.) </dd></dl>
+<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga94a235bd4f1088f61ad87b4eadb64c9c" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
 
 </div>
 </div>
index 3cc1b3e2a6afeb4c6a55b9fef3d0228f5f3916e5..6b27f3131a5039197e68d50d8c58256e61ae7f2f 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 8e6f815fa1864fca3c5050b27c72221537269479..8b381510e64e668cf01069bc169319e465d1a849 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 444aaef215977046b94a8f2665ec3b4cbecdb94b..eec0aee3e7e21804e474541d94bdd7a25f542155 100644 (file)
@@ -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']]],
index 69410b051ebee784aa150107f8addd96ae2471b6..f284a2c0202a0b3cec7fa67361be2b551ace865c 100644 (file)
@@ -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']]],
index af2a473f0cb05152d79be7cf4181b0819e3d96a4..36c0afac65263043e189b77809d931e7770ff1e6 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 3bb50f5fed1a5822bf7b1cc6a9e214512d66b759..2f549004fd934f8e3ba87c26a20a6007b2b05381 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 9fd97f7b086171acbf7144e5c88284c0bd524075..d9536a38480e0d7e262d9cc95bb592799a08c71b 100644 (file)
@@ -24,7 +24,7 @@
  <tr style="height: 56px;">
   <td style="padding-left: 0.5em;">
    <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">1.5</span>
+   &#160;<span id="projectnumber">1.6</span>
    </div>
   </td>
  </tr>
index 172312370859fb97a5c75ef3463dc7c16573fe86..2f2ab66c39cbce5a43c4d4bafa40c1a6b4f2f9e4 100644 (file)
@@ -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
index eaba670cf3fc91107f342768d10b0f3c44231e6b..b53a8b9ead7715a750f61fe05a42af426a463c64 100644 (file)
@@ -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")
 
index 35d55ae37a8edc6f1725c67aef384cde12f094f1..8c389aa6cdcad30b498e024965e956fc456c058e 100755 (executable)
@@ -54,3 +54,9 @@ TURBOJPEG_1.4
                tjPlaneSizeYUV;
                tjPlaneWidth;
 } TURBOJPEG_1.2;
+
+TURBOJPEG_1.6
+{
+       global:
+               tjGetErrorStr2;
+} TURBOJPEG_1.4;
index 9c1d25bb8877f535e68570d8b56f43580cc6c8a9..7aa014439e810c8df1a9a3b2ecb8f899591db57b 100755 (executable)
@@ -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;
index f3c9922422539985343641b243ca75aebc747331..8b771006f91d47c7668a2ecd30eeb3ff5c4da784 100644 (file)
@@ -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<nc; i++)
@@ -694,10 +713,10 @@ DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp)
        int pw, nc, retval=0;
 
        if(width<1 || subsamp<0 || subsamp>=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);
index 583029fa7e6a88b58fbbf2b87ba963be92abbb16..7475fb36aabad0aa6426a3a26544ebb7369e50e7 100644 (file)
@@ -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);
+
 
 /**
  * @}