diff --git a/Makefile.am b/Makefile.am index bd77c33d..6096049b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -196,14 +196,14 @@ MD5_JPEG_CROP = b4197f377e621c4e9b1d20471432610d test: testclean all if WITH_TURBOJPEG -#if WITH_JAVA -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -bi -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -noyuvpad -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -# $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -noyuvpad -#endif +if WITH_JAVA + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -bi + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -noyuvpad + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi + $(JAVA) -cp java/turbojpeg.jar -Djava.library.path=.libs TJUnitTest -yuv -bi -noyuvpad +endif ./tjunittest ./tjunittest -alloc ./tjunittest -yuv diff --git a/java/TJUnitTest.java b/java/TJUnitTest.java index b4840006..56226e2b 100644 --- a/java/TJUnitTest.java +++ b/java/TJUnitTest.java @@ -61,11 +61,11 @@ public class TJUnitTest { private static final String[] pixFormatStr = { "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", - "RGBA", "BGRA", "ABGR", "ARGB" + "RGBA", "BGRA", "ABGR", "ARGB", "CMYK" }; private static final int[] alphaOffset = { - -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0 + -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1 }; private static final int[] _3byteFormats = { @@ -75,7 +75,7 @@ public class TJUnitTest { BufferedImage.TYPE_3BYTE_BGR }; private static final int[] _4byteFormats = { - TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB + TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB, TJ.PF_CMYK }; private static final int[] _4byteFormatsBI = { BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB, @@ -165,8 +165,8 @@ public class TJUnitTest { int ps = TJ.getPixelSize(pf); int index, row, col, halfway = 16; - Arrays.fill(buf, (byte)0); if (pf == TJ.PF_GRAY) { + Arrays.fill(buf, (byte)0); for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { if ((flags & TJ.FLAG_BOTTOMUP) != 0) @@ -181,6 +181,27 @@ public class TJUnitTest { } return; } + if (pf == TJ.PF_CMYK) { + Arrays.fill(buf, (byte)255); + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + if ((flags & TJ.FLAG_BOTTOMUP) != 0) + index = (h - row - 1) * w + col; + else + index = row * w + col; + if (((row / 8) + (col / 8)) % 2 == 0) { + if (row >= halfway) buf[index * ps + 3] = 0; + } else { + buf[index * ps + 2] = 0; + if (row < halfway) + buf[index * ps + 1] = 0; + } + } + } + return; + } + + Arrays.fill(buf, (byte)0); for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { if ((flags & TJ.FLAG_BOTTOMUP) != 0) @@ -299,6 +320,39 @@ public class TJUnitTest { int blockSize = 8 * sf.getNum() / sf.getDenom(); try { + + if (pf == TJ.PF_CMYK) { + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + if ((flags & TJ.FLAG_BOTTOMUP) != 0) + index = (h - row - 1) * w + col; + else + index = row * w + col; + byte c = buf[index * ps]; + byte m = buf[index * ps + 1]; + byte y = buf[index * ps + 2]; + byte k = buf[index * ps + 3]; + checkVal255(row, col, c, "C"); + if (((row / blockSize) + (col / blockSize)) % 2 == 0) { + checkVal255(row, col, m, "M"); + checkVal255(row, col, y, "Y"); + if (row < halfway) + checkVal255(row, col, k, "K"); + else + checkVal0(row, col, k, "K"); + } else { + checkVal0(row, col, y, "Y"); + checkVal255(row, col, k, "K"); + if (row < halfway) + checkVal0(row, col, m, "M"); + else + checkVal255(row, col, m, "M"); + } + } + } + return 1; + } + for (row = 0; row < halfway; row++) { for (col = 0; col < w; col++) { if ((flags & TJ.FLAG_BOTTOMUP) != 0) @@ -351,13 +405,25 @@ public class TJUnitTest { if (retval == 0) { for (row = 0; row < h; row++) { for (col = 0; col < w; col++) { - int r = buf[pitch * row + col * ps + roffset]; - int g = buf[pitch * row + col * ps + goffset]; - int b = buf[pitch * row + col * ps + boffset]; - if (r < 0) r += 256; - if (g < 0) g += 256; - if (b < 0) b += 256; - System.out.format("%3d/%3d/%3d ", r, g, b); + if (pf == TJ.PF_CMYK) { + int c = buf[pitch * row + col * ps]; + int m = buf[pitch * row + col * ps + 1]; + int y = buf[pitch * row + col * ps + 2]; + int k = buf[pitch * row + col * ps + 3]; + if (c < 0) c += 256; + if (m < 0) m += 256; + if (y < 0) y += 256; + if (k < 0) k += 256; + System.out.format("%3d/%3d/%3d/%3d ", c, m, y, k); + } else { + int r = buf[pitch * row + col * ps + roffset]; + int g = buf[pitch * row + col * ps + goffset]; + int b = buf[pitch * row + col * ps + boffset]; + if (r < 0) r += 256; + if (g < 0) g += 256; + if (b < 0) b += 256; + System.out.format("%3d/%3d/%3d ", r, g, b); + } } System.out.print("\n"); } @@ -788,6 +854,7 @@ public class TJUnitTest { tjd = new TJDecompressor(); for (int pf : formats) { + if (pf < 0) continue; for (int i = 0; i < 2; i++) { int flags = 0; if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 || @@ -880,7 +947,10 @@ public class TJUnitTest { testName = "javabitest"; } } - if (doyuv) yuv = YUVENCODE; + if (doyuv) { + yuv = YUVENCODE; + _4byteFormats[4] = -1; + } doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444, testName); doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444, @@ -904,6 +974,7 @@ public class TJUnitTest { doTest(39, 41, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName); doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY, testName); + _4byteFormats[4] = -1; doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY, testName); if (!doyuv && !bi) diff --git a/java/doc/constant-values.html b/java/doc/constant-values.html index e1a5a984..01f950f3 100644 --- a/java/doc/constant-values.html +++ b/java/doc/constant-values.html @@ -99,6 +99,36 @@ org.libjpegturbo.*
public static final intCS_CMYK3public static final intCS_GRAY2public static final intCS_RGB0public static final intCS_YCbCr1public static final intCS_YCCK4public static final intFLAG_ACCURATEDCT128public static final intNUMCS5public static final intNUMPF11123public static final intPF_CMYK11public static final intPF_GRAYsrcImage
and return a buffer containing a JPEG image.
+static intCS_CMYK
+
+static intCS_GRAY
+
+static intCS_RGB
+
+static intCS_YCbCr
+
+static intCS_YCCK
+
+static intFLAG_ACCURATEDCT
static intNUMCS
+
+static intNUMPF
static intPF_CMYK
+
+static intPF_GRAY
+public static final int PF_CMYK+
CS_YCCK) and decompressing YCCK JPEG
+ images into CMYK pixels.
++
+public static final int NUMCS+
+
+public static final int CS_RGB+
+
+public static final int CS_YCbCr+
+
+public static final int CS_GRAY+
+
+public static final int CS_CMYK+
+
+public static final int CS_YCCK+
+
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html index 40511c0e..30d5ff31 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html @@ -420,8 +420,8 @@ public void setSourceImage(byte[] srcImage,
srcImage - image buffer containing RGB or grayscale pixels to be
- compressedx - x offset (in pixels) of the region from which the JPEG image
+srcImage - image buffer containing RGB, grayscale, or CMYK pixels to
+ be compressedx - x offset (in pixels) of the region from which the JPEG image
should be compressed, relative to the start of srcImage.y - y offset (in pixels) of the region from which the JPEG image
should be compressed, relative to the start of srcImage.width - width (in pixels) of the region in the source image from
which the JPEG image should be compressed.pitch - bytes per line of the source image. Normally, this should be
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
index 4cb26157..d4f6bff9 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
@@ -122,7 +122,7 @@ Custom filter callback interface
protected int
jpegBufSize
+protected intjpegColorspace
+
+protected int jpegColorspace+
handle, jpegBuf, jpegBufSize, jpegHeight, jpegSubsamp, jpegWidthhandle, jpegBuf, jpegBufSize, jpegColorspace, jpegHeight, jpegSubsamp, jpegWidthsrcImage.
diff --git a/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
index 6e46fa1a..d862d66c 100644
--- a/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
+++ b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
@@ -39,7 +39,7 @@ public interface TJCustomFilter {
/**
* A callback function that can be used to modify the DCT coefficients after
* they are losslessly transformed but before they are transcoded to a new
- * JPEG file. This allows for custom filters or other transformations to be
+ * JPEG image. This allows for custom filters or other transformations to be
* applied in the frequency domain.
*
* @param coeffBuffer a buffer containing transformed DCT coefficients.
diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
index eb8d31cc..42c36912 100644
--- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
+++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
@@ -687,5 +687,6 @@ public class TJDecompressor {
protected int jpegWidth = 0;
protected int jpegHeight = 0;
protected int jpegSubsamp = -1;
+ protected int jpegColorspace = -1;
private ByteOrder byteOrder = null;
};
diff --git a/java/org_libjpegturbo_turbojpeg_TJ.h b/java/org_libjpegturbo_turbojpeg_TJ.h
index cec69e4c..d590831c 100644
--- a/java/org_libjpegturbo_turbojpeg_TJ.h
+++ b/java/org_libjpegturbo_turbojpeg_TJ.h
@@ -8,7 +8,7 @@
extern "C" {
#endif
#undef org_libjpegturbo_turbojpeg_TJ_NUMSAMP
-#define org_libjpegturbo_turbojpeg_TJ_NUMSAMP 5L
+#define org_libjpegturbo_turbojpeg_TJ_NUMSAMP 6L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP_444
#define org_libjpegturbo_turbojpeg_TJ_SAMP_444 0L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP_422
@@ -19,8 +19,10 @@ extern "C" {
#define org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY 3L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP_440
#define org_libjpegturbo_turbojpeg_TJ_SAMP_440 4L
+#undef org_libjpegturbo_turbojpeg_TJ_SAMP_411
+#define org_libjpegturbo_turbojpeg_TJ_SAMP_411 5L
#undef org_libjpegturbo_turbojpeg_TJ_NUMPF
-#define org_libjpegturbo_turbojpeg_TJ_NUMPF 11L
+#define org_libjpegturbo_turbojpeg_TJ_NUMPF 12L
#undef org_libjpegturbo_turbojpeg_TJ_PF_RGB
#define org_libjpegturbo_turbojpeg_TJ_PF_RGB 0L
#undef org_libjpegturbo_turbojpeg_TJ_PF_BGR
@@ -43,6 +45,20 @@ extern "C" {
#define org_libjpegturbo_turbojpeg_TJ_PF_ABGR 9L
#undef org_libjpegturbo_turbojpeg_TJ_PF_ARGB
#define org_libjpegturbo_turbojpeg_TJ_PF_ARGB 10L
+#undef org_libjpegturbo_turbojpeg_TJ_PF_CMYK
+#define org_libjpegturbo_turbojpeg_TJ_PF_CMYK 11L
+#undef org_libjpegturbo_turbojpeg_TJ_NUMCS
+#define org_libjpegturbo_turbojpeg_TJ_NUMCS 5L
+#undef org_libjpegturbo_turbojpeg_TJ_CS_RGB
+#define org_libjpegturbo_turbojpeg_TJ_CS_RGB 0L
+#undef org_libjpegturbo_turbojpeg_TJ_CS_YCbCr
+#define org_libjpegturbo_turbojpeg_TJ_CS_YCbCr 1L
+#undef org_libjpegturbo_turbojpeg_TJ_CS_GRAY
+#define org_libjpegturbo_turbojpeg_TJ_CS_GRAY 2L
+#undef org_libjpegturbo_turbojpeg_TJ_CS_CMYK
+#define org_libjpegturbo_turbojpeg_TJ_CS_CMYK 3L
+#undef org_libjpegturbo_turbojpeg_TJ_CS_YCCK
+#define org_libjpegturbo_turbojpeg_TJ_CS_YCCK 4L
#undef org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP
#define org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP 2L
#undef org_libjpegturbo_turbojpeg_TJ_FLAG_FORCEMMX
diff --git a/tjbench.c b/tjbench.c
index 615f2f73..b2ef8d6d 100644
--- a/tjbench.c
+++ b/tjbench.c
@@ -69,13 +69,13 @@ double benchtime=5.0;
char *formatName(int subsamp, int cs, char *buf)
{
- if(cs==TJCS_YCbCr) return subNameLong[subsamp];
+ if(cs==TJCS_YCbCr) return (char *)subNameLong[subsamp];
else if(cs==TJCS_YCCK)
{
snprintf(buf, 80, "%s %s", csName[cs], subNameLong[subsamp]);
return buf;
}
- else return csName[cs];
+ else return (char *)csName[cs];
}
diff --git a/tjunittest.c b/tjunittest.c
index 16ecd093..b738c6c2 100644
--- a/tjunittest.c
+++ b/tjunittest.c
@@ -467,7 +467,7 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
if(yuv==YUVENCODE) return;
if(yuv==YUVDECODE)
- printf("JPEG -> YUV %s ... ", subNameLong[subsamp]);
+ printf("JPEG -> YUV %s ", subNameLong[subsamp]);
else
printf("JPEG -> %s %s ", pixFormatStr[pf],
(flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down ");
diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c
index 174558e9..09c557b4 100644
--- a/turbojpeg-jni.c
+++ b/turbojpeg-jni.c
@@ -382,7 +382,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
{
tjhandle handle=0;
unsigned char *jpegBuf=NULL;
- int width=0, height=0, jpegSubsamp=-1;
+ int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
gethandle();
@@ -391,8 +391,8 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
- if(tjDecompressHeader2(handle, jpegBuf, (unsigned long)jpegSize,
- &width, &height, &jpegSubsamp)==-1)
+ if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
+ &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
{
(*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
_throw(tjGetErrorStr());
@@ -401,6 +401,8 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
(*env)->SetIntField(env, obj, _fid, jpegSubsamp);
+ bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegColorspace", "I"));
+ (*env)->SetIntField(env, obj, _fid, jpegColorspace);
bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
(*env)->SetIntField(env, obj, _fid, width);
bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
diff --git a/turbojpeg.h b/turbojpeg.h
index d0981439..065150c5 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -225,10 +225,39 @@ enum TJPF
};
+/**
+ * Red offset (in bytes) for a given pixel format. This specifies the number
+ * of bytes that the red component is offset from the start of the pixel. For
+ * instance, if a pixel of format TJ_BGRX is stored in char pixel[],
+ * then the red component will be pixel[tjRedOffset[TJ_BGRX]].
+ */
+static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1, -1};
+/**
+ * Green offset (in bytes) for a given pixel format. This specifies the number
+ * of bytes that the green component is offset from the start of the pixel.
+ * For instance, if a pixel of format TJ_BGRX is stored in
+ * char pixel[], then the green component will be
+ * pixel[tjGreenOffset[TJ_BGRX]].
+ */
+static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2, -1};
+/**
+ * Blue offset (in bytes) for a given pixel format. This specifies the number
+ * of bytes that the Blue component is offset from the start of the pixel. For
+ * instance, if a pixel of format TJ_BGRX is stored in char pixel[],
+ * then the blue component will be pixel[tjBlueOffset[TJ_BGRX]].
+ */
+static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3, -1};
+
+/**
+ * Pixel size (in bytes) for a given pixel format.
+ */
+static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4};
+
+
/**
* The number of JPEG colorspaces
*/
-#define TJ_NUMCS 12
+#define TJ_NUMCS 5
/**
* JPEG colorspaces
@@ -287,35 +316,6 @@ enum TJCS
};
-/**
- * Red offset (in bytes) for a given pixel format. This specifies the number
- * of bytes that the red component is offset from the start of the pixel. For
- * instance, if a pixel of format TJ_BGRX is stored in char pixel[],
- * then the red component will be pixel[tjRedOffset[TJ_BGRX]].
- */
-static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1, -1};
-/**
- * Green offset (in bytes) for a given pixel format. This specifies the number
- * of bytes that the green component is offset from the start of the pixel.
- * For instance, if a pixel of format TJ_BGRX is stored in
- * char pixel[], then the green component will be
- * pixel[tjGreenOffset[TJ_BGRX]].
- */
-static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2, -1};
-/**
- * Blue offset (in bytes) for a given pixel format. This specifies the number
- * of bytes that the Blue component is offset from the start of the pixel. For
- * instance, if a pixel of format TJ_BGRX is stored in char pixel[],
- * then the blue component will be pixel[tjBlueOffset[TJ_BGRX]].
- */
-static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3, -1};
-
-/**
- * Pixel size (in bytes) for a given pixel format.
- */
-static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4};
-
-
/**
* The uncompressed source/destination image is stored in bottom-up (Windows,
* OpenGL) order, not top-down (X11) order.