diff --git a/java/TJBench.java b/java/TJBench.java index eaf5fa38..e5ca2f4a 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -45,11 +45,11 @@ class TJBench { }; static final String[] subNameLong = { - "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" + "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1" }; static final String[] subName = { - "444", "422", "420", "GRAY", "440" + "444", "422", "420", "GRAY", "440", "411" }; static TJScalingFactor sf; @@ -601,6 +601,7 @@ class TJBench { System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the"); System.out.println(" underlying codec"); System.out.println("-440 = Test 4:4:0 chrominance subsampling instead of 4:2:2"); + System.out.println("-411 = Test 4:1:1 chrominance subsampling instead of 4:2:0"); System.out.println("-quiet = Output results in tabular rather than verbose format"); System.out.println("-yuvencode = Encode RGB input as planar YUV rather than compressing as JPEG"); System.out.println("-yuvdecode = Decode JPEG image to planar YUV rather than RGB"); @@ -637,7 +638,7 @@ class TJBench { byte[] srcBuf = null; int w = 0, h = 0; int minQual = -1, maxQual = -1; int minArg = 1; int retval = 0; - boolean do440 = false; + boolean do440 = false, do411 = false; try { @@ -717,6 +718,8 @@ class TJBench { } if (argv[i].equals("-440")) do440 = true; + if (argv[i].equals("-411")) + do411 = true; if (argv[i].equalsIgnoreCase("-rgb")) pf = TJ.PF_RGB; if (argv[i].equalsIgnoreCase("-rgbx")) @@ -834,7 +837,7 @@ class TJBench { System.out.println(""); System.gc(); for (int i = maxQual; i >= minQual; i--) - doTest(srcBuf, w, h, TJ.SAMP_420, i, argv[0]); + doTest(srcBuf, w, h, do411 ? TJ.SAMP_411 : TJ.SAMP_420, i, argv[0]); System.out.println(""); System.gc(); for (int i = maxQual; i >= minQual; i--) diff --git a/java/TJUnitTest.java b/java/TJUnitTest.java index c894b13c..b4840006 100644 --- a/java/TJUnitTest.java +++ b/java/TJUnitTest.java @@ -53,10 +53,10 @@ public class TJUnitTest { } private static final String[] subNameLong = { - "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" + "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1" }; private static final String[] subName = { - "444", "422", "420", "GRAY", "440" + "444", "422", "420", "GRAY", "440", "411" }; private static final String[] pixFormatStr = { @@ -762,7 +762,10 @@ public class TJUnitTest { int num = sf[i].getNum(); int denom = sf[i].getDenom(); if (subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY || - (num == 1 && (denom == 4 || denom == 2 || denom == 1))) + (subsamp == TJ.SAMP_411 && num == 1 && + (denom == 2 || denom == 1)) || + (subsamp != TJ.SAMP_411 && num == 1 && + (denom == 4 || denom == 2 || denom == 1))) decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp, flags, sf[i]); } @@ -788,7 +791,7 @@ public class TJUnitTest { for (int i = 0; i < 2; i++) { int flags = 0; if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 || - subsamp == TJ.SAMP_440) + subsamp == TJ.SAMP_440 || subsamp == TJ.SAMP_411) flags |= TJ.FLAG_FASTUPSAMPLE; if (i == 1) { if (yuv == YUVDECODE) { @@ -894,10 +897,14 @@ public class TJUnitTest { testName); doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440, testName); - doTest(35, 39, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName); - doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY, + doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_411, testName); - doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY, + doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_411, + testName); + doTest(39, 41, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName); + doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY, + testName); + doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY, testName); if (!doyuv && !bi) bufSizeTest(); @@ -911,10 +918,12 @@ public class TJUnitTest { doTest(41, 35, onlyRGB, TJ.SAMP_420, "javatest_yuv1"); doTest(48, 48, onlyRGB, TJ.SAMP_440, "javatest_yuv0"); doTest(35, 39, onlyRGB, TJ.SAMP_440, "javatest_yuv1"); + doTest(48, 48, onlyRGB, TJ.SAMP_411, "javatest_yuv0"); + doTest(39, 41, onlyRGB, TJ.SAMP_411, "javatest_yuv1"); doTest(48, 48, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv0"); - doTest(35, 39, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv1"); + doTest(41, 35, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv1"); doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0"); - doTest(39, 41, onlyGray, TJ.SAMP_GRAY, "javatest_yuv1"); + doTest(35, 39, onlyGray, TJ.SAMP_GRAY, "javatest_yuv1"); } } catch(Exception e) { e.printStackTrace(); diff --git a/java/doc/constant-values.html b/java/doc/constant-values.html index e4adb67a..e1a5a984 100644 --- a/java/doc/constant-values.html +++ b/java/doc/constant-values.html @@ -156,7 +156,7 @@ org.libjpegturbo.* public static final int NUMSAMP -5 +6 @@ -225,6 +225,12 @@ org.libjpegturbo.* 5 + +public static final int +SAMP_411 +5 + + public static final int SAMP_420 diff --git a/java/doc/index-all.html b/java/doc/index-all.html index 56ac2d5b..2630fb1c 100644 --- a/java/doc/index-all.html +++ b/java/doc/index-all.html @@ -465,6 +465,9 @@ Static variable in class org.libjpegturbo.turbojpeg.

