Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: java/TJUnitTest.java

Issue 1934113002: Update libjpeg_turbo to 1.4.90 from https://github.com/libjpeg-turbo/ (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C)2011-2016 D. R. Commander. All Rights Reserved.
3 *
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
33 import java.io.*;
34 import java.util.*;
35 import java.awt.image.*;
36 import javax.imageio.*;
37 import java.nio.*;
38 import org.libjpegturbo.turbojpeg.*;
39
40 public class TJUnitTest {
41
42 private static final String classname =
43 new TJUnitTest().getClass().getName();
44
45 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("-noyuvpad = do not pad each line of each Y, U, and V pla ne to the nearest\n");
50 System.out.println(" 4-byte boundary\n");
51 System.out.println("-bi = test BufferedImage support\n");
52 System.exit(1);
53 }
54
55 private static final String[] subNameLong = {
56 "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
57 };
58 private static final String[] subName = {
59 "444", "422", "420", "GRAY", "440", "411"
60 };
61
62 private static final String[] pixFormatStr = {
63 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
64 "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
65 };
66
67 private static final int[] alphaOffset = {
68 -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
69 };
70
71 private static final int[] _3byteFormats = {
72 TJ.PF_RGB, TJ.PF_BGR
73 };
74 private static final int[] _3byteFormatsBI = {
75 BufferedImage.TYPE_3BYTE_BGR
76 };
77 private static final int[] _4byteFormats = {
78 TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB, TJ.PF_CMYK
79 };
80 private static final int[] _4byteFormatsBI = {
81 BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
82 BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
83 BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
84 };
85 private static final int[] onlyGray = {
86 TJ.PF_GRAY
87 };
88 private static final int[] onlyGrayBI = {
89 BufferedImage.TYPE_BYTE_GRAY
90 };
91 private static final int[] onlyRGB = {
92 TJ.PF_RGB
93 };
94
95 private static boolean doYUV = false;
96 private static int pad = 4;
97 private static boolean bi = false;
98
99 private static int exitStatus = 0;
100
101 private static int biTypePF(int biType) {
102 ByteOrder byteOrder = ByteOrder.nativeOrder();
103 switch(biType) {
104 case BufferedImage.TYPE_3BYTE_BGR:
105 return TJ.PF_BGR;
106 case BufferedImage.TYPE_4BYTE_ABGR:
107 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
108 return TJ.PF_ABGR;
109 case BufferedImage.TYPE_BYTE_GRAY:
110 return TJ.PF_GRAY;
111 case BufferedImage.TYPE_INT_BGR:
112 if (byteOrder == ByteOrder.BIG_ENDIAN)
113 return TJ.PF_XBGR;
114 else
115 return TJ.PF_RGBX;
116 case BufferedImage.TYPE_INT_RGB:
117 if (byteOrder == ByteOrder.BIG_ENDIAN)
118 return TJ.PF_XRGB;
119 else
120 return TJ.PF_BGRX;
121 case BufferedImage.TYPE_INT_ARGB:
122 case BufferedImage.TYPE_INT_ARGB_PRE:
123 if (byteOrder == ByteOrder.BIG_ENDIAN)
124 return TJ.PF_ARGB;
125 else
126 return TJ.PF_BGRA;
127 }
128 return 0;
129 }
130
131 private static String biTypeStr(int biType) {
132 switch(biType) {
133 case BufferedImage.TYPE_3BYTE_BGR:
134 return "3BYTE_BGR";
135 case BufferedImage.TYPE_4BYTE_ABGR:
136 return "4BYTE_ABGR";
137 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
138 return "4BYTE_ABGR_PRE";
139 case BufferedImage.TYPE_BYTE_GRAY:
140 return "BYTE_GRAY";
141 case BufferedImage.TYPE_INT_BGR:
142 return "INT_BGR";
143 case BufferedImage.TYPE_INT_RGB:
144 return "INT_RGB";
145 case BufferedImage.TYPE_INT_ARGB:
146 return "INT_ARGB";
147 case BufferedImage.TYPE_INT_ARGB_PRE:
148 return "INT_ARGB_PRE";
149 }
150 return "Unknown";
151 }
152
153 private static void initBuf(byte[] buf, int w, int pitch, int h, int pf,
154 int flags) throws Exception {
155 int roffset = TJ.getRedOffset(pf);
156 int goffset = TJ.getGreenOffset(pf);
157 int boffset = TJ.getBlueOffset(pf);
158 int aoffset = alphaOffset[pf];
159 int ps = TJ.getPixelSize(pf);
160 int index, row, col, halfway = 16;
161
162 if (pf == TJ.PF_GRAY) {
163 Arrays.fill(buf, (byte)0);
164 for (row = 0; row < h; row++) {
165 for (col = 0; col < w; col++) {
166 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
167 index = pitch * (h - row - 1) + col;
168 else
169 index = pitch * row + col;
170 if (((row / 8) + (col / 8)) % 2 == 0)
171 buf[index] = (row < halfway) ? (byte)255 : 0;
172 else
173 buf[index] = (row < halfway) ? 76 : (byte)226;
174 }
175 }
176 return;
177 }
178 if (pf == TJ.PF_CMYK) {
179 Arrays.fill(buf, (byte)255);
180 for (row = 0; row < h; row++) {
181 for (col = 0; col < w; col++) {
182 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
183 index = (h - row - 1) * w + col;
184 else
185 index = row * w + col;
186 if (((row / 8) + (col / 8)) % 2 == 0) {
187 if (row >= halfway) buf[index * ps + 3] = 0;
188 } else {
189 buf[index * ps + 2] = 0;
190 if (row < halfway)
191 buf[index * ps + 1] = 0;
192 }
193 }
194 }
195 return;
196 }
197
198 Arrays.fill(buf, (byte)0);
199 for (row = 0; row < h; row++) {
200 for (col = 0; col < w; col++) {
201 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
202 index = pitch * (h - row - 1) + col * ps;
203 else
204 index = pitch * row + col * ps;
205 if (((row / 8) + (col / 8)) % 2 == 0) {
206 if (row < halfway) {
207 buf[index + roffset] = (byte)255;
208 buf[index + goffset] = (byte)255;
209 buf[index + boffset] = (byte)255;
210 }
211 } else {
212 buf[index + roffset] = (byte)255;
213 if (row >= halfway)
214 buf[index + goffset] = (byte)255;
215 }
216 if (aoffset >= 0)
217 buf[index + aoffset] = (byte)255;
218 }
219 }
220 }
221
222 private static void initIntBuf(int[] buf, int w, int pitch, int h, int pf,
223 int flags) throws Exception {
224 int rshift = TJ.getRedOffset(pf) * 8;
225 int gshift = TJ.getGreenOffset(pf) * 8;
226 int bshift = TJ.getBlueOffset(pf) * 8;
227 int ashift = alphaOffset[pf] * 8;
228 int index, row, col, halfway = 16;
229
230 Arrays.fill(buf, 0);
231 for (row = 0; row < h; row++) {
232 for (col = 0; col < w; col++) {
233 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
234 index = pitch * (h - row - 1) + col;
235 else
236 index = pitch * row + col;
237 if (((row / 8) + (col / 8)) % 2 == 0) {
238 if (row < halfway) {
239 buf[index] |= (255 << rshift);
240 buf[index] |= (255 << gshift);
241 buf[index] |= (255 << bshift);
242 }
243 } else {
244 buf[index] |= (255 << rshift);
245 if (row >= halfway)
246 buf[index] |= (255 << gshift);
247 }
248 if (ashift >= 0)
249 buf[index] |= (255 << ashift);
250 }
251 }
252 }
253
254 private static void initImg(BufferedImage img, int pf, int flags)
255 throws Exception {
256 WritableRaster wr = img.getRaster();
257 int imgType = img.getType();
258 if (imgType == BufferedImage.TYPE_INT_RGB ||
259 imgType == BufferedImage.TYPE_INT_BGR ||
260 imgType == BufferedImage.TYPE_INT_ARGB ||
261 imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
262 SinglePixelPackedSampleModel sm =
263 (SinglePixelPackedSampleModel)img.getSampleModel();
264 int pitch = sm.getScanlineStride();
265 DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
266 int[] buf = db.getData();
267 initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
268 } else {
269 ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
270 int pitch = sm.getScanlineStride();
271 DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
272 byte[] buf = db.getData();
273 initBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
274 }
275 }
276
277 private static void checkVal(int row, int col, int v, String vname, int cv)
278 throws Exception {
279 v = (v < 0) ? v + 256 : v;
280 if (v < cv - 1 || v > cv + 1) {
281 throw new Exception("Comp. " + vname + " at " + row + "," + col +
282 " should be " + cv + ", not " + v);
283 }
284 }
285
286 private static void checkVal0(int row, int col, int v, String vname)
287 throws Exception {
288 v = (v < 0) ? v + 256 : v;
289 if (v > 1) {
290 throw new Exception("Comp. " + vname + " at " + row + "," + col +
291 " should be 0, not " + v);
292 }
293 }
294
295 private static void checkVal255(int row, int col, int v, String vname)
296 throws Exception {
297 v = (v < 0) ? v + 256 : v;
298 if (v < 254) {
299 throw new Exception("Comp. " + vname + " at " + row + "," + col +
300 " should be 255, not " + v);
301 }
302 }
303
304 private static int checkBuf(byte[] buf, int w, int pitch, int h, int pf,
305 int subsamp, TJScalingFactor sf, int flags)
306 throws Exception {
307 int roffset = TJ.getRedOffset(pf);
308 int goffset = TJ.getGreenOffset(pf);
309 int boffset = TJ.getBlueOffset(pf);
310 int aoffset = alphaOffset[pf];
311 int ps = TJ.getPixelSize(pf);
312 int index, row, col, retval = 1;
313 int halfway = 16 * sf.getNum() / sf.getDenom();
314 int blockSize = 8 * sf.getNum() / sf.getDenom();
315
316 try {
317
318 if (pf == TJ.PF_CMYK) {
319 for (row = 0; row < h; row++) {
320 for (col = 0; col < w; col++) {
321 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
322 index = (h - row - 1) * w + col;
323 else
324 index = row * w + col;
325 byte c = buf[index * ps];
326 byte m = buf[index * ps + 1];
327 byte y = buf[index * ps + 2];
328 byte k = buf[index * ps + 3];
329 checkVal255(row, col, c, "C");
330 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
331 checkVal255(row, col, m, "M");
332 checkVal255(row, col, y, "Y");
333 if (row < halfway)
334 checkVal255(row, col, k, "K");
335 else
336 checkVal0(row, col, k, "K");
337 } else {
338 checkVal0(row, col, y, "Y");
339 checkVal255(row, col, k, "K");
340 if (row < halfway)
341 checkVal0(row, col, m, "M");
342 else
343 checkVal255(row, col, m, "M");
344 }
345 }
346 }
347 return 1;
348 }
349
350 for (row = 0; row < halfway; row++) {
351 for (col = 0; col < w; col++) {
352 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
353 index = pitch * (h - row - 1) + col * ps;
354 else
355 index = pitch * row + col * ps;
356 byte r = buf[index + roffset];
357 byte g = buf[index + goffset];
358 byte b = buf[index + boffset];
359 byte a = aoffset >= 0 ? buf[index + aoffset] : (byte)255;
360 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
361 if (row < halfway) {
362 checkVal255(row, col, r, "R");
363 checkVal255(row, col, g, "G");
364 checkVal255(row, col, b, "B");
365 } else {
366 checkVal0(row, col, r, "R");
367 checkVal0(row, col, g, "G");
368 checkVal0(row, col, b, "B");
369 }
370 } else {
371 if (subsamp == TJ.SAMP_GRAY) {
372 if (row < halfway) {
373 checkVal(row, col, r, "R", 76);
374 checkVal(row, col, g, "G", 76);
375 checkVal(row, col, b, "B", 76);
376 } else {
377 checkVal(row, col, r, "R", 226);
378 checkVal(row, col, g, "G", 226);
379 checkVal(row, col, b, "B", 226);
380 }
381 } else {
382 checkVal255(row, col, r, "R");
383 if (row < halfway) {
384 checkVal0(row, col, g, "G");
385 } else {
386 checkVal255(row, col, g, "G");
387 }
388 checkVal0(row, col, b, "B");
389 }
390 }
391 checkVal255(row, col, a, "A");
392 }
393 }
394 } catch(Exception e) {
395 System.out.println("\n" + e.getMessage());
396 retval = 0;
397 }
398
399 if (retval == 0) {
400 for (row = 0; row < h; row++) {
401 for (col = 0; col < w; col++) {
402 if (pf == TJ.PF_CMYK) {
403 int c = buf[pitch * row + col * ps];
404 int m = buf[pitch * row + col * ps + 1];
405 int y = buf[pitch * row + col * ps + 2];
406 int k = buf[pitch * row + col * ps + 3];
407 if (c < 0) c += 256;
408 if (m < 0) m += 256;
409 if (y < 0) y += 256;
410 if (k < 0) k += 256;
411 System.out.format("%3d/%3d/%3d/%3d ", c, m, y, k);
412 } else {
413 int r = buf[pitch * row + col * ps + roffset];
414 int g = buf[pitch * row + col * ps + goffset];
415 int b = buf[pitch * row + col * ps + boffset];
416 if (r < 0) r += 256;
417 if (g < 0) g += 256;
418 if (b < 0) b += 256;
419 System.out.format("%3d/%3d/%3d ", r, g, b);
420 }
421 }
422 System.out.print("\n");
423 }
424 }
425 return retval;
426 }
427
428 private static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
429 int subsamp, TJScalingFactor sf, int flags)
430 throws Exception {
431 int rshift = TJ.getRedOffset(pf) * 8;
432 int gshift = TJ.getGreenOffset(pf) * 8;
433 int bshift = TJ.getBlueOffset(pf) * 8;
434 int ashift = alphaOffset[pf] * 8;
435 int index, row, col, retval = 1;
436 int halfway = 16 * sf.getNum() / sf.getDenom();
437 int blockSize = 8 * sf.getNum() / sf.getDenom();
438
439 try {
440 for (row = 0; row < halfway; row++) {
441 for (col = 0; col < w; col++) {
442 if ((flags & TJ.FLAG_BOTTOMUP) != 0)
443 index = pitch * (h - row - 1) + col;
444 else
445 index = pitch * row + col;
446 int r = (buf[index] >> rshift) & 0xFF;
447 int g = (buf[index] >> gshift) & 0xFF;
448 int b = (buf[index] >> bshift) & 0xFF;
449 int a = ashift >= 0 ? (buf[index] >> ashift) & 0xFF : 255;
450 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
451 if (row < halfway) {
452 checkVal255(row, col, r, "R");
453 checkVal255(row, col, g, "G");
454 checkVal255(row, col, b, "B");
455 } else {
456 checkVal0(row, col, r, "R");
457 checkVal0(row, col, g, "G");
458 checkVal0(row, col, b, "B");
459 }
460 } else {
461 if (subsamp == TJ.SAMP_GRAY) {
462 if (row < halfway) {
463 checkVal(row, col, r, "R", 76);
464 checkVal(row, col, g, "G", 76);
465 checkVal(row, col, b, "B", 76);
466 } else {
467 checkVal(row, col, r, "R", 226);
468 checkVal(row, col, g, "G", 226);
469 checkVal(row, col, b, "B", 226);
470 }
471 } else {
472 checkVal255(row, col, r, "R");
473 if (row < halfway) {
474 checkVal0(row, col, g, "G");
475 } else {
476 checkVal255(row, col, g, "G");
477 }
478 checkVal0(row, col, b, "B");
479 }
480 }
481 checkVal255(row, col, a, "A");
482 }
483 }
484 } catch(Exception e) {
485 System.out.println("\n" + e.getMessage());
486 retval = 0;
487 }
488
489 if (retval == 0) {
490 for (row = 0; row < h; row++) {
491 for (col = 0; col < w; col++) {
492 int r = (buf[pitch * row + col] >> rshift) & 0xFF;
493 int g = (buf[pitch * row + col] >> gshift) & 0xFF;
494 int b = (buf[pitch * row + col] >> bshift) & 0xFF;
495 if (r < 0) r += 256;
496 if (g < 0) g += 256;
497 if (b < 0) b += 256;
498 System.out.format("%3d/%3d/%3d ", r, g, b);
499 }
500 System.out.print("\n");
501 }
502 }
503 return retval;
504 }
505
506 private static int checkImg(BufferedImage img, int pf, int subsamp,
507 TJScalingFactor sf, int flags) throws Exception {
508 WritableRaster wr = img.getRaster();
509 int imgType = img.getType();
510 if (imgType == BufferedImage.TYPE_INT_RGB ||
511 imgType == BufferedImage.TYPE_INT_BGR ||
512 imgType == BufferedImage.TYPE_INT_ARGB ||
513 imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
514 SinglePixelPackedSampleModel sm =
515 (SinglePixelPackedSampleModel)img.getSampleModel();
516 int pitch = sm.getScanlineStride();
517 DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
518 int[] buf = db.getData();
519 return checkIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf,
520 subsamp, sf, flags);
521 } else {
522 ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
523 int pitch = sm.getScanlineStride();
524 DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
525 byte[] buf = db.getData();
526 return checkBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, subsamp,
527 sf, flags);
528 }
529 }
530
531 private static int PAD(int v, int p) {
532 return ((v + (p) - 1) & (~((p) - 1)));
533 }
534
535 private static int checkBufYUV(byte[] buf, int size, int w, int h,
536 int subsamp, TJScalingFactor sf)
537 throws Exception {
538 int row, col;
539 int hsf = TJ.getMCUWidth(subsamp) / 8, vsf = TJ.getMCUHeight(subsamp) / 8;
540 int pw = PAD(w, hsf), ph = PAD(h, vsf);
541 int cw = pw / hsf, ch = ph / vsf;
542 int ypitch = PAD(pw, pad), uvpitch = PAD(cw, pad);
543 int retval = 1;
544 int correctsize = ypitch * ph +
545 (subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2);
546 int halfway = 16 * sf.getNum() / sf.getDenom();
547 int blockSize = 8 * sf.getNum() / sf.getDenom();
548
549 try {
550 if (size != correctsize)
551 throw new Exception("Incorrect size " + size + ". Should be " +
552 correctsize);
553
554 for (row = 0; row < ph; row++) {
555 for (col = 0; col < pw; col++) {
556 byte y = buf[ypitch * row + col];
557 if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
558 if (row < halfway)
559 checkVal255(row, col, y, "Y");
560 else
561 checkVal0(row, col, y, "Y");
562 } else {
563 if (row < halfway)
564 checkVal(row, col, y, "Y", 76);
565 else
566 checkVal(row, col, y, "Y", 226);
567 }
568 }
569 }
570 if (subsamp != TJ.SAMP_GRAY) {
571 halfway = 16 / vsf * sf.getNum() / sf.getDenom();
572 for (row = 0; row < ch; row++) {
573 for (col = 0; col < cw; col++) {
574 byte u = buf[ypitch * ph + (uvpitch * row + col)],
575 v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
576 if (((row * vsf / blockSize) + (col * hsf / blockSize)) % 2 == 0) {
577 checkVal(row, col, u, "U", 128);
578 checkVal(row, col, v, "V", 128);
579 } else {
580 if (row < halfway) {
581 checkVal(row, col, u, "U", 85);
582 checkVal255(row, col, v, "V");
583 } else {
584 checkVal0(row, col, u, "U");
585 checkVal(row, col, v, "V", 149);
586 }
587 }
588 }
589 }
590 }
591 } catch(Exception e) {
592 System.out.println("\n" + e.getMessage());
593 retval = 0;
594 }
595
596 if (retval == 0) {
597 for (row = 0; row < ph; row++) {
598 for (col = 0; col < pw; col++) {
599 int y = buf[ypitch * row + col];
600 if (y < 0) y += 256;
601 System.out.format("%3d ", y);
602 }
603 System.out.print("\n");
604 }
605 System.out.print("\n");
606 for (row = 0; row < ch; row++) {
607 for (col = 0; col < cw; col++) {
608 int u = buf[ypitch * ph + (uvpitch * row + col)];
609 if (u < 0) u += 256;
610 System.out.format("%3d ", u);
611 }
612 System.out.print("\n");
613 }
614 System.out.print("\n");
615 for (row = 0; row < ch; row++) {
616 for (col = 0; col < cw; col++) {
617 int v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
618 if (v < 0) v += 256;
619 System.out.format("%3d ", v);
620 }
621 System.out.print("\n");
622 }
623 }
624
625 return retval;
626 }
627
628 private static void writeJPEG(byte[] jpegBuf, int jpegBufSize,
629 String filename) throws Exception {
630 File file = new File(filename);
631 FileOutputStream fos = new FileOutputStream(file);
632 fos.write(jpegBuf, 0, jpegBufSize);
633 fos.close();
634 }
635
636 private static int compTest(TJCompressor tjc, byte[] dstBuf, int w,
637 int h, int pf, String baseName, int subsamp,
638 int jpegQual, int flags) throws Exception {
639 String tempStr;
640 byte[] srcBuf = null;
641 BufferedImage img = null;
642 String pfStr, pfStrLong;
643 String buStr = (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD";
644 String buStrLong = (flags & TJ.FLAG_BOTTOMUP) != 0 ?
645 "Bottom-Up" : "Top-Down ";
646 int size = 0, ps, imgType = pf;
647
648 if (bi) {
649 pf = biTypePF(imgType);
650 pfStr = biTypeStr(imgType);
651 pfStrLong = pfStr + " (" + pixFormatStr[pf] + ")";
652 } else {
653 pfStr = pixFormatStr[pf];
654 pfStrLong = pfStr;
655 }
656 ps = TJ.getPixelSize(pf);
657
658 if (bi) {
659 img = new BufferedImage(w, h, imgType);
660 initImg(img, pf, flags);
661 tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
662 subName[subsamp] + "_Q" + jpegQual + ".png";
663 File file = new File(tempStr);
664 ImageIO.write(img, "png", file);
665 tjc.setSourceImage(img, 0, 0, 0, 0);
666 } else {
667 srcBuf = new byte[w * h * ps + 1];
668 initBuf(srcBuf, w, w * ps, h, pf, flags);
669 tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, pf);
670 }
671 Arrays.fill(dstBuf, (byte)0);
672
673 tjc.setSubsamp(subsamp);
674 tjc.setJPEGQuality(jpegQual);
675 if (doYUV) {
676 System.out.format("%s %s -> YUV %s ... ", pfStrLong, buStrLong,
677 subNameLong[subsamp]);
678 YUVImage yuvImage = tjc.encodeYUV(pad, flags);
679 if (checkBufYUV(yuvImage.getBuf(), yuvImage.getSize(), w, h, subsamp,
680 new TJScalingFactor(1, 1)) == 1)
681 System.out.print("Passed.\n");
682 else {
683 System.out.print("FAILED!\n");
684 exitStatus = -1;
685 }
686
687 System.out.format("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp],
688 buStrLong, jpegQual);
689 tjc.setSourceImage(yuvImage);
690 } else {
691 System.out.format("%s %s -> %s Q%d ... ", pfStrLong, buStrLong,
692 subNameLong[subsamp], jpegQual);
693 }
694 tjc.compress(dstBuf, flags);
695 size = tjc.getCompressedSize();
696
697 tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
698 subName[subsamp] + "_Q" + jpegQual + ".jpg";
699 writeJPEG(dstBuf, size, tempStr);
700 System.out.println("Done.\n Result in " + tempStr);
701
702 return size;
703 }
704
705 private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
706 int jpegSize, int w, int h, int pf,
707 String baseName, int subsamp, int flags,
708 TJScalingFactor sf) throws Exception {
709 String pfStr, pfStrLong, tempStr;
710 String buStrLong = (flags & TJ.FLAG_BOTTOMUP) != 0 ?
711 "Bottom-Up" : "Top-Down ";
712 int scaledWidth = sf.getScaled(w);
713 int scaledHeight = sf.getScaled(h);
714 int temp1, temp2, imgType = pf;
715 BufferedImage img = null;
716 byte[] dstBuf = null;
717
718 if (bi) {
719 pf = biTypePF(imgType);
720 pfStr = biTypeStr(imgType);
721 pfStrLong = pfStr + " (" + pixFormatStr[pf] + ")";
722 } else {
723 pfStr = pixFormatStr[pf];
724 pfStrLong = pfStr;
725 }
726
727 tjd.setSourceImage(jpegBuf, jpegSize);
728 if (tjd.getWidth() != w || tjd.getHeight() != h ||
729 tjd.getSubsamp() != subsamp)
730 throw new Exception("Incorrect JPEG header");
731
732 temp1 = scaledWidth;
733 temp2 = scaledHeight;
734 temp1 = tjd.getScaledWidth(temp1, temp2);
735 temp2 = tjd.getScaledHeight(temp1, temp2);
736 if (temp1 != scaledWidth || temp2 != scaledHeight)
737 throw new Exception("Scaled size mismatch");
738
739 if (doYUV) {
740 System.out.format("JPEG -> YUV %s ", subNameLong[subsamp]);
741 if(!sf.isOne())
742 System.out.format("%d/%d ... ", sf.getNum(), sf.getDenom());
743 else System.out.print("... ");
744 YUVImage yuvImage = tjd.decompressToYUV(scaledWidth, pad, scaledHeight,
745 flags);
746 if (checkBufYUV(yuvImage.getBuf(), yuvImage.getSize(), scaledWidth,
747 scaledHeight, subsamp, sf) == 1)
748 System.out.print("Passed.\n");
749 else {
750 System.out.print("FAILED!\n"); exitStatus = -1;
751 }
752
753 System.out.format("YUV %s -> %s %s ... ", subNameLong[subsamp],
754 pfStrLong, buStrLong);
755 tjd.setSourceImage(yuvImage);
756 } else {
757 System.out.format("JPEG -> %s %s ", pfStrLong, buStrLong);
758 if(!sf.isOne())
759 System.out.format("%d/%d ... ", sf.getNum(), sf.getDenom());
760 else System.out.print("... ");
761 }
762 if (bi)
763 img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags);
764 else
765 dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags);
766
767 if (bi) {
768 tempStr = baseName + "_dec_" + pfStr + "_" +
769 (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
770 subName[subsamp] + "_" +
771 (double)sf.getNum() / (double)sf.getDenom() + "x" + ".png";
772 File file = new File(tempStr);
773 ImageIO.write(img, "png", file);
774 }
775
776 if ((bi && checkImg(img, pf, subsamp, sf, flags) == 1) ||
777 (!bi && checkBuf(dstBuf, scaledWidth,
778 scaledWidth * TJ.getPixelSize(pf), scaledHeight, pf,
779 subsamp, sf, flags) == 1))
780 System.out.print("Passed.\n");
781 else {
782 System.out.print("FAILED!\n");
783 exitStatus = -1;
784 }
785 }
786
787 private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
788 int jpegSize, int w, int h, int pf,
789 String baseName, int subsamp,
790 int flags) throws Exception {
791 int i;
792 TJScalingFactor[] sf = TJ.getScalingFactors();
793 for (i = 0; i < sf.length; i++) {
794 int num = sf[i].getNum();
795 int denom = sf[i].getDenom();
796 if (subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY ||
797 (subsamp == TJ.SAMP_411 && num == 1 &&
798 (denom == 2 || denom == 1)) ||
799 (subsamp != TJ.SAMP_411 && num == 1 &&
800 (denom == 4 || denom == 2 || denom == 1)))
801 decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
802 flags, sf[i]);
803 }
804 }
805
806 private static void doTest(int w, int h, int[] formats, int subsamp,
807 String baseName) throws Exception {
808 TJCompressor tjc = null;
809 TJDecompressor tjd = null;
810 int size;
811 byte[] dstBuf;
812
813 dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
814
815 try {
816 tjc = new TJCompressor();
817 tjd = new TJDecompressor();
818
819 for (int pf : formats) {
820 if (pf < 0) continue;
821 for (int i = 0; i < 2; i++) {
822 int flags = 0;
823 if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 ||
824 subsamp == TJ.SAMP_440 || subsamp == TJ.SAMP_411)
825 flags |= TJ.FLAG_FASTUPSAMPLE;
826 if (i == 1)
827 flags |= TJ.FLAG_BOTTOMUP;
828 size = compTest(tjc, dstBuf, w, h, pf, baseName, subsamp, 100,
829 flags);
830 decompTest(tjd, dstBuf, size, w, h, pf, baseName, subsamp, flags);
831 if (pf >= TJ.PF_RGBX && pf <= TJ.PF_XRGB && !bi) {
832 System.out.print("\n");
833 decompTest(tjd, dstBuf, size, w, h, pf + (TJ.PF_RGBA - TJ.PF_RGBX),
834 baseName, subsamp, flags);
835 }
836 System.out.print("\n");
837 }
838 }
839 System.out.print("--------------------\n\n");
840 } catch(Exception e) {
841 if (tjc != null) tjc.close();
842 if (tjd != null) tjd.close();
843 throw e;
844 }
845 if (tjc != null) tjc.close();
846 if (tjd != null) tjd.close();
847 }
848
849 private static void bufSizeTest() throws Exception {
850 int w, h, i, subsamp;
851 byte[] srcBuf, dstBuf = null;
852 YUVImage dstImage = null;
853 TJCompressor tjc = null;
854 Random r = new Random();
855
856 try {
857 tjc = new TJCompressor();
858 System.out.println("Buffer size regression test");
859 for (subsamp = 0; subsamp < TJ.NUMSAMP; subsamp++) {
860 for (w = 1; w < 48; w++) {
861 int maxh = (w == 1) ? 2048 : 48;
862 for (h = 1; h < maxh; h++) {
863 if (h % 100 == 0)
864 System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h);
865 srcBuf = new byte[w * h * 4];
866 if (doYUV)
867 dstImage = new YUVImage(w, pad, h, subsamp);
868 else
869 dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
870 for (i = 0; i < w * h * 4; i++) {
871 srcBuf[i] = (byte)(r.nextInt(2) * 255);
872 }
873 tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, TJ.PF_BGRX);
874 tjc.setSubsamp(subsamp);
875 tjc.setJPEGQuality(100);
876 if (doYUV)
877 tjc.encodeYUV(dstImage, 0);
878 else
879 tjc.compress(dstBuf, 0);
880
881 srcBuf = new byte[h * w * 4];
882 if (doYUV)
883 dstImage = new YUVImage(h, pad, w, subsamp);
884 else
885 dstBuf = new byte[TJ.bufSize(h, w, subsamp)];
886 for (i = 0; i < h * w * 4; i++) {
887 srcBuf[i] = (byte)(r.nextInt(2) * 255);
888 }
889 tjc.setSourceImage(srcBuf, 0, 0, h, 0, w, TJ.PF_BGRX);
890 if (doYUV)
891 tjc.encodeYUV(dstImage, 0);
892 else
893 tjc.compress(dstBuf, 0);
894 }
895 dstImage = null;
896 dstBuf = null;
897 System.gc();
898 }
899 }
900 System.out.println("Done. ");
901 } catch(Exception e) {
902 if (tjc != null) tjc.close();
903 throw e;
904 }
905 if (tjc != null) tjc.close();
906 }
907
908 public static void main(String[] argv) {
909 try {
910 String testName = "javatest";
911 for (int i = 0; i < argv.length; i++) {
912 if (argv[i].equalsIgnoreCase("-yuv"))
913 doYUV = true;
914 if (argv[i].equalsIgnoreCase("-noyuvpad"))
915 pad = 1;
916 if (argv[i].substring(0, 1).equalsIgnoreCase("-h") ||
917 argv[i].equalsIgnoreCase("-?"))
918 usage();
919 if (argv[i].equalsIgnoreCase("-bi")) {
920 bi = true;
921 testName = "javabitest";
922 }
923 }
924 if (doYUV)
925 _4byteFormats[4] = -1;
926 doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444,
927 testName);
928 doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444,
929 testName);
930 doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_422,
931 testName);
932 doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_422,
933 testName);
934 doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_420,
935 testName);
936 doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_420,
937 testName);
938 doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_440,
939 testName);
940 doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440,
941 testName);
942 doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_411,
943 testName);
944 doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_411,
945 testName);
946 doTest(39, 41, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName);
947 doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY,
948 testName);
949 _4byteFormats[4] = -1;
950 doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
951 testName);
952 if (!bi)
953 bufSizeTest();
954 if (doYUV && !bi) {
955 System.out.print("\n--------------------\n\n");
956 doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0");
957 doTest(48, 48, onlyRGB, TJ.SAMP_422, "javatest_yuv0");
958 doTest(48, 48, onlyRGB, TJ.SAMP_420, "javatest_yuv0");
959 doTest(48, 48, onlyRGB, TJ.SAMP_440, "javatest_yuv0");
960 doTest(48, 48, onlyRGB, TJ.SAMP_411, "javatest_yuv0");
961 doTest(48, 48, onlyRGB, TJ.SAMP_GRAY, "javatest_yuv0");
962 doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0");
963 }
964 } catch(Exception e) {
965 e.printStackTrace();
966 exitStatus = -1;
967 }
968 System.exit(exitStatus);
969 }
970 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698