2
* Copyright (C)2011 D. R. Commander. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
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.
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.
30
* This program demonstrates how to compress and decompress JPEG files using
31
* the TurboJPEG JNI wrapper
35
import java.awt.image.*;
36
import javax.imageio.*;
38
import org.libjpegturbo.turbojpeg.*;
40
public class TJExample {
42
public static final String classname = new TJExample().getClass().getName();
44
private static void usage() throws Exception {
45
System.out.println("\nUSAGE: java " + classname + " <Input file> <Output file> [options]\n");
46
System.out.println("Input and output files can be any image format that the Java Image I/O");
47
System.out.println("extensions understand. If either filename ends in a .jpg extension, then");
48
System.out.println("TurboJPEG will be used to compress or decompress the file.\n");
49
System.out.println("Options:\n");
50
System.out.println("-scale M/N = if the input image is a JPEG file, scale the width/height of the");
51
System.out.print(" output image by a factor of M/N (M/N = ");
52
for(int i = 0; i < sf.length; i++) {
53
System.out.print(sf[i].getNum() + "/" + sf[i].getDenom());
54
if(sf.length == 2 && i != sf.length - 1) System.out.print(" or ");
55
else if(sf.length > 2) {
56
if(i != sf.length - 1) System.out.print(", ");
57
if(i == sf.length - 2) System.out.print("or ");
60
System.out.println(")\n");
61
System.out.println("-samp <444|422|420|gray> = If the output image is a JPEG file, this specifies");
62
System.out.println(" the level of chrominance subsampling to use when");
63
System.out.println(" recompressing it. Default is to use the same level");
64
System.out.println(" of subsampling as the input, if the input is a JPEG");
65
System.out.println(" file, or 4:4:4 otherwise.\n");
66
System.out.println("-q <1-100> = If the output image is a JPEG file, this specifies the JPEG");
67
System.out.println(" quality to use when recompressing it (default = 95).\n");
68
System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
69
System.out.println(" If the input image is a JPEG file, perform the corresponding lossless");
70
System.out.println(" transform prior to decompression (these options are mutually exclusive)\n");
71
System.out.println("-grayscale = If the input image is a JPEG file, perform lossless grayscale");
72
System.out.println(" conversion prior to decompression (can be combined with the other");
73
System.out.println(" transforms above)\n");
74
System.out.println("-crop X,Y,WxH = If the input image is a JPEG file, perform lossless cropping");
75
System.out.println(" prior to decompression. X,Y specifies the upper left corner of the");
76
System.out.println(" cropping region, and WxH specifies its width and height. X,Y must be");
77
System.out.println(" evenly divible by the MCU block size (8x8 if the source image was");
78
System.out.println(" compressed using no subsampling or grayscale, or 16x8 for 4:2:2 or 16x16");
79
System.out.println(" for 4:2:0.)\n");
80
System.out.println("-display = Display output image (Output file need not be specified in this");
81
System.out.println(" case.)\n");
85
private final static String sampName[] = {
86
"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0"
89
public static void main(String argv[]) {
91
BufferedImage img = null; byte[] bmpBuf = null;
92
TJTransform xform = new TJTransform();
96
sf = TJ.getScalingFactors();
102
TJScalingFactor scaleFactor = new TJScalingFactor(1, 1);
103
String inFormat = "jpg", outFormat = "jpg";
104
int outSubsamp = -1, outQual = 95;
105
boolean display = false;
107
if(argv.length > 1) {
108
for(int i = 1; i < argv.length; i++) {
109
if(argv[i].length() < 2) continue;
110
if(argv[i].length() > 2
111
&& argv[i].substring(0, 3).equalsIgnoreCase("-sc")) {
113
if(i < argv.length - 1) {
114
String[] scaleArg = argv[++i].split("/");
115
if(scaleArg.length == 2) {
116
TJScalingFactor tempsf =
117
new TJScalingFactor(Integer.parseInt(scaleArg[0]),
118
Integer.parseInt(scaleArg[1]));
119
for(int j = 0; j < sf.length; j++) {
120
if(tempsf.equals(sf[j])) {
127
if(match != 1) usage();
129
if(argv[i].equalsIgnoreCase("-h") || argv[i].equalsIgnoreCase("-?"))
131
if(argv[i].length() > 2
132
&& argv[i].substring(0, 3).equalsIgnoreCase("-sa")) {
133
if(i < argv.length - 1) {
135
if(argv[i].substring(0, 1).equalsIgnoreCase("g"))
136
outSubsamp = TJ.SAMP_GRAY;
137
else if(argv[i].equals("444")) outSubsamp = TJ.SAMP_444;
138
else if(argv[i].equals("422")) outSubsamp = TJ.SAMP_422;
139
else if(argv[i].equals("420")) outSubsamp = TJ.SAMP_420;
144
if(argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
145
if(i < argv.length - 1) {
146
int qual = Integer.parseInt(argv[++i]);
147
if(qual >= 1 && qual <= 100) outQual = qual;
152
if(argv[i].substring(0, 2).equalsIgnoreCase("-g"))
153
xform.options |= TJTransform.OPT_GRAY;
154
if(argv[i].equalsIgnoreCase("-hflip"))
155
xform.op = TJTransform.OP_HFLIP;
156
if(argv[i].equalsIgnoreCase("-vflip"))
157
xform.op = TJTransform.OP_VFLIP;
158
if(argv[i].equalsIgnoreCase("-transpose"))
159
xform.op = TJTransform.OP_TRANSPOSE;
160
if(argv[i].equalsIgnoreCase("-transverse"))
161
xform.op = TJTransform.OP_TRANSVERSE;
162
if(argv[i].equalsIgnoreCase("-rot90"))
163
xform.op = TJTransform.OP_ROT90;
164
if(argv[i].equalsIgnoreCase("-rot180"))
165
xform.op = TJTransform.OP_ROT180;
166
if(argv[i].equalsIgnoreCase("-rot270"))
167
xform.op = TJTransform.OP_ROT270;
168
if(argv[i].length() > 2
169
&& argv[i].substring(0, 2).equalsIgnoreCase("-c")) {
170
if(i >= argv.length - 1) usage();
171
String[] cropArg = argv[++i].split(",");
172
if(cropArg.length != 3) usage();
173
String[] dimArg = cropArg[2].split("[xX]");
174
if(dimArg.length != 2) usage();
175
int tempx = Integer.parseInt(cropArg[0]);
176
int tempy = Integer.parseInt(cropArg[1]);
177
int tempw = Integer.parseInt(dimArg[0]);
178
int temph = Integer.parseInt(dimArg[1]);
179
if(tempx < 0 || tempy < 0 || tempw < 0 || temph < 0) usage();
180
xform.x = tempx; xform.y = tempy;
181
xform.width = tempw; xform.height = temph;
182
xform.options |= TJTransform.OPT_CROP;
184
if(argv[i].substring(0, 2).equalsIgnoreCase("-d"))
188
String[] inFileTokens = argv[0].split("\\.");
189
if(inFileTokens.length > 1)
190
inFormat = inFileTokens[inFileTokens.length - 1];
191
String[] outFileTokens;
192
if(display) outFormat = "bmp";
194
outFileTokens = argv[1].split("\\.");
195
if(outFileTokens.length > 1)
196
outFormat = outFileTokens[outFileTokens.length - 1];
199
File file = new File(argv[0]);
202
if(inFormat.equalsIgnoreCase("jpg")) {
203
FileInputStream fis = new FileInputStream(file);
204
int inputSize = fis.available();
206
System.out.println("Input file contains no data");
209
byte[] inputBuf = new byte[inputSize];
214
if(xform.op != TJTransform.OP_NONE || xform.options != 0) {
215
TJTransformer tjt = new TJTransformer(inputBuf);
216
TJTransform t[] = new TJTransform[1];
218
t[0].options |= TJTransform.OPT_TRIM;
219
TJDecompressor[] tjdx = tjt.transform(t, 0);
222
else tjd = new TJDecompressor(inputBuf);
224
width = tjd.getWidth();
225
height = tjd.getHeight();
226
int inSubsamp = tjd.getSubsamp();
227
System.out.println("Source Image: " + width + " x " + height
228
+ " pixels, " + sampName[inSubsamp] + " subsampling");
229
if(outSubsamp < 0) outSubsamp = inSubsamp;
231
if(outFormat.equalsIgnoreCase("jpg")
232
&& (xform.op != TJTransform.OP_NONE || xform.options != 0)
233
&& scaleFactor.isOne()) {
234
file = new File(argv[1]);
235
FileOutputStream fos = new FileOutputStream(file);
236
fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
241
width = scaleFactor.getScaled(width);
242
height = scaleFactor.getScaled(height);
244
if(!outFormat.equalsIgnoreCase("jpg"))
245
img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB, 0);
246
else bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, 0);
250
img = ImageIO.read(file);
251
width = img.getWidth();
252
height = img.getHeight();
254
if(img.getType() == BufferedImage.TYPE_BYTE_GRAY)
255
outSubsamp = TJ.SAMP_GRAY;
256
else outSubsamp = TJ.SAMP_444;
261
System.out.print("Dest. Image (" + outFormat + "): " + width + " x "
262
+ height + " pixels");
265
ImageIcon icon = new ImageIcon(img);
266
JLabel label = new JLabel(icon, JLabel.CENTER);
267
JOptionPane.showMessageDialog(null, label, "Output Image",
268
JOptionPane.PLAIN_MESSAGE);
270
else if(outFormat.equalsIgnoreCase("jpg")) {
271
System.out.println(", " + sampName[outSubsamp]
272
+ " subsampling, quality = " + outQual);
273
TJCompressor tjc = new TJCompressor();
277
tjc.setSubsamp(outSubsamp);
278
tjc.setJPEGQuality(outQual);
280
jpegBuf = tjc.compress(img, 0);
282
tjc.setSourceImage(bmpBuf, width, 0, height, TJ.PF_BGRX);
283
jpegBuf = tjc.compress(0);
285
jpegSize = tjc.getCompressedSize();
288
file = new File(argv[1]);
289
FileOutputStream fos = new FileOutputStream(file);
290
fos.write(jpegBuf, 0, jpegSize);
294
System.out.print("\n");
295
file = new File(argv[1]);
296
ImageIO.write(img, outFormat, file);
306
static TJScalingFactor sf [] = null;