diff --git a/java/TJBench.java b/java/TJBench.java index f1de27a0..07338169 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -63,6 +63,26 @@ class TJBench { } + static String tjErrorMsg; + static int tjErrorCode = -1; + + static void handleTJException(TJException e) throws TJException { + String _tjErrorMsg = e.getMessage(); + int _tjErrorCode = e.getErrorCode(); + + if ((flags & TJ.FLAG_STOPONWARNING) == 0 && + _tjErrorCode == TJ.ERR_WARNING) { + if (tjErrorMsg == null || !tjErrorMsg.equals(_tjErrorMsg) || + tjErrorCode != _tjErrorCode) { + tjErrorMsg = _tjErrorMsg; + tjErrorCode = _tjErrorCode; + System.out.println("WARNING: " + _tjErrorMsg); + } + } else + throw e; + } + + static String formatName(int subsamp, int cs) { if (cs == TJ.CS_YCbCr) return subNameLong[subsamp]; @@ -174,14 +194,21 @@ class TJBench { tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]); if (doYUV) { yuvImage.setBuf(yuvImage.getBuf(), width, yuvpad, height, subsamp); - tjd.decompressToYUV(yuvImage, flags); + try { + tjd.decompressToYUV(yuvImage, flags); + } catch (TJException e) { handleTJException(e); } double startDecode = getTime(); tjd.setSourceImage(yuvImage); - tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags); + try { + tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags); + } catch (TJException e) { handleTJException(e); } if (iter >= 0) elapsedDecode += getTime() - startDecode; - } else - tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags); + } else { + try { + tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags); + } catch (TJException e) { handleTJException(e); } + } } } elapsed += getTime() - start; diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/java/doc/org/libjpegturbo/turbojpeg/TJ.html index a544179d..d5691268 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJ.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJ.html @@ -995,7 +995,12 @@ public static final int FLAG_FORCESSE3
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.
+ error is encountered. +

+ NOTE: due to the design of the TurboJPEG Java API, only certain methods + (specifically, TJDecompressor.decompress*() methods + with a void return type) will complete and leave the output image in a + fully recoverable state after a non-fatal error occurs.

See Also:
Constant Field Values
@@ -1032,7 +1037,12 @@ public static final int FLAG_FORCESSE3

ERR_WARNING

public static final int ERR_WARNING
The error was non-fatal and recoverable, but the image may still be - corrupt.
+ corrupt. +

+ NOTE: due to the design of the TurboJPEG Java API, only certain methods + (specifically, TJDecompressor.decompress*() methods + with a void return type) will complete and leave the output image in a + fully recoverable state after a non-fatal error occurs.

