diff --git a/ChangeLog.txt b/ChangeLog.txt index 475d8309..d4808e8e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -34,6 +34,9 @@ calling conventions. images (specifically, images in which the component count was erroneously set to a large value) would cause libjpeg-turbo to segfault. +[8] Extended the TurboJPEG Java API so that it can be used to decompress a +JPEG image into an arbitrary position in a large output buffer. + 1.2.0 ===== diff --git a/java/doc/allclasses-frame.html b/java/doc/allclasses-frame.html index a2b04992..73d5fb90 100644 --- a/java/doc/allclasses-frame.html +++ b/java/doc/allclasses-frame.html @@ -2,12 +2,12 @@
- + voiddecompress(byte[] dstBuf,
+ int x,
+ int y,
+ int desiredWidth,
+ int pitch,
+ int desiredHeight,
+ int pixelFormat,
+ int flags)
+
+ voiddecompress(int[] dstBuf,
+ int x,
+ int y,
+ int desiredWidth,
+ int stride,
+ int desiredHeight,
+ int pixelFormat,
+ int flags)
+
public void decompress(byte[] dstBuf,
+ int x,
+ int y,
int desiredWidth,
int pitch,
int desiredHeight,
@@ -707,7 +741,13 @@ public void decompress(byte[] dstBuf,
buffer should normally be pitch * scaledHeight bytes in size,
where scaledHeight can be determined by calling
scalingFactor.getScaled(jpegHeight)
- with one of the scaling factors returned from TJ.getScalingFactors() or by calling getScaledHeight(int, int).desiredWidth - desired width (in pixels) of the decompressed image.
+ with one of the scaling factors returned from TJ.getScalingFactors() or by calling getScaledHeight(int, int). However,
+ the buffer may also be larger than the dimensions of the JPEG image, in
+ which case the x, y, and pitch
+ parameters can be used to specify the region into which the JPEG image
+ should be decompressed.x - x offset (in pixels) of the region into which the JPEG image
+ should be decompressed, relative to the start of dstBuf.y - y offset (in pixels) of the region into which the JPEG image
+ should be decompressed, relative to the start of dstBuf.desiredWidth - desired width (in pixels) of the decompressed image.
If the desired image dimensions are smaller than the dimensions of the
JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG
decompressor to generate the largest possible image that will fit within
@@ -716,7 +756,8 @@ public void decompress(byte[] dstBuf,
considered when determining the scaled image size.)pitch - bytes per line of the destination image. Normally, this
should be set to scaledWidth * TJ.pixelSize(pixelFormat) if
the decompressed image is unpadded, but you can use this to, for instance,
- pad each line of the decompressed image to a 4-byte boundary. NOTE:
+ pad each line of the decompressed image to a 4-byte boundary or to
+ decompress the JPEG image into a region of a larger image. NOTE:
scaledWidth can be determined by calling
scalingFactor.getScaled(jpegWidth)
or by calling getScaledWidth(int, int). Setting this parameter to
@@ -735,6 +776,37 @@ public void decompress(byte[] dstBuf,
+public void decompress(byte[] dstBuf, + int desiredWidth, + int pitch, + int desiredHeight, + int pixelFormat, + int flags) + throws java.lang.Exception+
+
dstBuf - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptiondesiredWidth - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptionpitch - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptiondesiredHeight - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptionpixelFormat - pixel format of the decompressed image (one of
+ TJ.PF_*)flags - the bitwise OR of one or more of TJ.FLAG_*
+java.lang.Exception@@ -750,9 +822,12 @@ public byte[] decompress(int desiredWidth,
desiredWidth - see
- decompress(byte[], int, int, int, int, int) for descriptionpitch - see
- decompress(byte[], int, int, int, int, int) for descriptiondesiredHeight - see
- decompress(byte[], int, int, int, int, int) for descriptionpixelFormat - pixel format of the decompressed image (one of
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptionpitch - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptiondesiredHeight - see
+ decompress(byte[], int, int, int, int, int, int, int)
+ for descriptionpixelFormat - pixel format of the decompressed image (one of
TJ.PF_*)flags - the bitwise OR of one or more of TJ.FLAG_*
+public void decompress(int[] dstBuf, + int x, + int y, + int desiredWidth, + int stride, + int desiredHeight, + int pixelFormat, + int flags) + throws java.lang.Exception+
+
dstBuf - buffer that will receive the decompressed image. This
+ buffer should normally be stride * scaledHeight pixels in
+ size, where scaledHeight can be determined by calling
+ scalingFactor.getScaled(jpegHeight)
+ with one of the scaling factors returned from TJ.getScalingFactors() or by calling getScaledHeight(int, int). However,
+ the buffer may also be larger than the dimensions of the JPEG image, in
+ which case the x, y, and stride
+ parameters can be used to specify the region into which the JPEG image
+ should be decompressed.x - x offset (in pixels) of the region into which the JPEG image
+ should be decompressed, relative to the start of dstBuf.y - y offset (in pixels) of the region into which the JPEG image
+ should be decompressed, relative to the start of dstBuf.desiredWidth - desired width (in pixels) of the decompressed image.
+ If the desired image dimensions are smaller than the dimensions of the
+ JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG
+ decompressor to generate the largest possible image that will fit within
+ the desired dimensions. Setting this to 0 is the same as setting it to
+ the width of the JPEG image (in other words, the width will not be
+ considered when determining the scaled image size.)stride - pixels per line of the destination image. Normally, this
+ should be set to scaledWidth, but you can use this to, for
+ instance, decompress the JPEG image into a region of a larger image.
+ NOTE: scaledWidth can be determined by calling
+ scalingFactor.getScaled(jpegWidth)
+ or by calling getScaledWidth(int, int). Setting this parameter to
+ 0 is the equivalent of setting it to scaledWidth.desiredHeight - desired height (in pixels) of the decompressed image.
+ If the desired image dimensions are smaller than the dimensions of the
+ JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG
+ decompressor to generate the largest possible image that will fit within
+ the desired dimensions. Setting this to 0 is the same as setting it to
+ the height of the JPEG image (in other words, the height will not be
+ considered when determining the scaled image size.)pixelFormat - pixel format of the decompressed image (one of
+ TJ.PF_*)flags - the bitwise OR of one or more of TJ.FLAG_*
+java.lang.Exception@@ -841,8 +969,10 @@ public java.awt.image.BufferedImage decompress(int desiredWidth,
desiredWidth - see
- decompress(byte[], int, int, int, int, int) for descriptiondesiredHeight - see
- decompress(byte[], int, int, int, int, int) for descriptionbufferedImageType - the image type of the newly-created
+ decompress(byte[], int, int, int, int, int, int, int) for
+ descriptiondesiredHeight - see
+ decompress(byte[], int, int, int, int, int, int, int) for
+ descriptionbufferedImageType - the image type of the newly-created
BufferedImage instance (for instance,
BufferedImage.TYPE_INT_RGB)flags - the bitwise OR of one or more of TJ.FLAG_*
BufferedImage instance containing the
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
index decf4306..68e64b84 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
@@ -2,12 +2,12 @@
-
+
close, decompress, decompress, decompress, decompress, decompressToYUV, decompressToYUV, finalize, getHeight, getJPEGBuf, getJPEGSize, getScaledHeight, getScaledWidth, getSubsamp, getWidth, setJPEGImageclose, decompress, decompress, decompress, decompress, decompress, decompress, decompressToYUV, decompressToYUV, finalize, getHeight, getJPEGBuf, getJPEGSize, getScaledHeight, getScaledWidth, getSubsamp, getWidth, setJPEGImagescaledHeight can be determined by calling
* scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegHeight)
* with one of the scaling factors returned from {@link
- * TJ#getScalingFactors} or by calling {@link #getScaledHeight}.
+ * TJ#getScalingFactors} or by calling {@link #getScaledHeight}. However,
+ * the buffer may also be larger than the dimensions of the JPEG image, in
+ * which case the x, y, and pitch
+ * parameters can be used to specify the region into which the JPEG image
+ * should be decompressed.
+ *
+ * @param x x offset (in pixels) of the region into which the JPEG image
+ * should be decompressed, relative to the start of dstBuf.
+ *
+ * @param y y offset (in pixels) of the region into which the JPEG image
+ * should be decompressed, relative to the start of dstBuf.
*
* @param desiredWidth desired width (in pixels) of the decompressed image.
* If the desired image dimensions are smaller than the dimensions of the
@@ -252,7 +262,8 @@ public class TJDecompressor {
* @param pitch bytes per line of the destination image. Normally, this
* should be set to scaledWidth * TJ.pixelSize(pixelFormat) if
* the decompressed image is unpadded, but you can use this to, for instance,
- * pad each line of the decompressed image to a 4-byte boundary. NOTE:
+ * pad each line of the decompressed image to a 4-byte boundary or to
+ * decompress the JPEG image into a region of a larger image. NOTE:
* scaledWidth can be determined by calling
* scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegWidth)
* or by calling {@link #getScaledWidth}. Setting this parameter to
@@ -272,28 +283,65 @@ public class TJDecompressor {
*
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/
- public void decompress(byte[] dstBuf, int desiredWidth, int pitch,
- int desiredHeight, int pixelFormat, int flags) throws Exception {
+ public void decompress(byte[] dstBuf, int x, int y, int desiredWidth,
+ int pitch, int desiredHeight, int pixelFormat, int flags)
+ throws Exception {
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR);
- if(dstBuf == null || desiredWidth < 0 || pitch < 0 || desiredHeight < 0
- || pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
+ if(dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || pitch < 0
+ || desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF
+ || flags < 0)
throw new Exception("Invalid argument in decompress()");
- decompress(jpegBuf, jpegBufSize, dstBuf, desiredWidth, pitch,
+ decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, pitch,
desiredHeight, pixelFormat, flags);
}
+ /**
+ * Decompress the JPEG source image associated with this decompressor
+ * instance and output a decompressed image to the given destination buffer.
+ *
+ * @param dstBuf see
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
+ *
+ * @param desiredWidth see
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
+ *
+ * @param pitch see
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
+ *
+ * @param desiredHeight see
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
+ *
+ * @param pixelFormat pixel format of the decompressed image (one of
+ * {@link TJ TJ.PF_*})
+ *
+ * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
+ */
+ public void decompress(byte[] dstBuf, int desiredWidth, int pitch,
+ int desiredHeight, int pixelFormat, int flags)
+ throws Exception {
+ decompress(dstBuf, 0, 0, desiredWidth, pitch, desiredHeight, pixelFormat,
+ flags);
+ }
+
/**
* Decompress the JPEG source image associated with this decompressor
* instance and return a buffer containing the decompressed image.
*
* @param desiredWidth see
- * {@link #decompress(byte[], int, int, int, int, int)} for description
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
*
* @param pitch see
- * {@link #decompress(byte[], int, int, int, int, int)} for description
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
*
* @param desiredHeight see
- * {@link #decompress(byte[], int, int, int, int, int)} for description
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)}
+ * for description
*
* @param pixelFormat pixel format of the decompressed image (one of
* {@link TJ TJ.PF_*})
@@ -362,6 +410,68 @@ public class TJDecompressor {
return buf;
}
+ /**
+ * Decompress the JPEG source image associated with this decompressor
+ * instance and output a decompressed image to the given destination buffer.
+ *
+ * @param dstBuf buffer that will receive the decompressed image. This
+ * buffer should normally be stride * scaledHeight pixels in
+ * size, where scaledHeight can be determined by calling
+ * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegHeight)
+ * with one of the scaling factors returned from {@link
+ * TJ#getScalingFactors} or by calling {@link #getScaledHeight}. However,
+ * the buffer may also be larger than the dimensions of the JPEG image, in
+ * which case the x, y, and stride
+ * parameters can be used to specify the region into which the JPEG image
+ * should be decompressed.
+ *
+ * @param x x offset (in pixels) of the region into which the JPEG image
+ * should be decompressed, relative to the start of dstBuf.
+ *
+ * @param y y offset (in pixels) of the region into which the JPEG image
+ * should be decompressed, relative to the start of dstBuf.
+ *
+ * @param desiredWidth desired width (in pixels) of the decompressed image.
+ * If the desired image dimensions are smaller than the dimensions of the
+ * JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG
+ * decompressor to generate the largest possible image that will fit within
+ * the desired dimensions. Setting this to 0 is the same as setting it to
+ * the width of the JPEG image (in other words, the width will not be
+ * considered when determining the scaled image size.)
+ *
+ * @param stride pixels per line of the destination image. Normally, this
+ * should be set to scaledWidth, but you can use this to, for
+ * instance, decompress the JPEG image into a region of a larger image.
+ * NOTE: scaledWidth can be determined by calling
+ * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegWidth)
+ * or by calling {@link #getScaledWidth}. Setting this parameter to
+ * 0 is the equivalent of setting it to scaledWidth.
+ *
+ * @param desiredHeight desired height (in pixels) of the decompressed image.
+ * If the desired image dimensions are smaller than the dimensions of the
+ * JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG
+ * decompressor to generate the largest possible image that will fit within
+ * the desired dimensions. Setting this to 0 is the same as setting it to
+ * the height of the JPEG image (in other words, the height will not be
+ * considered when determining the scaled image size.)
+ *
+ * @param pixelFormat pixel format of the decompressed image (one of
+ * {@link TJ TJ.PF_*})
+ *
+ * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
+ */
+ public void decompress(int[] dstBuf, int x, int y, int desiredWidth,
+ int stride, int desiredHeight, int pixelFormat, int flags)
+ throws Exception {
+ if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR);
+ if(dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || stride < 0
+ || desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF
+ || flags < 0)
+ throw new Exception("Invalid argument in decompress()");
+ decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, stride,
+ desiredHeight, pixelFormat, flags);
+ }
+
/**
* Decompress the JPEG source image associated with this decompressor
* instance and output a decompressed image to the given
@@ -444,10 +554,12 @@ public class TJDecompressor {
* decompressed image.
*
* @param desiredWidth see
- * {@link #decompress(byte[], int, int, int, int, int)} for description
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)} for
+ * description
*
* @param desiredHeight see
- * {@link #decompress(byte[], int, int, int, int, int)} for description
+ * {@link #decompress(byte[], int, int, int, int, int, int, int)} for
+ * description
*
* @param bufferedImageType the image type of the newly-created
* BufferedImage instance (for instance,
@@ -498,8 +610,18 @@ public class TJDecompressor {
int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
throws Exception;
+ private native void decompress(byte[] srcBuf, int size, byte[] dstBuf, int x,
+ int y, int desiredWidth, int pitch, int desiredHeight, int pixelFormat,
+ int flags)
+ throws Exception;
+
private native void decompress(byte[] srcBuf, int size, int[] dstBuf,
- int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
+ int desiredWidth, int stride, int desiredHeight, int pixelFormat, int flags)
+ throws Exception;
+
+ private native void decompress(byte[] srcBuf, int size, int[] dstBuf, int x,
+ int y, int desiredWidth, int stride, int desiredHeight, int pixelFormat,
+ int flags)
throws Exception;
private native void decompressToYUV(byte[] srcBuf, int size, byte[] dstBuf,
diff --git a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h
index 6b67296b..f798a77f 100644
--- a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h
+++ b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h
@@ -39,6 +39,14 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
(JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint);
+/*
+ * Class: org_libjpegturbo_turbojpeg_TJDecompressor
+ * Method: decompress
+ * Signature: ([BI[BIIIIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
+ (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint, jint, jint);
+
/*
* Class: org_libjpegturbo_turbojpeg_TJDecompressor
* Method: decompress
@@ -47,6 +55,14 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
(JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint, jint);
+/*
+ * Class: org_libjpegturbo_turbojpeg_TJDecompressor
+ * Method: decompress
+ * Signature: ([BI[IIIIIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
+ (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint, jint, jint, jint);
+
/*
* Class: org_libjpegturbo_turbojpeg_TJDecompressor
* Method: decompressToYUV
diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c
index 1ff9bbaf..3b9624a1 100644
--- a/turbojpeg-jni.c
+++ b/turbojpeg-jni.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C)2011 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2011-2012 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:
@@ -350,12 +350,12 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
return;
}
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
(JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
- jint width, jint pitch, jint height, jint pf, jint flags)
+ jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
{
tjhandle handle=0;
- jsize arraySize=0;
+ jsize arraySize=0, actualPitch;
unsigned char *jpegBuf=NULL, *dstBuf=NULL;
gethandle();
@@ -367,15 +367,68 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
if((*env)->GetArrayLength(env, src)