| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- /*
- * Copyright (C)2011-2012, 2014-2015 D. R. Commander. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * - Neither the name of the libjpeg-turbo Project nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * This program demonstrates how to compress and decompress JPEG files using
- * the TurboJPEG JNI wrapper
- */
- import java.io.*;
- import java.awt.*;
- import java.awt.image.*;
- import java.nio.*;
- import javax.imageio.*;
- import javax.swing.*;
- import org.libjpegturbo.turbojpeg.*;
- public class TJExample implements TJCustomFilter {
- public static final String classname = new TJExample().getClass().getName();
- private static void usage() throws Exception {
- System.out.println("\nUSAGE: java " + classname + " <Input file> <Output file> [options]\n");
- System.out.println("Input and output files can be any image format that the Java Image I/O");
- System.out.println("extensions understand. If either filename ends in a .jpg extension, then");
- System.out.println("TurboJPEG will be used to compress or decompress the file.\n");
- System.out.println("Options:\n");
- System.out.println("-scale M/N = if the input image is a JPEG file, scale the width/height of the");
- System.out.print(" output image by a factor of M/N (M/N = ");
- for (int i = 0; i < sf.length; i++) {
- System.out.print(sf[i].getNum() + "/" + sf[i].getDenom());
- if (sf.length == 2 && i != sf.length - 1)
- System.out.print(" or ");
- else if (sf.length > 2) {
- if (i != sf.length - 1)
- System.out.print(", ");
- if (i == sf.length - 2)
- System.out.print("or ");
- }
- }
- System.out.println(")\n");
- System.out.println("-samp <444|422|420|gray> = If the output image is a JPEG file, this specifies");
- System.out.println(" the level of chrominance subsampling to use when");
- System.out.println(" recompressing it. Default is to use the same level");
- System.out.println(" of subsampling as the input, if the input is a JPEG");
- System.out.println(" file, or 4:4:4 otherwise.\n");
- System.out.println("-q <1-100> = If the output image is a JPEG file, this specifies the JPEG");
- System.out.println(" quality to use when recompressing it (default = 95).\n");
- System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
- System.out.println(" If the input image is a JPEG file, perform the corresponding lossless");
- System.out.println(" transform prior to decompression (these options are mutually exclusive)\n");
- System.out.println("-grayscale = If the input image is a JPEG file, perform lossless grayscale");
- System.out.println(" conversion prior to decompression (can be combined with the other");
- System.out.println(" transforms above)\n");
- System.out.println("-crop X,Y,WxH = If the input image is a JPEG file, perform lossless cropping");
- System.out.println(" prior to decompression. X,Y specifies the upper left corner of the");
- System.out.println(" cropping region, and WxH specifies its width and height. X,Y must be");
- System.out.println(" evenly divible by the MCU block size (8x8 if the source image was");
- System.out.println(" compressed using no subsampling or grayscale, or 16x8 for 4:2:2 or 16x16");
- System.out.println(" for 4:2:0.)\n");
- System.out.println("-display = Display output image (Output file need not be specified in this");
- System.out.println(" case.)\n");
- System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available in");
- System.out.println(" the underlying codec\n");
- System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
- System.out.println(" codec\n");
- System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the");
- System.out.println(" underlying codec\n");
- System.exit(1);
- }
- private static final String[] sampName = {
- "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0"
- };
- public static void main(String[] argv) {
- BufferedImage img = null;
- byte[] bmpBuf = null;
- TJTransform xform = new TJTransform();
- int flags = 0;
- try {
- sf = TJ.getScalingFactors();
- if (argv.length < 2) {
- usage();
- }
- TJScalingFactor scaleFactor = new TJScalingFactor(1, 1);
- String inFormat = "jpg", outFormat = "jpg";
- int outSubsamp = -1, outQual = 95;
- boolean display = false;
- if (argv.length > 1) {
- for (int i = 1; i < argv.length; i++) {
- if (argv[i].length() < 2)
- continue;
- if (argv[i].length() > 2 &&
- argv[i].substring(0, 3).equalsIgnoreCase("-sc")) {
- int match = 0;
- if (i < argv.length - 1) {
- String[] scaleArg = argv[++i].split("/");
- if (scaleArg.length == 2) {
- TJScalingFactor tempsf =
- new TJScalingFactor(Integer.parseInt(scaleArg[0]),
- Integer.parseInt(scaleArg[1]));
- for (int j = 0; j < sf.length; j++) {
- if (tempsf.equals(sf[j])) {
- scaleFactor = sf[j];
- match = 1;
- break;
- }
- }
- }
- }
- if (match != 1) usage();
- }
- if (argv[i].equalsIgnoreCase("-h") || argv[i].equalsIgnoreCase("-?"))
- usage();
- if (argv[i].length() > 2 &&
- argv[i].substring(0, 3).equalsIgnoreCase("-sa")) {
- if (i < argv.length - 1) {
- i++;
- if (argv[i].substring(0, 1).equalsIgnoreCase("g"))
- outSubsamp = TJ.SAMP_GRAY;
- else if (argv[i].equals("444"))
- outSubsamp = TJ.SAMP_444;
- else if (argv[i].equals("422"))
- outSubsamp = TJ.SAMP_422;
- else if (argv[i].equals("420"))
- outSubsamp = TJ.SAMP_420;
- else
- usage();
- } else
- usage();
- }
- if (argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
- if (i < argv.length - 1) {
- int qual = Integer.parseInt(argv[++i]);
- if (qual >= 1 && qual <= 100)
- outQual = qual;
- else
- usage();
- } else
- usage();
- }
- if (argv[i].substring(0, 2).equalsIgnoreCase("-g"))
- xform.options |= TJTransform.OPT_GRAY;
- if (argv[i].equalsIgnoreCase("-hflip"))
- xform.op = TJTransform.OP_HFLIP;
- if (argv[i].equalsIgnoreCase("-vflip"))
- xform.op = TJTransform.OP_VFLIP;
- if (argv[i].equalsIgnoreCase("-transpose"))
- xform.op = TJTransform.OP_TRANSPOSE;
- if (argv[i].equalsIgnoreCase("-transverse"))
- xform.op = TJTransform.OP_TRANSVERSE;
- if (argv[i].equalsIgnoreCase("-rot90"))
- xform.op = TJTransform.OP_ROT90;
- if (argv[i].equalsIgnoreCase("-rot180"))
- xform.op = TJTransform.OP_ROT180;
- if (argv[i].equalsIgnoreCase("-rot270"))
- xform.op = TJTransform.OP_ROT270;
- if (argv[i].equalsIgnoreCase("-custom"))
- xform.cf = new TJExample();
- else if (argv[i].length() > 2 &&
- argv[i].substring(0, 2).equalsIgnoreCase("-c")) {
- if (i >= argv.length - 1)
- usage();
- String[] cropArg = argv[++i].split(",");
- if (cropArg.length != 3)
- usage();
- String[] dimArg = cropArg[2].split("[xX]");
- if (dimArg.length != 2)
- usage();
- int tempx = Integer.parseInt(cropArg[0]);
- int tempy = Integer.parseInt(cropArg[1]);
- int tempw = Integer.parseInt(dimArg[0]);
- int temph = Integer.parseInt(dimArg[1]);
- if (tempx < 0 || tempy < 0 || tempw < 0 || temph < 0)
- usage();
- xform.x = tempx;
- xform.y = tempy;
- xform.width = tempw;
- xform.height = temph;
- xform.options |= TJTransform.OPT_CROP;
- }
- if (argv[i].substring(0, 2).equalsIgnoreCase("-d"))
- display = true;
- if (argv[i].equalsIgnoreCase("-fastupsample")) {
- System.out.println("Using fast upsampling code");
- flags |= TJ.FLAG_FASTUPSAMPLE;
- }
- if (argv[i].equalsIgnoreCase("-fastdct")) {
- System.out.println("Using fastest DCT/IDCT algorithm");
- flags |= TJ.FLAG_FASTDCT;
- }
- if (argv[i].equalsIgnoreCase("-accuratedct")) {
- System.out.println("Using most accurate DCT/IDCT algorithm");
- flags |= TJ.FLAG_ACCURATEDCT;
- }
- }
- }
- String[] inFileTokens = argv[0].split("\\.");
- if (inFileTokens.length > 1)
- inFormat = inFileTokens[inFileTokens.length - 1];
- String[] outFileTokens;
- if (display)
- outFormat = "bmp";
- else {
- outFileTokens = argv[1].split("\\.");
- if (outFileTokens.length > 1)
- outFormat = outFileTokens[outFileTokens.length - 1];
- }
- File file = new File(argv[0]);
- int width, height;
- if (inFormat.equalsIgnoreCase("jpg")) {
- FileInputStream fis = new FileInputStream(file);
- int inputSize = fis.available();
- if (inputSize < 1) {
- System.out.println("Input file contains no data");
- System.exit(1);
- }
- byte[] inputBuf = new byte[inputSize];
- fis.read(inputBuf);
- fis.close();
- TJDecompressor tjd;
- if (xform.op != TJTransform.OP_NONE || xform.options != 0 ||
- xform.cf != null) {
- TJTransformer tjt = new TJTransformer(inputBuf);
- TJTransform[] t = new TJTransform[1];
- t[0] = xform;
- t[0].options |= TJTransform.OPT_TRIM;
- TJDecompressor[] tjdx = tjt.transform(t, 0);
- tjd = tjdx[0];
- } else
- tjd = new TJDecompressor(inputBuf);
- width = tjd.getWidth();
- height = tjd.getHeight();
- int inSubsamp = tjd.getSubsamp();
- System.out.println("Source Image: " + width + " x " + height +
- " pixels, " + sampName[inSubsamp] + " subsampling");
- if (outSubsamp < 0)
- outSubsamp = inSubsamp;
- if (outFormat.equalsIgnoreCase("jpg") &&
- (xform.op != TJTransform.OP_NONE || xform.options != 0) &&
- scaleFactor.isOne()) {
- file = new File(argv[1]);
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
- fos.close();
- System.exit(0);
- }
- width = scaleFactor.getScaled(width);
- height = scaleFactor.getScaled(height);
- if (!outFormat.equalsIgnoreCase("jpg"))
- img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB,
- flags);
- else
- bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags);
- tjd.close();
- } else {
- img = ImageIO.read(file);
- if (img == null)
- throw new Exception("Input image type not supported.");
- width = img.getWidth();
- height = img.getHeight();
- if (outSubsamp < 0) {
- if (img.getType() == BufferedImage.TYPE_BYTE_GRAY)
- outSubsamp = TJ.SAMP_GRAY;
- else
- outSubsamp = TJ.SAMP_444;
- }
- }
- System.gc();
- if (!display)
- System.out.print("Dest. Image (" + outFormat + "): " + width + " x " +
- height + " pixels");
- if (display) {
- ImageIcon icon = new ImageIcon(img);
- JLabel label = new JLabel(icon, JLabel.CENTER);
- JOptionPane.showMessageDialog(null, label, "Output Image",
- JOptionPane.PLAIN_MESSAGE);
- } else if (outFormat.equalsIgnoreCase("jpg")) {
- System.out.println(", " + sampName[outSubsamp] +
- " subsampling, quality = " + outQual);
- TJCompressor tjc = new TJCompressor();
- int jpegSize;
- byte[] jpegBuf;
- tjc.setSubsamp(outSubsamp);
- tjc.setJPEGQuality(outQual);
- if (img != null)
- tjc.setSourceImage(img, 0, 0, 0, 0);
- else {
- tjc.setSourceImage(bmpBuf, 0, 0, width, 0, height, TJ.PF_BGRX);
- }
- jpegBuf = tjc.compress(flags);
- jpegSize = tjc.getCompressedSize();
- tjc.close();
- file = new File(argv[1]);
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(jpegBuf, 0, jpegSize);
- fos.close();
- } else {
- System.out.print("\n");
- file = new File(argv[1]);
- ImageIO.write(img, outFormat, file);
- }
- } catch(Exception e) {
- e.printStackTrace();
- System.exit(-1);
- }
- }
- public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
- Rectangle planeRegion, int componentIndex,
- int transformIndex, TJTransform transform)
- throws TJException {
- for (int i = 0; i < bufferRegion.width * bufferRegion.height; i++) {
- coeffBuffer.put(i, (short)(-coeffBuffer.get(i)));
- }
- }
- static TJScalingFactor[] sf = null;
- };
|