From: DRC Date: Tue, 27 Jun 2017 15:54:21 +0000 (-0500) Subject: TurboJPEG: Improve error handling X-Git-Tag: 1.5.90~71 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d4092f6b4dd94c64864662987b070d517c399490;p=libjpeg-turbo TurboJPEG: Improve error handling - Provide a new C API function and TJException method that allows calling programs to query the severity of a compression/decompression/ transform error. - Provide a new flag that instructs the library to immediately stop compressing/decompressing/transforming if a warning is encountered. Fixes #151 --- diff --git a/ChangeLog.md b/ChangeLog.md index f96d5fc..731500b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -48,6 +48,17 @@ 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. + - Introduced a new function (`tjGetErrorCode()`) in the TurboJPEG C API +and a new method (`TJException.getErrorCode()`) in the TurboJPEG Java API that +can be used to determine the severity of the last +compression/decompression/transform error. This allows applications to +choose whether to ignore warnings (non-fatal errors) from the underlying +libjpeg API or to treat them as fatal. + - Introduced a new flag (`TJFLAG_STOPONWARNING` in the TurboJPEG C API and +`TJ.FLAG_STOPONWARNING` in the TurboJPEG Java API) that causes the library to +immediately halt a compression/decompression/transform operation if it +encounters a warning from the underlying libjpeg API (the default behavior is +to allow the operation to complete unless a fatal error is encountered.) 1.5.2 diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index fb5da8c..49c54ca 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -128,6 +128,12 @@ Macros #define TJFLAG_ACCURATEDCT  Use the most accurate DCT/IDCT algorithm available in the underlying codec. More...
  +#define TJFLAG_STOPONWARNING + Immediately discontinue the current compression/decompression/transform operation if the underlying codec throws a warning (non-fatal error). More...
+  +#define TJ_NUMERR + The number of error codes. More...
+  #define TJ_NUMXOP  The number of transform operations. More...
  @@ -206,6 +212,11 @@ Enumerations }  JPEG colorspaces. More...
  +enum  TJERR { TJERR_WARNING, +TJERR_FATAL + } + Error codes. More...
