From 2e8ff4b084dd77fa9991f55c6a72d971c0e66390 Mon Sep 17 00:00:00 2001 From: DRC Date: Tue, 5 Nov 2013 19:53:12 +0000 Subject: [PATCH] Add the ability to test scaling when decompressing to YUV; compression from YUV to JPEG; and YUV padding. Replace clunky -411 and -440 parameters with a -subsamp parameter that allows any of the subsampling options to be tested in isolation. git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1075 632fc199-4ca6-4c93-a231-07263d6284db --- java/TJBench.java | 195 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 135 insertions(+), 60 deletions(-) diff --git a/java/TJBench.java b/java/TJBench.java index c4055f2..5257a1b 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -36,9 +36,10 @@ class TJBench { static final int YUVENCODE = 1; static final int YUVDECODE = 2; + static final int YUVCOMPRESS = 3; - static int flags = 0, yuv = 0, quiet = 0, pf = TJ.PF_BGR; - static boolean decompOnly, doTile; + static int flags = 0, yuv = 0, quiet = 0, pf = TJ.PF_BGR, yuvpad = 1; + static boolean compOnly, decompOnly, doTile; static final String[] pixFormatStr = { "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY" @@ -141,9 +142,9 @@ class TJBench { TJDecompressor tjd; double start, elapsed; int ps = TJ.getPixelSize(pf), i; - int yuvSize = TJ.bufSizeYUV(w, h, subsamp), bufsize; - int scaledw = (yuv == YUVDECODE) ? w : sf.getScaled(w); - int scaledh = (yuv == YUVDECODE) ? h : sf.getScaled(h); + int scaledw = sf.getScaled(w); + int scaledh = sf.getScaled(h); + int yuvSize = TJ.bufSizeYUV(scaledw, yuvpad, scaledh, subsamp), bufsize; int pitch = scaledw * ps; if (jpegQual > 0) @@ -162,7 +163,7 @@ class TJBench { /* Execute once to preload cache */ tjd.setJPEGImage(jpegBuf[0], jpegSize[0]); if (yuv == YUVDECODE) - tjd.decompressToYUV(dstBuf, flags); + tjd.decompressToYUV(dstBuf, scaledw, yuvpad, scaledh, flags); else tjd.decompress(dstBuf, scaledw, pitch, scaledh, pf, flags); @@ -171,7 +172,7 @@ class TJBench { i++) { int tile = 0; if (yuv == YUVDECODE) - tjd.decompressToYUV(dstBuf, flags); + tjd.decompressToYUV(dstBuf, scaledw, yuvpad, scaledh, flags); else { for (int y = 0; y < h; y += tileh) { for (int x = 0; x < w; x += tilew, tile++) { @@ -197,23 +198,24 @@ class TJBench { (double)(w * h) / 1000000. * (double)i / elapsed); } + if (sf.getNum() != 1 || sf.getDenom() != 1) + sizeStr = new String(sf.getNum() + "_" + sf.getDenom()); + else if (tilew != w || tileh != h) + sizeStr = new String(tilew + "x" + tileh); + else + sizeStr = new String("full"); + if (decompOnly) + tempStr = new String(fileName + "_" + sizeStr + + (yuv != 0 ? ".yuv" : ".bmp")); + else + tempStr = new String(fileName + "_" + subName[subsamp] + qualStr + + "_" + sizeStr + (yuv != 0 ? ".yuv" : ".bmp")); + if (yuv == YUVDECODE) { - tempStr = fileName + "_" + subName[subsamp] + qualStr + ".yuv"; FileOutputStream fos = new FileOutputStream(tempStr); fos.write(dstBuf, 0, yuvSize); fos.close(); } else { - if (sf.getNum() != 1 || sf.getDenom() != 1) - sizeStr = new String(sf.getNum() + "_" + sf.getDenom()); - else if (tilew != w || tileh != h) - sizeStr = new String(tilew + "x" + tileh); - else - sizeStr = new String("full"); - if (decompOnly) - tempStr = new String(fileName + "_" + sizeStr + ".bmp"); - else - tempStr = new String(fileName + "_" + subName[subsamp] + qualStr + - "_" + sizeStr + ".bmp"); saveImage(tempStr, dstBuf, scaledw, scaledh, pf); int ndx = tempStr.indexOf('.'); tempStr = new String(tempStr.substring(0, ndx) + "-err.bmp"); @@ -319,7 +321,9 @@ class TJBench { int[] jpegSize; double start, elapsed; int totalJpegSize = 0, tilew, tileh, i; - int ps = TJ.getPixelSize(pf), ntilesw = 1, ntilesh = 1, pitch = w * ps; + int ps = (yuv == YUVCOMPRESS ? 3 : TJ.getPixelSize(pf)); + int ntilesw = 1, ntilesh = 1, pitch = w * ps; + String pfStr = (yuv == YUVCOMPRESS ? "YUV" : pixFormatStr[pf]); if (yuv == YUVENCODE) { doTestYUV(srcBuf, w, h, subsamp, fileName); @@ -329,8 +333,7 @@ class TJBench { tmpBuf = new byte[pitch * h]; if (quiet == 0) - System.out.format(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", - pixFormatStr[pf], + System.out.format(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr, (flags & TJ.FLAG_BOTTOMUP) != 0 ? "Bottom-up" : "Top-down", subNameLong[subsamp], jpegQual); @@ -350,12 +353,16 @@ class TJBench { /* Compression test */ if (quiet == 1) - System.out.format("%s\t%s\t%s\t%d\t", pixFormatStr[pf], + System.out.format("%s\t%s\t%s\t%d\t", pfStr, (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD", subNameLong[subsamp], jpegQual); - for (i = 0; i < h; i++) - System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps); - tjc.setSourceImage(srcBuf, tilew, pitch, tileh, pf); + if (yuv != YUVCOMPRESS) + for (i = 0; i < h; i++) + System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps); + if (yuv == YUVCOMPRESS) + tjc.setSourceImageYUV(srcBuf, tilew, yuvpad, tileh); + else + tjc.setSourceImage(srcBuf, tilew, pitch, tileh, pf); tjc.setJPEGQuality(jpegQual); tjc.setSubsamp(subsamp); @@ -371,7 +378,8 @@ class TJBench { for (int x = 0; x < w; x += tilew, tile++) { int width = Math.min(tilew, w - x); int height = Math.min(tileh, h - y); - tjc.setSourceImage(srcBuf, x, y, width, pitch, height, pf); + if (yuv != YUVCOMPRESS) + tjc.setSourceImage(srcBuf, x, y, width, pitch, height, pf); tjc.compress(jpegBuf[tile], flags); jpegSize[tile] = tjc.getCompressedSize(); totalJpegSize += jpegSize[tile]; @@ -412,8 +420,9 @@ class TJBench { } /* Decompression test */ - decompTest(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual, - fileName, tilew, tileh); + if (!compOnly) + decompTest(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual, + fileName, tilew, tileh); for (i = 0; i < ntilesw * ntilesh; i++) jpegBuf[i] = null; @@ -601,7 +610,7 @@ class TJBench { String className = new TJBench().getClass().getName(); System.out.println("\nUSAGE: java " + className); - System.out.println(" [options]\n"); + System.out.println(" [options]\n"); System.out.println(" java " + className); System.out.println(" [options]\n"); System.out.println("Options:\n"); @@ -619,11 +628,21 @@ class TJBench { System.out.println(" codec"); System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the"); System.out.println(" underlying codec"); - System.out.println("-440 = Test 4:4:0 chrominance subsampling instead of 4:2:2"); - System.out.println("-411 = Test 4:1:1 chrominance subsampling instead of 4:2:0"); + System.out.println("-subsamp = if compressing a JPEG image from a YUV planar source image,"); + System.out.println(" this specifies the level of chrominance subsampling used in the source"); + System.out.println(" image. Otherwise, this specifies the level of chrominance subsampling"); + System.out.println(" to use in the JPEG destination image. = 444, 422, 440, 420, 411,"); + System.out.println(" or GRAY"); System.out.println("-quiet = Output results in tabular rather than verbose format"); System.out.println("-yuvencode = Encode RGB input as planar YUV rather than compressing as JPEG"); System.out.println("-yuvdecode = Decode JPEG image to planar YUV rather than RGB"); + System.out.println("-yuvsize WxH = if compressing a JPEG image from a YUV planar source image, this"); + System.out.println(" specifies the width and height of the source image."); + System.out.println("-yuvpad

= if compressing a JPEG image from a YUV planar source image, this"); + System.out.println(" specifies the number of bytes to which each row of each plane in the"); + System.out.println(" source image is padded. If decompressing a JPEG image to a YUV planar"); + System.out.println(" destination image, this specifies the row padding for each plane of the"); + System.out.println(" destination image. (default=1)"); System.out.println("-scale M/N = scale down the width/height of the decompressed JPEG image by a"); System.out.print (" factor of M/N (M/N = "); for (i = 0; i < nsf; i++) { @@ -646,7 +665,8 @@ class TJBench { System.out.println(" decompression (these options are mutually exclusive)"); System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression"); System.out.println(" test (can be combined with the other transforms above)"); - System.out.println("-benchTime = Run each benchmark for at least seconds (default = 5.0)\n"); + System.out.println("-benchtime = Run each benchmark for at least seconds (default = 5.0)"); + System.out.println("-componly = Stop after running compression tests. Do not test decompression.\n"); System.out.println("NOTE: If the quality is specified as a range (e.g. 90-100), a separate"); System.out.println("test will be performed for all quality values in the range.\n"); System.exit(1); @@ -657,7 +677,7 @@ class TJBench { byte[] srcBuf = null; int w = 0, h = 0; int minQual = -1, maxQual = -1; int minArg = 1; int retval = 0; - boolean do440 = false, do411 = false; + int subsamp = -1; try { @@ -667,6 +687,8 @@ class TJBench { String tempStr = argv[0].toLowerCase(); if (tempStr.endsWith(".jpg") || tempStr.endsWith(".jpeg")) decompOnly = true; + if (tempStr.endsWith(".yuv")) + yuv = YUVCOMPRESS; System.out.println(""); @@ -735,10 +757,6 @@ class TJBench { System.out.println("Using most accurate DCT/IDCT algorithm\n"); flags |= TJ.FLAG_ACCURATEDCT; } - if (argv[i].equals("-440")) - do440 = true; - if (argv[i].equals("-411")) - do411 = true; if (argv[i].equalsIgnoreCase("-rgb")) pf = TJ.PF_RGB; if (argv[i].equalsIgnoreCase("-rgbx")) @@ -808,6 +826,44 @@ class TJBench { else usage(); } + if (argv[i].equalsIgnoreCase("-yuvsize") && i < argv.length - 1) { + int temp1 = 0, temp2 = 0; + Scanner scanner = new Scanner(argv[++i]).useDelimiter("x"); + try { + temp1 = scanner.nextInt(); + temp2 = scanner.nextInt(); + } catch(Exception e) {} + if (temp1 >= 1 && temp2 >= 1) { + w = temp1; + h = temp2; + } else + usage(); + } + if (argv[i].equalsIgnoreCase("-yuvpad") && i < argv.length - 1) { + int temp = 0; + try { + temp = Integer.parseInt(argv[++i]); + } catch (NumberFormatException e) {} + if (temp >= 1) + yuvpad = temp; + } + if (argv[i].equalsIgnoreCase("-subsamp") && i < argv.length - 1) { + i++; + if (argv[i].toUpperCase().startsWith("G")) + subsamp = TJ.SAMP_GRAY; + else if (argv[i].equals("444")) + subsamp = TJ.SAMP_444; + else if (argv[i].equals("422")) + subsamp = TJ.SAMP_422; + else if (argv[i].equals("440")) + subsamp = TJ.SAMP_440; + else if (argv[i].equals("420")) + subsamp = TJ.SAMP_420; + else if (argv[i].equals("411")) + subsamp = TJ.SAMP_411; + } + if (argv[i].equalsIgnoreCase("-componly")) + compOnly = true; if (argv[i].equalsIgnoreCase("-?")) usage(); } @@ -824,17 +880,30 @@ class TJBench { if (yuv != 0 && doTile) { System.out.println("Disabling tiled compression/decompression tests, because those tests do not"); - System.out.println("work when YUV encoding or decoding is enabled.\n"); + System.out.println("work when YUV encoding, compression, or decoding is enabled.\n"); doTile = false; } if (!decompOnly) { - int[] width = new int[1], height = new int[1]; - srcBuf = loadImage(argv[0], width, height, pf); - w = width[0]; h = height[0]; - int index = -1; - if ((index = argv[0].indexOf('.')) >= 0) - argv[0] = argv[0].substring(0, index); + if(yuv == YUVCOMPRESS) { + if (w < 1 || h < 1 || subsamp < 0 || subsamp >= TJ.NUMSAMP) + throw new Exception("YUV image size and/or subsampling not specified"); + FileInputStream fis = new FileInputStream(argv[0]); + int srcSize = (int)fis.getChannel().size(); + if (srcSize != TJ.bufSizeYUV(w, yuvpad, h, subsamp)) + throw new Exception("YUV image file is the wrong size"); + srcBuf = new byte[srcSize]; + fis.read(srcBuf, 0, srcSize); + fis.close(); + } + else { + int[] width = new int[1], height = new int[1]; + srcBuf = loadImage(argv[0], width, height, pf); + w = width[0]; h = height[0]; + int index = -1; + if ((index = argv[0].indexOf('.')) >= 0) + argv[0] = argv[0].substring(0, index); + } } if (quiet == 1 && !decompOnly) { @@ -851,21 +920,27 @@ class TJBench { } System.gc(); - for (int i = maxQual; i >= minQual; i--) - doTest(srcBuf, w, h, TJ.SAMP_GRAY, i, argv[0]); - System.out.println(""); - System.gc(); - for (int i = maxQual; i >= minQual; i--) - doTest(srcBuf, w, h, do411 ? TJ.SAMP_411 : TJ.SAMP_420, i, argv[0]); - System.out.println(""); - System.gc(); - for (int i = maxQual; i >= minQual; i--) - doTest(srcBuf, w, h, do440 ? TJ.SAMP_440 : TJ.SAMP_422, i, argv[0]); - System.out.println(""); - System.gc(); - for (int i = maxQual; i >= minQual; i--) - doTest(srcBuf, w, h, TJ.SAMP_444, i, argv[0]); - System.out.println(""); + if (yuv == YUVCOMPRESS || (subsamp >= 0 && subsamp < TJ.NUMSAMP)) { + for (int i = maxQual; i >= minQual; i--) + doTest(srcBuf, w, h, subsamp, i, argv[0]); + System.out.println(""); + } else { + for (int i = maxQual; i >= minQual; i--) + doTest(srcBuf, w, h, TJ.SAMP_GRAY, i, argv[0]); + System.out.println(""); + System.gc(); + for (int i = maxQual; i >= minQual; i--) + doTest(srcBuf, w, h, TJ.SAMP_420, i, argv[0]); + System.out.println(""); + System.gc(); + for (int i = maxQual; i >= minQual; i--) + doTest(srcBuf, w, h, TJ.SAMP_422, i, argv[0]); + System.out.println(""); + System.gc(); + for (int i = maxQual; i >= minQual; i--) + doTest(srcBuf, w, h, TJ.SAMP_444, i, argv[0]); + System.out.println(""); + } } catch (Exception e) { System.out.println("ERROR: " + e.getMessage()); -- 2.40.0