blob: 6c7b29eb1057ce67a0db10fc5d93fc0eb9134df0 [file] [log] [blame]
DRC3bad53f2011-02-23 02:20:49 +00001/*
DRCa15f19f2014-03-11 09:46:50 +00002 * Copyright (C)2011-2012, 2014 D. R. Commander. All Rights Reserved.
DRC3bad53f2011-02-23 02:20:49 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of the libjpeg-turbo Project nor the names of its
13 * contributors may be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * This program tests the various code paths in the TurboJPEG JNI Wrapper
31 */
32
33import java.io.*;
34import java.util.*;
DRC84a1bcc2011-02-23 12:09:56 +000035import java.awt.image.*;
36import javax.imageio.*;
DRCc08e8c12011-09-08 23:54:40 +000037import java.nio.*;
DRC3bad53f2011-02-23 02:20:49 +000038import org.libjpegturbo.turbojpeg.*;
39
40public class TJUnitTest {
41
DRCf7f3ea42011-03-01 20:03:32 +000042 private static final String classname =
43 new TJUnitTest().getClass().getName();
DRC3bad53f2011-02-23 02:20:49 +000044
DRCf7f3ea42011-03-01 20:03:32 +000045 private static void usage() {
46 System.out.println("\nUSAGE: java " + classname + " [options]\n");
47 System.out.println("Options:\n");
48 System.out.println("-yuv = test YUV encoding/decoding support\n");
49 System.out.println("-bi = test BufferedImage support\n");
50 System.exit(1);
51 }
DRC3bad53f2011-02-23 02:20:49 +000052
DRC67bee862013-04-27 12:36:07 +000053 private static final String[] subNameLong = {
DRCd0a81362011-03-04 13:04:24 +000054 "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0"
DRCf7f3ea42011-03-01 20:03:32 +000055 };
DRC67bee862013-04-27 12:36:07 +000056 private static final String[] subName = {
DRCd0a81362011-03-04 13:04:24 +000057 "444", "422", "420", "GRAY", "440"
DRCf7f3ea42011-03-01 20:03:32 +000058 };
DRC3bad53f2011-02-23 02:20:49 +000059
DRC67bee862013-04-27 12:36:07 +000060 private static final String[] pixFormatStr = {
DRC67ce3b22011-12-19 02:21:03 +000061 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
62 "RGBA", "BGRA", "ABGR", "ARGB"
DRCf7f3ea42011-03-01 20:03:32 +000063 };
DRCc08e8c12011-09-08 23:54:40 +000064
DRC67bee862013-04-27 12:36:07 +000065 private static final int[] alphaOffset = {
DRC67ce3b22011-12-19 02:21:03 +000066 -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0
DRCf7f3ea42011-03-01 20:03:32 +000067 };
DRC3bad53f2011-02-23 02:20:49 +000068
DRC67bee862013-04-27 12:36:07 +000069 private static final int[] _3byteFormats = {
DRCf7f3ea42011-03-01 20:03:32 +000070 TJ.PF_RGB, TJ.PF_BGR
71 };
DRC67bee862013-04-27 12:36:07 +000072 private static final int[] _3byteFormatsBI = {
DRCc08e8c12011-09-08 23:54:40 +000073 BufferedImage.TYPE_3BYTE_BGR
DRCf7f3ea42011-03-01 20:03:32 +000074 };
DRC67bee862013-04-27 12:36:07 +000075 private static final int[] _4byteFormats = {
DRCf7f3ea42011-03-01 20:03:32 +000076 TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB
77 };
DRC67bee862013-04-27 12:36:07 +000078 private static final int[] _4byteFormatsBI = {
DRCc08e8c12011-09-08 23:54:40 +000079 BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
80 BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
81 BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
DRCf7f3ea42011-03-01 20:03:32 +000082 };
DRC67bee862013-04-27 12:36:07 +000083 private static final int[] onlyGray = {
DRCf7f3ea42011-03-01 20:03:32 +000084 TJ.PF_GRAY
85 };
DRC67bee862013-04-27 12:36:07 +000086 private static final int[] onlyGrayBI = {
DRCc08e8c12011-09-08 23:54:40 +000087 BufferedImage.TYPE_BYTE_GRAY
88 };
DRC67bee862013-04-27 12:36:07 +000089 private static final int[] onlyRGB = {
DRCf7f3ea42011-03-01 20:03:32 +000090 TJ.PF_RGB
91 };
DRC3bad53f2011-02-23 02:20:49 +000092
DRC67bee862013-04-27 12:36:07 +000093 private static final int YUVENCODE = 1;
94 private static final int YUVDECODE = 2;
DRCf7f3ea42011-03-01 20:03:32 +000095 private static int yuv = 0;
96 private static boolean bi = false;
DRC3bad53f2011-02-23 02:20:49 +000097
DRCf7f3ea42011-03-01 20:03:32 +000098 private static int exitStatus = 0;
DRC3bad53f2011-02-23 02:20:49 +000099
DRCc08e8c12011-09-08 23:54:40 +0000100 private static int biTypePF(int biType) {
101 ByteOrder byteOrder = ByteOrder.nativeOrder();
102 switch(biType) {
103 case BufferedImage.TYPE_3BYTE_BGR:
104 return TJ.PF_BGR;
105 case BufferedImage.TYPE_4BYTE_ABGR:
106 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
107 return TJ.PF_XBGR;
108 case BufferedImage.TYPE_BYTE_GRAY:
109 return TJ.PF_GRAY;
110 case BufferedImage.TYPE_INT_BGR:
DRC67bee862013-04-27 12:36:07 +0000111 if (byteOrder == ByteOrder.BIG_ENDIAN)
DRCc08e8c12011-09-08 23:54:40 +0000112 return TJ.PF_XBGR;
113 else
114 return TJ.PF_RGBX;
115 case BufferedImage.TYPE_INT_RGB:
DRC67bee862013-04-27 12:36:07 +0000116 if (byteOrder == ByteOrder.BIG_ENDIAN)
DRCc08e8c12011-09-08 23:54:40 +0000117 return TJ.PF_XRGB;
118 else
119 return TJ.PF_BGRX;
DRC67ce3b22011-12-19 02:21:03 +0000120 case BufferedImage.TYPE_INT_ARGB:
121 case BufferedImage.TYPE_INT_ARGB_PRE:
DRC67bee862013-04-27 12:36:07 +0000122 if (byteOrder == ByteOrder.BIG_ENDIAN)
DRC67ce3b22011-12-19 02:21:03 +0000123 return TJ.PF_ARGB;
124 else
125 return TJ.PF_BGRA;
DRCc08e8c12011-09-08 23:54:40 +0000126 }
127 return 0;
128 }
129
130 private static String biTypeStr(int biType) {
131 switch(biType) {
132 case BufferedImage.TYPE_3BYTE_BGR:
133 return "3BYTE_BGR";
134 case BufferedImage.TYPE_4BYTE_ABGR:
135 return "4BYTE_ABGR";
136 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
137 return "4BYTE_ABGR_PRE";
138 case BufferedImage.TYPE_BYTE_GRAY:
139 return "BYTE_GRAY";
140 case BufferedImage.TYPE_INT_BGR:
141 return "INT_BGR";
142 case BufferedImage.TYPE_INT_RGB:
143 return "INT_RGB";
144 case BufferedImage.TYPE_INT_ARGB:
145 return "INT_ARGB";
146 case BufferedImage.TYPE_INT_ARGB_PRE:
147 return "INT_ARGB_PRE";
148 }
149 return "Unknown";
150 }
DRCc08e8c12011-09-08 23:54:40 +0000151
DRCf7f3ea42011-03-01 20:03:32 +0000152 private static double getTime() {
153 return (double)System.nanoTime() / 1.0e9;
154 }
DRC3bad53f2011-02-23 02:20:49 +0000155
DRCf7f3ea42011-03-01 20:03:32 +0000156 private static void initBuf(byte[] buf, int w, int pitch, int h, int pf,
DRC67bee862013-04-27 12:36:07 +0000157 int flags) throws Exception {
DRC2c74e512011-03-16 00:02:53 +0000158 int roffset = TJ.getRedOffset(pf);
159 int goffset = TJ.getGreenOffset(pf);
160 int boffset = TJ.getBlueOffset(pf);
DRCc08e8c12011-09-08 23:54:40 +0000161 int aoffset = alphaOffset[pf];
DRCf7f3ea42011-03-01 20:03:32 +0000162 int ps = TJ.getPixelSize(pf);
DRCf962fbb2011-05-23 05:49:08 +0000163 int index, row, col, halfway = 16;
DRC3bad53f2011-02-23 02:20:49 +0000164
DRCf7f3ea42011-03-01 20:03:32 +0000165 Arrays.fill(buf, (byte)0);
DRC67bee862013-04-27 12:36:07 +0000166 if (pf == TJ.PF_GRAY) {
167 for (row = 0; row < h; row++) {
168 for (col = 0; col < w; col++) {
169 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
DRCf962fbb2011-05-23 05:49:08 +0000170 index = pitch * (h - row - 1) + col;
DRC67bee862013-04-27 12:36:07 +0000171 else
172 index = pitch * row + col;
173 if (((row / 8) + (col / 8)) % 2 == 0)
DRCf962fbb2011-05-23 05:49:08 +0000174 buf[index] = (row < halfway) ? (byte)255 : 0;
DRC67bee862013-04-27 12:36:07 +0000175 else
176 buf[index] = (row < halfway) ? 76 : (byte)226;
DRCf7f3ea42011-03-01 20:03:32 +0000177 }
178 }
179 return;
180 }
DRC67bee862013-04-27 12:36:07 +0000181 for (row = 0; row < h; row++) {
182 for (col = 0; col < w; col++) {
183 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
DRCf962fbb2011-05-23 05:49:08 +0000184 index = pitch * (h - row - 1) + col * ps;
DRC67bee862013-04-27 12:36:07 +0000185 else
186 index = pitch * row + col * ps;
187 if (((row / 8) + (col / 8)) % 2 == 0) {
188 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000189 buf[index + roffset] = (byte)255;
190 buf[index + goffset] = (byte)255;
191 buf[index + boffset] = (byte)255;
192 }
DRC67bee862013-04-27 12:36:07 +0000193 } else {
DRCf962fbb2011-05-23 05:49:08 +0000194 buf[index + roffset] = (byte)255;
DRC67bee862013-04-27 12:36:07 +0000195 if (row >= halfway)
196 buf[index + goffset] = (byte)255;
DRCf7f3ea42011-03-01 20:03:32 +0000197 }
DRC67bee862013-04-27 12:36:07 +0000198 if (aoffset >= 0)
199 buf[index + aoffset] = (byte)255;
DRCf7f3ea42011-03-01 20:03:32 +0000200 }
201 }
202 }
DRC3bad53f2011-02-23 02:20:49 +0000203
DRCf7f3ea42011-03-01 20:03:32 +0000204 private static void initIntBuf(int[] buf, int w, int pitch, int h, int pf,
DRC67bee862013-04-27 12:36:07 +0000205 int flags) throws Exception {
DRC2c74e512011-03-16 00:02:53 +0000206 int rshift = TJ.getRedOffset(pf) * 8;
207 int gshift = TJ.getGreenOffset(pf) * 8;
208 int bshift = TJ.getBlueOffset(pf) * 8;
DRCc08e8c12011-09-08 23:54:40 +0000209 int ashift = alphaOffset[pf] * 8;
DRCf962fbb2011-05-23 05:49:08 +0000210 int index, row, col, halfway = 16;
DRC84a1bcc2011-02-23 12:09:56 +0000211
DRCf7f3ea42011-03-01 20:03:32 +0000212 Arrays.fill(buf, 0);
DRC67bee862013-04-27 12:36:07 +0000213 for (row = 0; row < h; row++) {
214 for (col = 0; col < w; col++) {
215 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
DRCf962fbb2011-05-23 05:49:08 +0000216 index = pitch * (h - row - 1) + col;
DRC67bee862013-04-27 12:36:07 +0000217 else
218 index = pitch * row + col;
219 if (((row / 8) + (col / 8)) % 2 == 0) {
220 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000221 buf[index] |= (255 << rshift);
222 buf[index] |= (255 << gshift);
223 buf[index] |= (255 << bshift);
224 }
DRC67bee862013-04-27 12:36:07 +0000225 } else {
DRCf962fbb2011-05-23 05:49:08 +0000226 buf[index] |= (255 << rshift);
DRC67bee862013-04-27 12:36:07 +0000227 if (row >= halfway)
228 buf[index] |= (255 << gshift);
DRCf7f3ea42011-03-01 20:03:32 +0000229 }
DRC67bee862013-04-27 12:36:07 +0000230 if (ashift >= 0)
231 buf[index] |= (255 << ashift);
DRCf7f3ea42011-03-01 20:03:32 +0000232 }
233 }
234 }
DRC84a1bcc2011-02-23 12:09:56 +0000235
DRCf7f3ea42011-03-01 20:03:32 +0000236 private static void initImg(BufferedImage img, int pf, int flags)
DRC67bee862013-04-27 12:36:07 +0000237 throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000238 WritableRaster wr = img.getRaster();
DRCc08e8c12011-09-08 23:54:40 +0000239 int imgType = img.getType();
DRC67bee862013-04-27 12:36:07 +0000240 if (imgType == BufferedImage.TYPE_INT_RGB ||
241 imgType == BufferedImage.TYPE_INT_BGR ||
242 imgType == BufferedImage.TYPE_INT_ARGB ||
243 imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
DRCf7f3ea42011-03-01 20:03:32 +0000244 SinglePixelPackedSampleModel sm =
245 (SinglePixelPackedSampleModel)img.getSampleModel();
246 int pitch = sm.getScanlineStride();
247 DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
248 int[] buf = db.getData();
249 initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
DRC67bee862013-04-27 12:36:07 +0000250 } else {
DRCf7f3ea42011-03-01 20:03:32 +0000251 ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
252 int pitch = sm.getScanlineStride();
253 DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
254 byte[] buf = db.getData();
255 initBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
256 }
257 }
DRC3bad53f2011-02-23 02:20:49 +0000258
DRCf962fbb2011-05-23 05:49:08 +0000259 private static void checkVal(int row, int col, int v, String vname, int cv)
DRC67bee862013-04-27 12:36:07 +0000260 throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000261 v = (v < 0) ? v + 256 : v;
DRC67bee862013-04-27 12:36:07 +0000262 if (v < cv - 1 || v > cv + 1) {
DRC49df7832013-05-04 23:31:32 +0000263 throw new Exception("Comp. " + vname + " at " + row + "," + col +
264 " should be " + cv + ", not " + v);
DRCf7f3ea42011-03-01 20:03:32 +0000265 }
266 }
DRC3bad53f2011-02-23 02:20:49 +0000267
DRCf962fbb2011-05-23 05:49:08 +0000268 private static void checkVal0(int row, int col, int v, String vname)
DRC67bee862013-04-27 12:36:07 +0000269 throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000270 v = (v < 0) ? v + 256 : v;
DRC67bee862013-04-27 12:36:07 +0000271 if (v > 1) {
DRC49df7832013-05-04 23:31:32 +0000272 throw new Exception("Comp. " + vname + " at " + row + "," + col +
273 " should be 0, not " + v);
DRCf7f3ea42011-03-01 20:03:32 +0000274 }
275 }
DRC3bad53f2011-02-23 02:20:49 +0000276
DRCf962fbb2011-05-23 05:49:08 +0000277 private static void checkVal255(int row, int col, int v, String vname)
DRC67bee862013-04-27 12:36:07 +0000278 throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000279 v = (v < 0) ? v + 256 : v;
DRC67bee862013-04-27 12:36:07 +0000280 if (v < 254) {
DRC49df7832013-05-04 23:31:32 +0000281 throw new Exception("Comp. " + vname + " at " + row + "," + col +
282 " should be 255, not " + v);
DRCf7f3ea42011-03-01 20:03:32 +0000283 }
284 }
DRC3bad53f2011-02-23 02:20:49 +0000285
DRCf7f3ea42011-03-01 20:03:32 +0000286 private static int checkBuf(byte[] buf, int w, int pitch, int h, int pf,
DRC67bee862013-04-27 12:36:07 +0000287 int subsamp, TJScalingFactor sf, int flags)
288 throws Exception {
DRC2c74e512011-03-16 00:02:53 +0000289 int roffset = TJ.getRedOffset(pf);
290 int goffset = TJ.getGreenOffset(pf);
291 int boffset = TJ.getBlueOffset(pf);
DRCc08e8c12011-09-08 23:54:40 +0000292 int aoffset = alphaOffset[pf];
DRCf7f3ea42011-03-01 20:03:32 +0000293 int ps = TJ.getPixelSize(pf);
DRCf962fbb2011-05-23 05:49:08 +0000294 int index, row, col, retval = 1;
DRCb2f94152011-04-02 02:09:03 +0000295 int halfway = 16 * sf.getNum() / sf.getDenom();
296 int blockSize = 8 * sf.getNum() / sf.getDenom();
DRC3bad53f2011-02-23 02:20:49 +0000297
DRCf7f3ea42011-03-01 20:03:32 +0000298 try {
DRC67bee862013-04-27 12:36:07 +0000299 for (row = 0; row < halfway; row++) {
300 for (col = 0; col < w; col++) {
301 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
DRCf962fbb2011-05-23 05:49:08 +0000302 index = pitch * (h - row - 1) + col * ps;
DRC67bee862013-04-27 12:36:07 +0000303 else
304 index = pitch * row + col * ps;
DRCf962fbb2011-05-23 05:49:08 +0000305 byte r = buf[index + roffset];
306 byte g = buf[index + goffset];
307 byte b = buf[index + boffset];
DRCc08e8c12011-09-08 23:54:40 +0000308 byte a = aoffset >= 0 ? buf[index + aoffset] : (byte)255;
DRC67bee862013-04-27 12:36:07 +0000309 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
310 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000311 checkVal255(row, col, r, "R");
312 checkVal255(row, col, g, "G");
313 checkVal255(row, col, b, "B");
DRC67bee862013-04-27 12:36:07 +0000314 } else {
DRCf962fbb2011-05-23 05:49:08 +0000315 checkVal0(row, col, r, "R");
316 checkVal0(row, col, g, "G");
317 checkVal0(row, col, b, "B");
318 }
DRC67bee862013-04-27 12:36:07 +0000319 } else {
320 if (subsamp == TJ.SAMP_GRAY) {
321 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000322 checkVal(row, col, r, "R", 76);
323 checkVal(row, col, g, "G", 76);
324 checkVal(row, col, b, "B", 76);
DRC67bee862013-04-27 12:36:07 +0000325 } else {
DRCf962fbb2011-05-23 05:49:08 +0000326 checkVal(row, col, r, "R", 226);
327 checkVal(row, col, g, "G", 226);
328 checkVal(row, col, b, "B", 226);
329 }
DRC67bee862013-04-27 12:36:07 +0000330 } else {
DRCf962fbb2011-05-23 05:49:08 +0000331 checkVal255(row, col, r, "R");
DRC67bee862013-04-27 12:36:07 +0000332 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000333 checkVal0(row, col, g, "G");
DRC67bee862013-04-27 12:36:07 +0000334 } else {
DRCf962fbb2011-05-23 05:49:08 +0000335 checkVal255(row, col, g, "G");
336 }
DRC67bee862013-04-27 12:36:07 +0000337 checkVal0(row, col, b, "B");
DRCf7f3ea42011-03-01 20:03:32 +0000338 }
339 }
DRCc08e8c12011-09-08 23:54:40 +0000340 checkVal255(row, col, a, "A");
DRCf7f3ea42011-03-01 20:03:32 +0000341 }
342 }
DRC67bee862013-04-27 12:36:07 +0000343 } catch(Exception e) {
DRC49df7832013-05-04 23:31:32 +0000344 System.out.println("\n" + e.getMessage());
DRCf7f3ea42011-03-01 20:03:32 +0000345 retval = 0;
346 }
DRC4f1580c2011-02-25 06:11:03 +0000347
DRC67bee862013-04-27 12:36:07 +0000348 if (retval == 0) {
DRC67bee862013-04-27 12:36:07 +0000349 for (row = 0; row < h; row++) {
350 for (col = 0; col < w; col++) {
DRCf962fbb2011-05-23 05:49:08 +0000351 int r = buf[pitch * row + col * ps + roffset];
352 int g = buf[pitch * row + col * ps + goffset];
353 int b = buf[pitch * row + col * ps + boffset];
DRC67bee862013-04-27 12:36:07 +0000354 if (r < 0) r += 256;
355 if (g < 0) g += 256;
356 if (b < 0) b += 256;
DRCf7f3ea42011-03-01 20:03:32 +0000357 System.out.format("%3d/%3d/%3d ", r, g, b);
358 }
359 System.out.print("\n");
360 }
361 }
362 return retval;
363 }
DRC4f1580c2011-02-25 06:11:03 +0000364
DRCf7f3ea42011-03-01 20:03:32 +0000365 private static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
DRC67bee862013-04-27 12:36:07 +0000366 int subsamp, TJScalingFactor sf, int flags)
367 throws Exception {
DRC2c74e512011-03-16 00:02:53 +0000368 int rshift = TJ.getRedOffset(pf) * 8;
369 int gshift = TJ.getGreenOffset(pf) * 8;
370 int bshift = TJ.getBlueOffset(pf) * 8;
DRCc08e8c12011-09-08 23:54:40 +0000371 int ashift = alphaOffset[pf] * 8;
DRCf962fbb2011-05-23 05:49:08 +0000372 int index, row, col, retval = 1;
DRCb2f94152011-04-02 02:09:03 +0000373 int halfway = 16 * sf.getNum() / sf.getDenom();
374 int blockSize = 8 * sf.getNum() / sf.getDenom();
DRC4f1580c2011-02-25 06:11:03 +0000375
DRCf7f3ea42011-03-01 20:03:32 +0000376 try {
DRC67bee862013-04-27 12:36:07 +0000377 for (row = 0; row < halfway; row++) {
378 for (col = 0; col < w; col++) {
379 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
DRCf962fbb2011-05-23 05:49:08 +0000380 index = pitch * (h - row - 1) + col;
DRC67bee862013-04-27 12:36:07 +0000381 else
382 index = pitch * row + col;
DRCf962fbb2011-05-23 05:49:08 +0000383 int r = (buf[index] >> rshift) & 0xFF;
384 int g = (buf[index] >> gshift) & 0xFF;
385 int b = (buf[index] >> bshift) & 0xFF;
DRCc08e8c12011-09-08 23:54:40 +0000386 int a = ashift >= 0 ? (buf[index] >> ashift) & 0xFF : 255;
DRC67bee862013-04-27 12:36:07 +0000387 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
388 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000389 checkVal255(row, col, r, "R");
390 checkVal255(row, col, g, "G");
391 checkVal255(row, col, b, "B");
DRC67bee862013-04-27 12:36:07 +0000392 } else {
DRCf962fbb2011-05-23 05:49:08 +0000393 checkVal0(row, col, r, "R");
394 checkVal0(row, col, g, "G");
395 checkVal0(row, col, b, "B");
396 }
DRC67bee862013-04-27 12:36:07 +0000397 } else {
398 if (subsamp == TJ.SAMP_GRAY) {
399 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000400 checkVal(row, col, r, "R", 76);
401 checkVal(row, col, g, "G", 76);
402 checkVal(row, col, b, "B", 76);
DRC67bee862013-04-27 12:36:07 +0000403 } else {
DRCf962fbb2011-05-23 05:49:08 +0000404 checkVal(row, col, r, "R", 226);
405 checkVal(row, col, g, "G", 226);
406 checkVal(row, col, b, "B", 226);
407 }
DRC67bee862013-04-27 12:36:07 +0000408 } else {
DRCf962fbb2011-05-23 05:49:08 +0000409 checkVal255(row, col, r, "R");
DRC67bee862013-04-27 12:36:07 +0000410 if (row < halfway) {
DRCf962fbb2011-05-23 05:49:08 +0000411 checkVal0(row, col, g, "G");
DRC67bee862013-04-27 12:36:07 +0000412 } else {
DRCf962fbb2011-05-23 05:49:08 +0000413 checkVal255(row, col, g, "G");
414 }
415 checkVal0(row, col, b, "B");
DRCf7f3ea42011-03-01 20:03:32 +0000416 }
417 }
DRCc08e8c12011-09-08 23:54:40 +0000418 checkVal255(row, col, a, "A");
DRCf7f3ea42011-03-01 20:03:32 +0000419 }
420 }
DRC67bee862013-04-27 12:36:07 +0000421 } catch(Exception e) {
DRC49df7832013-05-04 23:31:32 +0000422 System.out.println("\n" + e.getMessage());
DRCf7f3ea42011-03-01 20:03:32 +0000423 retval = 0;
424 }
DRC4f1580c2011-02-25 06:11:03 +0000425
DRC67bee862013-04-27 12:36:07 +0000426 if (retval == 0) {
DRC67bee862013-04-27 12:36:07 +0000427 for (row = 0; row < h; row++) {
428 for (col = 0; col < w; col++) {
DRCf962fbb2011-05-23 05:49:08 +0000429 int r = (buf[pitch * row + col] >> rshift) & 0xFF;
430 int g = (buf[pitch * row + col] >> gshift) & 0xFF;
431 int b = (buf[pitch * row + col] >> bshift) & 0xFF;
DRC67bee862013-04-27 12:36:07 +0000432 if (r < 0) r += 256;
433 if (g < 0) g += 256;
434 if (b < 0) b += 256;
DRCf7f3ea42011-03-01 20:03:32 +0000435 System.out.format("%3d/%3d/%3d ", r, g, b);
436 }
437 System.out.print("\n");
438 }
439 }
440 return retval;
441 }
DRC3bad53f2011-02-23 02:20:49 +0000442
DRC67bee862013-04-27 12:36:07 +0000443 private static int checkImg(BufferedImage img, int pf, int subsamp,
444 TJScalingFactor sf, int flags) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000445 WritableRaster wr = img.getRaster();
DRCc08e8c12011-09-08 23:54:40 +0000446 int imgType = img.getType();
DRC67bee862013-04-27 12:36:07 +0000447 if (imgType == BufferedImage.TYPE_INT_RGB ||
448 imgType == BufferedImage.TYPE_INT_BGR ||
449 imgType == BufferedImage.TYPE_INT_ARGB ||
450 imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
451 SinglePixelPackedSampleModel sm =
DRCf7f3ea42011-03-01 20:03:32 +0000452 (SinglePixelPackedSampleModel)img.getSampleModel();
453 int pitch = sm.getScanlineStride();
454 DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
455 int[] buf = db.getData();
456 return checkIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf,
DRC67bee862013-04-27 12:36:07 +0000457 subsamp, sf, flags);
458 } else {
DRCf7f3ea42011-03-01 20:03:32 +0000459 ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
460 int pitch = sm.getScanlineStride();
461 DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
462 byte[] buf = db.getData();
463 return checkBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, subsamp,
DRC67bee862013-04-27 12:36:07 +0000464 sf, flags);
DRCf7f3ea42011-03-01 20:03:32 +0000465 }
466 }
DRC84a1bcc2011-02-23 12:09:56 +0000467
DRCf7f3ea42011-03-01 20:03:32 +0000468 private static int PAD(int v, int p) {
469 return ((v + (p) - 1) & (~((p) - 1)));
470 }
DRC3bad53f2011-02-23 02:20:49 +0000471
DRCf7f3ea42011-03-01 20:03:32 +0000472 private static int checkBufYUV(byte[] buf, int size, int w, int h,
DRC67bee862013-04-27 12:36:07 +0000473 int subsamp) throws Exception {
DRC215aa8b2011-05-27 02:10:42 +0000474 int row, col;
DRC67bee862013-04-27 12:36:07 +0000475 int hsf = TJ.getMCUWidth(subsamp) / 8, vsf = TJ.getMCUHeight(subsamp) / 8;
DRCf7f3ea42011-03-01 20:03:32 +0000476 int pw = PAD(w, hsf), ph = PAD(h, vsf);
477 int cw = pw / hsf, ch = ph / vsf;
478 int ypitch = PAD(pw, 4), uvpitch = PAD(cw, 4);
479 int retval = 1;
DRC67bee862013-04-27 12:36:07 +0000480 int correctsize = ypitch * ph +
481 (subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2);
DRC215aa8b2011-05-27 02:10:42 +0000482 int halfway = 16;
DRC3bad53f2011-02-23 02:20:49 +0000483
DRCf7f3ea42011-03-01 20:03:32 +0000484 try {
DRC67bee862013-04-27 12:36:07 +0000485 if (size != correctsize)
DRC49df7832013-05-04 23:31:32 +0000486 throw new Exception("Incorrect size " + size + ". Should be " +
DRC67bee862013-04-27 12:36:07 +0000487 correctsize);
DRC3bad53f2011-02-23 02:20:49 +0000488
DRC67bee862013-04-27 12:36:07 +0000489 for (row = 0; row < ph; row++) {
490 for (col = 0; col < pw; col++) {
DRC215aa8b2011-05-27 02:10:42 +0000491 byte y = buf[ypitch * row + col];
DRC67bee862013-04-27 12:36:07 +0000492 if (((row / 8) + (col / 8)) % 2 == 0) {
493 if (row < halfway)
494 checkVal255(row, col, y, "Y");
495 else
496 checkVal0(row, col, y, "Y");
497 } else {
498 if (row < halfway)
499 checkVal(row, col, y, "Y", 76);
500 else
501 checkVal(row, col, y, "Y", 226);
DRC215aa8b2011-05-27 02:10:42 +0000502 }
DRCf7f3ea42011-03-01 20:03:32 +0000503 }
504 }
DRC67bee862013-04-27 12:36:07 +0000505 if (subsamp != TJ.SAMP_GRAY) {
DRC215aa8b2011-05-27 02:10:42 +0000506 halfway = 16 / vsf;
DRC67bee862013-04-27 12:36:07 +0000507 for (row = 0; row < ch; row++) {
508 for (col = 0; col < cw; col++) {
DRC215aa8b2011-05-27 02:10:42 +0000509 byte u = buf[ypitch * ph + (uvpitch * row + col)],
DRC67bee862013-04-27 12:36:07 +0000510 v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
511 if (((row * vsf / 8) + (col * hsf / 8)) % 2 == 0) {
DRC215aa8b2011-05-27 02:10:42 +0000512 checkVal(row, col, u, "U", 128);
513 checkVal(row, col, v, "V", 128);
DRC67bee862013-04-27 12:36:07 +0000514 } else {
515 if (row < halfway) {
DRC215aa8b2011-05-27 02:10:42 +0000516 checkVal(row, col, u, "U", 85);
517 checkVal255(row, col, v, "V");
DRC67bee862013-04-27 12:36:07 +0000518 } else {
DRC215aa8b2011-05-27 02:10:42 +0000519 checkVal0(row, col, u, "U");
520 checkVal(row, col, v, "V", 149);
521 }
DRCf7f3ea42011-03-01 20:03:32 +0000522 }
523 }
524 }
525 }
DRC67bee862013-04-27 12:36:07 +0000526 } catch(Exception e) {
DRC49df7832013-05-04 23:31:32 +0000527 System.out.println("\n" + e.getMessage());
DRCf7f3ea42011-03-01 20:03:32 +0000528 retval = 0;
529 }
DRC3bad53f2011-02-23 02:20:49 +0000530
DRC67bee862013-04-27 12:36:07 +0000531 if (retval == 0) {
532 for (row = 0; row < ph; row++) {
533 for (col = 0; col < pw; col++) {
DRC215aa8b2011-05-27 02:10:42 +0000534 int y = buf[ypitch * row + col];
DRC67bee862013-04-27 12:36:07 +0000535 if (y < 0) y += 256;
DRCf7f3ea42011-03-01 20:03:32 +0000536 System.out.format("%3d ", y);
537 }
538 System.out.print("\n");
539 }
540 System.out.print("\n");
DRC67bee862013-04-27 12:36:07 +0000541 for (row = 0; row < ch; row++) {
542 for (col = 0; col < cw; col++) {
DRC215aa8b2011-05-27 02:10:42 +0000543 int u = buf[ypitch * ph + (uvpitch * row + col)];
DRC67bee862013-04-27 12:36:07 +0000544 if (u < 0) u += 256;
DRCf7f3ea42011-03-01 20:03:32 +0000545 System.out.format("%3d ", u);
546 }
547 System.out.print("\n");
548 }
549 System.out.print("\n");
DRC67bee862013-04-27 12:36:07 +0000550 for (row = 0; row < ch; row++) {
551 for (col = 0; col < cw; col++) {
DRC215aa8b2011-05-27 02:10:42 +0000552 int v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
DRC67bee862013-04-27 12:36:07 +0000553 if (v < 0) v += 256;
DRCf7f3ea42011-03-01 20:03:32 +0000554 System.out.format("%3d ", v);
555 }
556 System.out.print("\n");
557 }
DRCf7f3ea42011-03-01 20:03:32 +0000558 }
DRC3bad53f2011-02-23 02:20:49 +0000559
DRCf7f3ea42011-03-01 20:03:32 +0000560 return retval;
561 }
DRC3bad53f2011-02-23 02:20:49 +0000562
DRCf7f3ea42011-03-01 20:03:32 +0000563 private static void writeJPEG(byte[] jpegBuf, int jpegBufSize,
DRC67bee862013-04-27 12:36:07 +0000564 String filename) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000565 File file = new File(filename);
566 FileOutputStream fos = new FileOutputStream(file);
567 fos.write(jpegBuf, 0, jpegBufSize);
568 fos.close();
569 }
DRC3bad53f2011-02-23 02:20:49 +0000570
DRCf962fbb2011-05-23 05:49:08 +0000571 private static int compTest(TJCompressor tjc, byte[] dstBuf, int w,
DRC67bee862013-04-27 12:36:07 +0000572 int h, int pf, String baseName, int subsamp,
573 int jpegQual, int flags) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000574 String tempstr;
DRCf962fbb2011-05-23 05:49:08 +0000575 byte[] srcBuf = null;
DRCf7f3ea42011-03-01 20:03:32 +0000576 BufferedImage img = null;
577 String pfStr;
578 double t;
DRCc08e8c12011-09-08 23:54:40 +0000579 int size = 0, ps, imgType = pf;
DRC3bad53f2011-02-23 02:20:49 +0000580
DRCc08e8c12011-09-08 23:54:40 +0000581 if (bi) {
582 pf = biTypePF(imgType);
583 pfStr = biTypeStr(imgType);
DRC67bee862013-04-27 12:36:07 +0000584 } else
585 pfStr = pixFormatStr[pf];
DRCc08e8c12011-09-08 23:54:40 +0000586 ps = TJ.getPixelSize(pf);
DRC3bad53f2011-02-23 02:20:49 +0000587
DRCf7f3ea42011-03-01 20:03:32 +0000588 System.out.print(pfStr + " ");
DRC67bee862013-04-27 12:36:07 +0000589 if (bi)
590 System.out.print("(" + pixFormatStr[pf] + ") ");
591 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
592 System.out.print("Bottom-Up");
593 else
594 System.out.print("Top-Down ");
DRCf7f3ea42011-03-01 20:03:32 +0000595 System.out.print(" -> " + subNameLong[subsamp] + " ");
DRC67bee862013-04-27 12:36:07 +0000596 if (yuv == YUVENCODE)
597 System.out.print("YUV ... ");
598 else
599 System.out.print("Q" + jpegQual + " ... ");
DRC3bad53f2011-02-23 02:20:49 +0000600
DRC67bee862013-04-27 12:36:07 +0000601 if (bi) {
DRCc08e8c12011-09-08 23:54:40 +0000602 img = new BufferedImage(w, h, imgType);
DRCf7f3ea42011-03-01 20:03:32 +0000603 initImg(img, pf, flags);
DRC67bee862013-04-27 12:36:07 +0000604 tempstr = baseName + "_enc_" + pfStr + "_" +
605 (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
606 subName[subsamp] + "_Q" + jpegQual + ".png";
DRCf7f3ea42011-03-01 20:03:32 +0000607 File file = new File(tempstr);
608 ImageIO.write(img, "png", file);
DRC67bee862013-04-27 12:36:07 +0000609 } else {
DRCf962fbb2011-05-23 05:49:08 +0000610 srcBuf = new byte[w * h * ps + 1];
611 initBuf(srcBuf, w, w * ps, h, pf, flags);
DRCf7f3ea42011-03-01 20:03:32 +0000612 }
DRCf962fbb2011-05-23 05:49:08 +0000613 Arrays.fill(dstBuf, (byte)0);
DRC3bad53f2011-02-23 02:20:49 +0000614
DRCf7f3ea42011-03-01 20:03:32 +0000615 t = getTime();
616 tjc.setSubsamp(subsamp);
DRCf962fbb2011-05-23 05:49:08 +0000617 tjc.setJPEGQuality(jpegQual);
DRC67bee862013-04-27 12:36:07 +0000618 if (bi) {
619 if (yuv == YUVENCODE)
620 tjc.encodeYUV(img, dstBuf, flags);
621 else
622 tjc.compress(img, dstBuf, flags);
623 } else {
DRCc33347c2014-03-15 13:25:11 +0000624 tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, pf);
DRC67bee862013-04-27 12:36:07 +0000625 if (yuv == YUVENCODE)
626 tjc.encodeYUV(dstBuf, flags);
627 else
628 tjc.compress(dstBuf, flags);
DRCf7f3ea42011-03-01 20:03:32 +0000629 }
630 size = tjc.getCompressedSize();
631 t = getTime() - t;
DRC3bad53f2011-02-23 02:20:49 +0000632
DRC67bee862013-04-27 12:36:07 +0000633 if (yuv == YUVENCODE)
634 tempstr = baseName + "_enc_" + pfStr + "_" +
635 (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
636 subName[subsamp] + ".yuv";
DRCf7f3ea42011-03-01 20:03:32 +0000637 else
DRC67bee862013-04-27 12:36:07 +0000638 tempstr = baseName + "_enc_" + pfStr + "_" +
639 (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
640 subName[subsamp] + "_Q" + jpegQual + ".jpg";
DRCf962fbb2011-05-23 05:49:08 +0000641 writeJPEG(dstBuf, size, tempstr);
DRC84a1bcc2011-02-23 12:09:56 +0000642
DRC67bee862013-04-27 12:36:07 +0000643 if (yuv == YUVENCODE) {
644 if (checkBufYUV(dstBuf, size, w, h, subsamp) == 1)
DRCf7f3ea42011-03-01 20:03:32 +0000645 System.out.print("Passed.");
646 else {
DRC67bee862013-04-27 12:36:07 +0000647 System.out.print("FAILED!");
648 exitStatus = -1;
DRCf7f3ea42011-03-01 20:03:32 +0000649 }
DRC67bee862013-04-27 12:36:07 +0000650 } else
651 System.out.print("Done.");
DRCf7f3ea42011-03-01 20:03:32 +0000652 System.out.format(" %.6f ms\n", t * 1000.);
653 System.out.println(" Result in " + tempstr);
DRC3bad53f2011-02-23 02:20:49 +0000654
DRCf7f3ea42011-03-01 20:03:32 +0000655 return size;
656 }
DRC3bad53f2011-02-23 02:20:49 +0000657
DRCf962fbb2011-05-23 05:49:08 +0000658 private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
DRC67bee862013-04-27 12:36:07 +0000659 int jpegSize, int w, int h, int pf,
660 String baseName, int subsamp, int flags,
661 TJScalingFactor sf) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000662 String pfStr, tempstr;
663 double t;
DRCb2f94152011-04-02 02:09:03 +0000664 int scaledWidth = sf.getScaled(w);
665 int scaledHeight = sf.getScaled(h);
DRCc08e8c12011-09-08 23:54:40 +0000666 int temp1, temp2, imgType = pf;
DRCf7f3ea42011-03-01 20:03:32 +0000667 BufferedImage img = null;
DRCf962fbb2011-05-23 05:49:08 +0000668 byte[] dstBuf = null;
DRC3bad53f2011-02-23 02:20:49 +0000669
DRC67bee862013-04-27 12:36:07 +0000670 if (yuv == YUVENCODE) return;
DRC3bad53f2011-02-23 02:20:49 +0000671
DRCc08e8c12011-09-08 23:54:40 +0000672 if (bi) {
673 pf = biTypePF(imgType);
674 pfStr = biTypeStr(imgType);
DRC67bee862013-04-27 12:36:07 +0000675 } else
676 pfStr = pixFormatStr[pf];
DRCc08e8c12011-09-08 23:54:40 +0000677
DRCf7f3ea42011-03-01 20:03:32 +0000678 System.out.print("JPEG -> ");
DRC67bee862013-04-27 12:36:07 +0000679 if (yuv == YUVDECODE)
DRC49df7832013-05-04 23:31:32 +0000680 System.out.print("YUV " + subNameLong[subsamp] + " ... ");
DRCf7f3ea42011-03-01 20:03:32 +0000681 else {
682 System.out.print(pfStr + " ");
DRC67bee862013-04-27 12:36:07 +0000683 if (bi)
684 System.out.print("(" + pixFormatStr[pf] + ") ");
685 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
686 System.out.print("Bottom-Up ");
687 else
688 System.out.print("Top-Down ");
689 if (!sf.isOne())
DRCb2f94152011-04-02 02:09:03 +0000690 System.out.print(sf.getNum() + "/" + sf.getDenom() + " ... ");
DRC67bee862013-04-27 12:36:07 +0000691 else
692 System.out.print("... ");
DRCf7f3ea42011-03-01 20:03:32 +0000693 }
DRC3bad53f2011-02-23 02:20:49 +0000694
DRCf7f3ea42011-03-01 20:03:32 +0000695 t = getTime();
DRCf962fbb2011-05-23 05:49:08 +0000696 tjd.setJPEGImage(jpegBuf, jpegSize);
DRC67bee862013-04-27 12:36:07 +0000697 if (tjd.getWidth() != w || tjd.getHeight() != h ||
698 tjd.getSubsamp() != subsamp)
DRCf7f3ea42011-03-01 20:03:32 +0000699 throw new Exception("Incorrect JPEG header");
DRC3bad53f2011-02-23 02:20:49 +0000700
DRCf7f3ea42011-03-01 20:03:32 +0000701 temp1 = scaledWidth;
702 temp2 = scaledHeight;
703 temp1 = tjd.getScaledWidth(temp1, temp2);
704 temp2 = tjd.getScaledHeight(temp1, temp2);
DRC67bee862013-04-27 12:36:07 +0000705 if (temp1 != scaledWidth || temp2 != scaledHeight)
DRCf7f3ea42011-03-01 20:03:32 +0000706 throw new Exception("Scaled size mismatch");
DRC3bad53f2011-02-23 02:20:49 +0000707
DRC67bee862013-04-27 12:36:07 +0000708 if (yuv == YUVDECODE)
709 dstBuf = tjd.decompressToYUV(flags);
DRCf7f3ea42011-03-01 20:03:32 +0000710 else {
DRC67bee862013-04-27 12:36:07 +0000711 if (bi)
DRCc08e8c12011-09-08 23:54:40 +0000712 img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags);
DRC67bee862013-04-27 12:36:07 +0000713 else
714 dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags);
DRCf7f3ea42011-03-01 20:03:32 +0000715 }
716 t = getTime() - t;
DRC3bad53f2011-02-23 02:20:49 +0000717
DRC67bee862013-04-27 12:36:07 +0000718 if (bi) {
719 tempstr = baseName + "_dec_" + pfStr + "_" +
720 (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
721 subName[subsamp] + "_" +
722 (double)sf.getNum() / (double)sf.getDenom() + "x" + ".png";
DRCf7f3ea42011-03-01 20:03:32 +0000723 File file = new File(tempstr);
724 ImageIO.write(img, "png", file);
725 }
DRC84a1bcc2011-02-23 12:09:56 +0000726
DRC67bee862013-04-27 12:36:07 +0000727 if (yuv == YUVDECODE) {
728 if (checkBufYUV(dstBuf, dstBuf.length, w, h, subsamp) == 1)
DRCf7f3ea42011-03-01 20:03:32 +0000729 System.out.print("Passed.");
730 else {
731 System.out.print("FAILED!"); exitStatus = -1;
732 }
DRC67bee862013-04-27 12:36:07 +0000733 } else {
734 if ((bi && checkImg(img, pf, subsamp, sf, flags) == 1) ||
735 (!bi && checkBuf(dstBuf, scaledWidth,
736 scaledWidth * TJ.getPixelSize(pf), scaledHeight, pf,
737 subsamp, sf, flags) == 1))
DRCf7f3ea42011-03-01 20:03:32 +0000738 System.out.print("Passed.");
739 else {
DRC67bee862013-04-27 12:36:07 +0000740 System.out.print("FAILED!");
741 exitStatus = -1;
DRCf7f3ea42011-03-01 20:03:32 +0000742 }
743 }
744 System.out.format(" %.6f ms\n", t * 1000.);
745 }
DRC3bad53f2011-02-23 02:20:49 +0000746
DRCf962fbb2011-05-23 05:49:08 +0000747 private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
DRC67bee862013-04-27 12:36:07 +0000748 int jpegSize, int w, int h, int pf,
749 String baseName, int subsamp,
750 int flags) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000751 int i;
DRC67bee862013-04-27 12:36:07 +0000752 if ((subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY) && yuv == 0) {
753 TJScalingFactor[] sf = TJ.getScalingFactors();
754 for (i = 0; i < sf.length; i++)
DRCf962fbb2011-05-23 05:49:08 +0000755 decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
DRC67bee862013-04-27 12:36:07 +0000756 flags, sf[i]);
757 } else
DRCf962fbb2011-05-23 05:49:08 +0000758 decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
DRC67bee862013-04-27 12:36:07 +0000759 flags, new TJScalingFactor(1, 1));
DRCf7f3ea42011-03-01 20:03:32 +0000760 }
DRC3bad53f2011-02-23 02:20:49 +0000761
DRCf7f3ea42011-03-01 20:03:32 +0000762 private static void doTest(int w, int h, int[] formats, int subsamp,
DRC67bee862013-04-27 12:36:07 +0000763 String baseName) throws Exception {
DRCf7f3ea42011-03-01 20:03:32 +0000764 TJCompressor tjc = null;
765 TJDecompressor tjd = null;
DRC4f8c2952011-03-31 10:06:17 +0000766 int size;
DRCf962fbb2011-05-23 05:49:08 +0000767 byte[] dstBuf;
DRC3bad53f2011-02-23 02:20:49 +0000768
DRC67bee862013-04-27 12:36:07 +0000769 if (yuv == YUVENCODE)
770 dstBuf = new byte[TJ.bufSizeYUV(w, h, subsamp)];
771 else
772 dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
DRC3bad53f2011-02-23 02:20:49 +0000773
DRCf7f3ea42011-03-01 20:03:32 +0000774 try {
775 tjc = new TJCompressor();
DRC67bee862013-04-27 12:36:07 +0000776 tjd = new TJDecompressor();
DRC3bad53f2011-02-23 02:20:49 +0000777
DRC67bee862013-04-27 12:36:07 +0000778 for (int pf : formats) {
779 for (int i = 0; i < 2; i++) {
DRCf7f3ea42011-03-01 20:03:32 +0000780 int flags = 0;
DRC67bee862013-04-27 12:36:07 +0000781 if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 ||
782 subsamp == TJ.SAMP_440)
DRCcac10512012-03-16 14:37:36 +0000783 flags |= TJ.FLAG_FASTUPSAMPLE;
DRC67bee862013-04-27 12:36:07 +0000784 if (i == 1) {
785 if (yuv == YUVDECODE) {
786 tjc.close();
787 tjd.close();
788 return;
789 } else
790 flags |= TJ.FLAG_BOTTOMUP;
DRCf7f3ea42011-03-01 20:03:32 +0000791 }
DRCf962fbb2011-05-23 05:49:08 +0000792 size = compTest(tjc, dstBuf, w, h, pf, baseName, subsamp, 100,
DRC67bee862013-04-27 12:36:07 +0000793 flags);
DRCf962fbb2011-05-23 05:49:08 +0000794 decompTest(tjd, dstBuf, size, w, h, pf, baseName, subsamp, flags);
DRC67bee862013-04-27 12:36:07 +0000795 if (pf >= TJ.PF_RGBX && pf <= TJ.PF_XRGB && !bi)
DRC67ce3b22011-12-19 02:21:03 +0000796 decompTest(tjd, dstBuf, size, w, h, pf + (TJ.PF_RGBA - TJ.PF_RGBX),
DRC67bee862013-04-27 12:36:07 +0000797 baseName, subsamp, flags);
DRC49df7832013-05-04 23:31:32 +0000798 System.out.print("\n");
DRCf7f3ea42011-03-01 20:03:32 +0000799 }
800 }
DRC49df7832013-05-04 23:31:32 +0000801 System.out.print("--------------------\n\n");
DRC67bee862013-04-27 12:36:07 +0000802 } catch(Exception e) {
803 if (tjc != null) tjc.close();
804 if (tjd != null) tjd.close();
DRCf7f3ea42011-03-01 20:03:32 +0000805 throw e;
806 }
DRC67bee862013-04-27 12:36:07 +0000807 if (tjc != null) tjc.close();
808 if (tjd != null) tjd.close();
DRCf7f3ea42011-03-01 20:03:32 +0000809 }
DRC3bad53f2011-02-23 02:20:49 +0000810
DRC724c56b2011-07-12 06:22:06 +0000811 private static void bufSizeTest() throws Exception {
812 int w, h, i, subsamp;
DRC2c0c8072014-02-11 09:56:12 +0000813 byte[] srcBuf, dstBuf;
DRCf7f3ea42011-03-01 20:03:32 +0000814 TJCompressor tjc = null;
DRC724c56b2011-07-12 06:22:06 +0000815 Random r = new Random();
DRC3bad53f2011-02-23 02:20:49 +0000816
DRCf7f3ea42011-03-01 20:03:32 +0000817 try {
818 tjc = new TJCompressor();
819 System.out.println("Buffer size regression test");
DRC67bee862013-04-27 12:36:07 +0000820 for (subsamp = 0; subsamp < TJ.NUMSAMP; subsamp++) {
821 for (w = 1; w < 48; w++) {
DRC724c56b2011-07-12 06:22:06 +0000822 int maxh = (w == 1) ? 2048 : 48;
DRC67bee862013-04-27 12:36:07 +0000823 for (h = 1; h < maxh; h++) {
824 if (h % 100 == 0)
DRC724c56b2011-07-12 06:22:06 +0000825 System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h);
826 srcBuf = new byte[w * h * 4];
DRC2c0c8072014-02-11 09:56:12 +0000827 if (yuv == YUVENCODE)
828 dstBuf = new byte[TJ.bufSizeYUV(w, h, subsamp)];
829 else
830 dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
DRC67bee862013-04-27 12:36:07 +0000831 for (i = 0; i < w * h * 4; i++) {
DRC724c56b2011-07-12 06:22:06 +0000832 srcBuf[i] = (byte)(r.nextInt(2) * 255);
833 }
DRCc33347c2014-03-15 13:25:11 +0000834 tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, TJ.PF_BGRX);
DRC724c56b2011-07-12 06:22:06 +0000835 tjc.setSubsamp(subsamp);
836 tjc.setJPEGQuality(100);
DRC2c0c8072014-02-11 09:56:12 +0000837 if (yuv == YUVENCODE)
838 tjc.encodeYUV(dstBuf, 0);
839 else
840 tjc.compress(dstBuf, 0);
DRC3bad53f2011-02-23 02:20:49 +0000841
DRC724c56b2011-07-12 06:22:06 +0000842 srcBuf = new byte[h * w * 4];
DRC2c0c8072014-02-11 09:56:12 +0000843 if (yuv == YUVENCODE)
844 dstBuf = new byte[TJ.bufSizeYUV(h, w, subsamp)];
845 else
846 dstBuf = new byte[TJ.bufSize(h, w, subsamp)];
DRC67bee862013-04-27 12:36:07 +0000847 for (i = 0; i < h * w * 4; i++) {
DRC724c56b2011-07-12 06:22:06 +0000848 srcBuf[i] = (byte)(r.nextInt(2) * 255);
849 }
DRCc33347c2014-03-15 13:25:11 +0000850 tjc.setSourceImage(srcBuf, 0, 0, h, 0, w, TJ.PF_BGRX);
DRC2c0c8072014-02-11 09:56:12 +0000851 if (yuv == YUVENCODE)
852 tjc.encodeYUV(dstBuf, 0);
853 else
854 tjc.compress(dstBuf, 0);
DRCf7f3ea42011-03-01 20:03:32 +0000855 }
DRCf7f3ea42011-03-01 20:03:32 +0000856 }
857 }
858 System.out.println("Done. ");
DRC67bee862013-04-27 12:36:07 +0000859 } catch(Exception e) {
860 if (tjc != null) tjc.close();
DRCf7f3ea42011-03-01 20:03:32 +0000861 throw e;
862 }
DRC67bee862013-04-27 12:36:07 +0000863 if (tjc != null) tjc.close();
DRCf7f3ea42011-03-01 20:03:32 +0000864 }
DRC3bad53f2011-02-23 02:20:49 +0000865
DRC67bee862013-04-27 12:36:07 +0000866 public static void main(String[] argv) {
DRCf7f3ea42011-03-01 20:03:32 +0000867 try {
DRCb6ed7d32011-03-31 20:58:03 +0000868 String testName = "javatest";
DRCf7f3ea42011-03-01 20:03:32 +0000869 boolean doyuv = false;
DRC67bee862013-04-27 12:36:07 +0000870 for (int i = 0; i < argv.length; i++) {
871 if (argv[i].equalsIgnoreCase("-yuv"))
872 doyuv = true;
873 if (argv[i].substring(0, 1).equalsIgnoreCase("-h") ||
874 argv[i].equalsIgnoreCase("-?"))
DRCf7f3ea42011-03-01 20:03:32 +0000875 usage();
DRC67bee862013-04-27 12:36:07 +0000876 if (argv[i].equalsIgnoreCase("-bi")) {
DRCb6ed7d32011-03-31 20:58:03 +0000877 bi = true;
878 testName = "javabitest";
879 }
DRCf7f3ea42011-03-01 20:03:32 +0000880 }
DRC67bee862013-04-27 12:36:07 +0000881 if (doyuv) yuv = YUVENCODE;
882 doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444,
883 testName);
884 doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444,
885 testName);
DRCcac10512012-03-16 14:37:36 +0000886 doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_422,
DRC67bee862013-04-27 12:36:07 +0000887 testName);
DRCcac10512012-03-16 14:37:36 +0000888 doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_422,
DRC67bee862013-04-27 12:36:07 +0000889 testName);
DRCcac10512012-03-16 14:37:36 +0000890 doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_420,
DRC67bee862013-04-27 12:36:07 +0000891 testName);
DRCcac10512012-03-16 14:37:36 +0000892 doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_420,
DRC67bee862013-04-27 12:36:07 +0000893 testName);
DRCcac10512012-03-16 14:37:36 +0000894 doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_440,
DRC67bee862013-04-27 12:36:07 +0000895 testName);
DRCcac10512012-03-16 14:37:36 +0000896 doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440,
DRC67bee862013-04-27 12:36:07 +0000897 testName);
DRCc08e8c12011-09-08 23:54:40 +0000898 doTest(35, 39, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName);
DRCf7f3ea42011-03-01 20:03:32 +0000899 doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY,
DRC67bee862013-04-27 12:36:07 +0000900 testName);
DRCf7f3ea42011-03-01 20:03:32 +0000901 doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
DRC67bee862013-04-27 12:36:07 +0000902 testName);
DRC2c0c8072014-02-11 09:56:12 +0000903 if (!bi)
DRC67bee862013-04-27 12:36:07 +0000904 bufSizeTest();
905 if (doyuv && !bi) {
DRCa15f19f2014-03-11 09:46:50 +0000906 System.out.print("\n--------------------\n\n");
DRCf7f3ea42011-03-01 20:03:32 +0000907 yuv = YUVDECODE;
DRCb6ed7d32011-03-31 20:58:03 +0000908 doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0");
909 doTest(35, 39, onlyRGB, TJ.SAMP_444, "javatest_yuv1");
910 doTest(48, 48, onlyRGB, TJ.SAMP_422, "javatest_yuv0");
911 doTest(39, 41, onlyRGB, TJ.SAMP_422, "javatest_yuv1");
912 doTest(48, 48, onlyRGB, TJ.SAMP_420, "javatest_yuv0");
913 doTest(41, 35, onlyRGB, TJ.SAMP_420, "javatest_yuv1");
914 doTest(48, 48, onlyRGB, TJ.SAMP_440, "javatest_yuv0");
915 doTest(35, 39, onlyRGB, TJ.SAMP_440, "javatest_yuv1");
916 doTest(48, 48, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv0");
917 doTest(35, 39, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv1");
918 doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0");
919 doTest(39, 41, onlyGray, TJ.SAMP_GRAY, "javatest_yuv1");
DRCf7f3ea42011-03-01 20:03:32 +0000920 }
DRC67bee862013-04-27 12:36:07 +0000921 } catch(Exception e) {
DRC2e2358e2011-03-04 09:54:59 +0000922 e.printStackTrace();
DRCf7f3ea42011-03-01 20:03:32 +0000923 exitStatus = -1;
924 }
925 System.exit(exitStatus);
926 }
DRC3bad53f2011-02-23 02:20:49 +0000927}