S

+
SAMP_411 - +Static variable in class org.libjpegturbo.turbojpeg.TJ +
4:1:1 chrominance subsampling.
SAMP_420 - Static variable in class org.libjpegturbo.turbojpeg.TJ
4:2:0 chrominance subsampling. diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/java/doc/org/libjpegturbo/turbojpeg/TJ.html index 50ade498..2f272465 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJ.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJ.html @@ -291,6 +291,14 @@ TurboJPEG utility class (cannot be instantiated) static int +SAMP_411 + +
+          4:1:1 chrominance subsampling. + + + +static int SAMP_420
@@ -550,6 +558,25 @@ public static final int SAMP_440

+

+SAMP_411

+
+public static final int SAMP_411
+
+
4:1:1 chrominance subsampling. The JPEG or YUV image will contain one + chrominance component for every 4x1 block of pixels in the source image. + JPEG images compressed with 4:1:1 subsampling will be almost exactly the + same size as those compressed with 4:2:0 subsampling, and in the + aggregate, both subsampling methods produce approximately the same + perceptual quality. However, 4:1:1 is better able to reproduce sharp + horizontal features. Note that 4:1:1 subsampling is not fully accelerated + in libjpeg-turbo. +

+

+
See Also:
Constant Field Values
+
+
+

NUMPF

diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java
index f240ad58..833ae97e 100644
--- a/java/org/libjpegturbo/turbojpeg/TJ.java
+++ b/java/org/libjpegturbo/turbojpeg/TJ.java
@@ -37,7 +37,7 @@ public final class TJ {
   /**
    * The number of chrominance subsampling options
    */
-  public static final int NUMSAMP   = 5;
+  public static final int NUMSAMP   = 6;
   /**
    * 4:4:4 chrominance subsampling (no chrominance subsampling).  The JPEG
    * or YUV image will contain one chrominance component for every pixel in the
@@ -64,6 +64,17 @@ public final class TJ {
    * Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
    */
   public static final int SAMP_440  = 4;
+  /**
+   * 4:1:1 chrominance subsampling.  The JPEG or YUV image will contain one
+   * chrominance component for every 4x1 block of pixels in the source image.
+   * JPEG images compressed with 4:1:1 subsampling will be almost exactly the
+   * same size as those compressed with 4:2:0 subsampling, and in the
+   * aggregate, both subsampling methods produce approximately the same
+   * perceptual quality.  However, 4:1:1 is better able to reproduce sharp
+   * horizontal features.  Note that 4:1:1 subsampling is not fully accelerated
+   * in libjpeg-turbo.
+   */
+  public static final int SAMP_411  = 5;
 
 
   /**
@@ -82,7 +93,7 @@ public final class TJ {
   }
 
   private static final int[] mcuWidth = {
-    8, 16, 16, 8, 8
+    8, 16, 16, 8, 8, 32
   };
 
 
@@ -103,7 +114,7 @@ public final class TJ {
   }
 
   private static final int[] mcuHeight = {
-    8, 8, 16, 8, 16
+    8, 8, 16, 8, 16, 8
   };