Add 4:1:1 subsampling support in the TurboJPEG Java API

This commit is contained in:
DRC
2013-08-18 11:04:21 +00:00
parent 2296d513c1
commit 45b2cca4c0
6 changed files with 76 additions and 17 deletions

View File

@@ -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--)

View File

@@ -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();

View File

@@ -156,7 +156,7 @@ org.libjpegturbo.*</FONT></TH>
<A NAME="org.libjpegturbo.turbojpeg.TJ.NUMSAMP"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
<TD ALIGN="left"><CODE><A HREF="org/libjpegturbo/turbojpeg/TJ.html#NUMSAMP">NUMSAMP</A></CODE></TD>
<TD ALIGN="right"><CODE>5</CODE></TD>
<TD ALIGN="right"><CODE>6</CODE></TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<A NAME="org.libjpegturbo.turbojpeg.TJ.PF_ABGR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
@@ -225,6 +225,12 @@ org.libjpegturbo.*</FONT></TH>
<TD ALIGN="right"><CODE>5</CODE></TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<A NAME="org.libjpegturbo.turbojpeg.TJ.SAMP_411"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
<TD ALIGN="left"><CODE><A HREF="org/libjpegturbo/turbojpeg/TJ.html#SAMP_411">SAMP_411</A></CODE></TD>
<TD ALIGN="right"><CODE>5</CODE></TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<A NAME="org.libjpegturbo.turbojpeg.TJ.SAMP_420"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
<TD ALIGN="left"><CODE><A HREF="org/libjpegturbo/turbojpeg/TJ.html#SAMP_420">SAMP_420</A></CODE></TD>

View File

@@ -465,6 +465,9 @@ Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/
<A NAME="_S_"><!-- --></A><H2>
<B>S</B></H2>
<DL>
<DT><A HREF="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_411"><B>SAMP_411</B></A> -
Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</A>
<DD>4:1:1 chrominance subsampling.
<DT><A HREF="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_420"><B>SAMP_420</B></A> -
Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</A>
<DD>4:2:0 chrominance subsampling.

View File

@@ -291,6 +291,14 @@ TurboJPEG utility class (cannot be instantiated)
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>static&nbsp;int</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_411">SAMP_411</A></B></CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4:1:1 chrominance subsampling.</TD>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>static&nbsp;int</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_420">SAMP_420</A></B></CODE>
<BR>
@@ -550,6 +558,25 @@ public static final int <B>SAMP_440</B></PRE>
</DL>
<HR>
<A NAME="SAMP_411"><!-- --></A><H3>
SAMP_411</H3>
<PRE>
public static final int <B>SAMP_411</B></PRE>
<DL>
<DD>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.
<P>
<DL>
<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_411">Constant Field Values</A></DL>
</DL>
<HR>
<A NAME="NUMPF"><!-- --></A><H3>
NUMPF</H3>
<PRE>

View File

@@ -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
};