Imported Upstream version 3.0.1
[platform/upstream/libjpeg-turbo.git] / java / org / libjpegturbo / turbojpeg / TJTransformer.java
1 /*
2  * Copyright (C)2011, 2013-2015, 2023 D. R. Commander.  All Rights Reserved.
3  * Copyright (C)2015 Viktor Szathmáry.  All Rights Reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice,
9  *   this list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  *   this list of conditions and the following disclaimer in the documentation
12  *   and/or other materials provided with the distribution.
13  * - Neither the name of the libjpeg-turbo Project nor the names of its
14  *   contributors may be used to endorse or promote products derived from this
15  *   software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 package org.libjpegturbo.turbojpeg;
31
32 /**
33  * TurboJPEG lossless transformer
34  */
35 public class TJTransformer extends TJDecompressor {
36
37   /**
38    * Create a TurboJPEG lossless transformer instance.
39    */
40   public TJTransformer() throws TJException {
41     init();
42   }
43
44   /**
45    * Create a TurboJPEG lossless transformer instance and associate the JPEG
46    * source image stored in <code>jpegImage</code> with the newly created
47    * instance.
48    *
49    * @param jpegImage buffer containing the JPEG source image to transform.
50    * (The size of the JPEG image is assumed to be the length of the array.)
51    * This buffer is not modified.
52    */
53   public TJTransformer(byte[] jpegImage) throws TJException {
54     init();
55     setSourceImage(jpegImage, jpegImage.length);
56   }
57
58   /**
59    * Create a TurboJPEG lossless transformer instance and associate the JPEG
60    * source image of length <code>imageSize</code> bytes stored in
61    * <code>jpegImage</code> with the newly created instance.
62    *
63    * @param jpegImage buffer containing the JPEG source image to transform.
64    * This buffer is not modified.
65    *
66    * @param imageSize size of the JPEG source image (in bytes)
67    */
68   public TJTransformer(byte[] jpegImage, int imageSize) throws TJException {
69     init();
70     setSourceImage(jpegImage, imageSize);
71   }
72
73   /**
74    * Losslessly transform the JPEG source image associated with this
75    * transformer instance into one or more JPEG images stored in the given
76    * destination buffers.  Lossless transforms work by moving the raw
77    * coefficients from one JPEG image structure to another without altering the
78    * values of the coefficients.  While this is typically faster than
79    * decompressing the image, transforming it, and re-compressing it, lossless
80    * transforms are not free.  Each lossless transform requires reading and
81    * performing Huffman decoding on all of the coefficients in the source
82    * image, regardless of the size of the destination image.  Thus, this method
83    * provides a means of generating multiple transformed images from the same
84    * source or of applying multiple transformations simultaneously, in order to
85    * eliminate the need to read the source coefficients multiple times.
86    *
87    * @param dstBufs an array of JPEG destination buffers.
88    * <code>dstbufs[i]</code> will receive a JPEG image that has been
89    * transformed using the parameters in <code>transforms[i]</code>.  Use
90    * {@link TJ#bufSize TJ.bufSize()} to determine the maximum size for each
91    * buffer based on the transformed or cropped width and height and the level
92    * of subsampling used in the source image.
93    *
94    * @param transforms an array of {@link TJTransform} instances, each of
95    * which specifies the transform parameters and/or cropping region for the
96    * corresponding transformed JPEG image
97    */
98   public void transform(byte[][] dstBufs, TJTransform[] transforms)
99                         throws TJException {
100     transformedSizes = transform(getJPEGBuf(), getJPEGSize(), dstBufs,
101                                  transforms);
102   }
103
104   /**
105    * @deprecated Use {@link #set TJDecompressor.set()} and
106    * {@link #transform(byte[][], TJTransform[])} instead.
107    */
108   @SuppressWarnings("checkstyle:JavadocMethod")
109   @Deprecated
110   public void transform(byte[][] dstBufs, TJTransform[] transforms,
111                         int flags) throws TJException {
112     processFlags(flags);
113     transform(dstBufs, transforms);
114   }
115
116   /**
117    * Losslessly transform the JPEG source image associated with this
118    * transformer instance and return an array of {@link TJDecompressor}
119    * instances, each of which has a transformed JPEG image associated with it.
120    *
121    * @param transforms an array of {@link TJTransform} instances, each of
122    * which specifies the transform parameters and/or cropping region for the
123    * corresponding transformed JPEG image
124    *
125    * @return an array of {@link TJDecompressor} instances, each of
126    * which has a transformed JPEG image associated with it.
127    */
128   public TJDecompressor[] transform(TJTransform[] transforms)
129                                     throws TJException {
130     byte[][] dstBufs = new byte[transforms.length][];
131     if (getWidth() < 1 || getHeight() < 1)
132       throw new IllegalStateException("JPEG buffer not initialized");
133     checkSubsampling();
134     for (int i = 0; i < transforms.length; i++) {
135       int w = getWidth(), h = getHeight();
136       if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
137         if (transforms[i].width != 0) w = transforms[i].width;
138         if (transforms[i].height != 0) h = transforms[i].height;
139       }
140       dstBufs[i] = new byte[TJ.bufSize(w, h, get(TJ.PARAM_SUBSAMP))];
141     }
142     TJDecompressor[] tjd = new TJDecompressor[transforms.length];
143     transform(dstBufs, transforms);
144     for (int i = 0; i < transforms.length; i++)
145       tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
146     return tjd;
147   }
148
149   /**
150    * @deprecated Use {@link #set TJDecompressor.set()} and
151    * {@link #transform(TJTransform[])} instead.
152    */
153   @SuppressWarnings("checkstyle:JavadocMethod")
154   @Deprecated
155   public TJDecompressor[] transform(TJTransform[] transforms, int flags)
156                                     throws TJException {
157     processFlags(flags);
158     return transform(transforms);
159   }
160
161   /**
162    * Returns an array containing the sizes of the transformed JPEG images
163    * (in bytes) generated by the most recent transform operation.
164    *
165    * @return an array containing the sizes of the transformed JPEG images
166    * (in bytes) generated by the most recent transform operation.
167    */
168   public int[] getTransformedSizes() {
169     if (transformedSizes == null)
170       throw new IllegalStateException("No image has been transformed yet");
171     return transformedSizes;
172   }
173
174   private native void init() throws TJException;
175
176   private native int[] transform(byte[] srcBuf, int srcSize, byte[][] dstBufs,
177     TJTransform[] transforms) throws TJException;
178
179   static {
180     TJLoader.load();
181   }
182
183   private int[] transformedSizes = null;
184 }