blob: 8913c7269baf4528c71709823961ae460915a291 [file] [log] [blame]
DRCf8e00552011-02-04 11:06:36 +00001/*
2 * Copyright (C)2011 D. R. Commander. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of the libjpeg-turbo Project nor the names of its
13 * contributors may be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * This program demonstrates how to compress and decompress JPEG files using
31 * the TurboJPEG JNI wrapper
32 */
33
34import java.io.*;
DRC026f7ce2011-02-23 20:51:54 +000035import java.awt.image.*;
36import javax.imageio.*;
DRCc5a41992011-02-08 06:54:36 +000037import org.libjpegturbo.turbojpeg.*;
DRCf8e00552011-02-04 11:06:36 +000038
DRC2413cb82011-02-08 02:11:37 +000039public class TJExample {
DRCf8e00552011-02-04 11:06:36 +000040
DRC026f7ce2011-02-23 20:51:54 +000041 public static final String classname = new TJExample().getClass().getName();
DRCf8e00552011-02-04 11:06:36 +000042
DRC5528b552011-03-01 20:43:47 +000043 private static void usage() throws Exception {
DRC026f7ce2011-02-23 20:51:54 +000044 System.out.println("\nUSAGE: java " + classname + " <Input file> <Output file> [options]\n");
45 System.out.println("Input and output files can be any image format that the Java Image I/O");
46 System.out.println("extensions understand. If either filename ends in a .jpg extension, then");
47 System.out.println("TurboJPEG will be used to compress or decompress the file.\n");
DRCe1303ef2011-02-16 03:26:48 +000048 System.out.println("Options:\n");
DRC5528b552011-03-01 20:43:47 +000049 System.out.println("-scale M/N = if the input image is a JPEG file, scale the width/height of the");
50 System.out.print(" output image by a factor of M/N (M/N = ");
51 for(int i = 0; i < sf.length; i++) {
52 System.out.print(sf[i].num + "/" + sf[i].denom);
53 if(sf.length == 2 && i != sf.length - 1) System.out.print(" or ");
54 else if(sf.length > 2) {
55 if(i != sf.length - 1) System.out.print(", ");
56 if(i == sf.length - 2) System.out.print("or ");
57 }
58 }
59 System.out.println(")\n");
DRC026f7ce2011-02-23 20:51:54 +000060 System.out.println("-samp <444|422|420|gray> = If the output image is a JPEG file, this specifies");
61 System.out.println(" the level of chrominance subsampling to use when");
62 System.out.println(" recompressing it. Default is to use the same level");
63 System.out.println(" of subsampling as the input, if the input is a JPEG");
64 System.out.println(" file, or 4:4:4 otherwise.\n");
65 System.out.println("-q <1-100> = If the output image is a JPEG file, this specifies the JPEG");
66 System.out.println(" quality to use when recompressing it (default = 95).\n");
DRCe1303ef2011-02-16 03:26:48 +000067 System.exit(1);
68 }
69
DRC026f7ce2011-02-23 20:51:54 +000070 private final static String sampName[] = {
71 "4:4:4", "4:2:2", "4:2:0", "Grayscale"
72 };
73
DRCf8e00552011-02-04 11:06:36 +000074 public static void main(String argv[]) {
75
DRCf7f3ea42011-03-01 20:03:32 +000076 BufferedImage img = null; byte[] bmpBuf = null;
DRC026f7ce2011-02-23 20:51:54 +000077
DRCf8e00552011-02-04 11:06:36 +000078 try {
79
DRC5528b552011-03-01 20:43:47 +000080 sf = TJ.getScalingFactors();
81
DRC026f7ce2011-02-23 20:51:54 +000082 if(argv.length < 2) {
DRCe1303ef2011-02-16 03:26:48 +000083 usage();
84 }
85
DRC5528b552011-03-01 20:43:47 +000086 int scaleNum = 1, scaleDenom = 1;
DRC026f7ce2011-02-23 20:51:54 +000087 String inFormat = "jpg", outFormat = "jpg";
88 int outSubsamp = -1, outQual = 95;
89
90 if(argv.length > 2) {
91 for(int i = 2; i < argv.length; i++) {
92 if(argv[i].length() < 2) continue;
93 if(argv[i].length() > 2
94 && argv[i].substring(0, 3).equalsIgnoreCase("-sc")) {
DRC5528b552011-03-01 20:43:47 +000095 int match = 0;
DRC026f7ce2011-02-23 20:51:54 +000096 if(i < argv.length - 1) {
DRC5528b552011-03-01 20:43:47 +000097 int temp1 = 0, temp2 = 0;
DRCf7f3ea42011-03-01 20:03:32 +000098 String[] scaleArg = argv[++i].split("/");
DRC5528b552011-03-01 20:43:47 +000099 if(scaleArg.length == 2) {
100 temp1 = Integer.parseInt(scaleArg[0]);
101 temp2 = Integer.parseInt(scaleArg[1]);
102 for(int j = 0; j < sf.length; j++) {
103 if(temp1 == sf[j].num && temp2 == sf[j].denom) {
104 scaleNum = temp1; scaleDenom = temp2;
105 match = 1; break;
106 }
107 }
108 }
DRC026f7ce2011-02-23 20:51:54 +0000109 }
DRC5528b552011-03-01 20:43:47 +0000110 if(match != 1) usage();
DRC026f7ce2011-02-23 20:51:54 +0000111 }
112 if(argv[i].substring(0, 2).equalsIgnoreCase("-h")
113 || argv[i].equalsIgnoreCase("-?"))
114 usage();
115 if(argv[i].length() > 2
116 && argv[i].substring(0, 3).equalsIgnoreCase("-sa")) {
117 if(i < argv.length - 1) {
118 i++;
119 if(argv[i].substring(0, 1).equalsIgnoreCase("g"))
120 outSubsamp = TJ.SAMP_GRAY;
121 else if(argv[i].equals("444")) outSubsamp = TJ.SAMP_444;
122 else if(argv[i].equals("422")) outSubsamp = TJ.SAMP_422;
123 else if(argv[i].equals("420")) outSubsamp = TJ.SAMP_420;
124 else usage();
125 }
126 else usage();
127 }
128 if(argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
129 if(i < argv.length - 1) {
130 int qual = Integer.parseInt(argv[++i]);
131 if(qual >= 1 && qual <= 100) outQual = qual;
132 else usage();
133 }
134 else usage();
DRCe1303ef2011-02-16 03:26:48 +0000135 }
136 }
DRCf8e00552011-02-04 11:06:36 +0000137 }
DRCf7f3ea42011-03-01 20:03:32 +0000138 String[] inFileTokens = argv[0].split("\\.");
DRC026f7ce2011-02-23 20:51:54 +0000139 if(inFileTokens.length > 1)
140 inFormat = inFileTokens[inFileTokens.length - 1];
DRCf7f3ea42011-03-01 20:03:32 +0000141 String[] outFileTokens = argv[1].split("\\.");
DRC026f7ce2011-02-23 20:51:54 +0000142 if(outFileTokens.length > 1)
143 outFormat = outFileTokens[outFileTokens.length - 1];
DRCf8e00552011-02-04 11:06:36 +0000144
DRC026f7ce2011-02-23 20:51:54 +0000145 File file = new File(argv[0]);
146 int width, height, subsamp = TJ.SAMP_444;
147
148 if(inFormat.equalsIgnoreCase("jpg")) {
149 FileInputStream fis = new FileInputStream(file);
150 int inputSize = fis.available();
151 if(inputSize < 1) {
152 System.out.println("Input file contains no data");
153 System.exit(1);
154 }
DRCf7f3ea42011-03-01 20:03:32 +0000155 byte[] inputBuf = new byte[inputSize];
DRC026f7ce2011-02-23 20:51:54 +0000156 fis.read(inputBuf);
157 fis.close();
158
159 TJDecompressor tjd = new TJDecompressor(inputBuf);
160 width = tjd.getWidth();
161 height = tjd.getHeight();
162 int inSubsamp = tjd.getSubsamp();
163 System.out.println("Source Image: " + width + " x " + height
164 + " pixels, " + sampName[inSubsamp] + " subsampling");
165 if(outSubsamp < 0) outSubsamp = inSubsamp;
166
DRC5528b552011-03-01 20:43:47 +0000167 if(scaleNum != 1 || scaleDenom != 1) {
168 width = (width * scaleNum + scaleDenom - 1) / scaleDenom;
169 height = (height * scaleNum + scaleDenom - 1) / scaleDenom;
DRC026f7ce2011-02-23 20:51:54 +0000170 }
171
DRC4f1580c2011-02-25 06:11:03 +0000172 if(!outFormat.equalsIgnoreCase("jpg"))
173 img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB, 0);
DRC026f7ce2011-02-23 20:51:54 +0000174 else bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, 0);
175 tjd.close();
DRCf8e00552011-02-04 11:06:36 +0000176 }
DRC026f7ce2011-02-23 20:51:54 +0000177 else {
178 img = ImageIO.read(file);
179 width = img.getWidth();
180 height = img.getHeight();
181 if(outSubsamp < 0) {
182 if(img.getType() == BufferedImage.TYPE_BYTE_GRAY)
183 outSubsamp = TJ.SAMP_GRAY;
184 else outSubsamp = TJ.SAMP_444;
185 }
DRCf8e00552011-02-04 11:06:36 +0000186 }
DRC026f7ce2011-02-23 20:51:54 +0000187 System.out.print("Dest. Image (" + outFormat + "): " + width + " x "
188 + height + " pixels");
DRCe1303ef2011-02-16 03:26:48 +0000189
DRC026f7ce2011-02-23 20:51:54 +0000190 if(outFormat.equalsIgnoreCase("jpg")) {
191 System.out.println(", " + sampName[outSubsamp]
192 + " subsampling, quality = " + outQual);
193 TJCompressor tjc = new TJCompressor();
194 int jpegSize;
DRCf7f3ea42011-03-01 20:03:32 +0000195 byte[] jpegBuf;
DRC026f7ce2011-02-23 20:51:54 +0000196
DRC4f1580c2011-02-25 06:11:03 +0000197 tjc.setSubsamp(outSubsamp);
198 tjc.setJPEGQuality(outQual);
DRC026f7ce2011-02-23 20:51:54 +0000199 if(img != null)
DRC4f1580c2011-02-25 06:11:03 +0000200 jpegBuf = tjc.compress(img, 0);
DRC026f7ce2011-02-23 20:51:54 +0000201 else {
202 tjc.setBitmapBuffer(bmpBuf, width, 0, height, TJ.PF_BGRX);
DRC4f1580c2011-02-25 06:11:03 +0000203 jpegBuf = tjc.compress(0);
DRC026f7ce2011-02-23 20:51:54 +0000204 }
DRC4f1580c2011-02-25 06:11:03 +0000205 jpegSize = tjc.getCompressedSize();
DRC026f7ce2011-02-23 20:51:54 +0000206 tjc.close();
207
208 file = new File(argv[1]);
209 FileOutputStream fos = new FileOutputStream(file);
210 fos.write(jpegBuf, 0, jpegSize);
211 fos.close();
DRCe1303ef2011-02-16 03:26:48 +0000212 }
DRC026f7ce2011-02-23 20:51:54 +0000213 else {
DRC0ad78a62011-02-23 20:57:17 +0000214 System.out.print("\n");
DRC026f7ce2011-02-23 20:51:54 +0000215 file = new File(argv[1]);
216 ImageIO.write(img, outFormat, file);
217 }
DRCf8e00552011-02-04 11:06:36 +0000218
DRCf7f3ea42011-03-01 20:03:32 +0000219 }
220 catch(Exception e) {
DRCf8e00552011-02-04 11:06:36 +0000221 System.out.println(e);
222 }
223 }
224
DRC5528b552011-03-01 20:43:47 +0000225 static TJ.ScalingFactor sf [] = null;
DRCf8e00552011-02-04 11:06:36 +0000226};