2 * Copyright (C)2011-2015, 2018, 2020, 2022-2023 D. R. Commander.
4 * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * - Neither the name of the libjpeg-turbo Project nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 package org.libjpegturbo.turbojpeg;
33 import java.awt.image.*;
38 * TurboJPEG compressor
40 public class TJCompressor implements Closeable {
43 * Create a TurboJPEG compressor instance.
45 public TJCompressor() throws TJException {
50 * Create a TurboJPEG compressor instance and associate the 8-bit-per-sample
51 * packed-pixel source image stored in <code>srcImage</code> with the newly
54 * @param srcImage see {@link #setSourceImage} for description
56 * @param x see {@link #setSourceImage} for description
58 * @param y see {@link #setSourceImage} for description
60 * @param width see {@link #setSourceImage} for description
62 * @param pitch see {@link #setSourceImage} for description
64 * @param height see {@link #setSourceImage} for description
66 * @param pixelFormat pixel format of the source image (one of
67 * {@link TJ#PF_RGB TJ.PF_*})
69 public TJCompressor(byte[] srcImage, int x, int y, int width, int pitch,
70 int height, int pixelFormat) throws TJException {
71 setSourceImage(srcImage, x, y, width, pitch, height, pixelFormat);
75 * Create a TurboJPEG compressor instance and associate the 8-bit-per-sample
76 * packed-pixel source image stored in <code>srcImage</code> with the newly
80 * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
83 * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
86 * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
89 * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
92 * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
94 public TJCompressor(BufferedImage srcImage, int x, int y, int width,
95 int height) throws TJException {
96 setSourceImage(srcImage, x, y, width, height);
100 * Associate an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK source
101 * image with this compressor instance.
103 * @param srcImage buffer containing a packed-pixel RGB, grayscale, or CMYK
104 * source image to be compressed or encoded. This buffer is not modified.
106 * @param x x offset (in pixels) of the region in the source image from which
107 * the JPEG or YUV image should be compressed/encoded
109 * @param y y offset (in pixels) of the region in the source image from which
110 * the JPEG or YUV image should be compressed/encoded
112 * @param width width (in pixels) of the region in the source image from
113 * which the JPEG or YUV image should be compressed/encoded
115 * @param pitch bytes per row in the source image. Normally this should be
116 * <code>width * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>,
117 * if the source image is unpadded. (Setting this parameter to 0 is the
118 * equivalent of setting it to <code>width *
119 * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>.) However,
120 * you can also use this parameter to specify the row alignment/padding of
121 * the source image, to skip rows, or to compress/encode a JPEG or YUV image
122 * from a specific region of a larger source image.
124 * @param height height (in pixels) of the region in the source image from
125 * which the JPEG or YUV image should be compressed/encoded
127 * @param pixelFormat pixel format of the source image (one of
128 * {@link TJ#PF_RGB TJ.PF_*})
130 public void setSourceImage(byte[] srcImage, int x, int y, int width,
131 int pitch, int height, int pixelFormat)
133 if (handle == 0) init();
134 if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
135 pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
136 throw new IllegalArgumentException("Invalid argument in setSourceImage()");
140 srcPitch = width * TJ.getPixelSize(pixelFormat);
144 srcPixelFormat = pixelFormat;
154 * Associate a 12-bit-per-sample packed-pixel RGB, grayscale, or CMYK source
155 * image with this compressor instance. Note that 12-bit-per-sample
156 * packed-pixel source images can only be compressed into 12-bit-per-sample
159 * @param srcImage buffer containing a packed-pixel RGB, grayscale, or CMYK
160 * source image to be compressed. This buffer is not modified.
162 * @param x x offset (in pixels) of the region in the source image from which
163 * the JPEG image should be compressed
165 * @param y y offset (in pixels) of the region in the source image from which
166 * the JPEG image should be compressed
168 * @param width width (in pixels) of the region in the source image from
169 * which the JPEG image should be compressed
171 * @param pitch samples per row in the source image. Normally this should be
172 * <code>width * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>,
173 * if the source image is unpadded. (Setting this parameter to 0 is the
174 * equivalent of setting it to <code>width *
175 * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>.) However,
176 * you can also use this parameter to specify the row alignment/padding of
177 * the source image, to skip rows, or to compress a JPEG image from a
178 * specific region of a larger source image.
180 * @param height height (in pixels) of the region in the source image from
181 * which the JPEG image should be compressed
183 * @param pixelFormat pixel format of the source image (one of
184 * {@link TJ#PF_RGB TJ.PF_*})
186 public void setSourceImage12(short[] srcImage, int x, int y, int width,
187 int pitch, int height, int pixelFormat)
189 if (handle == 0) init();
190 if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
191 pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
192 throw new IllegalArgumentException("Invalid argument in setSourceImage()");
196 srcPitch = width * TJ.getPixelSize(pixelFormat);
200 srcPixelFormat = pixelFormat;
210 * Associate a 16-bit-per-sample packed-pixel RGB, grayscale, or CMYK source
211 * image with this compressor instance. Note that 16-bit-per-sample
212 * packed-pixel source images can only be compressed into 16-bit-per-sample
213 * lossless JPEG images.
215 * @param srcImage buffer containing a packed-pixel RGB, grayscale, or CMYK
216 * source image to be compressed. This buffer is not modified.
218 * @param x x offset (in pixels) of the region in the source image from which
219 * the JPEG image should be compressed
221 * @param y y offset (in pixels) of the region in the source image from which
222 * the JPEG image should be compressed
224 * @param width width (in pixels) of the region in the source image from
225 * which the JPEG image should be compressed
227 * @param pitch samples per row in the source image. Normally this should be
228 * <code>width * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>,
229 * if the source image is unpadded. (Setting this parameter to 0 is the
230 * equivalent of setting it to <code>width *
231 * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat)</code>.) However,
232 * you can also use this parameter to specify the row alignment/padding of
233 * the source image, to skip rows, or to compress a JPEG image from a
234 * specific region of a larger source image.
236 * @param height height (in pixels) of the region in the source image from
237 * which the JPEG image should be compressed
239 * @param pixelFormat pixel format of the source image (one of
240 * {@link TJ#PF_RGB TJ.PF_*})
242 public void setSourceImage16(short[] srcImage, int x, int y, int width,
243 int pitch, int height, int pixelFormat)
245 if (handle == 0) init();
246 if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
247 pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
248 throw new IllegalArgumentException("Invalid argument in setSourceImage()");
252 srcPitch = width * TJ.getPixelSize(pixelFormat);
256 srcPixelFormat = pixelFormat;
266 * Associate an 8-bit-per-pixel packed-pixel RGB or grayscale source image
267 * with this compressor instance.
269 * @param srcImage a <code>BufferedImage</code> instance containing a
270 * packed-pixel RGB or grayscale source image to be compressed or encoded.
271 * This image is not modified.
273 * @param x x offset (in pixels) of the region in the source image from which
274 * the JPEG or YUV image should be compressed/encoded
276 * @param y y offset (in pixels) of the region in the source image from which
277 * the JPEG or YUV image should be compressed/encoded
279 * @param width width (in pixels) of the region in the source image from
280 * which the JPEG or YUV image should be compressed/encoded (0 = use the
281 * width of the source image)
283 * @param height height (in pixels) of the region in the source image from
284 * which the JPEG or YUV image should be compressed/encoded (0 = use the
285 * height of the source image)
287 public void setSourceImage(BufferedImage srcImage, int x, int y, int width,
288 int height) throws TJException {
289 if (handle == 0) init();
290 if (srcImage == null || x < 0 || y < 0 || width < 0 || height < 0)
291 throw new IllegalArgumentException("Invalid argument in setSourceImage()");
294 srcWidth = (width == 0) ? srcImage.getWidth() : width;
295 srcHeight = (height == 0) ? srcImage.getHeight() : height;
296 if (x + width > srcImage.getWidth() || y + height > srcImage.getHeight())
297 throw new IllegalArgumentException("Compression region exceeds the bounds of the source image");
300 boolean intPixels = false;
301 if (byteOrder == null)
302 byteOrder = ByteOrder.nativeOrder();
303 switch (srcImage.getType()) {
304 case BufferedImage.TYPE_3BYTE_BGR:
305 pixelFormat = TJ.PF_BGR; break;
306 case BufferedImage.TYPE_4BYTE_ABGR:
307 case BufferedImage.TYPE_4BYTE_ABGR_PRE:
308 pixelFormat = TJ.PF_XBGR; break;
309 case BufferedImage.TYPE_BYTE_GRAY:
310 pixelFormat = TJ.PF_GRAY; break;
311 case BufferedImage.TYPE_INT_BGR:
312 if (byteOrder == ByteOrder.BIG_ENDIAN)
313 pixelFormat = TJ.PF_XBGR;
315 pixelFormat = TJ.PF_RGBX;
316 intPixels = true; break;
317 case BufferedImage.TYPE_INT_RGB:
318 case BufferedImage.TYPE_INT_ARGB:
319 case BufferedImage.TYPE_INT_ARGB_PRE:
320 if (byteOrder == ByteOrder.BIG_ENDIAN)
321 pixelFormat = TJ.PF_XRGB;
323 pixelFormat = TJ.PF_BGRX;
324 intPixels = true; break;
326 throw new IllegalArgumentException("Unsupported BufferedImage format");
328 srcPixelFormat = pixelFormat;
330 WritableRaster wr = srcImage.getRaster();
332 SinglePixelPackedSampleModel sm =
333 (SinglePixelPackedSampleModel)srcImage.getSampleModel();
334 srcStride = sm.getScanlineStride();
335 DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
336 srcBufInt = db.getData();
339 ComponentSampleModel sm =
340 (ComponentSampleModel)srcImage.getSampleModel();
341 int pixelSize = sm.getPixelStride();
342 if (pixelSize != TJ.getPixelSize(pixelFormat))
343 throw new IllegalArgumentException("Inconsistency between pixel format and pixel size in BufferedImage");
344 srcPitch = sm.getScanlineStride();
345 DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
346 srcBuf8 = db.getData();
353 * Associate an 8-bit-per-sample planar YUV source image with this compressor
354 * instance. This method sets {@link TJ#PARAM_SUBSAMP} to the chrominance
355 * subsampling level of the source image.
357 * @param srcImage planar YUV source image to be compressed. This image is
360 public void setSourceImage(YUVImage srcImage) throws TJException {
361 if (handle == 0) init();
362 if (srcImage == null)
363 throw new IllegalArgumentException("Invalid argument in setSourceImage()");
364 srcYUVImage = srcImage;
365 set(TJ.PARAM_SUBSAMP, srcImage.getSubsamp());
371 * Set the value of a compression parameter.
373 * @param param one of {@link TJ#PARAM_STOPONWARNING TJ.PARAM_*}
375 * @param value value of the compression parameter (refer to
376 * {@link TJ#PARAM_STOPONWARNING parameter documentation})
378 public native void set(int param, int value);
381 * Get the value of a compression parameter.
383 * @param param one of {@link TJ#PARAM_STOPONWARNING TJ.PARAM_*}
385 * @return the value of the specified compression parameter, or -1 if the
388 public native int get(int param);
392 * <code>{@link #set set}({@link TJ#PARAM_SUBSAMP}, ...)</code> instead.
394 @SuppressWarnings("checkstyle:JavadocMethod")
396 public void setSubsamp(int subsamp) {
397 if (subsamp < 0 || subsamp >= TJ.NUMSAMP)
398 throw new IllegalArgumentException("Invalid argument in setSubsamp()");
399 set(TJ.PARAM_SUBSAMP, subsamp);
404 * <code>{@link #set set}({@link TJ#PARAM_QUALITY}, ...)</code> instead.
406 @SuppressWarnings("checkstyle:JavadocMethod")
408 public void setJPEGQuality(int quality) {
409 if (quality < 1 || quality > 100)
410 throw new IllegalArgumentException("Invalid argument in setJPEGQuality()");
411 set(TJ.PARAM_QUALITY, quality);
415 * Compress the packed-pixel or planar YUV source image associated with this
416 * compressor instance and output a JPEG image to the given destination
419 * @param dstBuf buffer that will receive the JPEG image. Use
420 * {@link TJ#bufSize TJ.bufSize()} to determine the maximum size for this
421 * buffer based on the source image's width and height and the desired level
422 * of chrominance subsampling (see {@link TJ#PARAM_SUBSAMP}.)
424 public void compress(byte[] dstBuf) throws TJException {
426 throw new IllegalArgumentException("Invalid argument in compress()");
428 if (srcYUVImage != null) {
430 if (get(TJ.PARAM_SUBSAMP) != srcYUVImage.getSubsamp())
431 throw new IllegalStateException("TJ.PARAM_SUBSAMP must match subsampling level of YUV image");
432 compressedSize = compressFromYUV8(srcYUVImage.getPlanes(),
433 srcYUVImage.getOffsets(),
434 srcYUVImage.getWidth(),
435 srcYUVImage.getStrides(),
436 srcYUVImage.getHeight(), dstBuf);
437 } else if (srcBuf8 != null)
438 compressedSize = compress8(srcBuf8, srcX, srcY, srcWidth, srcPitch,
439 srcHeight, srcPixelFormat, dstBuf);
440 else if (srcBuf12 != null)
441 compressedSize = compress12(srcBuf12, srcX, srcY, srcWidth, srcPitch,
442 srcHeight, srcPixelFormat, dstBuf);
443 else if (srcBuf16 != null)
444 compressedSize = compress16(srcBuf16, srcX, srcY, srcWidth, srcPitch,
445 srcHeight, srcPixelFormat, dstBuf);
446 else if (srcBufInt != null)
447 compressedSize = compress8(srcBufInt, srcX, srcY, srcWidth, srcStride,
448 srcHeight, srcPixelFormat, dstBuf);
450 throw new IllegalStateException("No source image is associated with this instance");
454 * @deprecated Use {@link #set set()} and {@link #compress(byte[])} instead.
456 @SuppressWarnings("checkstyle:JavadocMethod")
458 public void compress(byte[] dstBuf, int flags) throws TJException {
460 throw new IllegalArgumentException("Invalid argument in compress()");
466 * Compress the packed-pixel or planar YUV source image associated with this
467 * compressor instance and return a buffer containing a JPEG image.
469 * @return a buffer containing a JPEG image. The length of this buffer will
470 * not be equal to the size of the JPEG image. Use
471 * {@link #getCompressedSize} to obtain the size of the JPEG image.
473 public byte[] compress() throws TJException {
475 if (srcYUVImage != null) {
476 buf = new byte[TJ.bufSize(srcYUVImage.getWidth(),
477 srcYUVImage.getHeight(),
478 srcYUVImage.getSubsamp())];
481 int subsamp = get(TJ.PARAM_SUBSAMP);
482 buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
489 * @deprecated Use {@link #set set()} and {@link #compress()} instead.
491 @SuppressWarnings("checkstyle:JavadocMethod")
493 public byte[] compress(int flags) throws TJException {
499 * Encode the 8-bit-per-sample packed-pixel source image associated with this
500 * compressor instance into an 8-bit-per-sample planar YUV image and store it
501 * in the given {@link YUVImage} instance. This method performs color
502 * conversion (which is accelerated in the libjpeg-turbo implementation) but
503 * does not execute any of the other steps in the JPEG compression process.
504 * Encoding CMYK source images into YUV images is not supported. This method
505 * sets {@link TJ#PARAM_SUBSAMP} to the chrominance subsampling level of the
508 * @param dstImage {@link YUVImage} instance that will receive the planar YUV
511 public void encodeYUV(YUVImage dstImage) throws TJException {
512 if (dstImage == null)
513 throw new IllegalArgumentException("Invalid argument in encodeYUV()");
514 if (srcBuf8 == null && srcBufInt == null)
515 throw new IllegalStateException("No 8-bit-per-sample source image is associated with this instance");
516 if (srcYUVImage != null)
517 throw new IllegalStateException("Source image is not correct type");
518 if (srcWidth != dstImage.getWidth() || srcHeight != dstImage.getHeight())
519 throw new IllegalStateException("Destination image is the wrong size");
520 set(TJ.PARAM_SUBSAMP, dstImage.getSubsamp());
522 if (srcBufInt != null) {
523 encodeYUV8(srcBufInt, srcX, srcY, srcWidth, srcStride, srcHeight,
524 srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
525 dstImage.getStrides());
527 encodeYUV8(srcBuf8, srcX, srcY, srcWidth, srcPitch, srcHeight,
528 srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
529 dstImage.getStrides());
535 * @deprecated Use {@link #set set()} and {@link #encodeYUV(YUVImage)}
538 @SuppressWarnings("checkstyle:JavadocMethod")
540 public void encodeYUV(YUVImage dstImage, int flags) throws TJException {
542 throw new IllegalArgumentException("Invalid argument in encodeYUV()");
549 * Encode the 8-bit-per-sample packed-pixel source image associated with this
550 * compressor instance into an 8-bit-per-sample unified planar YUV image and
551 * return a {@link YUVImage} instance containing the encoded image. This
552 * method performs color conversion (which is accelerated in the
553 * libjpeg-turbo implementation) but does not execute any of the other steps
554 * in the JPEG compression process. Encoding CMYK source images into YUV
555 * images is not supported.
557 * @param align row alignment (in bytes) of the YUV image (must be a power of
558 * 2.) Setting this parameter to n will cause each row in each plane of the
559 * YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.)
561 * @return a {@link YUVImage} instance containing the unified planar YUV
564 public YUVImage encodeYUV(int align) throws TJException {
565 if (srcBuf8 == null && srcBufInt == null)
566 throw new IllegalStateException("No 8-bit-per-sample source image is associated with this instance");
568 if (align < 1 || ((align & (align - 1)) != 0))
569 throw new IllegalStateException("Invalid argument in encodeYUV()");
570 YUVImage dstYUVImage = new YUVImage(srcWidth, align, srcHeight,
571 get(TJ.PARAM_SUBSAMP));
572 encodeYUV(dstYUVImage);
577 * @deprecated Use {@link #set set()} and {@link #encodeYUV(int)} instead.
579 @SuppressWarnings("checkstyle:JavadocMethod")
581 public YUVImage encodeYUV(int align, int flags) throws TJException {
583 return encodeYUV(align);
587 * Encode the 8-bit-per-sample packed-pixel source image associated with this
588 * compressor instance into separate 8-bit-per-sample Y, U (Cb), and V (Cr)
589 * image planes and return a {@link YUVImage} instance containing the encoded
590 * image planes. This method performs color conversion (which is accelerated
591 * in the libjpeg-turbo implementation) but does not execute any of the other
592 * steps in the JPEG compression process. Encoding CMYK source images into
593 * YUV images is not supported.
595 * @param strides an array of integers, each specifying the number of bytes
596 * per row in the corresponding plane of the YUV source image. Setting the
597 * stride for any plane to 0 is the same as setting it to the plane width
598 * (see {@link YUVImage}.) If <code>strides</code> is null, then the strides
599 * for all planes will be set to their respective plane widths. You can
600 * adjust the strides in order to add an arbitrary amount of row padding to
603 * @return a {@link YUVImage} instance containing the encoded image planes
605 public YUVImage encodeYUV(int[] strides) throws TJException {
606 if (srcBuf8 == null && srcBufInt == null)
607 throw new IllegalStateException("No 8-bit-per-sample source image is associated with this instance");
609 YUVImage dstYUVImage = new YUVImage(srcWidth, strides, srcHeight,
610 get(TJ.PARAM_SUBSAMP));
611 encodeYUV(dstYUVImage);
616 * @deprecated Use {@link #set set()} and {@link #encodeYUV(int[])} instead.
618 @SuppressWarnings("checkstyle:JavadocMethod")
620 public YUVImage encodeYUV(int[] strides, int flags) throws TJException {
622 return encodeYUV(strides);
626 * Returns the size of the image (in bytes) generated by the most recent
627 * compress operation.
629 * @return the size of the image (in bytes) generated by the most recent
630 * compress operation.
632 public int getCompressedSize() {
633 return compressedSize;
637 * Free the native structures associated with this compressor instance.
640 public void close() throws TJException {
645 @SuppressWarnings("checkstyle:DesignForExtension")
647 protected void finalize() throws Throwable {
650 } catch (TJException e) {
656 @SuppressWarnings("deprecation")
657 private void processFlags(int flags) {
658 set(TJ.PARAM_BOTTOMUP, (flags & TJ.FLAG_BOTTOMUP) != 0 ? 1 : 0);
660 if (get(TJ.PARAM_QUALITY) >= 96 || (flags & TJ.FLAG_ACCURATEDCT) != 0)
661 set(TJ.PARAM_FASTDCT, 0);
663 set(TJ.PARAM_FASTDCT, 1);
665 set(TJ.PARAM_STOPONWARNING, (flags & TJ.FLAG_STOPONWARNING) != 0 ? 1 : 0);
666 set(TJ.PARAM_PROGRESSIVE, (flags & TJ.FLAG_PROGRESSIVE) != 0 ? 1 : 0);
669 private void checkSubsampling() {
670 if (get(TJ.PARAM_SUBSAMP) == TJ.SAMP_UNKNOWN)
671 throw new IllegalStateException("TJ.PARAM_SUBSAMP must be specified");
674 private native void init() throws TJException;
676 private native void destroy() throws TJException;
678 // JPEG size in bytes is returned
679 @SuppressWarnings("checkstyle:HiddenField")
680 private native int compress8(byte[] srcBuf, int x, int y, int width,
681 int pitch, int height, int pixelFormat, byte[] jpegBuf) throws TJException;
683 @SuppressWarnings("checkstyle:HiddenField")
684 private native int compress12(short[] srcBuf, int x, int y, int width,
685 int pitch, int height, int pixelFormat, byte[] jpegBuf) throws TJException;
687 @SuppressWarnings("checkstyle:HiddenField")
688 private native int compress16(short[] srcBuf, int x, int y, int width,
689 int pitch, int height, int pixelFormat, byte[] jpegBuf) throws TJException;
691 @SuppressWarnings("checkstyle:HiddenField")
692 private native int compress8(int[] srcBuf, int x, int y, int width,
693 int stride, int height, int pixelFormat, byte[] jpegBuf)
696 @SuppressWarnings("checkstyle:HiddenField")
697 private native int compressFromYUV8(byte[][] srcPlanes, int[] srcOffsets,
698 int width, int[] srcStrides, int height, byte[] jpegBuf)
701 @SuppressWarnings("checkstyle:HiddenField")
702 private native void encodeYUV8(byte[] srcBuf, int x, int y, int width,
703 int pitch, int height, int pixelFormat, byte[][] dstPlanes,
704 int[] dstOffsets, int[] dstStrides) throws TJException;
706 @SuppressWarnings("checkstyle:HiddenField")
707 private native void encodeYUV8(int[] srcBuf, int x, int y, int width,
708 int srcStride, int height, int pixelFormat, byte[][] dstPlanes,
709 int[] dstOffsets, int[] dstStrides) throws TJException;
713 * Ugly hack alert. It isn't straightforward to load 12-bit-per-sample and
714 * 16-bit-per-sample images using the ImageIO and BufferedImage classes, and
715 * ImageIO doesn't support PBMPLUS files anyhow. This method accesses
716 * tj3LoadImage() through JNI and copies the pixel data between the C and
717 * Java heaps. Currently it is undocumented and used only by TJBench.
719 @SuppressWarnings("checkstyle:JavadocMethod")
720 public native Object loadImage(int precision, String fileName, int[] width,
721 int align, int[] height, int[] pixelFormat)
728 private long handle = 0;
729 private byte[] srcBuf8 = null;
730 private short[] srcBuf12 = null;
731 private short[] srcBuf16 = null;
732 private int[] srcBufInt = null;
733 private int srcWidth = 0;
734 private int srcHeight = 0;
735 private int srcX = -1;
736 private int srcY = -1;
737 private int srcPitch = 0;
738 private int srcStride = 0;
739 private int srcPixelFormat = -1;
740 private YUVImage srcYUVImage = null;
741 private int compressedSize = 0;
742 private ByteOrder byteOrder = null;