diff --git a/CMakeLists.txt b/CMakeLists.txt index 11337a16..a28240f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -753,6 +753,10 @@ if(WITH_JAVA) ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -yuv -noyuvpad) + add_test(TJUnitTest-lossless + ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar + -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} + TJUnitTest -lossless) add_test(TJUnitTest-bi ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} @@ -765,6 +769,10 @@ if(WITH_JAVA) ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} TJUnitTest -bi -yuv -noyuvpad) + add_test(TJUnitTest-bi-lossless + ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar + -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR} + TJUnitTest -bi -lossless) endif() set(TEST_LIBTYPES "") @@ -890,6 +898,10 @@ foreach(libtype ${TEST_LIBTYPES}) ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -alloc) add_test(tjunittest-${libtype}-yuv-nopad ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -noyuvpad) + add_test(tjunittest-${libtype}-lossless + ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -lossless) + add_test(tjunittest-${libtype}-lossless-alloc + ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -lossless -alloc) add_test(tjunittest-${libtype}-bmp ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -bmp) diff --git a/ChangeLog.md b/ChangeLog.md index fa9625a4..cc5df1e4 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -31,9 +31,12 @@ tables. have been removed. 4. Added support for 8-bit and 12-bit lossless JPEG images. A new libjpeg API -function (`jpeg_enable_lossless()`) and cjpeg command-line argument -(`-lossless`) can be used to create a lossless JPEG image. (Decompression of -lossless JPEG images is handled automatically.) +function (`jpeg_enable_lossless()`), TurboJPEG API flag (`TJFLAG_LOSSLESS` in +the C API and `TJ.FLAG_LOSSLESS` in the Java API), and cjpeg/TJBench +command-line argument (`-lossless`) can be used to create a lossless JPEG +image. (Decompression of lossless JPEG images is handled automatically.) Note +that the TurboJPEG API and TJBench can currently only be used to create and +decompress 8-bit lossless JPEG images. 5. Introduced a new flag in the TurboJPEG C and Java APIs (`TJFLAG_ARITHMETIC` and `TJ.FLAG_ARITHMETIC`, respectively) that causes the library to use diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index b02b44c4..ccfa8866 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -128,6 +128,9 @@ Macros
Limit the number of progressive JPEG scans that the decompression and transform functions will process.
If a progressive JPEG image contains an unreasonably large number of scans, then this flag will cause the decompression and transform functions to return an error. The primary purpose of this is to allow security-critical applications to guard against an exploit of the progressive JPEG format described in this report.
+ + + +| #define TJFLAG_LOSSLESS | +
Generate a lossless JPEG image when compressing.
+In most cases, compressing and decompressing lossless JPEG images is considerably slower than compressing and decompressing lossy JPEG images. Also note that the following features are not available with lossless JPEG images:
*jpegSize should be set to the size of your pre-allocated buffer. In any case, unless you have set TJFLAG_NOREALLOC, you should always check *jpegBuf upon return from this function, as it may have changed.
*jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) If *jpegBuf points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then *jpegSize is ignored.jpegQual is psv * 10 + Pt, where psv is the predictor selection value (1-7) and Pt is the point transform (0-7). A point transform value of 0 is necessary in order to create a fully lossless JPEG image. (A non-zero point transform value right-shifts the input samples by the specified number of bits, which is effectively a form of lossy color quantization.)32768public static final intFLAG_LOSSLESS131072public static final intFLAG_PROGRESSIVE16384public static final intFLAG_STOPONWARNING8192public static final intNUMCS5public static final intNUMERR2public static final intNUMPF12public static final intNUMSAMP6public static final intPF_ABGR9public static final intPF_ARGB10public static final intPF_BGR1public static final intPF_BGRA8public static final intPF_BGRX3public static final intPF_CMYK11public static final intPF_GRAY6public static final intPF_RGB0public static final intPF_RGBA7public static final intPF_RGBX2public static final intPF_XBGR4public static final intPF_XRGB5public static final intSAMP_4115public static final intSAMP_4202public static final intSAMP_4221public static final intSAMP_4404public static final intSAMP_4440public static final intstatic intFLAG_LOSSLESS
+static intFLAG_PROGRESSIVE
static intFLAG_STOPONWARNING
static intNUMCS
static intNUMERR
static intNUMPF
static intNUMSAMP
static intPF_ABGR
static intPF_ARGB
static intPF_BGR
static intPF_BGRA
static intPF_BGRX
static intPF_CMYK
static intPF_GRAY
static intPF_RGB
static intPF_RGBA
static intPF_RGBX
static intPF_XBGR
static intPF_XRGB
static intSAMP_411
static intSAMP_420
static intSAMP_422
static intSAMP_440
static intSAMP_444
static intSAMP_GRAY
public static final int FLAG_LOSSLESS+
public void setJPEGQuality(int quality)
quality - the new JPEG image quality level (1 to 100, 1 = worst,
- 100 = best)TJ.FLAG_LOSSLESS), quality is
+ psv * 10 + Pt, where psv is the predictor
+ selection value (1-7) and Pt is the point transform (0-7). A
+ point transform value of 0 is necessary in order to create a fully
+ lossless JPEG image. (A non-zero point transform value right-shifts the
+ input samples by the specified number of bits, which is effectively a form
+ of lossy color quantization.)
diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java
index 92d28566..98e01f14 100644
--- a/java/org/libjpegturbo/turbojpeg/TJ.java
+++ b/java/org/libjpegturbo/turbojpeg/TJ.java
@@ -377,7 +377,7 @@ public final class TJ {
* The uncompressed source/destination image is stored in bottom-up (Windows,
* OpenGL) order, not top-down (X11) order.
*/
- public static final int FLAG_BOTTOMUP = 2;
+ public static final int FLAG_BOTTOMUP = (1 << 1);
/**
* When decompressing an image that was compressed using chrominance
@@ -386,7 +386,7 @@ public final class TJ {
* creates a smooth transition between neighboring chrominance components in
* order to reduce upsampling artifacts in the decompressed image.
*/
- public static final int FLAG_FASTUPSAMPLE = 256;
+ public static final int FLAG_FASTUPSAMPLE = (1 << 8);
/**
* Use the fastest DCT/IDCT algorithm available in the underlying codec. The
* default if this flag is not specified is implementation-specific. For
@@ -395,7 +395,7 @@ public final class TJ {
* only a very slight effect on accuracy, but it uses the accurate algorithm
* when decompressing, because this has been shown to have a larger effect.
*/
- public static final int FLAG_FASTDCT = 2048;
+ public static final int FLAG_FASTDCT = (1 << 11);
/**
* Use the most accurate DCT/IDCT algorithm available in the underlying
* codec. The default if this flag is not specified is
@@ -405,7 +405,7 @@ public final class TJ {
* but it uses the accurate algorithm when decompressing, because this has
* been shown to have a larger effect.
*/
- public static final int FLAG_ACCURATEDCT = 4096;
+ public static final int FLAG_ACCURATEDCT = (1 << 12);
/**
* Immediately discontinue the current compression/decompression/transform
* operation if the underlying codec throws a warning (non-fatal error). The
@@ -417,7 +417,7 @@ public final class TJ {
* 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;
+ public static final int FLAG_STOPONWARNING = (1 << 13);
/**
* Use progressive entropy coding in JPEG images generated by compression and
* transform operations. Progressive entropy coding will generally improve
@@ -425,7 +425,7 @@ public final class TJ {
* reduce compression and decompression performance considerably. Can be
* combined with {@link #FLAG_ARITHMETIC}.
*/
- public static final int FLAG_PROGRESSIVE = 16384;
+ public static final int FLAG_PROGRESSIVE = (1 << 14);
/**
* Limit the number of progressive JPEG scans that the decompression and
* transform operations will process. If a progressive JPEG image contains
@@ -435,7 +435,7 @@ public final class TJ {
* against an exploit of the progressive JPEG format described in
* this report.
*/
- public static final int FLAG_LIMITSCANS = 32768;
+ public static final int FLAG_LIMITSCANS = (1 << 15);
/**
* Use arithmetic entropy coding in JPEG images generated by compression and
* transform operations. Arithmetic entropy coding will generally improve
@@ -443,7 +443,25 @@ public final class TJ {
* reduce compression and decompression performance considerably. Can be
* combined with {@link #FLAG_PROGRESSIVE}.
*/
- public static final int FLAG_ARITHMETIC = 65536;
+ public static final int FLAG_ARITHMETIC = (1 << 16);
+ /**
+ * Generate a lossless JPEG image when compressing. In most cases,
+ * compressing and decompressing lossless JPEG images is considerably slower
+ * than compressing and decompressing lossy JPEG images. Also note that the
+ * following features are not available with lossless JPEG images:
+ * quality is
+ * psv * 10 + Pt, where psv is the predictor
+ * selection value (1-7) and Pt is the point transform (0-7). A
+ * point transform value of 0 is necessary in order to create a fully
+ * lossless JPEG image. (A non-zero point transform value right-shifts the
+ * input samples by the specified number of bits, which is effectively a form
+ * of lossy color quantization.)
*/
public void setJPEGQuality(int quality) {
if (quality < 1 || quality > 100)
diff --git a/java/org/libjpegturbo/turbojpeg/TJTransform.java b/java/org/libjpegturbo/turbojpeg/TJTransform.java
index c655bf19..214768cf 100644
--- a/java/org/libjpegturbo/turbojpeg/TJTransform.java
+++ b/java/org/libjpegturbo/turbojpeg/TJTransform.java
@@ -103,21 +103,21 @@ public class TJTransform extends Rectangle {
* partial MCU blocks that cannot be transformed will be left in place, which
* will create odd-looking strips on the right or bottom edge of the image.
*/
- public static final int OPT_PERFECT = 1;
+ public static final int OPT_PERFECT = (1 << 0);
/**
* This option will discard any partial MCU blocks that cannot be
* transformed.
*/
- public static final int OPT_TRIM = 2;
+ public static final int OPT_TRIM = (1 << 1);
/**
* This option will enable lossless cropping.
*/
- public static final int OPT_CROP = 4;
+ public static final int OPT_CROP = (1 << 2);
/**
* This option will discard the color data in the input image and produce
* a grayscale output image.
*/
- public static final int OPT_GRAY = 8;
+ public static final int OPT_GRAY = (1 << 3);
/**
* This option will prevent {@link TJTransformer#transform
* TJTransformer.transform()} from outputting a JPEG image for this
@@ -125,7 +125,7 @@ public class TJTransform extends Rectangle {
* filter to capture the transformed DCT coefficients without transcoding
* them.
*/
- public static final int OPT_NOOUTPUT = 16;
+ public static final int OPT_NOOUTPUT = (1 << 4);
/**
* This option will enable progressive entropy coding in the output image
* generated by this particular transform. Progressive entropy coding will
@@ -133,13 +133,13 @@ public class TJTransform extends Rectangle {
* default), but it will reduce compression and decompression performance
* considerably. Can be combined with {@link #OPT_ARITHMETIC}.
*/
- public static final int OPT_PROGRESSIVE = 32;
+ public static final int OPT_PROGRESSIVE = (1 << 5);
/**
* This option will prevent {@link TJTransformer#transform
* TJTransformer.transform()} from copying any extra markers (including EXIF
* and ICC profile data) from the source image to the output image.
*/
- public static final int OPT_COPYNONE = 64;
+ public static final int OPT_COPYNONE = (1 << 6);
/**
* This option will enable arithmetic entropy coding in the output image
* generated by this particular transform. Arithmetic entropy coding will
@@ -147,7 +147,7 @@ public class TJTransform extends Rectangle {
* default), but it will reduce compression and decompression performance
* considerably. Can be combined with {@link #OPT_PROGRESSIVE}.
*/
- public static final int OPT_ARITHMETIC = 128;
+ public static final int OPT_ARITHMETIC = (1 << 7);
/**
diff --git a/tjbench.c b/tjbench.c
index b6848c43..b26c8f2f 100644
--- a/tjbench.c
+++ b/tjbench.c
@@ -775,6 +775,11 @@ static void usage(char *progName)
printf("-arithmetic = Use arithmetic entropy coding in JPEG images generated by\n");
printf(" compression and transform operations. (Can be combined with\n");
printf(" -progressive.)\n");
+ printf("-lossless = Generate lossless JPEG images (implies -subsamp 444). When\n");
+ printf(" generating lossless JPEG images, Quality is psv * 10 + Pt, where psv is\n");
+ printf(" the predictor selection value (1-7) and Pt is the point transform (0-7).\n");
+ printf(" A point transform value of 0 is necessary in order to create a fully\n");
+ printf(" lossless JPEG image.\n");
printf("-subsamp