See Also:
Constant Field Values
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html index a914de9e..8e332495 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html @@ -785,7 +785,11 @@ public void setJPEGImage(byte[] jpegImage, throws TJException
Decompress the JPEG source image or decode the YUV source image associated with this decompressor instance and output a grayscale, RGB, or CMYK image - to the given destination buffer.
+ to the given destination buffer. +

+ NOTE: The output image is fully recoverable if this method throws a + non-fatal TJException (unless + TJ.FLAG_STOPONWARNING is specified.)

Parameters:
dstBuf - buffer that will receive the decompressed/decoded image. If the source image is a JPEG image, then this buffer should normally be pitch * scaledHeight bytes in size, where @@ -895,7 +899,11 @@ public void decompress(byte[] dstBuf, YUVImage instance. This method performs JPEG decompression but leaves out the color conversion step, so a planar YUV image is generated instead of an RGB or grayscale image. This method cannot be - used to decompress JPEG source images with the CMYK or YCCK colorspace. + used to decompress JPEG source images with the CMYK or YCCK colorspace. +

+ NOTE: The YUV planar output image is fully recoverable if this method + throws a non-fatal TJException (unless + TJ.FLAG_STOPONWARNING is specified.)

Parameters:
dstImage - YUVImage instance that will receive the YUV planar image. The level of subsampling specified in this YUVImage instance must match that of the JPEG image, and the width and height @@ -1035,7 +1043,11 @@ public byte[] decompressToYUV(int flags) throws TJException
Decompress the JPEG source image or decode the YUV source image associated with this decompressor instance and output a grayscale, RGB, or CMYK image - to the given destination buffer.
+ to the given destination buffer. +

+ NOTE: The output image is fully recoverable if this method throws a + non-fatal TJException (unless + TJ.FLAG_STOPONWARNING is specified.)

Parameters:
dstBuf - buffer that will receive the decompressed/decoded image. If the source image is a JPEG image, then this buffer should normally be stride * scaledHeight pixels in size, where @@ -1092,7 +1104,11 @@ public byte[] decompressToYUV(int flags) throws TJException
Decompress the JPEG source image or decode the YUV source image associated with this decompressor instance and output a decompressed/decoded image to - the given BufferedImage instance.
+ the given BufferedImage instance. +

+ NOTE: The output image is fully recoverable if this method throws a + non-fatal TJException (unless + TJ.FLAG_STOPONWARNING is specified.)

Parameters:
dstImage - a BufferedImage instance that will receive the decompressed/decoded image. If the source image is a JPEG image, then the width and height of the BufferedImage instance must match diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java index 045e8295..ee000a90 100644 --- a/java/org/libjpegturbo/turbojpeg/TJ.java +++ b/java/org/libjpegturbo/turbojpeg/TJ.java @@ -391,6 +391,11 @@ public final class TJ { * 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. + *

+ * NOTE: due to the design of the TurboJPEG Java API, only certain methods + * (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods + * with a void return type) will complete and leave the output image in a + * fully recoverable state after a non-fatal error occurs. */ public static final int FLAG_STOPONWARNING = 8192; /** @@ -409,6 +414,11 @@ public final class TJ { /** * The error was non-fatal and recoverable, but the image may still be * corrupt. + *

+ * NOTE: due to the design of the TurboJPEG Java API, only certain methods + * (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods + * with a void return type) will complete and leave the output image in a + * fully recoverable state after a non-fatal error occurs. */ public static final int ERR_WARNING = 0; /** diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java index bd0e6943..be71cb08 100644 --- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java @@ -308,6 +308,10 @@ public class TJDecompressor implements Closeable { * Decompress the JPEG source image or decode the YUV source image associated * with this decompressor instance and output a grayscale, RGB, or CMYK image * to the given destination buffer. + *

+ * NOTE: The output image is fully recoverable if this method throws a + * non-fatal {@link TJException} (unless + * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.) * * @param dstBuf buffer that will receive the decompressed/decoded image. * If the source image is a JPEG image, then this buffer should normally be @@ -451,6 +455,10 @@ public class TJDecompressor implements Closeable { * but leaves out the color conversion step, so a planar YUV image is * generated instead of an RGB or grayscale image. This method cannot be * used to decompress JPEG source images with the CMYK or YCCK colorspace. + *

+ * NOTE: The YUV planar output image is fully recoverable if this method + * throws a non-fatal {@link TJException} (unless + * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.) * * @param dstImage {@link YUVImage} instance that will receive the YUV planar * image. The level of subsampling specified in this YUVImage @@ -618,6 +626,10 @@ public class TJDecompressor implements Closeable { * Decompress the JPEG source image or decode the YUV source image associated * with this decompressor instance and output a grayscale, RGB, or CMYK image * to the given destination buffer. + *

+ * NOTE: The output image is fully recoverable if this method throws a + * non-fatal {@link TJException} (unless + * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.) * * @param dstBuf buffer that will receive the decompressed/decoded image. * If the source image is a JPEG image, then this buffer should normally be @@ -699,6 +711,10 @@ public class TJDecompressor implements Closeable { * Decompress the JPEG source image or decode the YUV source image associated * with this decompressor instance and output a decompressed/decoded image to * the given BufferedImage instance. + *

+ * NOTE: The output image is fully recoverable if this method throws a + * non-fatal {@link TJException} (unless + * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.) * * @param dstImage a BufferedImage instance that will receive * the decompressed/decoded image. If the source image is a JPEG image, then diff --git a/tjbench.c b/tjbench.c index 450e1280..a6275101 100644 --- a/tjbench.c +++ b/tjbench.c @@ -38,15 +38,44 @@ #include "./turbojpeg.h" -#define _throw(op, err) { \ +#define _throw(op, err) \ +{ \ printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \ - retval=-1; goto bailout;} + retval=-1; goto bailout; \ +} #define _throwunix(m) _throw(m, strerror(errno)) -#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;} + +char tjErrorStr[JMSG_LENGTH_MAX]="\0", tjErrorMsg[JMSG_LENGTH_MAX]="\0"; +int tjErrorLine=-1, tjErrorCode=-1; + +#define _throwtj(m) \ +{ \ + int _tjErrorCode=tjGetErrorCode(handle); \ + char *_tjErrorStr=tjGetErrorStr2(handle); \ + \ + if(!(flags&TJFLAG_STOPONWARNING) && _tjErrorCode==TJERR_WARNING) \ + { \ + if(strncmp(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX) || \ + strncmp(tjErrorMsg, m, JMSG_LENGTH_MAX) || \ + tjErrorCode!=_tjErrorCode || tjErrorLine!=__LINE__) \ + { \ + strncpy(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX); \ + strncpy(tjErrorMsg, m, JMSG_LENGTH_MAX); \ + tjErrorCode=_tjErrorCode; \ + tjErrorLine=__LINE__; \ + printf("WARNING in line %d while %s:\n%s\n", __LINE__, m, \ + _tjErrorStr); \ + } \ + } \ + else \ + { \ + printf("%s in line %d while %s:\n%s\n", \ + _tjErrorCode==TJERR_WARNING ? "WARNING" : "ERROR", __LINE__, m, \ + _tjErrorStr); \ + retval=-1; goto bailout; \ + } \ +} + #define _throwbmp(m) _throw(m, bmpgeterr()) int flags=TJFLAG_NOREALLOC, componly=0, decomponly=0, doyuv=0, quiet=0,