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

Side by Side Diff: java/TJBench.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)2009-2014, 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 import java.io.*;
30 import java.awt.image.*;
31 import javax.imageio.*;
32 import java.util.*;
33 import org.libjpegturbo.turbojpeg.*;
34
35 class TJBench {
36
37 static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvpad = 1, warmup = 1;
38 static boolean compOnly, decompOnly, doTile, doYUV, write;
39
40 static final String[] pixFormatStr = {
41 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
42 };
43
44 static final String[] subNameLong = {
45 "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
46 };
47
48 static final String[] subName = {
49 "444", "422", "420", "GRAY", "440", "411"
50 };
51
52 static final String[] csName = {
53 "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
54 };
55
56 static TJScalingFactor sf;
57 static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
58 static double benchTime = 5.0;
59
60
61 static final double getTime() {
62 return (double)System.nanoTime() / 1.0e9;
63 }
64
65
66 static String formatName(int subsamp, int cs) {
67 if (cs == TJ.CS_YCbCr)
68 return subNameLong[subsamp];
69 else if (cs == TJ.CS_YCCK)
70 return csName[cs] + " " + subNameLong[subsamp];
71 else
72 return csName[cs];
73 }
74
75
76 static String sigFig(double val, int figs) {
77 String format;
78 int digitsAfterDecimal = figs - (int)Math.ceil(Math.log10(Math.abs(val)));
79 if (digitsAfterDecimal < 1)
80 format = new String("%.0f");
81 else
82 format = new String("%." + digitsAfterDecimal + "f");
83 return String.format(format, val);
84 }
85
86
87 static byte[] loadImage(String fileName, int[] w, int[] h, int pixelFormat)
88 throws Exception {
89 BufferedImage img = ImageIO.read(new File(fileName));
90 if (img == null)
91 throw new Exception("Could not read " + fileName);
92 w[0] = img.getWidth();
93 h[0] = img.getHeight();
94 int[] rgb = img.getRGB(0, 0, w[0], h[0], null, 0, w[0]);
95 int ps = TJ.getPixelSize(pixelFormat);
96 int rindex = TJ.getRedOffset(pixelFormat);
97 int gindex = TJ.getGreenOffset(pixelFormat);
98 int bindex = TJ.getBlueOffset(pixelFormat);
99 byte[] dstBuf = new byte[w[0] * h[0] * ps];
100 int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
101 while (pixels-- > 0) {
102 dstBuf[dstPtr + rindex] = (byte)((rgb[rgbPtr] >> 16) & 0xff);
103 dstBuf[dstPtr + gindex] = (byte)((rgb[rgbPtr] >> 8) & 0xff);
104 dstBuf[dstPtr + bindex] = (byte)(rgb[rgbPtr] & 0xff);
105 dstPtr += ps;
106 rgbPtr++;
107 }
108 return dstBuf;
109 }
110
111
112 static void saveImage(String fileName, byte[] srcBuf, int w, int h,
113 int pixelFormat) throws Exception {
114 BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
115 int pixels = w * h, srcPtr = 0;
116 int ps = TJ.getPixelSize(pixelFormat);
117 int rindex = TJ.getRedOffset(pixelFormat);
118 int gindex = TJ.getGreenOffset(pixelFormat);
119 int bindex = TJ.getBlueOffset(pixelFormat);
120 for (int y = 0; y < h; y++) {
121 for (int x = 0; x < w; x++, srcPtr += ps) {
122 int pixel = (srcBuf[srcPtr + rindex] & 0xff) << 16 |
123 (srcBuf[srcPtr + gindex] & 0xff) << 8 |
124 (srcBuf[srcPtr + bindex] & 0xff);
125 img.setRGB(x, y, pixel);
126 }
127 }
128 ImageIO.write(img, "bmp", new File(fileName));
129 }
130
131
132 /* Decompression test */
133 static void decomp(byte[] srcBuf, byte[][] jpegBuf, int[] jpegSize,
134 byte[] dstBuf, int w, int h, int subsamp, int jpegQual,
135 String fileName, int tilew, int tileh) throws Exception {
136 String qualStr = new String(""), sizeStr, tempStr;
137 TJDecompressor tjd;
138 double elapsed, elapsedDecode;
139 int ps = TJ.getPixelSize(pf), i, iter = 0;
140 int scaledw = sf.getScaled(w);
141 int scaledh = sf.getScaled(h);
142 int pitch = scaledw * ps;
143 YUVImage yuvImage = null;
144
145 if (jpegQual > 0)
146 qualStr = new String("_Q" + jpegQual);
147
148 tjd = new TJDecompressor();
149
150 if (dstBuf == null)
151 dstBuf = new byte[pitch * scaledh];
152
153 /* Set the destination buffer to gray so we know whether the decompressor
154 attempted to write to it */
155 Arrays.fill(dstBuf, (byte)127);
156
157 if (doYUV) {
158 int width = doTile ? tilew : scaledw;
159 int height = doTile ? tileh : scaledh;
160 yuvImage = new YUVImage(width, yuvpad, height, subsamp);
161 Arrays.fill(yuvImage.getBuf(), (byte)127);
162 }
163
164 /* Benchmark */
165 iter -= warmup;
166 elapsed = elapsedDecode = 0.0;
167 while (true) {
168 int tile = 0;
169 double start = getTime();
170 for (int y = 0; y < h; y += tileh) {
171 for (int x = 0; x < w; x += tilew, tile++) {
172 int width = doTile ? Math.min(tilew, w - x) : scaledw;
173 int height = doTile ? Math.min(tileh, h - y) : scaledh;
174 tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]);
175 if (doYUV) {
176 yuvImage.setBuf(yuvImage.getBuf(), width, yuvpad, height, subsamp);
177 tjd.decompressToYUV(yuvImage, flags);
178 double startDecode = getTime();
179 tjd.setSourceImage(yuvImage);
180 tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
181 if (iter >= 0)
182 elapsedDecode += getTime() - startDecode;
183 } else
184 tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
185 }
186 }
187 iter++;
188 if (iter >= 1) {
189 elapsed += getTime() - start;
190 if (elapsed >= benchTime)
191 break;
192 }
193 }
194 if(doYUV)
195 elapsed -= elapsedDecode;
196
197 tjd = null;
198 for (i = 0; i < jpegBuf.length; i++)
199 jpegBuf[i] = null;
200 jpegBuf = null; jpegSize = null;
201 System.gc();
202
203 if (quiet != 0) {
204 System.out.format("%-6s%s",
205 sigFig((double)(w * h) / 1000000. * (double)iter / elapsed, 4),
206 quiet == 2 ? "\n" : " ");
207 if (doYUV)
208 System.out.format("%s\n",
209 sigFig((double)(w * h) / 1000000. * (double)iter / elapsedDecode, 4));
210 else if (quiet != 2)
211 System.out.print("\n");
212 } else {
213 System.out.format("%s --> Frame rate: %f fps\n",
214 (doYUV ? "Decomp to YUV":"Decompress "),
215 (double)iter / elapsed);
216 System.out.format(" Throughput: %f Megapixels/sec \n",
217 (double)(w * h) / 1000000. * (double)iter / elapsed);
218 if (doYUV) {
219 System.out.format("YUV Decode --> Frame rate: %f fps\n",
220 (double)iter / elapsedDecode);
221 System.out.format(" Throughput: %f Megapixels/s ec\n",
222 (double)(w * h) / 1000000. * (double)iter / elapsedDec ode);
223 }
224 }
225
226 if (!write) return;
227
228 if (sf.getNum() != 1 || sf.getDenom() != 1)
229 sizeStr = new String(sf.getNum() + "_" + sf.getDenom());
230 else if (tilew != w || tileh != h)
231 sizeStr = new String(tilew + "x" + tileh);
232 else
233 sizeStr = new String("full");
234 if (decompOnly)
235 tempStr = new String(fileName + "_" + sizeStr + ".bmp");
236 else
237 tempStr = new String(fileName + "_" + subName[subsamp] + qualStr +
238 "_" + sizeStr + ".bmp");
239
240 saveImage(tempStr, dstBuf, scaledw, scaledh, pf);
241 int ndx = tempStr.lastIndexOf('.');
242 tempStr = new String(tempStr.substring(0, ndx) + "-err.bmp");
243 if (srcBuf != null && sf.getNum() == 1 && sf.getDenom() == 1) {
244 if (quiet == 0)
245 System.out.println("Compression error written to " + tempStr + ".");
246 if (subsamp == TJ.SAMP_GRAY) {
247 for (int y = 0, index = 0; y < h; y++, index += pitch) {
248 for (int x = 0, index2 = index; x < w; x++, index2 += ps) {
249 int rindex = index2 + TJ.getRedOffset(pf);
250 int gindex = index2 + TJ.getGreenOffset(pf);
251 int bindex = index2 + TJ.getBlueOffset(pf);
252 int lum = (int)((double)(srcBuf[rindex] & 0xff) * 0.299 +
253 (double)(srcBuf[gindex] & 0xff) * 0.587 +
254 (double)(srcBuf[bindex] & 0xff) * 0.114 + 0.5);
255 if (lum > 255) lum = 255;
256 if (lum < 0) lum = 0;
257 dstBuf[rindex] = (byte)Math.abs((dstBuf[rindex] & 0xff) - lum);
258 dstBuf[gindex] = (byte)Math.abs((dstBuf[gindex] & 0xff) - lum);
259 dstBuf[bindex] = (byte)Math.abs((dstBuf[bindex] & 0xff) - lum);
260 }
261 }
262 } else {
263 for (int y = 0; y < h; y++)
264 for (int x = 0; x < w * ps; x++)
265 dstBuf[pitch * y + x] =
266 (byte)Math.abs((dstBuf[pitch * y + x] & 0xff) -
267 (srcBuf[pitch * y + x] & 0xff));
268 }
269 saveImage(tempStr, dstBuf, w, h, pf);
270 }
271 }
272
273
274 static void fullTest(byte[] srcBuf, int w, int h, int subsamp, int jpegQual,
275 String fileName) throws Exception {
276 TJCompressor tjc;
277 byte[] tmpBuf;
278 byte[][] jpegBuf;
279 int[] jpegSize;
280 double start, elapsed, elapsedEncode;
281 int totalJpegSize = 0, tilew, tileh, i, iter;
282 int ps = TJ.getPixelSize(pf);
283 int ntilesw = 1, ntilesh = 1, pitch = w * ps;
284 String pfStr = pixFormatStr[pf];
285 YUVImage yuvImage = null;
286
287 tmpBuf = new byte[pitch * h];
288
289 if (quiet == 0)
290 System.out.format(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr,
291 (flags & TJ.FLAG_BOTTOMUP) != 0 ? "Bottom-up" : "Top-down",
292 subNameLong[subsamp], jpegQual);
293
294 tjc = new TJCompressor();
295
296 for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ;
297 tilew *= 2, tileh *= 2) {
298 if (tilew > w)
299 tilew = w;
300 if (tileh > h)
301 tileh = h;
302 ntilesw = (w + tilew - 1) / tilew;
303 ntilesh = (h + tileh - 1) / tileh;
304
305 jpegBuf = new byte[ntilesw * ntilesh][TJ.bufSize(tilew, tileh, subsamp)];
306 jpegSize = new int[ntilesw * ntilesh];
307
308 /* Compression test */
309 if (quiet == 1)
310 System.out.format("%-4s (%s) %-5s %-3d ", pfStr,
311 (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
312 subNameLong[subsamp], jpegQual);
313 for (i = 0; i < h; i++)
314 System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps);
315 tjc.setJPEGQuality(jpegQual);
316 tjc.setSubsamp(subsamp);
317
318 if (doYUV) {
319 yuvImage = new YUVImage(tilew, yuvpad, tileh, subsamp);
320 Arrays.fill(yuvImage.getBuf(), (byte)127);
321 }
322
323 /* Benchmark */
324 iter = -warmup;
325 elapsed = elapsedEncode = 0.0;
326 while (true) {
327 int tile = 0;
328 totalJpegSize = 0;
329 start = getTime();
330 for (int y = 0; y < h; y += tileh) {
331 for (int x = 0; x < w; x += tilew, tile++) {
332 int width = Math.min(tilew, w - x);
333 int height = Math.min(tileh, h - y);
334 tjc.setSourceImage(srcBuf, x, y, width, pitch, height, pf);
335 if (doYUV) {
336 double startEncode = getTime();
337 yuvImage.setBuf(yuvImage.getBuf(), width, yuvpad, height,
338 subsamp);
339 tjc.encodeYUV(yuvImage, flags);
340 if (iter >= 0)
341 elapsedEncode += getTime() - startEncode;
342 tjc.setSourceImage(yuvImage);
343 }
344 tjc.compress(jpegBuf[tile], flags);
345 jpegSize[tile] = tjc.getCompressedSize();
346 totalJpegSize += jpegSize[tile];
347 }
348 }
349 iter++;
350 if (iter >= 1) {
351 elapsed += getTime() - start;
352 if (elapsed >= benchTime)
353 break;
354 }
355 }
356 if (doYUV)
357 elapsed -= elapsedEncode;
358
359 if (quiet == 1)
360 System.out.format("%-5d %-5d ", tilew, tileh);
361 if (quiet != 0) {
362 if (doYUV)
363 System.out.format("%-6s%s",
364 sigFig((double)(w * h) / 1000000. * (double)iter / elapsedEncode, 4) ,
365 quiet == 2 ? "\n" : " ");
366 System.out.format("%-6s%s",
367 sigFig((double)(w * h) / 1000000. * (double)iter / elapsed, 4),
368 quiet == 2 ? "\n" : " ");
369 System.out.format("%-6s%s",
370 sigFig((double)(w * h * ps) / (double)totalJpegSize, 4),
371 quiet == 2 ? "\n" : " ");
372 } else {
373 System.out.format("\n%s size: %d x %d\n", doTile ? "Tile" : "Image",
374 tilew, tileh);
375 if (doYUV) {
376 System.out.format("Encode YUV --> Frame rate: %f fps\n",
377 (double)iter / elapsedEncode);
378 System.out.format(" Output image size: %d bytes\n",
379 yuvImage.getSize());
380 System.out.format(" Compression ratio: %f:1\n",
381 (double)(w * h * ps) / (double)yuvImage.getSize());
382 System.out.format(" Throughput: %f Megapixels /sec\n",
383 (double)(w * h) / 1000000. * (double)iter / elapsedE ncode);
384 System.out.format(" Output bit stream: %f Megabits/s ec\n",
385 (double)yuvImage.getSize() * 8. / 1000000. * (double)iter / elapsedE ncode);
386 }
387 System.out.format("%s --> Frame rate: %f fps\n",
388 doYUV ? "Comp from YUV" : "Compress ",
389 (double)iter / elapsed);
390 System.out.format(" Output image size: %d bytes\n",
391 totalJpegSize);
392 System.out.format(" Compression ratio: %f:1\n",
393 (double)(w * h * ps) / (double)totalJpegSize);
394 System.out.format(" Throughput: %f Megapixels/s ec\n",
395 (double)(w * h) / 1000000. * (double)iter / elapsed);
396 System.out.format(" Output bit stream: %f Megabits/sec \n",
397 (double)totalJpegSize * 8. / 1000000. * (double)iter / elapsed);
398 }
399 if (tilew == w && tileh == h && write) {
400 String tempStr = fileName + "_" + subName[subsamp] + "_" + "Q" +
401 jpegQual + ".jpg";
402 FileOutputStream fos = new FileOutputStream(tempStr);
403 fos.write(jpegBuf[0], 0, jpegSize[0]);
404 fos.close();
405 if (quiet == 0)
406 System.out.println("Reference image written to " + tempStr);
407 }
408
409 /* Decompression test */
410 if (!compOnly)
411 decomp(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual,
412 fileName, tilew, tileh);
413
414 if (tilew == w && tileh == h) break;
415 }
416 }
417
418
419 static void decompTest(String fileName) throws Exception {
420 TJTransformer tjt;
421 byte[][] jpegBuf = null;
422 byte[] srcBuf;
423 int[] jpegSize = null;
424 int totalJpegSize;
425 int w = 0, h = 0, subsamp = -1, cs = -1, _w, _h, _tilew, _tileh,
426 _ntilesw, _ntilesh, _subsamp, x, y, iter;
427 int ntilesw = 1, ntilesh = 1;
428 double start, elapsed;
429 int ps = TJ.getPixelSize(pf), tile;
430
431 FileInputStream fis = new FileInputStream(fileName);
432 int srcSize = (int)fis.getChannel().size();
433 srcBuf = new byte[srcSize];
434 fis.read(srcBuf, 0, srcSize);
435 fis.close();
436
437 int index = fileName.lastIndexOf('.');
438 if (index >= 0)
439 fileName = new String(fileName.substring(0, index));
440
441 tjt = new TJTransformer();
442
443 tjt.setSourceImage(srcBuf, srcSize);
444 w = tjt.getWidth();
445 h = tjt.getHeight();
446 subsamp = tjt.getSubsamp();
447 cs = tjt.getColorspace();
448
449 if (quiet == 1) {
450 System.out.println("All performance values in Mpixels/sec\n");
451 System.out.format("Bitmap JPEG JPEG %s %s Xform Comp Dec omp ",
452 (doTile ? "Tile " : "Image"),
453 (doTile ? "Tile " : "Image"));
454 if (doYUV)
455 System.out.print("Decode");
456 System.out.print("\n");
457 System.out.print("Format CS Subsamp Width Height Perf Ratio Perf ");
458 if (doYUV)
459 System.out.print("Perf");
460 System.out.println("\n");
461 } else if (quiet == 0)
462 System.out.format(">>>>> JPEG %s --> %s (%s) <<<<<\n",
463 formatName(subsamp, cs), pixFormatStr[pf],
464 (flags & TJ.FLAG_BOTTOMUP) != 0 ? "Bottom-up" : "Top-down");
465
466 for (int tilew = doTile ? 16 : w, tileh = doTile ? 16 : h; ;
467 tilew *= 2, tileh *= 2) {
468 if (tilew > w)
469 tilew = w;
470 if (tileh > h)
471 tileh = h;
472 ntilesw = (w + tilew - 1) / tilew;
473 ntilesh = (h + tileh - 1) / tileh;
474
475 _w = w; _h = h; _tilew = tilew; _tileh = tileh;
476 if (quiet == 0) {
477 System.out.format("\n%s size: %d x %d", (doTile ? "Tile" : "Image"),
478 _tilew, _tileh);
479 if (sf.getNum() != 1 || sf.getDenom() != 1)
480 System.out.format(" --> %d x %d", sf.getScaled(_w),
481 sf.getScaled(_h));
482 System.out.println("");
483 } else if (quiet == 1) {
484 System.out.format("%-4s (%s) %-5s %-5s ", pixFormatStr[pf],
485 (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
486 csName[cs], subNameLong[subsamp]);
487 System.out.format("%-5d %-5d ", tilew, tileh);
488 }
489
490 _subsamp = subsamp;
491 if (doTile || xformOp != TJTransform.OP_NONE || xformOpt != 0) {
492 if (xformOp == TJTransform.OP_TRANSPOSE ||
493 xformOp == TJTransform.OP_TRANSVERSE ||
494 xformOp == TJTransform.OP_ROT90 ||
495 xformOp == TJTransform.OP_ROT270) {
496 _w = h; _h = w; _tilew = tileh; _tileh = tilew;
497 }
498
499 if ((xformOpt & TJTransform.OPT_GRAY) != 0)
500 _subsamp = TJ.SAMP_GRAY;
501 if (xformOp == TJTransform.OP_HFLIP ||
502 xformOp == TJTransform.OP_ROT180)
503 _w = _w - (_w % TJ.getMCUWidth(_subsamp));
504 if (xformOp == TJTransform.OP_VFLIP ||
505 xformOp == TJTransform.OP_ROT180)
506 _h = _h - (_h % TJ.getMCUHeight(_subsamp));
507 if (xformOp == TJTransform.OP_TRANSVERSE ||
508 xformOp == TJTransform.OP_ROT90)
509 _w = _w - (_w % TJ.getMCUHeight(_subsamp));
510 if (xformOp == TJTransform.OP_TRANSVERSE ||
511 xformOp == TJTransform.OP_ROT270)
512 _h = _h - (_h % TJ.getMCUWidth(_subsamp));
513 _ntilesw = (_w + _tilew - 1) / _tilew;
514 _ntilesh = (_h + _tileh - 1) / _tileh;
515
516 if (xformOp == TJTransform.OP_TRANSPOSE ||
517 xformOp == TJTransform.OP_TRANSVERSE ||
518 xformOp == TJTransform.OP_ROT90 ||
519 xformOp == TJTransform.OP_ROT270) {
520 if (_subsamp == TJ.SAMP_422)
521 _subsamp = TJ.SAMP_440;
522 else if (_subsamp == TJ.SAMP_440)
523 _subsamp = TJ.SAMP_422;
524 }
525
526 TJTransform[] t = new TJTransform[_ntilesw * _ntilesh];
527 jpegBuf = new byte[_ntilesw * _ntilesh][TJ.bufSize(_tilew, _tileh, subsa mp)];
528
529 for (y = 0, tile = 0; y < _h; y += _tileh) {
530 for (x = 0; x < _w; x += _tilew, tile++) {
531 t[tile] = new TJTransform();
532 t[tile].width = Math.min(_tilew, _w - x);
533 t[tile].height = Math.min(_tileh, _h - y);
534 t[tile].x = x;
535 t[tile].y = y;
536 t[tile].op = xformOp;
537 t[tile].options = xformOpt | TJTransform.OPT_TRIM;
538 if ((t[tile].options & TJTransform.OPT_NOOUTPUT) != 0 &&
539 jpegBuf[tile] != null)
540 jpegBuf[tile] = null;
541 }
542 }
543
544 iter = -warmup;
545 elapsed = 0.;
546 while (true) {
547 start = getTime();
548 tjt.transform(jpegBuf, t, flags);
549 jpegSize = tjt.getTransformedSizes();
550 iter++;
551 if (iter >= 1) {
552 elapsed += getTime() - start;
553 if (elapsed >= benchTime)
554 break;
555 }
556 }
557 t = null;
558
559 for (tile = 0, totalJpegSize = 0; tile < _ntilesw * _ntilesh; tile++)
560 totalJpegSize += jpegSize[tile];
561
562 if (quiet != 0) {
563 System.out.format("%-6s%s%-6s%s",
564 sigFig((double)(w * h) / 1000000. / elapsed, 4),
565 quiet == 2 ? "\n" : " ",
566 sigFig((double)(w * h * ps) / (double)totalJpegSize, 4),
567 quiet == 2 ? "\n" : " ");
568 } else if (quiet == 0) {
569 System.out.format("Transform --> Frame rate: %f fps\n",
570 1.0 / elapsed);
571 System.out.format(" Output image size: %d bytes\n",
572 totalJpegSize);
573 System.out.format(" Compression ratio: %f:1\n",
574 (double)(w * h * ps) / (double)totalJpegSize);
575 System.out.format(" Throughput: %f Megapixels /sec\n",
576 (double)(w * h) / 1000000. / elapsed);
577 System.out.format(" Output bit stream: %f Megabits/s ec\n",
578 (double)totalJpegSize * 8. / 1000000. / elapsed);
579 }
580 } else {
581 if (quiet == 1)
582 System.out.print("N/A N/A ");
583 jpegBuf = new byte[1][TJ.bufSize(_tilew, _tileh, subsamp)];
584 jpegSize = new int[1];
585 jpegSize[0] = srcSize;
586 System.arraycopy(srcBuf, 0, jpegBuf[0], 0, srcSize);
587 }
588
589 if (w == tilew)
590 _tilew = _w;
591 if (h == tileh)
592 _tileh = _h;
593 if ((xformOpt & TJTransform.OPT_NOOUTPUT) == 0)
594 decomp(null, jpegBuf, jpegSize, null, _w, _h, _subsamp, 0,
595 fileName, _tilew, _tileh);
596 else if (quiet == 1)
597 System.out.println("N/A");
598
599 jpegBuf = null;
600 jpegSize = null;
601
602 if (tilew == w && tileh == h) break;
603 }
604 }
605
606
607 static void usage() throws Exception {
608 int i;
609 TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
610 int nsf = scalingFactors.length;
611 String className = new TJBench().getClass().getName();
612
613 System.out.println("\nUSAGE: java " + className);
614 System.out.println(" <Inputfile (BMP)> <Quality> [options]\n");
615 System.out.println(" java " + className);
616 System.out.println(" <Inputfile (JPG)> [options]\n");
617 System.out.println("Options:\n");
618 System.out.println("-alloc = Dynamically allocate JPEG image buffers");
619 System.out.println("-bottomup = Test bottom-up compression/decompression");
620 System.out.println("-tile = Test performance of the codec when the image is encoded as separate");
621 System.out.println(" tiles of varying sizes.");
622 System.out.println("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =");
623 System.out.println(" Test the specified color conversion path in the cod ec (default = BGR)");
624 System.out.println("-fastupsample = Use the fastest chrominance upsampling a lgorithm available in");
625 System.out.println(" the underlying codec");
626 System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
627 System.out.println(" codec");
628 System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the");
629 System.out.println(" underlying codec");
630 System.out.println("-subsamp <s> = When testing JPEG compression, this optio n specifies the level");
631 System.out.println(" of chrominance subsampling to use (<s> = 444, 422, 440, 420, 411, or");
632 System.out.println(" GRAY). The default is to test Grayscale, 4:2:0, 4: 2:2, and 4:4:4 in");
633 System.out.println(" sequence.");
634 System.out.println("-quiet = Output results in tabular rather than verbose f ormat");
635 System.out.println("-yuv = Test YUV encoding/decoding functions");
636 System.out.println("-yuvpad <p> = If testing YUV encoding/decoding, this spe cifies the number of");
637 System.out.println(" bytes to which each row of each plane in the interm ediate YUV image is");
638 System.out.println(" padded (default = 1)");
639 System.out.println("-scale M/N = Scale down the width/height of the decompre ssed JPEG image by a");
640 System.out.print (" factor of M/N (M/N = ");
641 for (i = 0; i < nsf; i++) {
642 System.out.format("%d/%d", scalingFactors[i].getNum(),
643 scalingFactors[i].getDenom());
644 if (nsf == 2 && i != nsf - 1)
645 System.out.print(" or ");
646 else if (nsf > 2) {
647 if (i != nsf - 1)
648 System.out.print(", ");
649 if (i == nsf - 2)
650 System.out.print("or ");
651 }
652 if (i % 8 == 0 && i != 0)
653 System.out.print("\n ");
654 }
655 System.out.println(")");
656 System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180 , -rot270 =");
657 System.out.println(" Perform the corresponding lossless transform prior to");
658 System.out.println(" decompression (these options are mutually exclusive )");
659 System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression");
660 System.out.println(" test (can be combined with the other transforms abo ve)");
661 System.out.println("-benchtime <t> = Run each benchmark for at least <t> sec onds (default = 5.0)");
662 System.out.println("-warmup <w> = Execute each benchmark <w> times to prime the cache before");
663 System.out.println(" taking performance measurements (default = 1)");
664 System.out.println("-componly = Stop after running compression tests. Do no t test decompression.");
665 System.out.println("-nowrite = Do not write reference or output images (impr oves consistency");
666 System.out.println(" of performance measurements.)\n");
667 System.out.println("NOTE: If the quality is specified as a range (e.g. 90-1 00), a separate");
668 System.out.println("test will be performed for all quality values in the ran ge.\n");
669 System.exit(1);
670 }
671
672
673 public static void main(String[] argv) {
674 byte[] srcBuf = null; int w = 0, h = 0;
675 int minQual = -1, maxQual = -1;
676 int minArg = 1; int retval = 0;
677 int subsamp = -1;
678
679 try {
680
681 if (argv.length < minArg)
682 usage();
683
684 String tempStr = argv[0].toLowerCase();
685 if (tempStr.endsWith(".jpg") || tempStr.endsWith(".jpeg"))
686 decompOnly = true;
687
688 System.out.println("");
689
690 if (!decompOnly) {
691 minArg = 2;
692 if (argv.length < minArg)
693 usage();
694 try {
695 minQual = Integer.parseInt(argv[1]);
696 } catch (NumberFormatException e) {}
697 if (minQual < 1 || minQual > 100)
698 throw new Exception("Quality must be between 1 and 100.");
699 int dashIndex = argv[1].indexOf('-');
700 if (dashIndex > 0 && argv[1].length() > dashIndex + 1) {
701 try {
702 maxQual = Integer.parseInt(argv[1].substring(dashIndex + 1));
703 } catch (NumberFormatException e) {}
704 }
705 if (maxQual < 1 || maxQual > 100)
706 maxQual = minQual;
707 }
708
709 if (argv.length > minArg) {
710 for (int i = minArg; i < argv.length; i++) {
711 if (argv[i].equalsIgnoreCase("-tile")) {
712 doTile = true; xformOpt |= TJTransform.OPT_CROP;
713 }
714 if (argv[i].equalsIgnoreCase("-fastupsample")) {
715 System.out.println("Using fast upsampling code\n");
716 flags |= TJ.FLAG_FASTUPSAMPLE;
717 }
718 if (argv[i].equalsIgnoreCase("-fastdct")) {
719 System.out.println("Using fastest DCT/IDCT algorithm\n");
720 flags |= TJ.FLAG_FASTDCT;
721 }
722 if (argv[i].equalsIgnoreCase("-accuratedct")) {
723 System.out.println("Using most accurate DCT/IDCT algorithm\n");
724 flags |= TJ.FLAG_ACCURATEDCT;
725 }
726 if (argv[i].equalsIgnoreCase("-rgb"))
727 pf = TJ.PF_RGB;
728 if (argv[i].equalsIgnoreCase("-rgbx"))
729 pf = TJ.PF_RGBX;
730 if (argv[i].equalsIgnoreCase("-bgr"))
731 pf = TJ.PF_BGR;
732 if (argv[i].equalsIgnoreCase("-bgrx"))
733 pf = TJ.PF_BGRX;
734 if (argv[i].equalsIgnoreCase("-xbgr"))
735 pf = TJ.PF_XBGR;
736 if (argv[i].equalsIgnoreCase("-xrgb"))
737 pf = TJ.PF_XRGB;
738 if (argv[i].equalsIgnoreCase("-bottomup"))
739 flags |= TJ.FLAG_BOTTOMUP;
740 if (argv[i].equalsIgnoreCase("-quiet"))
741 quiet = 1;
742 if (argv[i].equalsIgnoreCase("-qq"))
743 quiet = 2;
744 if (argv[i].equalsIgnoreCase("-scale") && i < argv.length - 1) {
745 int temp1 = 0, temp2 = 0;
746 boolean match = false, scanned = true;
747 Scanner scanner = new Scanner(argv[++i]).useDelimiter("/");
748 try {
749 temp1 = scanner.nextInt();
750 temp2 = scanner.nextInt();
751 } catch(Exception e) {}
752 if (temp2 <= 0) temp2 = 1;
753 if (temp1 > 0) {
754 TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
755 for (int j = 0; j < scalingFactors.length; j++) {
756 if ((double)temp1 / (double)temp2 ==
757 (double)scalingFactors[j].getNum() /
758 (double)scalingFactors[j].getDenom()) {
759 sf = scalingFactors[j];
760 match = true; break;
761 }
762 }
763 if (!match) usage();
764 } else
765 usage();
766 }
767 if (argv[i].equalsIgnoreCase("-hflip"))
768 xformOp = TJTransform.OP_HFLIP;
769 if (argv[i].equalsIgnoreCase("-vflip"))
770 xformOp = TJTransform.OP_VFLIP;
771 if (argv[i].equalsIgnoreCase("-transpose"))
772 xformOp = TJTransform.OP_TRANSPOSE;
773 if (argv[i].equalsIgnoreCase("-transverse"))
774 xformOp = TJTransform.OP_TRANSVERSE;
775 if (argv[i].equalsIgnoreCase("-rot90"))
776 xformOp = TJTransform.OP_ROT90;
777 if (argv[i].equalsIgnoreCase("-rot180"))
778 xformOp = TJTransform.OP_ROT180;
779 if (argv[i].equalsIgnoreCase("-rot270"))
780 xformOp = TJTransform.OP_ROT270;
781 if (argv[i].equalsIgnoreCase("-grayscale"))
782 xformOpt |= TJTransform.OPT_GRAY;
783 if (argv[i].equalsIgnoreCase("-nooutput"))
784 xformOpt |= TJTransform.OPT_NOOUTPUT;
785 if (argv[i].equalsIgnoreCase("-benchtime") && i < argv.length - 1) {
786 double temp = -1;
787 try {
788 temp = Double.parseDouble(argv[++i]);
789 } catch (NumberFormatException e) {}
790 if (temp > 0.0)
791 benchTime = temp;
792 else
793 usage();
794 }
795 if (argv[i].equalsIgnoreCase("-yuv")) {
796 System.out.println("Testing YUV planar encoding/decoding\n");
797 doYUV = true;
798 }
799 if (argv[i].equalsIgnoreCase("-yuvpad") && i < argv.length - 1) {
800 int temp = 0;
801 try {
802 temp = Integer.parseInt(argv[++i]);
803 } catch (NumberFormatException e) {}
804 if (temp >= 1)
805 yuvpad = temp;
806 }
807 if (argv[i].equalsIgnoreCase("-subsamp") && i < argv.length - 1) {
808 i++;
809 if (argv[i].toUpperCase().startsWith("G"))
810 subsamp = TJ.SAMP_GRAY;
811 else if (argv[i].equals("444"))
812 subsamp = TJ.SAMP_444;
813 else if (argv[i].equals("422"))
814 subsamp = TJ.SAMP_422;
815 else if (argv[i].equals("440"))
816 subsamp = TJ.SAMP_440;
817 else if (argv[i].equals("420"))
818 subsamp = TJ.SAMP_420;
819 else if (argv[i].equals("411"))
820 subsamp = TJ.SAMP_411;
821 }
822 if (argv[i].equalsIgnoreCase("-componly"))
823 compOnly = true;
824 if (argv[i].equalsIgnoreCase("-nowrite"))
825 write = false;
826 if (argv[i].equalsIgnoreCase("-warmup") && i < argv.length - 1) {
827 int temp = -1;
828 try {
829 temp = Integer.parseInt(argv[++i]);
830 } catch (NumberFormatException e) {}
831 if (temp >= 0) {
832 warmup = temp;
833 System.out.format("Warmup runs = %d\n\n", warmup);
834 }
835 }
836 if (argv[i].equalsIgnoreCase("-?"))
837 usage();
838 }
839 }
840
841 if (sf == null)
842 sf = new TJScalingFactor(1, 1);
843
844 if ((sf.getNum() != 1 || sf.getDenom() != 1) && doTile) {
845 System.out.println("Disabling tiled compression/decompression tests, bec ause those tests do not");
846 System.out.println("work when scaled decompression is enabled.");
847 doTile = false;
848 }
849
850 if (!decompOnly) {
851 int[] width = new int[1], height = new int[1];
852 srcBuf = loadImage(argv[0], width, height, pf);
853 w = width[0]; h = height[0];
854 int index = -1;
855 if ((index = argv[0].lastIndexOf('.')) >= 0)
856 argv[0] = argv[0].substring(0, index);
857 }
858
859 if (quiet == 1 && !decompOnly) {
860 System.out.println("All performance values in Mpixels/sec\n");
861 System.out.format("Bitmap JPEG JPEG %s %s ",
862 (doTile ? "Tile " : "Image"), (doTile ? "Tile " : "Image"));
863 if (doYUV)
864 System.out.print("Encode ");
865 System.out.print("Comp Comp Decomp ");
866 if (doYUV)
867 System.out.print("Decode");
868 System.out.print("\n");
869 System.out.print("Format Subsamp Qual Width Height ");
870 if (doYUV)
871 System.out.print("Perf ");
872 System.out.print("Perf Ratio Perf ");
873 if (doYUV)
874 System.out.print("Perf");
875 System.out.println("\n");
876 }
877
878 if (decompOnly) {
879 decompTest(argv[0]);
880 System.out.println("");
881 System.exit(retval);
882 }
883
884 System.gc();
885 if (subsamp >= 0 && subsamp < TJ.NUMSAMP) {
886 for (int i = maxQual; i >= minQual; i--)
887 fullTest(srcBuf, w, h, subsamp, i, argv[0]);
888 System.out.println("");
889 } else {
890 for (int i = maxQual; i >= minQual; i--)
891 fullTest(srcBuf, w, h, TJ.SAMP_GRAY, i, argv[0]);
892 System.out.println("");
893 System.gc();
894 for (int i = maxQual; i >= minQual; i--)
895 fullTest(srcBuf, w, h, TJ.SAMP_420, i, argv[0]);
896 System.out.println("");
897 System.gc();
898 for (int i = maxQual; i >= minQual; i--)
899 fullTest(srcBuf, w, h, TJ.SAMP_422, i, argv[0]);
900 System.out.println("");
901 System.gc();
902 for (int i = maxQual; i >= minQual; i--)
903 fullTest(srcBuf, w, h, TJ.SAMP_444, i, argv[0]);
904 System.out.println("");
905 }
906
907 } catch (Exception e) {
908 System.out.println("ERROR: " + e.getMessage());
909 e.printStackTrace();
910 retval = -1;
911 }
912
913 System.exit(retval);
914 }
915
916 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698