+  enum  TJXOP {
  TJXOP_NONE, TJXOP_HFLIP, @@ -298,6 +309,9 @@ Functions DLLEXPORT char *DLLCALL tjGetErrorStr2 (tjhandle handle)  Returns a descriptive error message explaining why the last command failed. More...
  +DLLEXPORT int DLLCALL tjGetErrorCode (tjhandle handle) + Returns a code indicating the severity of the last error. More...
+  @@ -341,6 +355,20 @@ Variables

The number of JPEG colorspaces.

+ + + +
+
+

Variables

+ + + +
#define TJ_NUMERR
+
+ +

The number of error codes.

+
@@ -457,6 +485,21 @@ Variables

Disable buffer (re)allocation.

If passed to tjCompress2() or tjTransform(), this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG.

+ + + +
+
+ + + + +
#define TJFLAG_STOPONWARNING
+
+ +

Immediately discontinue the current compression/decompression/transform operation if the underlying codec throws a warning (non-fatal error).

+

The default behavior is to allow the operation to complete unless a fatal error is encountered.

+
@@ -642,6 +685,28 @@ Variables + + + +
+
+ + + + +
enum TJERR
+
+ +

Error codes.

+ + + +
Enumerator
TJERR_WARNING  +

The error was non-fatal and recoverable, but the image may still be corrupt.

+
TJERR_FATAL  +

The error was fatal and non-recoverable.

+
+
@@ -1018,7 +1083,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1115,7 +1180,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1212,7 +1277,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1305,7 +1370,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1398,7 +1463,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1483,7 +1548,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1554,7 +1619,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1633,7 +1698,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1712,7 +1777,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1830,7 +1895,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1923,7 +1988,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
@@ -1951,6 +2016,32 @@ If you choose option 1, *jpegSize should be set to the size of your
See Also
tjAlloc()
+ + + +
+
+ + + + + + + + +
DLLEXPORT int DLLCALL tjGetErrorCode (tjhandle handle)
+
+ +

Returns a code indicating the severity of the last error.

+

See Error codes.

+
Parameters
+ + +
handlea handle to a TurboJPEG compressor, decompressor or transformer instance
+
+
+
Returns
a code indicating the severity of the last error. See Error codes.
+
@@ -2285,7 +2376,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 tjGetErrorStr2().)
+
Returns
0 if successful, or -1 if an error occurred (see tjGetErrorStr2() and tjGetErrorCode().)
diff --git a/doc/html/search/all_74.js b/doc/html/search/all_74.js index eec0aee..b18cdcd 100644 --- a/doc/html/search/all_74.js +++ b/doc/html/search/all_74.js @@ -1,6 +1,7 @@ var searchData= [ ['tj_5fnumcs',['TJ_NUMCS',['../group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71',1,'turbojpeg.h']]], + ['tj_5fnumerr',['TJ_NUMERR',['../group___turbo_j_p_e_g.html#ga79bde1b4a3e2351e00887e47781b966e',1,'turbojpeg.h']]], ['tj_5fnumpf',['TJ_NUMPF',['../group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e',1,'turbojpeg.h']]], ['tj_5fnumsamp',['TJ_NUMSAMP',['../group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c',1,'turbojpeg.h']]], ['tj_5fnumxop',['TJ_NUMXOP',['../group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c',1,'turbojpeg.h']]], @@ -26,12 +27,17 @@ var searchData= ['tjdestroy',['tjDestroy',['../group___turbo_j_p_e_g.html#ga674adee917b95ad4a896f1ba39e12540',1,'turbojpeg.h']]], ['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']]], + ['tjerr',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], + ['tjerr_5ffatal',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], + ['tjerr_5fwarning',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], ['tjflag_5faccuratedct',['TJFLAG_ACCURATEDCT',['../group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0',1,'turbojpeg.h']]], ['tjflag_5fbottomup',['TJFLAG_BOTTOMUP',['../group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec',1,'turbojpeg.h']]], ['tjflag_5ffastdct',['TJFLAG_FASTDCT',['../group___turbo_j_p_e_g.html#gaabce235db80d3f698b27f36cbd453da2',1,'turbojpeg.h']]], ['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']]], + ['tjflag_5fstoponwarning',['TJFLAG_STOPONWARNING',['../group___turbo_j_p_e_g.html#ga519cfa4ef6c18d9e5b455fdf59306a3a',1,'turbojpeg.h']]], ['tjfree',['tjFree',['../group___turbo_j_p_e_g.html#ga8c4a1231dc06a450514c835f6471f137',1,'turbojpeg.h']]], + ['tjgeterrorcode',['tjGetErrorCode',['../group___turbo_j_p_e_g.html#ga0be00a62bd1be897f170fa1fed5fb4cb',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']]], @@ -70,7 +76,7 @@ var searchData= ['tjsamp_5fgray',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]], ['tjscaled',['TJSCALED',['../group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df',1,'turbojpeg.h']]], ['tjscalingfactor',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]], - ['tjtransform',['tjtransform',['../structtjtransform.html',1,'tjtransform'],['../group___turbo_j_p_e_g.html#gad02cd42b69f193a0623a9c801788df3a',1,'tjTransform(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *transforms, int flags): turbojpeg.h'],['../group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31',1,'tjtransform(): turbojpeg.h']]], + ['tjtransform',['tjtransform',['../structtjtransform.html',1,'tjtransform'],['../group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31',1,'tjtransform(): turbojpeg.h'],['../group___turbo_j_p_e_g.html#gad02cd42b69f193a0623a9c801788df3a',1,'tjTransform(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *transforms, int flags): turbojpeg.h']]], ['tjxop',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]], ['tjxop_5fhflip',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]], ['tjxop_5fnone',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]], diff --git a/doc/html/search/enums_74.js b/doc/html/search/enums_74.js index 276aa24..19c20cf 100644 --- a/doc/html/search/enums_74.js +++ b/doc/html/search/enums_74.js @@ -1,6 +1,7 @@ var searchData= [ ['tjcs',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]], + ['tjerr',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], ['tjpf',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]], ['tjsamp',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]], ['tjxop',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]] diff --git a/doc/html/search/enumvalues_74.js b/doc/html/search/enumvalues_74.js index 7dc2f8d..799f9ac 100644 --- a/doc/html/search/enumvalues_74.js +++ b/doc/html/search/enumvalues_74.js @@ -5,6 +5,8 @@ var searchData= ['tjcs_5frgb',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]], ['tjcs_5fycbcr',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]], ['tjcs_5fycck',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]], + ['tjerr_5ffatal',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], + ['tjerr_5fwarning',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], ['tjpf_5fabgr',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]], ['tjpf_5fargb',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]], ['tjpf_5fbgr',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]], diff --git a/doc/html/search/functions_74.js b/doc/html/search/functions_74.js index f284a2c..d2164bb 100644 --- a/doc/html/search/functions_74.js +++ b/doc/html/search/functions_74.js @@ -16,6 +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']]], + ['tjgeterrorcode',['tjGetErrorCode',['../group___turbo_j_p_e_g.html#ga0be00a62bd1be897f170fa1fed5fb4cb',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']]], diff --git a/java/TJBench.java b/java/TJBench.java index 618cc97..3a63505 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -663,7 +663,10 @@ class TJBench { System.out.println(" taking performance measurements (default = 1)"); System.out.println("-componly = Stop after running compression tests. Do not test decompression."); System.out.println("-nowrite = Do not write reference or output images (improves consistency"); - System.out.println(" of performance measurements.)\n"); + System.out.println(" of performance measurements.)"); + System.out.println("-stoponwarning = Immediately discontinue the current"); + System.out.println(" compression/decompression/transform operation if the underlying codec"); + System.out.println(" throws a warning (non-fatal error)\n"); System.out.println("NOTE: If the quality is specified as a range (e.g. 90-100), a separate"); System.out.println("test will be performed for all quality values in the range.\n"); System.exit(1); @@ -833,6 +836,8 @@ class TJBench { System.out.format("Warmup runs = %d\n\n", warmup); } } + if (argv[i].equalsIgnoreCase("-stoponwarning")) + flags |= TJ.FLAG_STOPONWARNING; if (argv[i].equalsIgnoreCase("-?")) usage(); } @@ -905,7 +910,12 @@ class TJBench { } } catch (Exception e) { - System.out.println("ERROR: " + e.getMessage()); + if (e instanceof TJException) { + TJException tje = (TJException)e; + System.out.println((tje.getErrorCode() == TJ.ERR_WARNING ? + "WARNING: " : "ERROR: ") + tje.getMessage()); + } else + System.out.println("ERROR: " + e.getMessage()); e.printStackTrace(); retval = -1; } diff --git a/java/doc/constant-values.html b/java/doc/constant-values.html index ec1b21d..a180b68 100644 --- a/java/doc/constant-values.html +++ b/java/doc/constant-values.html @@ -115,6 +115,20 @@ 4 + + +public static final int +ERR_FATAL +1 + + + + +public static final int +ERR_WARNING +0 + + public static final int @@ -171,12 +185,26 @@ 128 + + +public static final int +FLAG_STOPONWARNING +8192 + + public static final int NUMCS 5 + + + +public static final int +NUMERR +2 + diff --git a/java/doc/index-all.html b/java/doc/index-all.html index a02d9c4..b88c20f 100644 --- a/java/doc/index-all.html +++ b/java/doc/index-all.html @@ -278,6 +278,15 @@
Returns true or false, depending on whether this instance and other have the same numerator and denominator.
+
ERR_FATAL - Static variable in class org.libjpegturbo.turbojpeg.TJ
+
+
The error was fatal and non-recoverable.
+
+
ERR_WARNING - Static variable in class org.libjpegturbo.turbojpeg.TJ
+
+
The error was non-fatal and recoverable, but the image may still be + corrupt.
+
@@ -324,6 +333,11 @@
Deprecated.
+
FLAG_STOPONWARNING - Static variable in class org.libjpegturbo.turbojpeg.TJ
+
+
Immediately discontinue the current compression/decompression/transform + operation if the underlying codec throws a warning (non-fatal error).
+
@@ -354,6 +368,11 @@
Returns denominator
+
getErrorCode() - Method in exception org.libjpegturbo.turbojpeg.TJException
+
+
Returns a code (one of TJ.ERR_*) indicating the severity of the + last error.
+
getGreenOffset(int) - Static method in class org.libjpegturbo.turbojpeg.TJ
For the given pixel format, returns the number of bytes that the green @@ -516,6 +535,10 @@
The number of JPEG colorspaces
+
NUMERR - Static variable in class org.libjpegturbo.turbojpeg.TJ
+
+
The number of error codes
+
NUMOP - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
The number of lossless transform operations
@@ -829,6 +852,8 @@
 
TJException(String) - Constructor for exception org.libjpegturbo.turbojpeg.TJException
 
+
TJException(String, int) - Constructor for exception org.libjpegturbo.turbojpeg.TJException
+
 
TJException(Throwable) - Constructor for exception org.libjpegturbo.turbojpeg.TJException
 
TJScalingFactor - Class in org.libjpegturbo.turbojpeg
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/java/doc/org/libjpegturbo/turbojpeg/TJ.html index ffef657..6733749 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJ.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJ.html @@ -145,6 +145,19 @@ extends java.lang.Object static int +ERR_FATAL +
The error was fatal and non-recoverable.
+ + + +static int +ERR_WARNING +
The error was non-fatal and recoverable, but the image may still be + corrupt.
+ + + +static int FLAG_ACCURATEDCT
Use the most accurate DCT/IDCT algorithm available in the underlying codec.
@@ -197,10 +210,23 @@ extends java.lang.Object static int +FLAG_STOPONWARNING +
Immediately discontinue the current compression/decompression/transform + operation if the underlying codec throws a warning (non-fatal error).
+ + + +static int NUMCS
The number of JPEG colorspaces
+ +static int +NUMERR +
The number of error codes
+ + static int NUMPF @@ -938,7 +964,7 @@ public static final int FLAG_FORCESSE3 - diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJException.html b/java/doc/org/libjpegturbo/turbojpeg/TJException.html index 6088066..a57b351 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJException.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJException.html @@ -60,13 +60,13 @@
  • Nested | 
  • Field | 
  • Constr | 
  • -
  • Method
  • +
  • Method
  • @@ -138,10 +138,14 @@ extends java.io.IOException TJException(java.lang.String message)  +TJException(java.lang.String message, + int code)  + + TJException(java.lang.String message, java.lang.Throwable cause)  - + TJException(java.lang.Throwable cause)  @@ -153,6 +157,20 @@ extends java.io.IOException

    Method Summary

    + + + + + + + + + + +
    Methods 
    Modifier and TypeMethod and Description
    intgetErrorCode() +
    Returns a code (one of TJ.ERR_*) indicating the severity of the + last error.
    +
    + + + + @@ -220,6 +248,27 @@ extends java.io.IOException + + @@ -270,13 +319,13 @@ extends java.io.IOException
  • Nested | 
  • Field | 
  • Constr | 
  • -
  • Method
  • +
  • Method
  • diff --git a/java/doc/script.js b/java/doc/script.js new file mode 100644 index 0000000..b346356 --- /dev/null +++ b/java/doc/script.js @@ -0,0 +1,30 @@ +function show(type) +{ + count = 0; + for (var key in methods) { + var row = document.getElementById(key); + if ((methods[key] & type) != 0) { + row.style.display = ''; + row.className = (count++ % 2) ? rowColor : altColor; + } + else + row.style.display = 'none'; + } + updateTabs(type); +} + +function updateTabs(type) +{ + for (var value in tabs) { + var sNode = document.getElementById(tabs[value][0]); + var spanNode = sNode.firstChild; + if (value == type) { + sNode.className = activeTableTab; + spanNode.innerHTML = tabs[value][1]; + } + else { + sNode.className = tableTab; + spanNode.innerHTML = "" + tabs[value][1] + ""; + } + } +} diff --git a/java/doc/serialized-form.html b/java/doc/serialized-form.html index 846cabc..9ba3fd9 100644 --- a/java/doc/serialized-form.html +++ b/java/doc/serialized-form.html @@ -74,6 +74,19 @@
    serialVersionUID:
    1L
    +
  • diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java index 02d14c0..4e97aed 100644 --- a/java/org/libjpegturbo/turbojpeg/TJ.java +++ b/java/org/libjpegturbo/turbojpeg/TJ.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2013 D. R. Commander. All Rights Reserved. + * Copyright (C)2011-2013, 2017 D. R. Commander. All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -386,6 +386,28 @@ public final class TJ { * been shown to have a larger effect. */ public static final int FLAG_ACCURATEDCT = 4096; + /** + * Immediately discontinue the current compression/decompression/transform + * operation if the underlying codec throws a warning (non-fatal error). The + * default behavior is to allow the operation to complete unless a fatal + * error is encountered. + */ + public static final int FLAG_STOPONWARNING = 8192; + + + /** + * The number of error codes + */ + public static final int NUMERR = 2; + /** + * The error was non-fatal and recoverable, but the image may still be + * corrupt. + */ + public static final int ERR_WARNING = 0; + /** + * The error was fatal and non-recoverable. + */ + public static final int ERR_FATAL = 1; /** diff --git a/java/org/libjpegturbo/turbojpeg/TJException.java b/java/org/libjpegturbo/turbojpeg/TJException.java index 59c2041..97659d4 100644 --- a/java/org/libjpegturbo/turbojpeg/TJException.java +++ b/java/org/libjpegturbo/turbojpeg/TJException.java @@ -1,5 +1,6 @@ /* * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. + * Copyright (C)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,8 +47,26 @@ public class TJException extends IOException { super(message); } + public TJException(String message, int code) { + super(message); + if (errorCode >= 0 && errorCode < TJ.NUMERR) + errorCode = code; + } + public TJException(Throwable cause) { super(cause); } + /** + * Returns a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the + * last error. + * + * @return a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the + * last error. + */ + public int getErrorCode() { + return errorCode; + } + + private int errorCode = TJ.ERR_FATAL; } diff --git a/tjbench.c b/tjbench.c index 12b4efe..50ac852 100644 --- a/tjbench.c +++ b/tjbench.c @@ -42,7 +42,11 @@ printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \ retval=-1; goto bailout;} #define _throwunix(m) _throw(m, strerror(errno)) -#define _throwtj(m) _throw(m, tjGetErrorStr()) +#define _throwtj(m) { \ + printf("%s in line %d while %s:\n%s\n", \ + tjGetErrorCode(handle)==TJERR_WARNING ? "WARNING" : "ERROR", __LINE__, \ + m, tjGetErrorStr2(handle)); \ + retval=-1; goto bailout;} #define _throwbmp(m) _throw(m, bmpgeterr()) int flags=TJFLAG_NOREALLOC, componly=0, decomponly=0, doyuv=0, quiet=0, @@ -769,7 +773,10 @@ void usage(char *progname) printf(" taking performance measurements (default = 1)\n"); printf("-componly = Stop after running compression tests. Do not test decompression.\n"); printf("-nowrite = Do not write reference or output images (improves consistency of\n"); - printf(" performance measurements.)\n\n"); + printf(" performance measurements.)\n"); + printf("-stoponwarning = Immediately discontinue the current\n"); + printf(" compression/decompression/transform operation if the underlying codec\n"); + printf(" throws a warning (non-fatal error)\n\n"); printf("NOTE: If the quality is specified as a range (e.g. 90-100), a separate\n"); printf("test will be performed for all quality values in the range.\n\n"); exit(1); @@ -783,7 +790,7 @@ int main(int argc, char *argv[]) int minarg=2, retval=0, subsamp=-1; if((scalingfactors=tjGetScalingFactors(&nsf))==NULL || nsf==0) - _throwtj("executing tjGetScalingFactors()"); + _throw("executing tjGetScalingFactors()", tjGetErrorStr()); if(argcExceptionCheck(env)) { \ + goto bailout; \ +}} + #define _throw(msg, exceptionClass) { \ jclass _exccls=(*env)->FindClass(env, exceptionClass); \ - if(!_exccls || (*env)->ExceptionCheck(env)) goto bailout; \ + bailif0(_exccls); \ (*env)->ThrowNew(env, _exccls, msg); \ goto bailout; \ } -#define _throwtj() _throw(tjGetErrorStr2(handle), "org/libjpegturbo/turbojpeg/TJException") +#define _throwtj() { \ + jclass _exccls; \ + jmethodID _excid; \ + jobject _excobj; \ + jstring _errstr; \ + bailif0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \ + bailif0(_exccls = (*env)->FindClass(env, \ + "org/libjpegturbo/turbojpeg/TJException")); \ + bailif0(_excid = (*env)->GetMethodID(env, _exccls, "", \ + "(Ljava/lang/String;I)V")); \ + bailif0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \ + tjGetErrorCode(handle))); \ + (*env)->Throw(env, _excobj); \ + goto bailout; \ +} #define _throwarg(msg) _throw(msg, "java/lang/IllegalArgumentException") #define _throwmem() _throw("Memory allocation failure", "java/lang/OutOfMemoryError"); -#define bailif0(f) {if(!(f) || (*env)->ExceptionCheck(env)) { \ - goto bailout; \ -}} - #define gethandle() \ jclass _cls=(*env)->GetObjectClass(env, obj); \ jfieldID _fid; \ - if(!_cls || (*env)->ExceptionCheck(env)) goto bailout; \ + bailif0(_cls); \ bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \ handle=(tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); \ @@ -174,7 +188,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init tjhandle handle; if((handle=tjInitCompress())==NULL) - _throwtj(); + _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); bailif0(cls=(*env)->GetObjectClass(env, obj)); bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); @@ -551,7 +565,8 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init jfieldID fid; tjhandle handle; - if((handle=tjInitDecompress())==NULL) _throwtj(); + if((handle=tjInitDecompress())==NULL) + _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); bailif0(cls=(*env)->GetObjectClass(env, obj)); bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); @@ -958,7 +973,8 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init jfieldID fid; tjhandle handle; - if((handle=tjInitTransform())==NULL) _throwtj(); + if((handle=tjInitTransform())==NULL) + _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); bailif0(cls=(*env)->GetObjectClass(env, obj)); bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); diff --git a/turbojpeg-mapfile b/turbojpeg-mapfile index 8c389aa..8df3687 100755 --- a/turbojpeg-mapfile +++ b/turbojpeg-mapfile @@ -58,5 +58,6 @@ TURBOJPEG_1.4 TURBOJPEG_1.6 { global: + tjGetErrorCode; tjGetErrorStr2; } TURBOJPEG_1.4; diff --git a/turbojpeg-mapfile.jni b/turbojpeg-mapfile.jni index 7aa0144..9395dca 100755 --- a/turbojpeg-mapfile.jni +++ b/turbojpeg-mapfile.jni @@ -94,5 +94,6 @@ TURBOJPEG_1.4 TURBOJPEG_1.6 { global: + tjGetErrorCode; tjGetErrorStr2; } TURBOJPEG_1.4; diff --git a/turbojpeg.c b/turbojpeg.c index 8b77100..569f114 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -60,7 +60,7 @@ struct my_error_mgr struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; void (*emit_message)(j_common_ptr, int); - boolean warning; + boolean warning, stopOnWarning; }; typedef struct my_error_mgr *my_error_ptr; @@ -82,7 +82,11 @@ 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; + if(msg_level<0) + { + myerr->warning=TRUE; + if(myerr->stopOnWarning) longjmp(myerr->setjmp_buffer, 1); + } } @@ -566,6 +570,14 @@ DLLEXPORT char* DLLCALL tjGetErrorStr(void) } +DLLEXPORT int DLLCALL tjGetErrorCode(tjhandle handle) +{ + tjinstance *this=(tjinstance *)handle; + if(this && this->jerr.warning) return TJERR_WARNING; + else return TJERR_FATAL; +} + + DLLEXPORT int DLLCALL tjDestroy(tjhandle handle) { getinstance(handle); @@ -783,6 +795,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, #endif getcinstance(handle) + this->jerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if((this->init&COMPRESS)==0) _throw("tjCompress2(): Instance has not been initialized for compression"); @@ -891,6 +904,7 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, #endif getcinstance(handle); + this->jerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for(i=0; ijerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for(i=0; ijerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if((this->init&DECOMPRESS)==0) _throw("tjDecompress2(): Instance has not been initialized for decompression"); @@ -1594,6 +1610,7 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, void (*old_reset_marker_reader)(j_decompress_ptr); getdinstance(handle); + this->jerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for(i=0; ijerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for(i=0; ijerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pad<1 || !isPow2(pad) || height<0) @@ -2068,6 +2087,7 @@ DLLEXPORT int DLLCALL tjTransform(tjhandle handle, int retval=0, i, jpegSubsamp; getinstance(handle); + this->jerr.stopOnWarning=(flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) _throw("tjTransform(): Instance has not been initialized for transformation"); diff --git a/turbojpeg.h b/turbojpeg.h index 7475fb3..dfe7b77 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -383,6 +383,35 @@ enum TJCS * when decompressing, because this has been shown to have a larger effect. */ #define TJFLAG_ACCURATEDCT 4096 +/** + * Immediately discontinue the current compression/decompression/transform + * operation if the underlying codec throws a warning (non-fatal error). The + * default behavior is to allow the operation to complete unless a fatal error + * is encountered. + */ +#define TJFLAG_STOPONWARNING 8192 + + +/** + * The number of error codes + */ +#define TJ_NUMERR 2 + +/** + * Error codes + */ +enum TJERR +{ + /** + * The error was non-fatal and recoverable, but the image may still be + * corrupt. + */ + TJERR_WARNING=0, + /** + * The error was fatal and non-recoverable. + */ + TJERR_FATAL +}; /** @@ -670,7 +699,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, @@ -734,7 +764,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, const unsigned char *srcBuf, int width, int pad, int height, int subsamp, @@ -804,7 +835,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, const unsigned char **srcPlanes, int width, const int *strides, int height, @@ -964,7 +996,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, @@ -1022,7 +1055,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, @@ -1062,7 +1096,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int *width, @@ -1129,7 +1164,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, @@ -1179,7 +1215,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, @@ -1235,7 +1272,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, @@ -1287,7 +1325,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, @@ -1344,7 +1383,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, const unsigned char **srcPlanes, const int *strides, int subsamp, @@ -1414,7 +1454,8 @@ 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 #tjGetErrorStr2().) + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() + * and #tjGetErrorCode().) */ DLLEXPORT int DLLCALL tjTransform(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, @@ -1475,6 +1516,19 @@ DLLEXPORT void DLLCALL tjFree(unsigned char *buffer); DLLEXPORT char* DLLCALL tjGetErrorStr2(tjhandle handle); +/** + * Returns a code indicating the severity of the last error. See + * @ref TJERR "Error codes". + * + * @param handle a handle to a TurboJPEG compressor, decompressor or + * transformer instance + * + * @return a code indicating the severity of the last error. See + * @ref TJERR "Error codes". + */ +DLLEXPORT int DLLCALL tjGetErrorCode(tjhandle handle); + + /* Deprecated functions and macros */ #define TJFLAG_FORCEMMX 8 #define TJFLAG_FORCESSE 16