shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * Copyright (C)2011-2012, 2014-2015, 2017-2018 D. R. Commander.
shun-iwasawa 82a8f5
 *                                              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
/*
shun-iwasawa 82a8f5
 * This program demonstrates how to compress, decompress, and transform JPEG
shun-iwasawa 82a8f5
 * images using the TurboJPEG Java API
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
import java.io.*;
shun-iwasawa 82a8f5
import java.awt.*;
shun-iwasawa 82a8f5
import java.awt.image.*;
shun-iwasawa 82a8f5
import java.nio.*;
shun-iwasawa 82a8f5
import javax.imageio.*;
shun-iwasawa 82a8f5
import javax.swing.*;
shun-iwasawa 82a8f5
import org.libjpegturbo.turbojpeg.*;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
@SuppressWarnings("checkstyle:JavadocType")
shun-iwasawa 82a8f5
class TJExample implements TJCustomFilter {
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String CLASS_NAME =
shun-iwasawa 82a8f5
    new TJExample().getClass().getName();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final int DEFAULT_SUBSAMP = TJ.SAMP_444;
shun-iwasawa 82a8f5
  static final int DEFAULT_QUALITY = 95;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] SUBSAMP_NAME = {
shun-iwasawa 82a8f5
    "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final String[] COLORSPACE_NAME = {
shun-iwasawa 82a8f5
    "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
shun-iwasawa 82a8f5
  };
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* DCT filter example.  This produces a negative of the image. */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  @SuppressWarnings("checkstyle:JavadocMethod")
shun-iwasawa 82a8f5
  public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
shun-iwasawa 82a8f5
                           Rectangle planeRegion, int componentIndex,
shun-iwasawa 82a8f5
                           int transformIndex, TJTransform transform)
