shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * Copyright (C)2009-2014, 2016-2019 D. R. Commander.  All Rights Reserved.
shun-iwasawa 82a8f5
 *
shun-iwasawa 82a8f5
 * Redistribution and use in source and binary forms, with or without
shun-iwasawa 82a8f5
 * modification, are permitted provided that the following conditions are met:
shun-iwasawa 82a8f5
 *
shun-iwasawa 82a8f5
 * - Redistributions of source code must retain the above copyright notice,
shun-iwasawa 82a8f5
 *   this list of conditions and the following disclaimer.
shun-iwasawa 82a8f5
 * - Redistributions in binary form must reproduce the above copyright notice,
shun-iwasawa 82a8f5
 *   this list of conditions and the following disclaimer in the documentation
shun-iwasawa 82a8f5
 *   and/or other materials provided with the distribution.
shun-iwasawa 82a8f5
 * - Neither the name of the libjpeg-turbo Project nor the names of its
shun-iwasawa 82a8f5
 *   contributors may be used to endorse or promote products derived from this
shun-iwasawa 82a8f5
 *   software without specific prior written permission.
shun-iwasawa 82a8f5
 *
shun-iwasawa 82a8f5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
shun-iwasawa 82a8f5
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
shun-iwasawa 82a8f5
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
shun-iwasawa 82a8f5
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
shun-iwasawa 82a8f5
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
shun-iwasawa 82a8f5
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
shun-iwasawa 82a8f5
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
shun-iwasawa 82a8f5
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
shun-iwasawa 82a8f5
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
shun-iwasawa 82a8f5
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
shun-iwasawa 82a8f5
 * POSSIBILITY OF SUCH DAMAGE.
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
import java.io.*;
shun-iwasawa 82a8f5
import java.awt.image.*;
shun-iwasawa 82a8f5
import javax.imageio.*;
shun-iwasawa 82a8f5
import java.util.*;
shun-iwasawa 82a8f5
import org.libjpegturbo.turbojpeg.*;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
final class TJBench {
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  private TJBench() {}
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  private static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvPad = 1;
shun-iwasawa 82a8f5
  private static boolean compOnly, decompOnly, doTile, doYUV, write = true;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] PIXFORMATSTR = {
shun-iwasawa 82a8f5
    "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] SUBNAME_LONG = {
shun-iwasawa 82a8f5
    "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] SUBNAME = {
shun-iwasawa 82a8f5
    "444", "422", "420", "GRAY", "440", "411"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] CSNAME = {
shun-iwasawa 82a8f5
    "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  private static TJScalingFactor sf;
shun-iwasawa 82a8f5
  private static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
shun-iwasawa 82a8f5
  private static double benchTime = 5.0, warmup = 1.0;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static double getTime() {
shun-iwasawa 82a8f5
    return (double)System.nanoTime() / 1.0e9;
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  private static String tjErrorMsg;
shun-iwasawa 82a8f5
  private static int tjErrorCode = -1;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void handleTJException(TJException e) throws TJException {
shun-iwasawa 82a8f5
    String errorMsg = e.getMessage();
shun-iwasawa 82a8f5
    int errorCode = e.getErrorCode();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if ((flags & TJ.FLAG_STOPONWARNING) == 0 &&
shun-iwasawa 82a8f5
        errorCode == TJ.ERR_WARNING) {
shun-iwasawa 82a8f5
      if (tjErrorMsg == null || !tjErrorMsg.equals(errorMsg) ||
shun-iwasawa 82a8f5
          tjErrorCode != errorCode) {
shun-iwasawa 82a8f5
        tjErrorMsg = errorMsg;
shun-iwasawa 82a8f5
        tjErrorCode = errorCode;
shun-iwasawa 82a8f5
        System.out.println("WARNING: " + errorMsg);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
    } else
shun-iwasawa 82a8f5
      throw e;
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static String formatName(int subsamp, int cs) {
shun-iwasawa 82a8f5
    if (cs == TJ.CS_YCbCr)
shun-iwasawa 82a8f5
      return SUBNAME_LONG[subsamp];
shun-iwasawa 82a8f5
    else if (cs == TJ.CS_YCCK)
shun-iwasawa 82a8f5
      return CSNAME[cs] + " " + SUBNAME_LONG[subsamp];
shun-iwasawa 82a8f5
    else
shun-iwasawa 82a8f5
      return CSNAME[cs];
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static String sigFig(double val, int figs) {
shun-iwasawa 82a8f5
    String format;
shun-iwasawa 82a8f5
    int digitsAfterDecimal = figs - (int)Math.ceil(Math.log10(Math.abs(val)));
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (digitsAfterDecimal < 1)
shun-iwasawa 82a8f5
      format = new String("%.0f");
shun-iwasawa 82a8f5
    else
shun-iwasawa 82a8f5
      format = new String("%." + digitsAfterDecimal + "f");
shun-iwasawa 82a8f5
    return String.format(format, val);
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static byte[] loadImage(String fileName, int[] w, int[] h, int pixelFormat)
shun-iwasawa 82a8f5
                          throws Exception {
shun-iwasawa 82a8f5
    BufferedImage img = ImageIO.read(new File(fileName));
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (img == null)
shun-iwasawa 82a8f5
      throw new Exception("Could not read " + fileName);
shun-iwasawa 82a8f5
    w[0] = img.getWidth();
shun-iwasawa 82a8f5
    h[0] = img.getHeight();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    int[] rgb = img.getRGB(0, 0, w[0], h[0], null, 0, w[0]);
shun-iwasawa 82a8f5
    int ps = TJ.getPixelSize(pixelFormat);
shun-iwasawa 82a8f5
    int rindex = TJ.getRedOffset(pixelFormat);
shun-iwasawa 82a8f5
    int gindex = TJ.getGreenOffset(pixelFormat);
shun-iwasawa 82a8f5
    int bindex = TJ.getBlueOffset(pixelFormat);
shun-iwasawa 82a8f5
    if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE)
shun-iwasawa 82a8f5
      throw new Exception("Image is too large");
shun-iwasawa 82a8f5
    byte[] dstBuf = new byte[w[0] * h[0] * ps];
shun-iwasawa 82a8f5
    int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    while (pixels-- > 0) {
shun-iwasawa 82a8f5
      dstBuf[dstPtr + rindex] = (byte)((rgb[rgbPtr] >> 16) & 0xff);
shun-iwasawa 82a8f5
      dstBuf[dstPtr + gindex] = (byte)((rgb[rgbPtr] >> 8) & 0xff);
shun-iwasawa 82a8f5
      dstBuf[dstPtr + bindex] = (byte)(rgb[rgbPtr] & 0xff);
shun-iwasawa 82a8f5
      dstPtr += ps;
shun-iwasawa 82a8f5
      rgbPtr++;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    return dstBuf;
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void saveImage(String fileName, byte[] srcBuf, int w, int h,
shun-iwasawa 82a8f5
                        int pixelFormat) throws Exception {
shun-iwasawa 82a8f5
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
shun-iwasawa 82a8f5
    int pixels = w * h, srcPtr = 0;
shun-iwasawa 82a8f5
    int ps = TJ.getPixelSize(pixelFormat);
shun-iwasawa 82a8f5
    int rindex = TJ.getRedOffset(pixelFormat);
shun-iwasawa 82a8f5
    int gindex = TJ.getGreenOffset(pixelFormat);
shun-iwasawa 82a8f5
    int bindex = TJ.getBlueOffset(pixelFormat);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    for (int y = 0; y < h; y++) {
shun-iwasawa 82a8f5
      for (int x = 0; x < w; x++, srcPtr += ps) {
shun-iwasawa 82a8f5
        int pixel = (srcBuf[srcPtr + rindex] & 0xff) << 16 |
shun-iwasawa 82a8f5
                    (srcBuf[srcPtr + gindex] & 0xff) << 8 |
shun-iwasawa 82a8f5
                    (srcBuf[srcPtr + bindex] & 0xff);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        img.setRGB(x, y, pixel);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    ImageIO.write(img, "bmp", new File(fileName));
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* Decompression test */
shun-iwasawa 82a8f5
  static void decomp(byte[] srcBuf, byte[][] jpegBuf, int[] jpegSize,
shun-iwasawa 82a8f5
                     byte[] dstBuf, int w, int h, int subsamp, int jpegQual,
shun-iwasawa 82a8f5
                     String fileName, int tilew, int tileh) throws Exception {
shun-iwasawa 82a8f5
    String qualStr = new String(""), sizeStr, tempStr;
shun-iwasawa 82a8f5
    TJDecompressor tjd;
shun-iwasawa 82a8f5
    double elapsed, elapsedDecode;
shun-iwasawa 82a8f5
    int ps = TJ.getPixelSize(pf), i, iter = 0;
shun-iwasawa 82a8f5
    int scaledw = sf.getScaled(w);
shun-iwasawa 82a8f5
    int scaledh = sf.getScaled(h);
shun-iwasawa 82a8f5
    int pitch = scaledw * ps;
shun-iwasawa 82a8f5
    YUVImage yuvImage = null;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (jpegQual > 0)
shun-iwasawa 82a8f5
      qualStr = new String("_Q" + jpegQual);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    tjd = new TJDecompressor();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (dstBuf == null) {
shun-iwasawa 82a8f5
      if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE)
shun-iwasawa 82a8f5
        throw new Exception("Image is too large");
shun-iwasawa 82a8f5
      dstBuf = new byte[pitch * scaledh];
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    /* Set the destination buffer to gray so we know whether the decompressor
shun-iwasawa 82a8f5
       attempted to write to it */
shun-iwasawa 82a8f5
    Arrays.fill(dstBuf, (byte)127);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (doYUV) {
shun-iwasawa 82a8f5
      int width = doTile ? tilew : scaledw;
shun-iwasawa 82a8f5
      int height = doTile ? tileh : scaledh;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      yuvImage = new YUVImage(width, yuvPad, height, subsamp);
shun-iwasawa 82a8f5
      Arrays.fill(yuvImage.getBuf(), (byte)127);
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    /* Benchmark */
shun-iwasawa 82a8f5
    iter = -1;
shun-iwasawa 82a8f5
    elapsed = elapsedDecode = 0.0;
shun-iwasawa 82a8f5
    while (true) {
shun-iwasawa 82a8f5
      int tile = 0;
shun-iwasawa 82a8f5
      double start = getTime();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      for (int y = 0; y < h; y += tileh) {
shun-iwasawa 82a8f5
        for (int x = 0; x < w; x += tilew, tile++) {
shun-iwasawa 82a8f5
          int width = doTile ? Math.min(tilew, w - x) : scaledw;
shun-iwasawa 82a8f5
          int height = doTile ? Math.min(tileh, h - y) : scaledh;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
          try {
shun-iwasawa 82a8f5
            tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]);
shun-iwasawa 82a8f5
          } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
          if (doYUV) {
shun-iwasawa 82a8f5
            yuvImage.setBuf(yuvImage.getBuf(), width, yuvPad, height, subsamp);
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              tjd.decompressToYUV(yuvImage, flags);
shun-iwasawa 82a8f5
            } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
            double startDecode = getTime();
shun-iwasawa 82a8f5
            tjd.setSourceImage(yuvImage);
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
shun-iwasawa 82a8f5
            } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
            if (iter >= 0)
shun-iwasawa 82a8f5
              elapsedDecode += getTime() - startDecode;
shun-iwasawa 82a8f5
          } else {
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
shun-iwasawa 82a8f5
            } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      elapsed += getTime() - start;
shun-iwasawa 82a8f5
      if (iter >= 0) {
shun-iwasawa 82a8f5
        iter++;
shun-iwasawa 82a8f5
        if (elapsed >= benchTime)
shun-iwasawa 82a8f5
          break;
shun-iwasawa 82a8f5
      } else if (elapsed >= warmup) {
shun-iwasawa 82a8f5
        iter = 0;
shun-iwasawa 82a8f5
        elapsed = elapsedDecode = 0.0;
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    if (doYUV)
shun-iwasawa 82a8f5
      elapsed -= elapsedDecode;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    tjd = null;
shun-iwasawa 82a8f5
    for (i = 0; i < jpegBuf.length; i++)
shun-iwasawa 82a8f5
      jpegBuf[i] = null;
shun-iwasawa 82a8f5
    jpegBuf = null;  jpegSize = null;
shun-iwasawa 82a8f5
    System.gc();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (quiet != 0) {
shun-iwasawa 82a8f5
      System.out.format("%-6s%s",
shun-iwasawa 82a8f5
                        sigFig((double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                               (double)iter / elapsed, 4),
shun-iwasawa 82a8f5
                        quiet == 2 ? "\n" : "  ");
shun-iwasawa 82a8f5
      if (doYUV)
shun-iwasawa 82a8f5
        System.out.format("%s\n",
shun-iwasawa 82a8f5
                          sigFig((double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                                 (double)iter / elapsedDecode, 4));
shun-iwasawa 82a8f5
      else if (quiet != 2)
shun-iwasawa 82a8f5
        System.out.print("\n");
shun-iwasawa 82a8f5
    } else {
shun-iwasawa 82a8f5
      System.out.format("%s --> Frame rate:         %f fps\n",
shun-iwasawa 82a8f5
                        (doYUV ? "Decomp to YUV" : "Decompress   "),
shun-iwasawa 82a8f5
                        (double)iter / elapsed);
shun-iwasawa 82a8f5
      System.out.format("                  Throughput:         %f Megapixels/sec\n",
shun-iwasawa 82a8f5
                        (double)(w * h) / 1000000. * (double)iter / elapsed);
shun-iwasawa 82a8f5
      if (doYUV) {
shun-iwasawa 82a8f5
        System.out.format("YUV Decode    --> Frame rate:         %f fps\n",
shun-iwasawa 82a8f5
                          (double)iter / elapsedDecode);
shun-iwasawa 82a8f5
        System.out.format("                  Throughput:         %f Megapixels/sec\n",
shun-iwasawa 82a8f5
                          (double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                          (double)iter / elapsedDecode);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (!write) return;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (sf.getNum() != 1 || sf.getDenom() != 1)
shun-iwasawa 82a8f5
      sizeStr = new String(sf.getNum() + "_" + sf.getDenom());
shun-iwasawa 82a8f5
    else if (tilew != w || tileh != h)
shun-iwasawa 82a8f5
      sizeStr = new String(tilew + "x" + tileh);
shun-iwasawa 82a8f5
    else
shun-iwasawa 82a8f5
      sizeStr = new String("full");
shun-iwasawa 82a8f5
    if (decompOnly)
shun-iwasawa 82a8f5
      tempStr = new String(fileName + "_" + sizeStr + ".bmp");
shun-iwasawa 82a8f5
    else
shun-iwasawa 82a8f5
      tempStr = new String(fileName + "_" + SUBNAME[subsamp] + qualStr +
shun-iwasawa 82a8f5
                           "_" + sizeStr + ".bmp");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    saveImage(tempStr, dstBuf, scaledw, scaledh, pf);
shun-iwasawa 82a8f5
    int ndx = tempStr.lastIndexOf('.');
shun-iwasawa 82a8f5
    tempStr = new String(tempStr.substring(0, ndx) + "-err.bmp");
shun-iwasawa 82a8f5
    if (srcBuf != null && sf.getNum() == 1 && sf.getDenom() == 1) {
shun-iwasawa 82a8f5
      if (quiet == 0)
shun-iwasawa 82a8f5
        System.out.println("Compression error written to " + tempStr + ".");
shun-iwasawa 82a8f5
      if (subsamp == TJ.SAMP_GRAY) {
shun-iwasawa 82a8f5
        for (int y = 0, index = 0; y < h; y++, index += pitch) {
shun-iwasawa 82a8f5
          for (int x = 0, index2 = index; x < w; x++, index2 += ps) {
shun-iwasawa 82a8f5
            int rindex = index2 + TJ.getRedOffset(pf);
shun-iwasawa 82a8f5
            int gindex = index2 + TJ.getGreenOffset(pf);
shun-iwasawa 82a8f5
            int bindex = index2 + TJ.getBlueOffset(pf);
shun-iwasawa 82a8f5
            int lum = (int)((double)(srcBuf[rindex] & 0xff) * 0.299 +
shun-iwasawa 82a8f5
                            (double)(srcBuf[gindex] & 0xff) * 0.587 +
shun-iwasawa 82a8f5
                            (double)(srcBuf[bindex] & 0xff) * 0.114 + 0.5);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            if (lum > 255) lum = 255;
shun-iwasawa 82a8f5
            if (lum < 0) lum = 0;
shun-iwasawa 82a8f5
            dstBuf[rindex] = (byte)Math.abs((dstBuf[rindex] & 0xff) - lum);
shun-iwasawa 82a8f5
            dstBuf[gindex] = (byte)Math.abs((dstBuf[gindex] & 0xff) - lum);
shun-iwasawa 82a8f5
            dstBuf[bindex] = (byte)Math.abs((dstBuf[bindex] & 0xff) - lum);
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        for (int y = 0; y < h; y++)
shun-iwasawa 82a8f5
          for (int x = 0; x < w * ps; x++)
shun-iwasawa 82a8f5
            dstBuf[pitch * y + x] =
shun-iwasawa 82a8f5
              (byte)Math.abs((dstBuf[pitch * y + x] & 0xff) -
shun-iwasawa 82a8f5
                             (srcBuf[pitch * y + x] & 0xff));
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      saveImage(tempStr, dstBuf, w, h, pf);
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void fullTest(byte[] srcBuf, int w, int h, int subsamp, int jpegQual,
shun-iwasawa 82a8f5
                       String fileName) throws Exception {
shun-iwasawa 82a8f5
    TJCompressor tjc;
shun-iwasawa 82a8f5
    byte[] tmpBuf;
shun-iwasawa 82a8f5
    byte[][] jpegBuf;
shun-iwasawa 82a8f5
    int[] jpegSize;
shun-iwasawa 82a8f5
    double start, elapsed, elapsedEncode;
shun-iwasawa 82a8f5
    int totalJpegSize = 0, tilew, tileh, i, iter;
shun-iwasawa 82a8f5
    int ps = TJ.getPixelSize(pf);
shun-iwasawa 82a8f5
    int ntilesw = 1, ntilesh = 1, pitch = w * ps;
shun-iwasawa 82a8f5
    String pfStr = PIXFORMATSTR[pf];
shun-iwasawa 82a8f5
    YUVImage yuvImage = null;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if ((long)pitch * (long)h > (long)Integer.MAX_VALUE)
shun-iwasawa 82a8f5
      throw new Exception("Image is too large");
shun-iwasawa 82a8f5
    tmpBuf = new byte[pitch * h];
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (quiet == 0)
shun-iwasawa 82a8f5
      System.out.format(">>>>>  %s (%s) <--> JPEG %s Q%d  <<<<<\n", pfStr,
shun-iwasawa 82a8f5
                        (flags & TJ.FLAG_BOTTOMUP) != 0 ?
shun-iwasawa 82a8f5
                        "Bottom-up" : "Top-down",
shun-iwasawa 82a8f5
                        SUBNAME_LONG[subsamp], jpegQual);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    tjc = new TJCompressor();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ;
shun-iwasawa 82a8f5
         tilew *= 2, tileh *= 2) {
shun-iwasawa 82a8f5
      if (tilew > w)
shun-iwasawa 82a8f5
        tilew = w;
shun-iwasawa 82a8f5
      if (tileh > h)
shun-iwasawa 82a8f5
        tileh = h;
shun-iwasawa 82a8f5
      ntilesw = (w + tilew - 1) / tilew;
shun-iwasawa 82a8f5
      ntilesh = (h + tileh - 1) / tileh;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      jpegBuf = new byte[ntilesw * ntilesh][TJ.bufSize(tilew, tileh, subsamp)];
shun-iwasawa 82a8f5
      jpegSize = new int[ntilesw * ntilesh];
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      /* Compression test */
shun-iwasawa 82a8f5
      if (quiet == 1)
shun-iwasawa 82a8f5
        System.out.format("%-4s (%s)  %-5s    %-3d   ", pfStr,
shun-iwasawa 82a8f5
                          (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
shun-iwasawa 82a8f5
                          SUBNAME_LONG[subsamp], jpegQual);
shun-iwasawa 82a8f5
      for (i = 0; i < h; i++)
shun-iwasawa 82a8f5
        System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps);
shun-iwasawa 82a8f5
      tjc.setJPEGQuality(jpegQual);
shun-iwasawa 82a8f5
      tjc.setSubsamp(subsamp);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (doYUV) {
shun-iwasawa 82a8f5
        yuvImage = new YUVImage(tilew, yuvPad, tileh, subsamp);
shun-iwasawa 82a8f5
        Arrays.fill(yuvImage.getBuf(), (byte)127);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      /* Benchmark */
shun-iwasawa 82a8f5
      iter = -1;
shun-iwasawa 82a8f5
      elapsed = elapsedEncode = 0.0;
shun-iwasawa 82a8f5
      while (true) {
shun-iwasawa 82a8f5
        int tile = 0;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        totalJpegSize = 0;
shun-iwasawa 82a8f5
        start = getTime();
shun-iwasawa 82a8f5
        for (int y = 0; y < h; y += tileh) {
shun-iwasawa 82a8f5
          for (int x = 0; x < w; x += tilew, tile++) {
shun-iwasawa 82a8f5
            int width = Math.min(tilew, w - x);
shun-iwasawa 82a8f5
            int height = Math.min(tileh, h - y);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            tjc.setSourceImage(srcBuf, x, y, width, pitch, height, pf);
shun-iwasawa 82a8f5
            if (doYUV) {
shun-iwasawa 82a8f5
              double startEncode = getTime();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
              yuvImage.setBuf(yuvImage.getBuf(), width, yuvPad, height,
shun-iwasawa 82a8f5
                              subsamp);
shun-iwasawa 82a8f5
              tjc.encodeYUV(yuvImage, flags);
shun-iwasawa 82a8f5
              if (iter >= 0)
shun-iwasawa 82a8f5
                elapsedEncode += getTime() - startEncode;
shun-iwasawa 82a8f5
              tjc.setSourceImage(yuvImage);
shun-iwasawa 82a8f5
            }
shun-iwasawa 82a8f5
            tjc.compress(jpegBuf[tile], flags);
shun-iwasawa 82a8f5
            jpegSize[tile] = tjc.getCompressedSize();
shun-iwasawa 82a8f5
            totalJpegSize += jpegSize[tile];
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        elapsed += getTime() - start;
shun-iwasawa 82a8f5
        if (iter >= 0) {
shun-iwasawa 82a8f5
          iter++;
shun-iwasawa 82a8f5
          if (elapsed >= benchTime)
shun-iwasawa 82a8f5
            break;
shun-iwasawa 82a8f5
        } else if (elapsed >= warmup) {
shun-iwasawa 82a8f5
          iter = 0;
shun-iwasawa 82a8f5
          elapsed = elapsedEncode = 0.0;
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      if (doYUV)
shun-iwasawa 82a8f5
        elapsed -= elapsedEncode;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (quiet == 1)
shun-iwasawa 82a8f5
        System.out.format("%-5d  %-5d   ", tilew, tileh);
shun-iwasawa 82a8f5
      if (quiet != 0) {
shun-iwasawa 82a8f5
        if (doYUV)
shun-iwasawa 82a8f5
          System.out.format("%-6s%s",
shun-iwasawa 82a8f5
                            sigFig((double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                                   (double)iter / elapsedEncode, 4),
shun-iwasawa 82a8f5
                            quiet == 2 ? "\n" : "  ");
shun-iwasawa 82a8f5
        System.out.format("%-6s%s",
shun-iwasawa 82a8f5
                          sigFig((double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                                 (double)iter / elapsed, 4),
shun-iwasawa 82a8f5
                          quiet == 2 ? "\n" : "  ");
shun-iwasawa 82a8f5
        System.out.format("%-6s%s",
shun-iwasawa 82a8f5
                          sigFig((double)(w * h * ps) / (double)totalJpegSize,
shun-iwasawa 82a8f5
                                 4),
shun-iwasawa 82a8f5
                          quiet == 2 ? "\n" : "  ");
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        System.out.format("\n%s size: %d x %d\n", doTile ? "Tile" : "Image",
shun-iwasawa 82a8f5
                          tilew, tileh);
shun-iwasawa 82a8f5
        if (doYUV) {
shun-iwasawa 82a8f5
          System.out.format("Encode YUV    --> Frame rate:         %f fps\n",
shun-iwasawa 82a8f5
                            (double)iter / elapsedEncode);
shun-iwasawa 82a8f5
          System.out.format("                  Output image size:  %d bytes\n",
shun-iwasawa 82a8f5
                            yuvImage.getSize());
shun-iwasawa 82a8f5
          System.out.format("                  Compression ratio:  %f:1\n",
shun-iwasawa 82a8f5
                            (double)(w * h * ps) / (double)yuvImage.getSize());
shun-iwasawa 82a8f5
          System.out.format("                  Throughput:         %f Megapixels/sec\n",
shun-iwasawa 82a8f5
                            (double)(w * h) / 1000000. *
shun-iwasawa 82a8f5
                            (double)iter / elapsedEncode);
shun-iwasawa 82a8f5
          System.out.format("                  Output bit stream:  %f Megabits/sec\n",
shun-iwasawa 82a8f5
                            (double)yuvImage.getSize() * 8. / 1000000. *
shun-iwasawa 82a8f5
                            (double)iter / elapsedEncode);
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        System.out.format("%s --> Frame rate:         %f fps\n",
shun-iwasawa 82a8f5
                          doYUV ? "Comp from YUV" : "Compress     ",
shun-iwasawa 82a8f5
                          (double)iter / elapsed);
shun-iwasawa 82a8f5
        System.out.format("                  Output image size:  %d bytes\n",
shun-iwasawa 82a8f5
                          totalJpegSize);
shun-iwasawa 82a8f5
        System.out.format("                  Compression ratio:  %f:1\n",
shun-iwasawa 82a8f5
                          (double)(w * h * ps) / (double)totalJpegSize);
shun-iwasawa 82a8f5
        System.out.format("                  Throughput:         %f Megapixels/sec\n",
shun-iwasawa 82a8f5
                          (double)(w * h) / 1000000. * (double)iter / elapsed);
shun-iwasawa 82a8f5
        System.out.format("                  Output bit stream:  %f Megabits/sec\n",
shun-iwasawa 82a8f5
                          (double)totalJpegSize * 8. / 1000000. *
shun-iwasawa 82a8f5
                          (double)iter / elapsed);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      if (tilew == w && tileh == h && write) {
shun-iwasawa 82a8f5
        String tempStr = fileName + "_" + SUBNAME[subsamp] + "_" + "Q" +
shun-iwasawa 82a8f5
                         jpegQual + ".jpg";
shun-iwasawa 82a8f5
        FileOutputStream fos = new FileOutputStream(tempStr);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        fos.write(jpegBuf[0], 0, jpegSize[0]);
shun-iwasawa 82a8f5
        fos.close();
shun-iwasawa 82a8f5
        if (quiet == 0)
shun-iwasawa 82a8f5
          System.out.println("Reference image written to " + tempStr);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      /* Decompression test */
shun-iwasawa 82a8f5
      if (!compOnly)
shun-iwasawa 82a8f5
        decomp(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual,
shun-iwasawa 82a8f5
               fileName, tilew, tileh);
shun-iwasawa 82a8f5
      else if (quiet == 1)
shun-iwasawa 82a8f5
        System.out.println("N/A");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (tilew == w && tileh == h) break;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void decompTest(String fileName) throws Exception {
shun-iwasawa 82a8f5
    TJTransformer tjt;
shun-iwasawa 82a8f5
    byte[][] jpegBuf = null;
shun-iwasawa 82a8f5
    byte[] srcBuf;
shun-iwasawa 82a8f5
    int[] jpegSize = null;
shun-iwasawa 82a8f5
    int totalJpegSize;
shun-iwasawa 82a8f5
    double start, elapsed;
shun-iwasawa 82a8f5
    int ps = TJ.getPixelSize(pf), tile, x, y, iter;
shun-iwasawa 82a8f5
    // Original image
shun-iwasawa 82a8f5
    int w = 0, h = 0, ntilesw = 1, ntilesh = 1, subsamp = -1, cs = -1;
shun-iwasawa 82a8f5
    // Transformed image
shun-iwasawa 82a8f5
    int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    FileInputStream fis = new FileInputStream(fileName);
shun-iwasawa 82a8f5
    if (fis.getChannel().size() > (long)Integer.MAX_VALUE)
shun-iwasawa 82a8f5
      throw new Exception("Image is too large");
shun-iwasawa 82a8f5
    int srcSize = (int)fis.getChannel().size();
shun-iwasawa 82a8f5
    srcBuf = new byte[srcSize];
shun-iwasawa 82a8f5
    fis.read(srcBuf, 0, srcSize);
shun-iwasawa 82a8f5
    fis.close();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    int index = fileName.lastIndexOf('.');
shun-iwasawa 82a8f5
    if (index >= 0)
shun-iwasawa 82a8f5
      fileName = new String(fileName.substring(0, index));
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    tjt = new TJTransformer();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    try {
shun-iwasawa 82a8f5
      tjt.setSourceImage(srcBuf, srcSize);
shun-iwasawa 82a8f5
    } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
    w = tjt.getWidth();
shun-iwasawa 82a8f5
    h = tjt.getHeight();
shun-iwasawa 82a8f5
    subsamp = tjt.getSubsamp();
shun-iwasawa 82a8f5
    cs = tjt.getColorspace();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    if (quiet == 1) {
shun-iwasawa 82a8f5
      System.out.println("All performance values in Mpixels/sec\n");
shun-iwasawa 82a8f5
      System.out.format("Bitmap     JPEG   JPEG     %s  %s   Xform   Comp    Decomp  ",
shun-iwasawa 82a8f5
                        (doTile ? "Tile " : "Image"),
shun-iwasawa 82a8f5
                        (doTile ? "Tile " : "Image"));
shun-iwasawa 82a8f5
      if (doYUV)
shun-iwasawa 82a8f5
        System.out.print("Decode");
shun-iwasawa 82a8f5
      System.out.print("\n");
shun-iwasawa 82a8f5
      System.out.print("Format     CS     Subsamp  Width  Height  Perf    Ratio   Perf    ");
shun-iwasawa 82a8f5
      if (doYUV)
shun-iwasawa 82a8f5
        System.out.print("Perf");
shun-iwasawa 82a8f5
      System.out.println("\n");
shun-iwasawa 82a8f5
    } else if (quiet == 0)
shun-iwasawa 82a8f5
      System.out.format(">>>>>  JPEG %s --> %s (%s)  <<<<<\n",
shun-iwasawa 82a8f5
                        formatName(subsamp, cs), PIXFORMATSTR[pf],
shun-iwasawa 82a8f5
                        (flags & TJ.FLAG_BOTTOMUP) != 0 ?
shun-iwasawa 82a8f5
                        "Bottom-up" : "Top-down");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    for (int tilew = doTile ? 16 : w, tileh = doTile ? 16 : h; ;
shun-iwasawa 82a8f5
         tilew *= 2, tileh *= 2) {
shun-iwasawa 82a8f5
      if (tilew > w)
shun-iwasawa 82a8f5
        tilew = w;
shun-iwasawa 82a8f5
      if (tileh > h)
shun-iwasawa 82a8f5
        tileh = h;
shun-iwasawa 82a8f5
      ntilesw = (w + tilew - 1) / tilew;
shun-iwasawa 82a8f5
      ntilesh = (h + tileh - 1) / tileh;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      tw = w;  th = h;  ttilew = tilew;  ttileh = tileh;
shun-iwasawa 82a8f5
      if (quiet == 0) {
shun-iwasawa 82a8f5
        System.out.format("\n%s size: %d x %d", (doTile ? "Tile" : "Image"),
shun-iwasawa 82a8f5
                          ttilew, ttileh);
shun-iwasawa 82a8f5
        if (sf.getNum() != 1 || sf.getDenom() != 1)
shun-iwasawa 82a8f5
          System.out.format(" --> %d x %d", sf.getScaled(tw),
shun-iwasawa 82a8f5
                            sf.getScaled(th));
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
      } else if (quiet == 1) {
shun-iwasawa 82a8f5
        System.out.format("%-4s (%s)  %-5s  %-5s    ", PIXFORMATSTR[pf],
shun-iwasawa 82a8f5
                          (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
shun-iwasawa 82a8f5
                          CSNAME[cs], SUBNAME_LONG[subsamp]);
shun-iwasawa 82a8f5
        System.out.format("%-5d  %-5d   ", tilew, tileh);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      tsubsamp = subsamp;
shun-iwasawa 82a8f5
      if (doTile || xformOp != TJTransform.OP_NONE || xformOpt != 0) {
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_TRANSPOSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_TRANSVERSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT90 ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT270) {
shun-iwasawa 82a8f5
          tw = h;  th = w;  ttilew = tileh;  ttileh = tilew;
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        if ((xformOpt & TJTransform.OPT_GRAY) != 0)
shun-iwasawa 82a8f5
          tsubsamp = TJ.SAMP_GRAY;
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_HFLIP ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT180)
shun-iwasawa 82a8f5
          tw = tw - (tw % TJ.getMCUWidth(tsubsamp));
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_VFLIP ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT180)
shun-iwasawa 82a8f5
          th = th - (th % TJ.getMCUHeight(tsubsamp));
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_TRANSVERSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT90)
shun-iwasawa 82a8f5
          tw = tw - (tw % TJ.getMCUHeight(tsubsamp));
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_TRANSVERSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT270)
shun-iwasawa 82a8f5
          th = th - (th % TJ.getMCUWidth(tsubsamp));
shun-iwasawa 82a8f5
        tntilesw = (tw + ttilew - 1) / ttilew;
shun-iwasawa 82a8f5
        tntilesh = (th + ttileh - 1) / ttileh;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        if (xformOp == TJTransform.OP_TRANSPOSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_TRANSVERSE ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT90 ||
shun-iwasawa 82a8f5
            xformOp == TJTransform.OP_ROT270) {
shun-iwasawa 82a8f5
          if (tsubsamp == TJ.SAMP_422)
shun-iwasawa 82a8f5
            tsubsamp = TJ.SAMP_440;
shun-iwasawa 82a8f5
          else if (tsubsamp == TJ.SAMP_440)
shun-iwasawa 82a8f5
            tsubsamp = TJ.SAMP_422;
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        TJTransform[] t = new TJTransform[tntilesw * tntilesh];
shun-iwasawa 82a8f5
        jpegBuf =
shun-iwasawa 82a8f5
          new byte[tntilesw * tntilesh][TJ.bufSize(ttilew, ttileh, subsamp)];
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        for (y = 0, tile = 0; y < th; y += ttileh) {
shun-iwasawa 82a8f5
          for (x = 0; x < tw; x += ttilew, tile++) {
shun-iwasawa 82a8f5
            t[tile] = new TJTransform();
shun-iwasawa 82a8f5
            t[tile].width = Math.min(ttilew, tw - x);
shun-iwasawa 82a8f5
            t[tile].height = Math.min(ttileh, th - y);
shun-iwasawa 82a8f5
            t[tile].x = x;
shun-iwasawa 82a8f5
            t[tile].y = y;
shun-iwasawa 82a8f5
            t[tile].op = xformOp;
shun-iwasawa 82a8f5
            t[tile].options = xformOpt | TJTransform.OPT_TRIM;
shun-iwasawa 82a8f5
            if ((t[tile].options & TJTransform.OPT_NOOUTPUT) != 0 &&
shun-iwasawa 82a8f5
                jpegBuf[tile] != null)
shun-iwasawa 82a8f5
              jpegBuf[tile] = null;
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        iter = -1;
shun-iwasawa 82a8f5
        elapsed = 0.;
shun-iwasawa 82a8f5
        while (true) {
shun-iwasawa 82a8f5
          start = getTime();
shun-iwasawa 82a8f5
          try {
shun-iwasawa 82a8f5
            tjt.transform(jpegBuf, t, flags);
shun-iwasawa 82a8f5
          } catch (TJException e) { handleTJException(e); }
shun-iwasawa 82a8f5
          jpegSize = tjt.getTransformedSizes();
shun-iwasawa 82a8f5
          elapsed += getTime() - start;
shun-iwasawa 82a8f5
          if (iter >= 0) {
shun-iwasawa 82a8f5
            iter++;
shun-iwasawa 82a8f5
            if (elapsed >= benchTime)
shun-iwasawa 82a8f5
              break;
shun-iwasawa 82a8f5
          } else if (elapsed >= warmup) {
shun-iwasawa 82a8f5
            iter = 0;
shun-iwasawa 82a8f5
            elapsed = 0.0;
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        t = null;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        for (tile = 0, totalJpegSize = 0; tile < tntilesw * tntilesh; tile++)
shun-iwasawa 82a8f5
          totalJpegSize += jpegSize[tile];
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        if (quiet != 0) {
shun-iwasawa 82a8f5
          System.out.format("%-6s%s%-6s%s",
shun-iwasawa 82a8f5
                            sigFig((double)(w * h) / 1000000. / elapsed, 4),
shun-iwasawa 82a8f5
                            quiet == 2 ? "\n" : "  ",
shun-iwasawa 82a8f5
                            sigFig((double)(w * h * ps) /
shun-iwasawa 82a8f5
                                   (double)totalJpegSize, 4),
shun-iwasawa 82a8f5
                            quiet == 2 ? "\n" : "  ");
shun-iwasawa 82a8f5
        } else if (quiet == 0) {
shun-iwasawa 82a8f5
          System.out.format("Transform     --> Frame rate:         %f fps\n",
shun-iwasawa 82a8f5
                            1.0 / elapsed);
shun-iwasawa 82a8f5
          System.out.format("                  Output image size:  %d bytes\n",
shun-iwasawa 82a8f5
                            totalJpegSize);
shun-iwasawa 82a8f5
          System.out.format("                  Compression ratio:  %f:1\n",
shun-iwasawa 82a8f5
                            (double)(w * h * ps) / (double)totalJpegSize);
shun-iwasawa 82a8f5
          System.out.format("                  Throughput:         %f Megapixels/sec\n",
shun-iwasawa 82a8f5
                            (double)(w * h) / 1000000. / elapsed);
shun-iwasawa 82a8f5
          System.out.format("                  Output bit stream:  %f Megabits/sec\n",
shun-iwasawa 82a8f5
                            (double)totalJpegSize * 8. / 1000000. / elapsed);
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        if (quiet == 1)
shun-iwasawa 82a8f5
          System.out.print("N/A     N/A     ");
shun-iwasawa 82a8f5
        jpegBuf = new byte[1][TJ.bufSize(ttilew, ttileh, subsamp)];
shun-iwasawa 82a8f5
        jpegSize = new int[1];
shun-iwasawa 82a8f5
        jpegBuf[0] = srcBuf;
shun-iwasawa 82a8f5
        jpegSize[0] = srcSize;
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (w == tilew)
shun-iwasawa 82a8f5
        ttilew = tw;
shun-iwasawa 82a8f5
      if (h == tileh)
shun-iwasawa 82a8f5
        ttileh = th;
shun-iwasawa 82a8f5
      if ((xformOpt & TJTransform.OPT_NOOUTPUT) == 0)
shun-iwasawa 82a8f5
        decomp(null, jpegBuf, jpegSize, null, tw, th, tsubsamp, 0,
shun-iwasawa 82a8f5
               fileName, ttilew, ttileh);
shun-iwasawa 82a8f5
      else if (quiet == 1)
shun-iwasawa 82a8f5
        System.out.println("N/A");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      jpegBuf = null;
shun-iwasawa 82a8f5
      jpegSize = null;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (tilew == w && tileh == h) break;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void usage() throws Exception {
shun-iwasawa 82a8f5
    int i;
shun-iwasawa 82a8f5
    TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
shun-iwasawa 82a8f5
    int nsf = scalingFactors.length;
shun-iwasawa 82a8f5
    String className = new TJBench().getClass().getName();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("\nUSAGE: java " + className);
shun-iwasawa 82a8f5
    System.out.println("       <inputfile (bmp)=""> <quality> [options]\n");</quality></inputfile>
shun-iwasawa 82a8f5
    System.out.println("       java " + className);
shun-iwasawa 82a8f5
    System.out.println("       <inputfile (jpg)=""> [options]\n");</inputfile>
shun-iwasawa 82a8f5
    System.out.println("Options:\n");
shun-iwasawa 82a8f5
    System.out.println("-alloc = Dynamically allocate JPEG image buffers");
shun-iwasawa 82a8f5
    System.out.println("-bottomup = Test bottom-up compression/decompression");
shun-iwasawa 82a8f5
    System.out.println("-tile = Test performance of the codec when the image is encoded as separate");
shun-iwasawa 82a8f5
    System.out.println("     tiles of varying sizes.");
shun-iwasawa 82a8f5
    System.out.println("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =");
shun-iwasawa 82a8f5
    System.out.println("     Test the specified color conversion path in the codec (default = BGR)");
shun-iwasawa 82a8f5
    System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available in");
shun-iwasawa 82a8f5
    System.out.println("     the underlying codec");
shun-iwasawa 82a8f5
    System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
shun-iwasawa 82a8f5
    System.out.println("     codec");
shun-iwasawa 82a8f5
    System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the");
shun-iwasawa 82a8f5
    System.out.println("     underlying codec");
shun-iwasawa 82a8f5
    System.out.println("-progressive = Use progressive entropy coding in JPEG images generated by");
shun-iwasawa 82a8f5
    System.out.println("     compression and transform operations.");
shun-iwasawa 82a8f5
    System.out.println("-subsamp <s> = When testing JPEG compression, this option specifies the level");</s>
shun-iwasawa 82a8f5
    System.out.println("     of chrominance subsampling to use (<s> = 444, 422, 440, 420, 411, or");</s>
shun-iwasawa 82a8f5
    System.out.println("     GRAY).  The default is to test Grayscale, 4:2:0, 4:2:2, and 4:4:4 in");
shun-iwasawa 82a8f5
    System.out.println("     sequence.");
shun-iwasawa 82a8f5
    System.out.println("-quiet = Output results in tabular rather than verbose format");
shun-iwasawa 82a8f5
    System.out.println("-yuv = Test YUV encoding/decoding functions");
shun-iwasawa 82a8f5
    System.out.println("-yuvpad 

= If testing YUV encoding/decoding, this specifies the number of");

shun-iwasawa 82a8f5
    System.out.println("     bytes to which each row of each plane in the intermediate YUV image is");
shun-iwasawa 82a8f5
    System.out.println("     padded (default = 1)");
shun-iwasawa 82a8f5
    System.out.println("-scale M/N = Scale down the width/height of the decompressed JPEG image by a");
shun-iwasawa 82a8f5
    System.out.print("     factor of M/N (M/N = ");
shun-iwasawa 82a8f5
    for (i = 0; i < nsf; i++) {
shun-iwasawa 82a8f5
      System.out.format("%d/%d", scalingFactors[i].getNum(),
shun-iwasawa 82a8f5
                        scalingFactors[i].getDenom());
shun-iwasawa 82a8f5
      if (nsf == 2 && i != nsf - 1)
shun-iwasawa 82a8f5
        System.out.print(" or ");
shun-iwasawa 82a8f5
      else if (nsf > 2) {
shun-iwasawa 82a8f5
        if (i != nsf - 1)
shun-iwasawa 82a8f5
          System.out.print(", ");
shun-iwasawa 82a8f5
        if (i == nsf - 2)
shun-iwasawa 82a8f5
          System.out.print("or ");
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      if (i % 8 == 0 && i != 0)
shun-iwasawa 82a8f5
        System.out.print("\n     ");
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    System.out.println(")");
shun-iwasawa 82a8f5
    System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
shun-iwasawa 82a8f5
    System.out.println("     Perform the corresponding lossless transform prior to");
shun-iwasawa 82a8f5
    System.out.println("     decompression (these options are mutually exclusive)");
shun-iwasawa 82a8f5
    System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression");
shun-iwasawa 82a8f5
    System.out.println("     test (can be combined with the other transforms above)");
shun-iwasawa 82a8f5
    System.out.println("-copynone = Do not copy any extra markers (including EXIF and ICC profile data)");
shun-iwasawa 82a8f5
    System.out.println("     when transforming the image.");
shun-iwasawa 82a8f5
    System.out.println("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)");</t></t>
shun-iwasawa 82a8f5
    System.out.println("-warmup <t> = Run each benchmark for <t> seconds (default = 1.0) prior to");</t></t>
shun-iwasawa 82a8f5
    System.out.println("     starting the timer, in order to prime the caches and thus improve the");
shun-iwasawa 82a8f5
    System.out.println("     consistency of the results.");
shun-iwasawa 82a8f5
    System.out.println("-componly = Stop after running compression tests.  Do not test decompression.");
shun-iwasawa 82a8f5
    System.out.println("-nowrite = Do not write reference or output images (improves consistency");
shun-iwasawa 82a8f5
    System.out.println("     of performance measurements.)");
shun-iwasawa 82a8f5
    System.out.println("-stoponwarning = Immediately discontinue the current");
shun-iwasawa 82a8f5
    System.out.println("     compression/decompression/transform operation if the underlying codec");
shun-iwasawa 82a8f5
    System.out.println("     throws a warning (non-fatal error)\n");
shun-iwasawa 82a8f5
    System.out.println("NOTE:  If the quality is specified as a range (e.g. 90-100), a separate");
shun-iwasawa 82a8f5
    System.out.println("test will be performed for all quality values in the range.\n");
shun-iwasawa 82a8f5
    System.exit(1);
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  public static void main(String[] argv) {
shun-iwasawa 82a8f5
    byte[] srcBuf = null;
shun-iwasawa 82a8f5
    int w = 0, h = 0, minQual = -1, maxQual = -1;
shun-iwasawa 82a8f5
    int minArg = 1, retval = 0;
shun-iwasawa 82a8f5
    int subsamp = -1;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    try {
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (argv.length < minArg)
shun-iwasawa 82a8f5
        usage();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      String tempStr = argv[0].toLowerCase();
shun-iwasawa 82a8f5
      if (tempStr.endsWith(".jpg") || tempStr.endsWith(".jpeg"))
shun-iwasawa 82a8f5
        decompOnly = true;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      System.out.println("");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (!decompOnly) {
shun-iwasawa 82a8f5
        minArg = 2;
shun-iwasawa 82a8f5
        if (argv.length < minArg)
shun-iwasawa 82a8f5
          usage();
shun-iwasawa 82a8f5
        try {
shun-iwasawa 82a8f5
          minQual = Integer.parseInt(argv[1]);
shun-iwasawa 82a8f5
        } catch (NumberFormatException e) {}
shun-iwasawa 82a8f5
        if (minQual < 1 || minQual > 100)
shun-iwasawa 82a8f5
          throw new Exception("Quality must be between 1 and 100.");
shun-iwasawa 82a8f5
        int dashIndex = argv[1].indexOf('-');
shun-iwasawa 82a8f5
        if (dashIndex > 0 && argv[1].length() > dashIndex + 1) {
shun-iwasawa 82a8f5
          try {
shun-iwasawa 82a8f5
            maxQual = Integer.parseInt(argv[1].substring(dashIndex + 1));
shun-iwasawa 82a8f5
          } catch (NumberFormatException e) {}
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        if (maxQual < 1 || maxQual > 100)
shun-iwasawa 82a8f5
          maxQual = minQual;
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (argv.length > minArg) {
shun-iwasawa 82a8f5
        for (int i = minArg; i < argv.length; i++) {
shun-iwasawa 82a8f5
          if (argv[i].equalsIgnoreCase("-tile")) {
shun-iwasawa 82a8f5
            doTile = true;  xformOpt |= TJTransform.OPT_CROP;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-fastupsample")) {
shun-iwasawa 82a8f5
            System.out.println("Using fast upsampling code\n");
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_FASTUPSAMPLE;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-fastdct")) {
shun-iwasawa 82a8f5
            System.out.println("Using fastest DCT/IDCT algorithm\n");
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_FASTDCT;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-accuratedct")) {
shun-iwasawa 82a8f5
            System.out.println("Using most accurate DCT/IDCT algorithm\n");
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_ACCURATEDCT;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-progressive")) {
shun-iwasawa 82a8f5
            System.out.println("Using progressive entropy coding\n");
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_PROGRESSIVE;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-rgb"))
shun-iwasawa 82a8f5
            pf = TJ.PF_RGB;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-rgbx"))
shun-iwasawa 82a8f5
            pf = TJ.PF_RGBX;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-bgr"))
shun-iwasawa 82a8f5
            pf = TJ.PF_BGR;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-bgrx"))
shun-iwasawa 82a8f5
            pf = TJ.PF_BGRX;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-xbgr"))
shun-iwasawa 82a8f5
            pf = TJ.PF_XBGR;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-xrgb"))
shun-iwasawa 82a8f5
            pf = TJ.PF_XRGB;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-bottomup"))
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_BOTTOMUP;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-quiet"))
shun-iwasawa 82a8f5
            quiet = 1;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-qq"))
shun-iwasawa 82a8f5
            quiet = 2;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-scale") && i < argv.length - 1) {
shun-iwasawa 82a8f5
            int temp1 = 0, temp2 = 0;
shun-iwasawa 82a8f5
            boolean match = false, scanned = true;
shun-iwasawa 82a8f5
            Scanner scanner = new Scanner(argv[++i]).useDelimiter("/");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              temp1 = scanner.nextInt();
shun-iwasawa 82a8f5
              temp2 = scanner.nextInt();
shun-iwasawa 82a8f5
            } catch (Exception e) {}
shun-iwasawa 82a8f5
            if (temp2 <= 0) temp2 = 1;
shun-iwasawa 82a8f5
            if (temp1 > 0) {
shun-iwasawa 82a8f5
              TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
              for (int j = 0; j < scalingFactors.length; j++) {
shun-iwasawa 82a8f5
                if ((double)temp1 / (double)temp2 ==
shun-iwasawa 82a8f5
                    (double)scalingFactors[j].getNum() /
shun-iwasawa 82a8f5
                    (double)scalingFactors[j].getDenom()) {
shun-iwasawa 82a8f5
                  sf = scalingFactors[j];
shun-iwasawa 82a8f5
                  match = true;  break;
shun-iwasawa 82a8f5
                }
shun-iwasawa 82a8f5
              }
shun-iwasawa 82a8f5
              if (!match) usage();
shun-iwasawa 82a8f5
            } else
shun-iwasawa 82a8f5
              usage();
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-hflip"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_HFLIP;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-vflip"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_VFLIP;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-transpose"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_TRANSPOSE;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-transverse"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_TRANSVERSE;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-rot90"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_ROT90;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-rot180"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_ROT180;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-rot270"))
shun-iwasawa 82a8f5
            xformOp = TJTransform.OP_ROT270;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-grayscale"))
shun-iwasawa 82a8f5
            xformOpt |= TJTransform.OPT_GRAY;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-nooutput"))
shun-iwasawa 82a8f5
            xformOpt |= TJTransform.OPT_NOOUTPUT;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-copynone"))
shun-iwasawa 82a8f5
            xformOpt |= TJTransform.OPT_COPYNONE;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-benchtime") &&
shun-iwasawa 82a8f5
                   i < argv.length - 1) {
shun-iwasawa 82a8f5
            double temp = -1;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              temp = Double.parseDouble(argv[++i]);
shun-iwasawa 82a8f5
            } catch (NumberFormatException e) {}
shun-iwasawa 82a8f5
            if (temp > 0.0)
shun-iwasawa 82a8f5
              benchTime = temp;
shun-iwasawa 82a8f5
            else
shun-iwasawa 82a8f5
              usage();
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-warmup") &&
shun-iwasawa 82a8f5
                     i < argv.length - 1) {
shun-iwasawa 82a8f5
            double temp = -1;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              temp = Double.parseDouble(argv[++i]);
shun-iwasawa 82a8f5
            } catch (NumberFormatException e) {}
shun-iwasawa 82a8f5
            if (temp >= 0.0) {
shun-iwasawa 82a8f5
              warmup = temp;
shun-iwasawa 82a8f5
              System.out.format("Warmup time = %.1f seconds\n\n", warmup);
shun-iwasawa 82a8f5
            } else
shun-iwasawa 82a8f5
              usage();
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-yuv")) {
shun-iwasawa 82a8f5
            System.out.println("Testing YUV planar encoding/decoding\n");
shun-iwasawa 82a8f5
            doYUV = true;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-yuvpad") &&
shun-iwasawa 82a8f5
                     i < argv.length - 1) {
shun-iwasawa 82a8f5
            int temp = 0;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
            try {
shun-iwasawa 82a8f5
              temp = Integer.parseInt(argv[++i]);
shun-iwasawa 82a8f5
            } catch (NumberFormatException e) {}
shun-iwasawa 82a8f5
            if (temp >= 1)
shun-iwasawa 82a8f5
              yuvPad = temp;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-subsamp") &&
shun-iwasawa 82a8f5
                     i < argv.length - 1) {
shun-iwasawa 82a8f5
            i++;
shun-iwasawa 82a8f5
            if (argv[i].toUpperCase().startsWith("G"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_GRAY;
shun-iwasawa 82a8f5
            else if (argv[i].equals("444"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_444;
shun-iwasawa 82a8f5
            else if (argv[i].equals("422"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_422;
shun-iwasawa 82a8f5
            else if (argv[i].equals("440"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_440;
shun-iwasawa 82a8f5
            else if (argv[i].equals("420"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_420;
shun-iwasawa 82a8f5
            else if (argv[i].equals("411"))
shun-iwasawa 82a8f5
              subsamp = TJ.SAMP_411;
shun-iwasawa 82a8f5
          } else if (argv[i].equalsIgnoreCase("-componly"))
shun-iwasawa 82a8f5
            compOnly = true;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-nowrite"))
shun-iwasawa 82a8f5
            write = false;
shun-iwasawa 82a8f5
          else if (argv[i].equalsIgnoreCase("-stoponwarning"))
shun-iwasawa 82a8f5
            flags |= TJ.FLAG_STOPONWARNING;
shun-iwasawa 82a8f5
          else usage();
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (sf == null)
shun-iwasawa 82a8f5
        sf = new TJScalingFactor(1, 1);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if ((sf.getNum() != 1 || sf.getDenom() != 1) && doTile) {
shun-iwasawa 82a8f5
        System.out.println("Disabling tiled compression/decompression tests, because those tests do not");
shun-iwasawa 82a8f5
        System.out.println("work when scaled decompression is enabled.");
shun-iwasawa 82a8f5
        doTile = false;
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (!decompOnly) {
shun-iwasawa 82a8f5
        int[] width = new int[1], height = new int[1];
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        srcBuf = loadImage(argv[0], width, height, pf);
shun-iwasawa 82a8f5
        w = width[0];  h = height[0];
shun-iwasawa 82a8f5
        int index = -1;
shun-iwasawa 82a8f5
        if ((index = argv[0].lastIndexOf('.')) >= 0)
shun-iwasawa 82a8f5
          argv[0] = argv[0].substring(0, index);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (quiet == 1 && !decompOnly) {
shun-iwasawa 82a8f5
        System.out.println("All performance values in Mpixels/sec\n");
shun-iwasawa 82a8f5
        System.out.format("Bitmap     JPEG     JPEG  %s  %s   ",
shun-iwasawa 82a8f5
                          (doTile ? "Tile " : "Image"),
shun-iwasawa 82a8f5
                          (doTile ? "Tile " : "Image"));
shun-iwasawa 82a8f5
        if (doYUV)
shun-iwasawa 82a8f5
          System.out.print("Encode  ");
shun-iwasawa 82a8f5
        System.out.print("Comp    Comp    Decomp  ");
shun-iwasawa 82a8f5
        if (doYUV)
shun-iwasawa 82a8f5
          System.out.print("Decode");
shun-iwasawa 82a8f5
        System.out.print("\n");
shun-iwasawa 82a8f5
        System.out.print("Format     Subsamp  Qual  Width  Height  ");
shun-iwasawa 82a8f5
        if (doYUV)
shun-iwasawa 82a8f5
          System.out.print("Perf    ");
shun-iwasawa 82a8f5
        System.out.print("Perf    Ratio   Perf    ");
shun-iwasawa 82a8f5
        if (doYUV)
shun-iwasawa 82a8f5
          System.out.print("Perf");
shun-iwasawa 82a8f5
        System.out.println("\n");
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (decompOnly) {
shun-iwasawa 82a8f5
        decompTest(argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
        System.exit(retval);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      System.gc();
shun-iwasawa 82a8f5
      if (subsamp >= 0 && subsamp < TJ.NUMSAMP) {
shun-iwasawa 82a8f5
        for (int i = maxQual; i >= minQual; i--)
shun-iwasawa 82a8f5
          fullTest(srcBuf, w, h, subsamp, i, argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        for (int i = maxQual; i >= minQual; i--)
shun-iwasawa 82a8f5
          fullTest(srcBuf, w, h, TJ.SAMP_GRAY, i, argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
        System.gc();
shun-iwasawa 82a8f5
        for (int i = maxQual; i >= minQual; i--)
shun-iwasawa 82a8f5
          fullTest(srcBuf, w, h, TJ.SAMP_420, i, argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
        System.gc();
shun-iwasawa 82a8f5
        for (int i = maxQual; i >= minQual; i--)
shun-iwasawa 82a8f5
          fullTest(srcBuf, w, h, TJ.SAMP_422, i, argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
        System.gc();
shun-iwasawa 82a8f5
        for (int i = maxQual; i >= minQual; i--)
shun-iwasawa 82a8f5
          fullTest(srcBuf, w, h, TJ.SAMP_444, i, argv[0]);
shun-iwasawa 82a8f5
        System.out.println("");
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    } catch (Exception e) {
shun-iwasawa 82a8f5
      if (e instanceof TJException) {
shun-iwasawa 82a8f5
        TJException tje = (TJException)e;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        System.out.println((tje.getErrorCode() == TJ.ERR_WARNING ?
shun-iwasawa 82a8f5
                            "WARNING: " : "ERROR: ") + tje.getMessage());
shun-iwasawa 82a8f5
      } else
shun-iwasawa 82a8f5
        System.out.println("ERROR: " + e.getMessage());
shun-iwasawa 82a8f5
      e.printStackTrace();
shun-iwasawa 82a8f5
      retval = -1;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.exit(retval);
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
}