Imported Upstream version 1.4.2
[platform/upstream/libjpeg-turbo.git] / java / org / libjpegturbo / turbojpeg / TJTransformer.java
1 /*
2  * Copyright (C)2011, 2013-2015 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 package org.libjpegturbo.turbojpeg;
30
31 /**
32  * TurboJPEG lossless transformer
33  */
34 public class TJTransformer extends TJDecompressor {
35
36   /**
37    * Create a TurboJPEG lossless transformer instance.
38    */
39   public TJTransformer() throws Exception {
40     init();
41   }
42
43   /**
44    * Create a TurboJPEG lossless transformer instance and associate the JPEG
45    * image stored in <code>jpegImage</code> with the newly created instance.
46    *
47    * @param jpegImage JPEG image buffer (size of the JPEG image is assumed to
48    * be the length of the array.)  This buffer is not modified.
49    */
50   public TJTransformer(byte[] jpegImage) throws Exception {
51     init();
52     setSourceImage(jpegImage, jpegImage.length);
53   }
54
55   /**
56    * Create a TurboJPEG lossless transformer instance and associate the JPEG
57    * image of length <code>imageSize</code> bytes stored in
58    * <code>jpegImage</code> with the newly created instance.
59    *
60    * @param jpegImage JPEG image buffer.  This buffer is not modified.
61    *
62    * @param imageSize size of the JPEG image (in bytes)
63    */
64   public TJTransformer(byte[] jpegImage, int imageSize) throws Exception {
65     init();
66     setSourceImage(jpegImage, imageSize);
67   }
68
69   /**
70    * Losslessly transform the JPEG image associated with this transformer
71    * instance into one or more JPEG images stored in the given destination
72    * buffers.  Lossless transforms work by moving the raw coefficients from one
73    * JPEG image structure to another without altering the values of the
74    * coefficients.  While this is typically faster than decompressing the
75    * image, transforming it, and re-compressing it, lossless transforms are not
76    * free.  Each lossless transform requires reading and performing Huffman
77    * decoding on all of the coefficients in the source image, regardless of the
78    * size of the destination image.  Thus, this method provides a means of
79    * generating multiple transformed images from the same source or of applying
80    * multiple transformations simultaneously, in order to eliminate the need to
81    * read the source coefficients multiple times.
82    *
83    * @param dstBufs an array of image buffers.  <code>dstbufs[i]</code> will
84    * receive a JPEG image that has been transformed using the parameters in
85    * <code>transforms[i]</code>.  Use {@link TJ#bufSize} to determine the
86    * maximum size for each buffer based on the transformed or cropped width and
87    * height and the level of subsampling used in the source image.
88    *
89    * @param transforms an array of {@link TJTransform} instances, each of
90    * which specifies the transform parameters and/or cropping region for the
91    * corresponding transformed output image
92    *
93    * @param flags the bitwise OR of one or more of
94    * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
95    */
96   public void transform(byte[][] dstBufs, TJTransform[] transforms,
97                         int flags) throws Exception {
98     if (jpegBuf == null)
99       throw new Exception("JPEG buffer not initialized");
100     transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms,
101                                  flags);
102   }
103
104   /**
105    * Losslessly transform the JPEG image associated with this transformer
106    * instance and return an array of {@link TJDecompressor} instances, each of
107    * which has a transformed JPEG image associated with it.
108    *
109    * @param transforms an array of {@link TJTransform} instances, each of
110    * which specifies the transform parameters and/or cropping region for the
111    * corresponding transformed output image
112    *
113    * @return an array of {@link TJDecompressor} instances, each of
114    * which has a transformed JPEG image associated with it.
115    *
116    * @param flags the bitwise OR of one or more of
117    * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
118    */
119   public TJDecompressor[] transform(TJTransform[] transforms, int flags)
120     throws Exception {
121     byte[][] dstBufs = new byte[transforms.length][];
122     if (jpegWidth < 1 || jpegHeight < 1)
123       throw new Exception("JPEG buffer not initialized");
124     for (int i = 0; i < transforms.length; i++) {
125       int w = jpegWidth, h = jpegHeight;
126       if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
127         if (transforms[i].width != 0) w = transforms[i].width;
128         if (transforms[i].height != 0) h = transforms[i].height;
129       }
130       dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)];
131     }
132     TJDecompressor[] tjd = new TJDecompressor[transforms.length];
133     transform(dstBufs, transforms, flags);
134     for (int i = 0; i < transforms.length; i++)
135       tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
136     return tjd;
137   }
138
139   /**
140    * Returns an array containing the sizes of the transformed JPEG images
141    * generated by the most recent transform operation.
142    *
143    * @return an array containing the sizes of the transformed JPEG images
144    * generated by the most recent transform operation.
145    */
146   public int[] getTransformedSizes() throws Exception {
147     if (transformedSizes == null)
148       throw new Exception("No image has been transformed yet");
149     return transformedSizes;
150   }
151
152   private native void init() throws Exception;
153
154   private native int[] transform(byte[] srcBuf, int srcSize, byte[][] dstBufs,
155     TJTransform[] transforms, int flags) throws Exception;
156
157   static {
158     TJLoader.load();
159   }
160
161   private int[] transformedSizes = null;
162 };