1/*
2 * Copyright (C)2011-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
29package org.libjpegturbo.turbojpeg;
30
31import java.awt.image.*;
32import java.nio.*;
33
34/**
35 * TurboJPEG compressor
36 */
37public class TJCompressor {
38
39  private static final String NO_ASSOC_ERROR =
40    "No source image is associated with this instance";
41
42  /**
43   * Create a TurboJPEG compressor instance.
44   */
45  public TJCompressor() throws Exception {
46    init();
47  }
48
49  /**
50   * Create a TurboJPEG compressor instance and associate the uncompressed
51   * source image stored in <code>srcImage</code> with the newly created
52   * instance.
53   *
54   * @param srcImage see {@link #setSourceImage} for description
55   *
56   * @param x see {@link #setSourceImage} for description
57   *
58   * @param y see {@link #setSourceImage} for description
59   *
60   * @param width see {@link #setSourceImage} for description
61   *
62   * @param pitch see {@link #setSourceImage} for description
63   *
64   * @param height see {@link #setSourceImage} for description
65   *
66   * @param pixelFormat pixel format of the source image (one of
67   * {@link TJ#PF_RGB TJ.PF_*})
68   */
69  public TJCompressor(byte[] srcImage, int x, int y, int width, int pitch,
70                      int height, int pixelFormat) throws Exception {
71    setSourceImage(srcImage, x, y, width, pitch, height, pixelFormat);
72  }
73
74  /**
75   * @deprecated Use
76   * {@link #TJCompressor(byte[], int, int, int, int, int, int)} instead.
77   */
78  @Deprecated
79  public TJCompressor(byte[] srcImage, int width, int pitch, int height,
80                      int pixelFormat) throws Exception {
81    setSourceImage(srcImage, width, pitch, height, pixelFormat);
82  }
83
84  /**
85   * Create a TurboJPEG compressor instance and associate the uncompressed
86   * source image stored in <code>srcImage</code> with the newly created
87   * instance.
88   *
89   * @param srcImage see
90   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
91   *
92   * @param x see
93   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
94   *
95   * @param y see
96   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
97   *
98   * @param width see
99   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
100   *
101   * @param height see
102   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
103   */
104  public TJCompressor(BufferedImage srcImage, int x, int y, int width,
105                      int height) throws Exception {
106    setSourceImage(srcImage, x, y, width, height);
107  }
108
109  /**
110   * Associate an uncompressed RGB, grayscale, or CMYK source image with this
111   * compressor instance.
112   *
113   * @param srcImage image buffer containing RGB, grayscale, or CMYK pixels to
114   * be compressed or encoded.  This buffer is not modified.
115   *
116   * @param x x offset (in pixels) of the region in the source image from which
117   * the JPEG or YUV image should be compressed/encoded
118   *
119   * @param y y offset (in pixels) of the region in the source image from which
120   * the JPEG or YUV image should be compressed/encoded
121   *
122   * @param width width (in pixels) of the region in the source image from
123   * which the JPEG or YUV image should be compressed/encoded
124   *
125   * @param pitch bytes per line of the source image.  Normally, this should be
126   * <code>width * TJ.pixelSize(pixelFormat)</code> if the source image is
127   * unpadded, but you can use this parameter to, for instance, specify that
128   * the scanlines in the source image are padded to a 4-byte boundary or to
129   * compress/encode a JPEG or YUV image from a region of a larger source
130   * image.  You can also be clever and use this parameter to skip lines, etc.
131   * Setting this parameter to 0 is the equivalent of setting it to
132   * <code>width * TJ.pixelSize(pixelFormat)</code>.
133   *
134   * @param height height (in pixels) of the region in the source image from
135   * which the JPEG or YUV image should be compressed/encoded
136   *
137   * @param pixelFormat pixel format of the source image (one of
138   * {@link TJ#PF_RGB TJ.PF_*})
139   */
140  public void setSourceImage(byte[] srcImage, int x, int y, int width,
141                             int pitch, int height, int pixelFormat)
142                             throws Exception {
143    if (handle == 0) init();
144    if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
145        pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
146      throw new Exception("Invalid argument in setSourceImage()");
147    srcBuf = srcImage;
148    srcWidth = width;
149    if (pitch == 0)
150      srcPitch = width * TJ.getPixelSize(pixelFormat);
151    else
152      srcPitch = pitch;
153    srcHeight = height;
154    srcPixelFormat = pixelFormat;
155    srcX = x;
156    srcY = y;
157    srcBufInt = null;
158    srcYUVImage = null;
159  }
160
161  /**
162   * @deprecated Use
163   * {@link #setSourceImage(byte[], int, int, int, int, int, int)} instead.
164   */
165  @Deprecated
166  public void setSourceImage(byte[] srcImage, int width, int pitch,
167                             int height, int pixelFormat) throws Exception {
168    setSourceImage(srcImage, 0, 0, width, pitch, height, pixelFormat);
169    srcX = srcY = -1;
170  }
171
172  /**
173   * Associate an uncompressed RGB or grayscale source image with this
174   * compressor instance.
175   *
176   * @param srcImage a <code>BufferedImage</code> instance containing RGB or
177   * grayscale pixels to be compressed or encoded.  This image is not modified.
178   *
179   * @param x x offset (in pixels) of the region in the source image from which
180   * the JPEG or YUV image should be compressed/encoded
181   *
182   * @param y y offset (in pixels) of the region in the source image from which
183   * the JPEG or YUV image should be compressed/encoded
184   *
185   * @param width width (in pixels) of the region in the source image from
186   * which the JPEG or YUV image should be compressed/encoded (0 = use the
187   * width of the source image)
188   *
189   * @param height height (in pixels) of the region in the source image from
190   * which the JPEG or YUV image should be compressed/encoded (0 = use the
191   * height of the source image)
192   */
193  public void setSourceImage(BufferedImage srcImage, int x, int y, int width,
194                             int height) throws Exception {
195    if (handle == 0) init();
196    if (srcImage == null || x < 0 || y < 0 || width < 0 || height < 0)
197      throw new Exception("Invalid argument in setSourceImage()");
198    srcX = x;
199    srcY = y;
200    srcWidth = (width == 0) ? srcImage.getWidth(): width;
201    srcHeight = (height == 0) ? srcImage.getHeight() : height;
202    if (x + width > srcImage.getWidth() || y + height > srcImage.getHeight())
203      throw new Exception("Compression region exceeds the bounds of the source image");
204
205    int pixelFormat;
206    boolean intPixels = false;
207    if (byteOrder == null)
208      byteOrder = ByteOrder.nativeOrder();
209    switch(srcImage.getType()) {
210      case BufferedImage.TYPE_3BYTE_BGR:
211        pixelFormat = TJ.PF_BGR;  break;
212      case BufferedImage.TYPE_4BYTE_ABGR:
213      case BufferedImage.TYPE_4BYTE_ABGR_PRE:
214        pixelFormat = TJ.PF_XBGR;  break;
215      case BufferedImage.TYPE_BYTE_GRAY:
216        pixelFormat = TJ.PF_GRAY;  break;
217      case BufferedImage.TYPE_INT_BGR:
218        if (byteOrder == ByteOrder.BIG_ENDIAN)
219          pixelFormat = TJ.PF_XBGR;
220        else
221          pixelFormat = TJ.PF_RGBX;
222        intPixels = true;  break;
223      case BufferedImage.TYPE_INT_RGB:
224      case BufferedImage.TYPE_INT_ARGB:
225      case BufferedImage.TYPE_INT_ARGB_PRE:
226        if (byteOrder == ByteOrder.BIG_ENDIAN)
227          pixelFormat = TJ.PF_XRGB;
228        else
229          pixelFormat = TJ.PF_BGRX;
230        intPixels = true;  break;
231      default:
232        throw new Exception("Unsupported BufferedImage format");
233    }
234    srcPixelFormat = pixelFormat;
235
236    WritableRaster wr = srcImage.getRaster();
237    if (intPixels) {
238      SinglePixelPackedSampleModel sm =
239        (SinglePixelPackedSampleModel)srcImage.getSampleModel();
240      srcStride = sm.getScanlineStride();
241      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
242      srcBufInt = db.getData();
243      srcBuf = null;
244    } else {
245      ComponentSampleModel sm =
246        (ComponentSampleModel)srcImage.getSampleModel();
247      int pixelSize = sm.getPixelStride();
248      if (pixelSize != TJ.getPixelSize(pixelFormat))
249        throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
250      srcPitch = sm.getScanlineStride();
251      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
252      srcBuf = db.getData();
253      srcBufInt = null;
254    }
255    srcYUVImage = null;
256  }
257
258  /**
259   * Associate an uncompressed YUV planar source image with this compressor
260   * instance.
261   *
262   * @param srcImage YUV planar image to be compressed.  This image is not
263   * modified.
264   */
265  public void setSourceImage(YUVImage srcImage) throws Exception {
266    if (handle == 0) init();
267    if (srcImage == null)
268      throw new Exception("Invalid argument in setSourceImage()");
269    srcYUVImage = srcImage;
270    srcBuf = null;
271    srcBufInt = null;
272  }
273
274  /**
275   * Set the level of chrominance subsampling for subsequent compress/encode
276   * operations.  When pixels are converted from RGB to YCbCr (see
277   * {@link TJ#CS_YCbCr}) or from CMYK to YCCK (see {@link TJ#CS_YCCK}) as part
278   * of the JPEG compression process, some of the Cb and Cr (chrominance)
279   * components can be discarded or averaged together to produce a smaller
280   * image with little perceptible loss of image clarity (the human eye is more
281   * sensitive to small changes in brightness than to small changes in color.)
282   * This is called "chrominance subsampling".
283   * <p>
284   * NOTE: This method has no effect when compressing a JPEG image from a YUV
285   * planar source.  In that case, the level of chrominance subsampling in
286   * the JPEG image is determined by the source.  Further, this method has no
287   * effect when encoding to a pre-allocated {@link YUVImage} instance.  In
288   * that case, the level of chrominance subsampling is determined by the
289   * destination.
290   *
291   * @param newSubsamp the level of chrominance subsampling to use in
292   * subsequent compress/encode oeprations (one of
293   * {@link TJ#SAMP_444 TJ.SAMP_*})
294   */
295  public void setSubsamp(int newSubsamp) throws Exception {
296    if (newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP)
297      throw new Exception("Invalid argument in setSubsamp()");
298    subsamp = newSubsamp;
299  }
300
301  /**
302   * Set the JPEG image quality level for subsequent compress operations.
303   *
304   * @param quality the new JPEG image quality level (1 to 100, 1 = worst,
305   * 100 = best)
306   */
307  public void setJPEGQuality(int quality) throws Exception {
308    if (quality < 1 || quality > 100)
309      throw new Exception("Invalid argument in setJPEGQuality()");
310    jpegQuality = quality;
311  }
312
313  /**
314   * Compress the uncompressed source image associated with this compressor
315   * instance and output a JPEG image to the given destination buffer.
316   *
317   * @param dstBuf buffer that will receive the JPEG image.  Use
318   * {@link TJ#bufSize} to determine the maximum size for this buffer based on
319   * the source image's width and height and the desired level of chrominance
320   * subsampling.
321   *
322   * @param flags the bitwise OR of one or more of
323   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
324   */
325  public void compress(byte[] dstBuf, int flags) throws Exception {
326    if (dstBuf == null || flags < 0)
327      throw new Exception("Invalid argument in compress()");
328    if (srcBuf == null && srcBufInt == null && srcYUVImage == null)
329      throw new Exception(NO_ASSOC_ERROR);
330    if (jpegQuality < 0)
331      throw new Exception("JPEG Quality not set");
332    if (subsamp < 0 && srcYUVImage == null)
333      throw new Exception("Subsampling level not set");
334
335    if (srcYUVImage != null)
336      compressedSize = compressFromYUV(srcYUVImage.getPlanes(),
337                                       srcYUVImage.getOffsets(),
338                                       srcYUVImage.getWidth(),
339                                       srcYUVImage.getStrides(),
340                                       srcYUVImage.getHeight(),
341                                       srcYUVImage.getSubsamp(),
342                                       dstBuf, jpegQuality, flags);
343    else if (srcBuf != null) {
344      if (srcX >= 0 && srcY >= 0)
345        compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch,
346                                  srcHeight, srcPixelFormat, dstBuf, subsamp,
347                                  jpegQuality, flags);
348      else
349        compressedSize = compress(srcBuf, srcWidth, srcPitch, srcHeight,
350                                  srcPixelFormat, dstBuf, subsamp, jpegQuality,
351                                  flags);
352    } else if (srcBufInt != null) {
353      if (srcX >= 0 && srcY >= 0)
354        compressedSize = compress(srcBufInt, srcX, srcY, srcWidth, srcStride,
355                                  srcHeight, srcPixelFormat, dstBuf, subsamp,
356                                  jpegQuality, flags);
357      else
358        compressedSize = compress(srcBufInt, srcWidth, srcStride, srcHeight,
359                                  srcPixelFormat, dstBuf, subsamp, jpegQuality,
360                                  flags);
361    }
362  }
363
364  /**
365   * Compress the uncompressed source image associated with this compressor
366   * instance and return a buffer containing a JPEG image.
367   *
368   * @param flags the bitwise OR of one or more of
369   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
370   *
371   * @return a buffer containing a JPEG image.  The length of this buffer will
372   * not be equal to the size of the JPEG image.  Use {@link
373   * #getCompressedSize} to obtain the size of the JPEG image.
374   */
375  public byte[] compress(int flags) throws Exception {
376    if (srcWidth < 1 || srcHeight < 1)
377      throw new Exception(NO_ASSOC_ERROR);
378    byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
379    compress(buf, flags);
380    return buf;
381  }
382
383  /**
384   * @deprecated Use
385   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
386   * {@link #compress(byte[], int)} instead.
387   */
388  @Deprecated
389  public void compress(BufferedImage srcImage, byte[] dstBuf, int flags)
390                       throws Exception {
391    setSourceImage(srcImage, 0, 0, 0, 0);
392    compress(dstBuf, flags);
393  }
394
395  /**
396   * @deprecated Use
397   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
398   * {@link #compress(int)} instead.
399   */
400  @Deprecated
401  public byte[] compress(BufferedImage srcImage, int flags) throws Exception {
402    setSourceImage(srcImage, 0, 0, 0, 0);
403    return compress(flags);
404  }
405
406  /**
407   * Encode the uncompressed source image associated with this compressor
408   * instance into a YUV planar image and store it in the given
409   * <code>YUVImage</code> instance.   This method uses the accelerated color
410   * conversion routines in TurboJPEG's underlying codec but does not execute
411   * any of the other steps in the JPEG compression process.  Encoding
412   * CMYK source images to YUV is not supported.
413   *
414   * @param dstImage {@link YUVImage} instance that will receive the YUV planar
415   * image
416   *
417   * @param flags the bitwise OR of one or more of
418   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
419   */
420  public void encodeYUV(YUVImage dstImage, int flags) throws Exception {
421    if (dstImage == null || flags < 0)
422      throw new Exception("Invalid argument in encodeYUV()");
423    if (srcBuf == null && srcBufInt == null)
424      throw new Exception(NO_ASSOC_ERROR);
425    if (srcYUVImage != null)
426      throw new Exception("Source image is not correct type");
427    if (subsamp < 0)
428      throw new Exception("Subsampling level not set");
429    if (srcWidth != dstImage.getWidth() || srcHeight != dstImage.getHeight())
430      throw new Exception("Destination image is the wrong size");
431
432    if (srcBufInt != null) {
433      encodeYUV(srcBufInt, srcX, srcY, srcWidth, srcStride, srcHeight,
434                srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
435                dstImage.getStrides(), dstImage.getSubsamp(), flags);
436    } else {
437      encodeYUV(srcBuf, srcX, srcY, srcWidth, srcPitch, srcHeight,
438                srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
439                dstImage.getStrides(), dstImage.getSubsamp(), flags);
440    }
441    compressedSize = 0;
442  }
443
444  /**
445   * @deprecated Use {@link #encodeYUV(YUVImage, int)} instead.
446   */
447  @Deprecated
448  public void encodeYUV(byte[] dstBuf, int flags) throws Exception {
449    if(dstBuf == null)
450      throw new Exception("Invalid argument in encodeYUV()");
451    if (srcWidth < 1 || srcHeight < 1)
452      throw new Exception(NO_ASSOC_ERROR);
453    if (subsamp < 0)
454      throw new Exception("Subsampling level not set");
455    YUVImage yuvImage = new YUVImage(dstBuf, srcWidth, 4, srcHeight, subsamp);
456    encodeYUV(yuvImage, flags);
457  }
458
459  /**
460   * Encode the uncompressed source image associated with this compressor
461   * instance into a unified YUV planar image buffer and return a
462   * <code>YUVImage</code> instance containing the encoded image.  This method
463   * uses the accelerated color conversion routines in TurboJPEG's underlying
464   * codec but does not execute any of the other steps in the JPEG compression
465   * process.  Encoding CMYK source images to YUV is not supported.
466   *
467   * @param pad the width of each line in each plane of the YUV image will be
468   * padded to the nearest multiple of this number of bytes (must be a power of
469   * 2.)
470   *
471   * @param flags the bitwise OR of one or more of
472   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
473   *
474   * @return a YUV planar image.
475   */
476  public YUVImage encodeYUV(int pad, int flags) throws Exception {
477    if (srcWidth < 1 || srcHeight < 1)
478      throw new Exception(NO_ASSOC_ERROR);
479    if (subsamp < 0)
480      throw new Exception("Subsampling level not set");
481    if(pad < 1 || ((pad & (pad - 1)) != 0))
482      throw new Exception("Invalid argument in encodeYUV()");
483    YUVImage yuvImage = new YUVImage(srcWidth, pad, srcHeight, subsamp);
484    encodeYUV(yuvImage, flags);
485    return yuvImage;
486  }
487
488  /**
489   * Encode the uncompressed source image associated with this compressor
490   * instance into separate Y, U (Cb), and V (Cr) image planes and return a
491   * <code>YUVImage</code> instance containing the encoded image planes.  This
492   * method uses the accelerated color conversion routines in TurboJPEG's
493   * underlying codec but does not execute any of the other steps in the JPEG
494   * compression process.  Encoding CMYK source images to YUV is not supported.
495   *
496   * @param strides an array of integers, each specifying the number of bytes
497   * per line in the corresponding plane of the output image.  Setting the
498   * stride for any plane to 0 is the same as setting it to the component width
499   * of the plane.  If <code>strides</code> is null, then the strides for all
500   * planes will be set to their respective component widths.  You can adjust
501   * the strides in order to add an arbitrary amount of line padding to each
502   * plane.
503   *
504   * @param flags the bitwise OR of one or more of
505   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
506   *
507   * @return a YUV planar image.
508   */
509  public YUVImage encodeYUV(int[] strides, int flags) throws Exception {
510    if (srcWidth < 1 || srcHeight < 1)
511      throw new Exception(NO_ASSOC_ERROR);
512    if (subsamp < 0)
513      throw new Exception("Subsampling level not set");
514    YUVImage yuvImage = new YUVImage(srcWidth, strides, srcHeight, subsamp);
515    encodeYUV(yuvImage, flags);
516    return yuvImage;
517  }
518
519  /**
520   * @deprecated Use {@link #encodeYUV(int, int)} instead.
521   */
522  @Deprecated
523  public byte[] encodeYUV(int flags) throws Exception {
524    if (srcWidth < 1 || srcHeight < 1)
525      throw new Exception(NO_ASSOC_ERROR);
526    if (subsamp < 0)
527      throw new Exception("Subsampling level not set");
528    YUVImage yuvImage = new YUVImage(srcWidth, 4, srcHeight, subsamp);
529    encodeYUV(yuvImage, flags);
530    return yuvImage.getBuf();
531  }
532
533  /**
534   * @deprecated Use
535   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
536   * {@link #encodeYUV(byte[], int)} instead.
537   */
538  @Deprecated
539  public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags)
540    throws Exception {
541    setSourceImage(srcImage, 0, 0, 0, 0);
542    encodeYUV(dstBuf, flags);
543  }
544
545  /**
546   * @deprecated Use
547   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
548   * {@link #encodeYUV(int, int)} instead.
549   */
550  @Deprecated
551  public byte[] encodeYUV(BufferedImage srcImage, int flags) throws Exception {
552    setSourceImage(srcImage, 0, 0, 0, 0);
553    return encodeYUV(flags);
554  }
555
556  /**
557   * Returns the size of the image (in bytes) generated by the most recent
558   * compress operation.
559   *
560   * @return the size of the image (in bytes) generated by the most recent
561   * compress operation.
562   */
563  public int getCompressedSize() {
564    return compressedSize;
565  }
566
567  /**
568   * Free the native structures associated with this compressor instance.
569   */
570  public void close() throws Exception {
571    if (handle != 0)
572      destroy();
573  }
574
575  protected void finalize() throws Throwable {
576    try {
577      close();
578    } catch(Exception e) {
579    } finally {
580      super.finalize();
581    }
582  };
583
584  private native void init() throws Exception;
585
586  private native void destroy() throws Exception;
587
588  // JPEG size in bytes is returned
589  private native int compress(byte[] srcBuf, int width, int pitch,
590    int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual,
591    int flags) throws Exception; // deprecated
592
593  private native int compress(byte[] srcBuf, int x, int y, int width,
594    int pitch, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp,
595    int jpegQual, int flags) throws Exception;
596
597  private native int compress(int[] srcBuf, int width, int stride,
598    int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual,
599    int flags) throws Exception; // deprecated
600
601  private native int compress(int[] srcBuf, int x, int y, int width,
602    int stride, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp,
603    int jpegQual, int flags) throws Exception;
604
605  private native int compressFromYUV(byte[][] srcPlanes, int[] srcOffsets,
606    int width, int[] srcStrides, int height, int subsamp, byte[] dstBuf,
607    int jpegQual, int flags)
608    throws Exception;
609
610  private native void encodeYUV(byte[] srcBuf, int width, int pitch,
611    int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
612    throws Exception; // deprecated
613
614  private native void encodeYUV(byte[] srcBuf, int x, int y, int width,
615    int pitch, int height, int pixelFormat, byte[][] dstPlanes,
616    int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
617    throws Exception;
618
619  private native void encodeYUV(int[] srcBuf, int width, int stride,
620    int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
621    throws Exception; // deprecated
622
623  private native void encodeYUV(int[] srcBuf, int x, int y, int width,
624    int srcStride, int height, int pixelFormat, byte[][] dstPlanes,
625    int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
626    throws Exception;
627
628  static {
629    TJLoader.load();
630  }
631
632  private long handle = 0;
633  private byte[] srcBuf = null;
634  private int[] srcBufInt = null;
635  private int srcWidth = 0;
636  private int srcHeight = 0;
637  private int srcX = -1;
638  private int srcY = -1;
639  private int srcPitch = 0;
640  private int srcStride = 0;
641  private int srcPixelFormat = -1;
642  private YUVImage srcYUVImage = null;
643  private int subsamp = -1;
644  private int jpegQuality = -1;
645  private int compressedSize = 0;
646  private int yuvPad = 4;
647  private ByteOrder byteOrder = null;
648};
649