shun-iwasawa 82a8f5
                           throws TJException {
shun-iwasawa 82a8f5
    for (int i = 0; i < bufferRegion.width * bufferRegion.height; i++) {
shun-iwasawa 82a8f5
      coeffBuffer.put(i, (short)(-coeffBuffer.get(i)));
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static void usage() throws Exception {
shun-iwasawa 82a8f5
    System.out.println("\nUSAGE: java [Java options] " + CLASS_NAME +
shun-iwasawa 82a8f5
                       " <input image=""> <output image=""> [options]\n");</output>
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("Input and output images can be in any image format that the Java Image I/O");
shun-iwasawa 82a8f5
    System.out.println("extensions understand.  If either filename ends in a .jpg extension, then");
shun-iwasawa 82a8f5
    System.out.println("the TurboJPEG API will be used to compress or decompress the image.\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("Compression Options (used if the output image is a JPEG image)");
shun-iwasawa 82a8f5
    System.out.println("--------------------------------------------------------------\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-subsamp <444|422|420|gray> = Apply this level of chrominance subsampling when");
shun-iwasawa 82a8f5
    System.out.println("     compressing the output image.  The default is to use the same level of");
shun-iwasawa 82a8f5
    System.out.println("     subsampling as in the input image, if the input image is also a JPEG");
shun-iwasawa 82a8f5
    System.out.println("     image, or to use grayscale if the input image is a grayscale non-JPEG");
shun-iwasawa 82a8f5
    System.out.println("     image, or to use " +
shun-iwasawa 82a8f5
                       SUBSAMP_NAME[DEFAULT_SUBSAMP] +
shun-iwasawa 82a8f5
                       " subsampling otherwise.\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-q <1-100> = Compress the output image with this JPEG quality level");
shun-iwasawa 82a8f5
    System.out.println("     (default = " + DEFAULT_QUALITY + ").\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("Decompression Options (used if the input image is a JPEG image)");
shun-iwasawa 82a8f5
    System.out.println("---------------------------------------------------------------\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-scale M/N = Scale the input image by a factor of M/N when decompressing it.");
shun-iwasawa 82a8f5
    System.out.print("(M/N = ");
shun-iwasawa 82a8f5
    for (int i = 0; i < SCALING_FACTORS.length; i++) {
shun-iwasawa 82a8f5
      System.out.print(SCALING_FACTORS[i].getNum() + "/" +
shun-iwasawa 82a8f5
                       SCALING_FACTORS[i].getDenom());
shun-iwasawa 82a8f5
      if (SCALING_FACTORS.length == 2 && i != SCALING_FACTORS.length - 1)
shun-iwasawa 82a8f5
        System.out.print(" or ");
shun-iwasawa 82a8f5
      else if (SCALING_FACTORS.length > 2) {
shun-iwasawa 82a8f5
        if (i != SCALING_FACTORS.length - 1)
shun-iwasawa 82a8f5
          System.out.print(", ");
shun-iwasawa 82a8f5
        if (i == SCALING_FACTORS.length - 2)
shun-iwasawa 82a8f5
          System.out.print("or ");
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    System.out.println(")\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
shun-iwasawa 82a8f5
    System.out.println("     Perform one of these lossless transform operations on the input image");
shun-iwasawa 82a8f5
    System.out.println("     prior to decompressing it (these options are mutually exclusive.)\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-grayscale = Perform lossless grayscale conversion on the input image prior");
shun-iwasawa 82a8f5
    System.out.println("     to decompressing it (can be combined with the other transform operations");
shun-iwasawa 82a8f5
    System.out.println("     above.)\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-crop WxH+X+Y = Perform lossless cropping on the input image prior to");
shun-iwasawa 82a8f5
    System.out.println("     decompressing it.  X and Y specify the upper left corner of the cropping");
shun-iwasawa 82a8f5
    System.out.println("     region, and W and H specify the width and height of the cropping region.");
shun-iwasawa 82a8f5
    System.out.println("     X and Y must be evenly divible by the MCU block size (8x8 if the input");
shun-iwasawa 82a8f5
    System.out.println("     image was compressed using no subsampling or grayscale, 16x8 if it was");
shun-iwasawa 82a8f5
    System.out.println("     compressed using 4:2:2 subsampling, or 16x16 if it was compressed using");
shun-iwasawa 82a8f5
    System.out.println("     4:2:0 subsampling.)\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("General Options");
shun-iwasawa 82a8f5
    System.out.println("---------------\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-display = Display output image (Output filename need not be specified in this");
shun-iwasawa 82a8f5
    System.out.println("     case.)\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available in");
shun-iwasawa 82a8f5
    System.out.println("     the underlying codec.\n");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
shun-iwasawa 82a8f5
    System.out.println("     codec.\n");
shun-iwasawa 82a8f5
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.\n");
shun-iwasawa 82a8f5
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
shun-iwasawa 82a8f5
    try {
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      TJScalingFactor scalingFactor = new TJScalingFactor(1, 1);
shun-iwasawa 82a8f5
      int outSubsamp = -1, outQual = -1;
shun-iwasawa 82a8f5
      TJTransform xform = new TJTransform();
shun-iwasawa 82a8f5
      boolean display = false;
shun-iwasawa 82a8f5
      int flags = 0;
shun-iwasawa 82a8f5
      int width, height;
shun-iwasawa 82a8f5
      String inFormat = "jpg", outFormat = "jpg";
shun-iwasawa 82a8f5
      BufferedImage img = null;
shun-iwasawa 82a8f5
      byte[] imgBuf = null;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (argv.length < 2)
shun-iwasawa 82a8f5
        usage();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (argv[1].substring(0, 2).equalsIgnoreCase("-d"))
shun-iwasawa 82a8f5
        display = true;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      /* Parse arguments. */
shun-iwasawa 82a8f5
      for (int i = 2; i < argv.length; i++) {
shun-iwasawa 82a8f5
        if (argv[i].length() < 2)
shun-iwasawa 82a8f5
          continue;
shun-iwasawa 82a8f5
        else if (argv[i].length() > 2 &&
shun-iwasawa 82a8f5
                 argv[i].substring(0, 3).equalsIgnoreCase("-sc") &&
shun-iwasawa 82a8f5
                 i < argv.length - 1) {
shun-iwasawa 82a8f5
          int match = 0;
shun-iwasawa 82a8f5
          String[] scaleArg = argv[++i].split("/");
shun-iwasawa 82a8f5
          if (scaleArg.length == 2) {
shun-iwasawa 82a8f5
            TJScalingFactor tempsf =
shun-iwasawa 82a8f5
              new TJScalingFactor(Integer.parseInt(scaleArg[0]),
shun-iwasawa 82a8f5
                                  Integer.parseInt(scaleArg[1]));
shun-iwasawa 82a8f5
            for (int j = 0; j < SCALING_FACTORS.length; j++) {
shun-iwasawa 82a8f5
              if (tempsf.equals(SCALING_FACTORS[j])) {
shun-iwasawa 82a8f5
                scalingFactor = SCALING_FACTORS[j];
shun-iwasawa 82a8f5
                match = 1;
shun-iwasawa 82a8f5
                break;
shun-iwasawa 82a8f5
              }
shun-iwasawa 82a8f5
            }
shun-iwasawa 82a8f5
          }
shun-iwasawa 82a8f5
          if (match != 1)
shun-iwasawa 82a8f5
            usage();
shun-iwasawa 82a8f5
        } else if (argv[i].length() > 2 &&
shun-iwasawa 82a8f5
                   argv[i].substring(0, 3).equalsIgnoreCase("-su") &&
shun-iwasawa 82a8f5
                   i < argv.length - 1) {
shun-iwasawa 82a8f5
          i++;
shun-iwasawa 82a8f5
          if (argv[i].substring(0, 1).equalsIgnoreCase("g"))
shun-iwasawa 82a8f5
            outSubsamp = TJ.SAMP_GRAY;
shun-iwasawa 82a8f5
          else if (argv[i].equals("444"))
shun-iwasawa 82a8f5
            outSubsamp = TJ.SAMP_444;
shun-iwasawa 82a8f5
          else if (argv[i].equals("422"))
shun-iwasawa 82a8f5
            outSubsamp = TJ.SAMP_422;
shun-iwasawa 82a8f5
          else if (argv[i].equals("420"))
shun-iwasawa 82a8f5
            outSubsamp = TJ.SAMP_420;
shun-iwasawa 82a8f5
          else
shun-iwasawa 82a8f5
            usage();
shun-iwasawa 82a8f5
        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-q") &&
shun-iwasawa 82a8f5
                   i < argv.length - 1) {
shun-iwasawa 82a8f5
          outQual = Integer.parseInt(argv[++i]);
shun-iwasawa 82a8f5
          if (outQual < 1 || outQual > 100)
shun-iwasawa 82a8f5
            usage();
shun-iwasawa 82a8f5
        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-g"))
shun-iwasawa 82a8f5
          xform.options |= TJTransform.OPT_GRAY;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-hflip"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_HFLIP;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-vflip"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_VFLIP;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-transpose"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_TRANSPOSE;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-transverse"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_TRANSVERSE;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-rot90"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_ROT90;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-rot180"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_ROT180;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-rot270"))
shun-iwasawa 82a8f5
          xform.op = TJTransform.OP_ROT270;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-custom"))
shun-iwasawa 82a8f5
          xform.cf = new TJExample();
shun-iwasawa 82a8f5
        else if (argv[i].length() > 2 &&
shun-iwasawa 82a8f5
                 argv[i].substring(0, 2).equalsIgnoreCase("-c") &&
shun-iwasawa 82a8f5
                 i < argv.length - 1) {
shun-iwasawa 82a8f5
          String[] cropArg = argv[++i].split("[x\\+]");
shun-iwasawa 82a8f5
          if (cropArg.length != 4)
shun-iwasawa 82a8f5
            usage();
shun-iwasawa 82a8f5
          xform.width = Integer.parseInt(cropArg[0]);
shun-iwasawa 82a8f5
          xform.height = Integer.parseInt(cropArg[1]);
shun-iwasawa 82a8f5
          xform.x = Integer.parseInt(cropArg[2]);
shun-iwasawa 82a8f5
          xform.y = Integer.parseInt(cropArg[3]);
shun-iwasawa 82a8f5
          if (xform.x < 0 || xform.y < 0 || xform.width < 1 ||
shun-iwasawa 82a8f5
              xform.height < 1)
shun-iwasawa 82a8f5
            usage();
shun-iwasawa 82a8f5
          xform.options |= TJTransform.OPT_CROP;
shun-iwasawa 82a8f5
        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-d"))
shun-iwasawa 82a8f5
          display = true;
shun-iwasawa 82a8f5
        else if (argv[i].equalsIgnoreCase("-fastupsample")) {
shun-iwasawa 82a8f5
          System.out.println("Using fast upsampling code");
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");
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");
shun-iwasawa 82a8f5
          flags |= TJ.FLAG_ACCURATEDCT;
shun-iwasawa 82a8f5
        } else usage();
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      /* Determine input and output image formats based on file extensions. */
shun-iwasawa 82a8f5
      String[] inFileTokens = argv[0].split("\\.");
shun-iwasawa 82a8f5
      if (inFileTokens.length > 1)
shun-iwasawa 82a8f5
        inFormat = inFileTokens[inFileTokens.length - 1];
shun-iwasawa 82a8f5
      String[] outFileTokens;
shun-iwasawa 82a8f5
      if (display)
shun-iwasawa 82a8f5
        outFormat = "bmp";
shun-iwasawa 82a8f5
      else {
shun-iwasawa 82a8f5
        outFileTokens = argv[1].split("\\.");
shun-iwasawa 82a8f5
        if (outFileTokens.length > 1)
shun-iwasawa 82a8f5
          outFormat = outFileTokens[outFileTokens.length - 1];
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (inFormat.equalsIgnoreCase("jpg")) {
shun-iwasawa 82a8f5
        /* Input image is a JPEG image.  Decompress and/or transform it. */
shun-iwasawa 82a8f5
        boolean doTransform = (xform.op != TJTransform.OP_NONE ||
shun-iwasawa 82a8f5
                               xform.options != 0 || xform.cf != null);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        /* Read the JPEG file into memory. */
shun-iwasawa 82a8f5
        File jpegFile = new File(argv[0]);
shun-iwasawa 82a8f5
        FileInputStream fis = new FileInputStream(jpegFile);
shun-iwasawa 82a8f5
        int jpegSize = fis.available();
shun-iwasawa 82a8f5
        if (jpegSize < 1) {
shun-iwasawa 82a8f5
          System.out.println("Input file contains no data");
shun-iwasawa 82a8f5
          System.exit(1);
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        byte[] jpegBuf = new byte[jpegSize];
shun-iwasawa 82a8f5
        fis.read(jpegBuf);
shun-iwasawa 82a8f5
        fis.close();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        TJDecompressor tjd;
shun-iwasawa 82a8f5
        if (doTransform) {
shun-iwasawa 82a8f5
          /* Transform it. */
shun-iwasawa 82a8f5
          TJTransformer tjt = new TJTransformer(jpegBuf);
shun-iwasawa 82a8f5
          TJTransform[] xforms = new TJTransform[1];
shun-iwasawa 82a8f5
          xforms[0] = xform;
shun-iwasawa 82a8f5
          xforms[0].options |= TJTransform.OPT_TRIM;
shun-iwasawa 82a8f5
          TJDecompressor[] tjds = tjt.transform(xforms, 0);
shun-iwasawa 82a8f5
          tjd = tjds[0];
shun-iwasawa 82a8f5
          tjt.close();
shun-iwasawa 82a8f5
        } else
shun-iwasawa 82a8f5
          tjd = new TJDecompressor(jpegBuf);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        width = tjd.getWidth();
shun-iwasawa 82a8f5
        height = tjd.getHeight();
shun-iwasawa 82a8f5
        int inSubsamp = tjd.getSubsamp();
shun-iwasawa 82a8f5
        int inColorspace = tjd.getColorspace();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        System.out.println((doTransform ? "Transformed" : "Input") +
shun-iwasawa 82a8f5
                           " Image (jpg):  " + width + " x " + height +
shun-iwasawa 82a8f5
                           " pixels, " + SUBSAMP_NAME[inSubsamp] +
shun-iwasawa 82a8f5
                           " subsampling, " + COLORSPACE_NAME[inColorspace]);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        if (outFormat.equalsIgnoreCase("jpg") && doTransform &&
shun-iwasawa 82a8f5
            scalingFactor.isOne() && outSubsamp < 0 && outQual < 0) {
shun-iwasawa 82a8f5
          /* Input image has been transformed, and no re-compression options
shun-iwasawa 82a8f5
             have been selected.  Write the transformed image to disk and
shun-iwasawa 82a8f5
             exit. */
shun-iwasawa 82a8f5
          File outFile = new File(argv[1]);
shun-iwasawa 82a8f5
          FileOutputStream fos = new FileOutputStream(outFile);
shun-iwasawa 82a8f5
          fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
shun-iwasawa 82a8f5
          fos.close();
shun-iwasawa 82a8f5
          System.exit(0);
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        /* Scaling and/or a non-JPEG output image format and/or compression
shun-iwasawa 82a8f5
           options have been selected, so we need to decompress the
shun-iwasawa 82a8f5
           input/transformed image. */
shun-iwasawa 82a8f5
        width = scalingFactor.getScaled(width);
shun-iwasawa 82a8f5
        height = scalingFactor.getScaled(height);
shun-iwasawa 82a8f5
        if (outSubsamp < 0)
shun-iwasawa 82a8f5
          outSubsamp = inSubsamp;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        if (!outFormat.equalsIgnoreCase("jpg"))
shun-iwasawa 82a8f5
          img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB,
shun-iwasawa 82a8f5
                               flags);
shun-iwasawa 82a8f5
        else
shun-iwasawa 82a8f5
          imgBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags);
shun-iwasawa 82a8f5
        tjd.close();
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        /* Input image is not a JPEG image.  Load it into memory. */
shun-iwasawa 82a8f5
        img = ImageIO.read(new File(argv[0]));
shun-iwasawa 82a8f5
        if (img == null)
shun-iwasawa 82a8f5
          throw new Exception("Input image type not supported.");
shun-iwasawa 82a8f5
        width = img.getWidth();
shun-iwasawa 82a8f5
        height = img.getHeight();
shun-iwasawa 82a8f5
        if (outSubsamp < 0) {
shun-iwasawa 82a8f5
          if (img.getType() == BufferedImage.TYPE_BYTE_GRAY)
shun-iwasawa 82a8f5
            outSubsamp = TJ.SAMP_GRAY;
shun-iwasawa 82a8f5
          else
shun-iwasawa 82a8f5
            outSubsamp = DEFAULT_SUBSAMP;
shun-iwasawa 82a8f5
        }
shun-iwasawa 82a8f5
        System.out.println("Input Image:  " + width + " x " + height +
shun-iwasawa 82a8f5
                           " pixels");
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      System.gc();
shun-iwasawa 82a8f5
      if (!display)
shun-iwasawa 82a8f5
        System.out.print("Output Image (" + outFormat + "):  " + width +
shun-iwasawa 82a8f5
                         " x " + height + " pixels");
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
      if (display) {
shun-iwasawa 82a8f5
        /* Display the uncompressed image */
shun-iwasawa 82a8f5
        ImageIcon icon = new ImageIcon(img);
shun-iwasawa 82a8f5
        JLabel label = new JLabel(icon, JLabel.CENTER);
shun-iwasawa 82a8f5
        JOptionPane.showMessageDialog(null, label, "Output Image",
shun-iwasawa 82a8f5
                                      JOptionPane.PLAIN_MESSAGE);
shun-iwasawa 82a8f5
      } else if (outFormat.equalsIgnoreCase("jpg")) {
shun-iwasawa 82a8f5
        /* Output image format is JPEG.  Compress the uncompressed image. */
shun-iwasawa 82a8f5
        if (outQual < 0)
shun-iwasawa 82a8f5
          outQual = DEFAULT_QUALITY;
shun-iwasawa 82a8f5
        System.out.println(", " + SUBSAMP_NAME[outSubsamp] +
shun-iwasawa 82a8f5
                           " subsampling, quality = " + outQual);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        TJCompressor tjc = new TJCompressor();
shun-iwasawa 82a8f5
        tjc.setSubsamp(outSubsamp);
shun-iwasawa 82a8f5
        tjc.setJPEGQuality(outQual);
shun-iwasawa 82a8f5
        if (img != null)
shun-iwasawa 82a8f5
          tjc.setSourceImage(img, 0, 0, 0, 0);
shun-iwasawa 82a8f5
        else
shun-iwasawa 82a8f5
          tjc.setSourceImage(imgBuf, 0, 0, width, 0, height, TJ.PF_BGRX);
shun-iwasawa 82a8f5
        byte[] jpegBuf = tjc.compress(flags);
shun-iwasawa 82a8f5
        int jpegSize = tjc.getCompressedSize();
shun-iwasawa 82a8f5
        tjc.close();
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
        /* Write the JPEG image to disk. */
shun-iwasawa 82a8f5
        File outFile = new File(argv[1]);
shun-iwasawa 82a8f5
        FileOutputStream fos = new FileOutputStream(outFile);
shun-iwasawa 82a8f5
        fos.write(jpegBuf, 0, jpegSize);
shun-iwasawa 82a8f5
        fos.close();
shun-iwasawa 82a8f5
      } else {
shun-iwasawa 82a8f5
        /* Output image format is not JPEG.  Save the uncompressed image
shun-iwasawa 82a8f5
           directly to disk. */
shun-iwasawa 82a8f5
        System.out.print("\n");
shun-iwasawa 82a8f5
        File outFile = new File(argv[1]);
shun-iwasawa 82a8f5
        ImageIO.write(img, outFormat, outFile);
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    } catch (Exception e) {
shun-iwasawa 82a8f5
      e.printStackTrace();
shun-iwasawa 82a8f5
      System.exit(-1);
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  static final TJScalingFactor[] SCALING_FACTORS =
shun-iwasawa 82a8f5
    TJ.getScalingFactors();
shun-iwasawa 82a8f5
};