mirror of
https://github.com/Cateners/tiny_computer.git
synced 2026-05-20 16:35:47 +08:00
Update code to v1.0.14 (10)
This commit is contained in:
601
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java
vendored
Normal file
601
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java
vendored
Normal file
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (C)2011-2013, 2017-2018, 2020-2021, 2023 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
/**
|
||||
* TurboJPEG utility class (cannot be instantiated)
|
||||
*/
|
||||
public final class TJ {
|
||||
|
||||
private TJ() {}
|
||||
|
||||
/**
|
||||
* The number of chrominance subsampling options
|
||||
*/
|
||||
public static final int NUMSAMP = 6;
|
||||
/**
|
||||
* 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG
|
||||
* or YUV image will contain one chrominance component for every pixel in the
|
||||
* source image.
|
||||
*/
|
||||
public static final int SAMP_444 = 0;
|
||||
/**
|
||||
* 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one
|
||||
* chrominance component for every 2x1 block of pixels in the source image.
|
||||
*/
|
||||
public static final int SAMP_422 = 1;
|
||||
/**
|
||||
* 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one
|
||||
* chrominance component for every 2x2 block of pixels in the source image.
|
||||
*/
|
||||
public static final int SAMP_420 = 2;
|
||||
/**
|
||||
* Grayscale. The JPEG or YUV image will contain no chrominance components.
|
||||
*/
|
||||
public static final int SAMP_GRAY = 3;
|
||||
/**
|
||||
* 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one
|
||||
* chrominance component for every 1x2 block of pixels in the source image.
|
||||
* Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
|
||||
*/
|
||||
public static final int SAMP_440 = 4;
|
||||
/**
|
||||
* 4:1:1 chrominance subsampling. The JPEG or YUV image will contain one
|
||||
* chrominance component for every 4x1 block of pixels in the source image.
|
||||
* JPEG images compressed with 4:1:1 subsampling will be almost exactly the
|
||||
* same size as those compressed with 4:2:0 subsampling, and in the
|
||||
* aggregate, both subsampling methods produce approximately the same
|
||||
* perceptual quality. However, 4:1:1 is better able to reproduce sharp
|
||||
* horizontal features. Note that 4:1:1 subsampling is not fully accelerated
|
||||
* in libjpeg-turbo.
|
||||
*/
|
||||
public static final int SAMP_411 = 5;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the MCU block width for the given level of chrominance
|
||||
* subsampling.
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling (one of
|
||||
* {@link #SAMP_444 SAMP_*})
|
||||
*
|
||||
* @return the MCU block width for the given level of chrominance
|
||||
* subsampling.
|
||||
*/
|
||||
public static int getMCUWidth(int subsamp) {
|
||||
checkSubsampling(subsamp);
|
||||
return MCU_WIDTH[subsamp];
|
||||
}
|
||||
|
||||
private static final int[] MCU_WIDTH = {
|
||||
8, 16, 16, 8, 8, 32
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the MCU block height for the given level of chrominance
|
||||
* subsampling.
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling (one of
|
||||
* {@link #SAMP_444 SAMP_*})
|
||||
*
|
||||
* @return the MCU block height for the given level of chrominance
|
||||
* subsampling.
|
||||
*/
|
||||
public static int getMCUHeight(int subsamp) {
|
||||
checkSubsampling(subsamp);
|
||||
return MCU_HEIGHT[subsamp];
|
||||
}
|
||||
|
||||
private static final int[] MCU_HEIGHT = {
|
||||
8, 8, 16, 8, 16, 8
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The number of pixel formats
|
||||
*/
|
||||
public static final int NUMPF = 12;
|
||||
/**
|
||||
* RGB pixel format. The red, green, and blue components in the image are
|
||||
* stored in 3-byte pixels in the order R, G, B from lowest to highest byte
|
||||
* address within each pixel.
|
||||
*/
|
||||
public static final int PF_RGB = 0;
|
||||
/**
|
||||
* BGR pixel format. The red, green, and blue components in the image are
|
||||
* stored in 3-byte pixels in the order B, G, R from lowest to highest byte
|
||||
* address within each pixel.
|
||||
*/
|
||||
public static final int PF_BGR = 1;
|
||||
/**
|
||||
* RGBX pixel format. The red, green, and blue components in the image are
|
||||
* stored in 4-byte pixels in the order R, G, B from lowest to highest byte
|
||||
* address within each pixel. The X component is ignored when compressing
|
||||
* and undefined when decompressing.
|
||||
*/
|
||||
public static final int PF_RGBX = 2;
|
||||
/**
|
||||
* BGRX pixel format. The red, green, and blue components in the image are
|
||||
* stored in 4-byte pixels in the order B, G, R from lowest to highest byte
|
||||
* address within each pixel. The X component is ignored when compressing
|
||||
* and undefined when decompressing.
|
||||
*/
|
||||
public static final int PF_BGRX = 3;
|
||||
/**
|
||||
* XBGR pixel format. The red, green, and blue components in the image are
|
||||
* stored in 4-byte pixels in the order R, G, B from highest to lowest byte
|
||||
* address within each pixel. The X component is ignored when compressing
|
||||
* and undefined when decompressing.
|
||||
*/
|
||||
public static final int PF_XBGR = 4;
|
||||
/**
|
||||
* XRGB pixel format. The red, green, and blue components in the image are
|
||||
* stored in 4-byte pixels in the order B, G, R from highest to lowest byte
|
||||
* address within each pixel. The X component is ignored when compressing
|
||||
* and undefined when decompressing.
|
||||
*/
|
||||
public static final int PF_XRGB = 5;
|
||||
/**
|
||||
* Grayscale pixel format. Each 1-byte pixel represents a luminance
|
||||
* (brightness) level from 0 to 255.
|
||||
*/
|
||||
public static final int PF_GRAY = 6;
|
||||
/**
|
||||
* RGBA pixel format. This is the same as {@link #PF_RGBX}, except that when
|
||||
* decompressing, the X byte is guaranteed to be 0xFF, which can be
|
||||
* interpreted as an opaque alpha channel.
|
||||
*/
|
||||
public static final int PF_RGBA = 7;
|
||||
/**
|
||||
* BGRA pixel format. This is the same as {@link #PF_BGRX}, except that when
|
||||
* decompressing, the X byte is guaranteed to be 0xFF, which can be
|
||||
* interpreted as an opaque alpha channel.
|
||||
*/
|
||||
public static final int PF_BGRA = 8;
|
||||
/**
|
||||
* ABGR pixel format. This is the same as {@link #PF_XBGR}, except that when
|
||||
* decompressing, the X byte is guaranteed to be 0xFF, which can be
|
||||
* interpreted as an opaque alpha channel.
|
||||
*/
|
||||
public static final int PF_ABGR = 9;
|
||||
/**
|
||||
* ARGB pixel format. This is the same as {@link #PF_XRGB}, except that when
|
||||
* decompressing, the X byte is guaranteed to be 0xFF, which can be
|
||||
* interpreted as an opaque alpha channel.
|
||||
*/
|
||||
public static final int PF_ARGB = 10;
|
||||
/**
|
||||
* CMYK pixel format. Unlike RGB, which is an additive color model used
|
||||
* primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive
|
||||
* color model used primarily for printing. In the CMYK color model, the
|
||||
* value of each color component typically corresponds to an amount of cyan,
|
||||
* magenta, yellow, or black ink that is applied to a white background. In
|
||||
* order to convert between CMYK and RGB, it is necessary to use a color
|
||||
* management system (CMS.) A CMS will attempt to map colors within the
|
||||
* printer's gamut to perceptually similar colors in the display's gamut and
|
||||
* vice versa, but the mapping is typically not 1:1 or reversible, nor can it
|
||||
* be defined with a simple formula. Thus, such a conversion is out of scope
|
||||
* for a codec library. However, the TurboJPEG API allows for compressing
|
||||
* packed-pixel CMYK images into YCCK JPEG images (see {@link #CS_YCCK}) and
|
||||
* decompressing YCCK JPEG images into packed-pixel CMYK images.
|
||||
*/
|
||||
public static final int PF_CMYK = 11;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the pixel size (in bytes) for the given pixel format.
|
||||
*
|
||||
* @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*})
|
||||
*
|
||||
* @return the pixel size (in bytes) for the given pixel format.
|
||||
*/
|
||||
public static int getPixelSize(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return PIXEL_SIZE[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] PIXEL_SIZE = {
|
||||
3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For the given pixel format, returns the number of bytes that the red
|
||||
* component is offset from the start of the pixel. For instance, if a pixel
|
||||
* of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
|
||||
* then the red component will be
|
||||
* <code>pixel[TJ.getRedOffset(TJ.PF_BGRX)]</code>.
|
||||
*
|
||||
* @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*})
|
||||
*
|
||||
* @return the red offset for the given pixel format, or -1 if the pixel
|
||||
* format does not have a red component.
|
||||
*/
|
||||
public static int getRedOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return RED_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] RED_OFFSET = {
|
||||
0, 2, 0, 2, 3, 1, -1, 0, 2, 3, 1, -1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For the given pixel format, returns the number of bytes that the green
|
||||
* component is offset from the start of the pixel. For instance, if a pixel
|
||||
* of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
|
||||
* then the green component will be
|
||||
* <code>pixel[TJ.getGreenOffset(TJ.PF_BGRX)]</code>.
|
||||
*
|
||||
* @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*})
|
||||
*
|
||||
* @return the green offset for the given pixel format, or -1 if the pixel
|
||||
* format does not have a green component.
|
||||
*/
|
||||
public static int getGreenOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return GREEN_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] GREEN_OFFSET = {
|
||||
1, 1, 1, 1, 2, 2, -1, 1, 1, 2, 2, -1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For the given pixel format, returns the number of bytes that the blue
|
||||
* component is offset from the start of the pixel. For instance, if a pixel
|
||||
* of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
|
||||
* then the blue component will be
|
||||
* <code>pixel[TJ.getBlueOffset(TJ.PF_BGRX)]</code>.
|
||||
*
|
||||
* @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*})
|
||||
*
|
||||
* @return the blue offset for the given pixel format, or -1 if the pixel
|
||||
* format does not have a blue component.
|
||||
*/
|
||||
public static int getBlueOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return BLUE_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] BLUE_OFFSET = {
|
||||
2, 0, 2, 0, 1, 3, -1, 2, 0, 1, 3, -1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For the given pixel format, returns the number of bytes that the alpha
|
||||
* component is offset from the start of the pixel. For instance, if a pixel
|
||||
* of format <code>TJ.PF_BGRA</code> is stored in <code>char pixel[]</code>,
|
||||
* then the alpha component will be
|
||||
* <code>pixel[TJ.getAlphaOffset(TJ.PF_BGRA)]</code>.
|
||||
*
|
||||
* @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*})
|
||||
*
|
||||
* @return the alpha offset for the given pixel format, or -1 if the pixel
|
||||
* format does not have a alpha component.
|
||||
*/
|
||||
public static int getAlphaOffset(int pixelFormat) {
|
||||
checkPixelFormat(pixelFormat);
|
||||
return ALPHA_OFFSET[pixelFormat];
|
||||
}
|
||||
|
||||
private static final int[] ALPHA_OFFSET = {
|
||||
-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The number of JPEG colorspaces
|
||||
*/
|
||||
public static final int NUMCS = 5;
|
||||
/**
|
||||
* RGB colorspace. When compressing the JPEG image, the R, G, and B
|
||||
* components in the source image are reordered into image planes, but no
|
||||
* colorspace conversion or subsampling is performed. RGB JPEG images can be
|
||||
* decompressed to packed-pixel images with any of the extended RGB or
|
||||
* grayscale pixel formats, but they cannot be decompressed to planar YUV
|
||||
* images.
|
||||
*/
|
||||
public static final int CS_RGB = 0;
|
||||
/**
|
||||
* YCbCr colorspace. YCbCr is not an absolute colorspace but rather a
|
||||
* mathematical transformation of RGB designed solely for storage and
|
||||
* transmission. YCbCr images must be converted to RGB before they can
|
||||
* actually be displayed. In the YCbCr colorspace, the Y (luminance)
|
||||
* component represents the black & white portion of the original image,
|
||||
* and the Cb and Cr (chrominance) components represent the color portion of
|
||||
* the original image. Originally, the analog equivalent of this
|
||||
* transformation allowed the same signal to drive both black & white and
|
||||
* color televisions, but JPEG images use YCbCr primarily because it allows
|
||||
* the color data to be optionally subsampled for the purposes of reducing
|
||||
* network or disk usage. YCbCr is the most common JPEG colorspace, and
|
||||
* YCbCr JPEG images can be compressed from and decompressed to packed-pixel
|
||||
* images with any of the extended RGB or grayscale pixel formats. YCbCr
|
||||
* JPEG images can also be compressed from and decompressed to planar YUV
|
||||
* images.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:ConstantName")
|
||||
public static final int CS_YCbCr = 1;
|
||||
/**
|
||||
* Grayscale colorspace. The JPEG image retains only the luminance data (Y
|
||||
* component), and any color data from the source image is discarded.
|
||||
* Grayscale JPEG images can be compressed from and decompressed to
|
||||
* packed-pixel images with any of the extended RGB or grayscale pixel
|
||||
* formats, or they can be compressed from and decompressed to planar YUV
|
||||
* images.
|
||||
*/
|
||||
public static final int CS_GRAY = 2;
|
||||
/**
|
||||
* CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K
|
||||
* components in the source image are reordered into image planes, but no
|
||||
* colorspace conversion or subsampling is performed. CMYK JPEG images can
|
||||
* only be decompressed to packed-pixel images with the CMYK pixel format.
|
||||
*/
|
||||
public static final int CS_CMYK = 3;
|
||||
/**
|
||||
* YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but
|
||||
* rather a mathematical transformation of CMYK designed solely for storage
|
||||
* and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be
|
||||
* reversibly transformed into YCCK, and as with YCbCr, the chrominance
|
||||
* components in the YCCK pixels can be subsampled without incurring major
|
||||
* perceptual loss. YCCK JPEG images can only be compressed from and
|
||||
* decompressed to packed-pixel images with the CMYK pixel format.
|
||||
*/
|
||||
public static final int CS_YCCK = 4;
|
||||
|
||||
|
||||
/**
|
||||
* Rows in the packed-pixel source/destination image are stored in bottom-up
|
||||
* (Windows, OpenGL) order rather than in top-down (X11) order.
|
||||
*/
|
||||
public static final int FLAG_BOTTOMUP = 2;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCEMMX = 8;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE = 16;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE2 = 32;
|
||||
@SuppressWarnings("checkstyle:JavadocVariable")
|
||||
@Deprecated
|
||||
public static final int FLAG_FORCESSE3 = 128;
|
||||
|
||||
/**
|
||||
* When decompressing an image that was compressed using chrominance
|
||||
* subsampling, use the fastest chrominance upsampling algorithm available.
|
||||
* The default is to use smooth upsampling, which creates a smooth transition
|
||||
* between neighboring chrominance components in order to reduce upsampling
|
||||
* artifacts in the decompressed image.
|
||||
*/
|
||||
public static final int FLAG_FASTUPSAMPLE = 256;
|
||||
/**
|
||||
* Use the fastest DCT/IDCT algorithm available. The default if this flag is
|
||||
* not specified is implementation-specific. For example, the implementation
|
||||
* of the TurboJPEG API in libjpeg-turbo uses the fast algorithm by default
|
||||
* when compressing, because this has been shown to have only a very slight
|
||||
* effect on accuracy, but it uses the accurate algorithm when decompressing,
|
||||
* because this has been shown to have a larger effect.
|
||||
*/
|
||||
public static final int FLAG_FASTDCT = 2048;
|
||||
/**
|
||||
* Use the most accurate DCT/IDCT algorithm available. The default if this
|
||||
* flag is not specified is implementation-specific. For example, the
|
||||
* implementation of the TurboJPEG API in libjpeg-turbo uses the fast
|
||||
* algorithm by default when compressing, because this has been shown to have
|
||||
* only a very slight effect on accuracy, but it uses the accurate algorithm
|
||||
* when decompressing, because this has been shown to have a larger effect.
|
||||
*/
|
||||
public static final int FLAG_ACCURATEDCT = 4096;
|
||||
/**
|
||||
* Immediately discontinue the current compression/decompression/transform
|
||||
* operation if a warning (non-fatal error) occurs. The default behavior is
|
||||
* to allow the operation to complete unless a fatal error is encountered.
|
||||
* <p>
|
||||
* NOTE: due to the design of the TurboJPEG Java API, only certain methods
|
||||
* (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods
|
||||
* with a void return type) will complete and leave the destination image in
|
||||
* a fully recoverable state after a non-fatal error occurs.
|
||||
*/
|
||||
public static final int FLAG_STOPONWARNING = 8192;
|
||||
/**
|
||||
* Use progressive entropy coding in JPEG images generated by compression and
|
||||
* transform operations. Progressive entropy coding will generally improve
|
||||
* compression relative to baseline entropy coding (the default), but it will
|
||||
* reduce compression and decompression performance considerably.
|
||||
*/
|
||||
public static final int FLAG_PROGRESSIVE = 16384;
|
||||
/**
|
||||
* Limit the number of progressive JPEG scans that the decompression and
|
||||
* transform operations will process. If a progressive JPEG image contains
|
||||
* an unreasonably large number of scans, then this flag will cause the
|
||||
* decompression and transform operations to throw an error. The primary
|
||||
* purpose of this is to allow security-critical applications to guard
|
||||
* against an exploit of the progressive JPEG format described in
|
||||
* <a href="https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf" target="_blank">this report</a>.
|
||||
*/
|
||||
public static final int FLAG_LIMITSCANS = 32768;
|
||||
|
||||
|
||||
/**
|
||||
* The number of error codes
|
||||
*/
|
||||
public static final int NUMERR = 2;
|
||||
/**
|
||||
* The error was non-fatal and recoverable, but the destination image may
|
||||
* still be corrupt.
|
||||
* <p>
|
||||
* NOTE: due to the design of the TurboJPEG Java API, only certain methods
|
||||
* (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods
|
||||
* with a void return type) will complete and leave the destination image in
|
||||
* a fully recoverable state after a non-fatal error occurs.
|
||||
*/
|
||||
public static final int ERR_WARNING = 0;
|
||||
/**
|
||||
* The error was fatal and non-recoverable.
|
||||
*/
|
||||
public static final int ERR_FATAL = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the maximum size of the buffer (in bytes) required to hold a JPEG
|
||||
* image with the given width, height, and level of chrominance subsampling.
|
||||
*
|
||||
* @param width the width (in pixels) of the JPEG image
|
||||
*
|
||||
* @param height the height (in pixels) of the JPEG image
|
||||
*
|
||||
* @param jpegSubsamp the level of chrominance subsampling to be used when
|
||||
* generating the JPEG image (one of {@link #SAMP_444 TJ.SAMP_*})
|
||||
*
|
||||
* @return the maximum size of the buffer (in bytes) required to hold a JPEG
|
||||
* image with the given width, height, and level of chrominance subsampling.
|
||||
*/
|
||||
public static native int bufSize(int width, int height, int jpegSubsamp);
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer (in bytes) required to hold a unified
|
||||
* planar YUV image with the given width, height, and level of chrominance
|
||||
* subsampling.
|
||||
*
|
||||
* @param width the width (in pixels) of the YUV image
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n specifies that each row in each plane of
|
||||
* the YUV image will be padded to the nearest multiple of n bytes
|
||||
* (1 = unpadded.)
|
||||
*
|
||||
* @param height the height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link #SAMP_444 TJ.SAMP_*})
|
||||
*
|
||||
* @return the size of the buffer (in bytes) required to hold a unified
|
||||
* planar YUV image with the given width, height, and level of chrominance
|
||||
* subsampling.
|
||||
*/
|
||||
public static native int bufSizeYUV(int width, int align, int height,
|
||||
int subsamp);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #bufSizeYUV(int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public static native int bufSizeYUV(int width, int height, int subsamp);
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer (in bytes) required to hold a YUV image
|
||||
* plane with the given parameters.
|
||||
*
|
||||
* @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
|
||||
* 2 = V/Cr)
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image. NOTE: this is the width
|
||||
* of the whole image, not the plane width.
|
||||
*
|
||||
* @param stride bytes per row in the image plane.
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image. NOTE: this is the
|
||||
* height of the whole image, not the plane height.
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link #SAMP_444 TJ.SAMP_*})
|
||||
*
|
||||
* @return the size of the buffer (in bytes) required to hold a YUV image
|
||||
* plane with the given parameters.
|
||||
*/
|
||||
public static native int planeSizeYUV(int componentID, int width, int stride,
|
||||
int height, int subsamp);
|
||||
|
||||
/**
|
||||
* Returns the plane width of a YUV image plane with the given parameters.
|
||||
* Refer to {@link YUVImage YUVImage} for a description of plane width.
|
||||
*
|
||||
* @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
|
||||
* 2 = V/Cr)
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV image
|
||||
* (one of {@link #SAMP_444 TJ.SAMP_*})
|
||||
*
|
||||
* @return the plane width of a YUV image plane with the given parameters.
|
||||
*/
|
||||
public static native int planeWidth(int componentID, int width, int subsamp);
|
||||
|
||||
/**
|
||||
* Returns the plane height of a YUV image plane with the given parameters.
|
||||
* Refer to {@link YUVImage YUVImage} for a description of plane height.
|
||||
*
|
||||
* @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
|
||||
* 2 = V/Cr)
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV image
|
||||
* (one of {@link #SAMP_444 TJ.SAMP_*})
|
||||
*
|
||||
* @return the plane height of a YUV image plane with the given parameters.
|
||||
*/
|
||||
public static native int planeHeight(int componentID, int height,
|
||||
int subsamp);
|
||||
|
||||
/**
|
||||
* Returns a list of fractional scaling factors that the JPEG decompressor
|
||||
* supports.
|
||||
*
|
||||
* @return a list of fractional scaling factors that the JPEG decompressor
|
||||
* supports.
|
||||
*/
|
||||
public static native TJScalingFactor[] getScalingFactors();
|
||||
|
||||
static {
|
||||
TJLoader.load();
|
||||
}
|
||||
|
||||
private static void checkPixelFormat(int pixelFormat) {
|
||||
if (pixelFormat < 0 || pixelFormat >= NUMPF)
|
||||
throw new IllegalArgumentException("Invalid pixel format");
|
||||
}
|
||||
|
||||
private static void checkSubsampling(int subsamp) {
|
||||
if (subsamp < 0 || subsamp >= NUMSAMP)
|
||||
throw new IllegalArgumentException("Invalid subsampling type");
|
||||
}
|
||||
|
||||
}
|
||||
689
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java
vendored
Normal file
689
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java
vendored
Normal file
@@ -0,0 +1,689 @@
|
||||
/*
|
||||
* Copyright (C)2011-2015, 2018, 2020, 2023 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.awt.image.*;
|
||||
import java.nio.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* TurboJPEG compressor
|
||||
*/
|
||||
public class TJCompressor implements Closeable {
|
||||
|
||||
private static final String NO_ASSOC_ERROR =
|
||||
"No source image is associated with this instance";
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG compressor instance.
|
||||
*/
|
||||
public TJCompressor() throws TJException {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG compressor instance and associate the packed-pixel
|
||||
* source image stored in <code>srcImage</code> with the newly created
|
||||
* instance.
|
||||
*
|
||||
* @param srcImage see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param x see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param y see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param width see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param pitch see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param height see {@link #setSourceImage} for description
|
||||
*
|
||||
* @param pixelFormat pixel format of the source image (one of
|
||||
* {@link TJ#PF_RGB TJ.PF_*})
|
||||
*/
|
||||
public TJCompressor(byte[] srcImage, int x, int y, int width, int pitch,
|
||||
int height, int pixelFormat) throws TJException {
|
||||
setSourceImage(srcImage, x, y, width, pitch, height, pixelFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #TJCompressor(byte[], int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public TJCompressor(byte[] srcImage, int width, int pitch, int height,
|
||||
int pixelFormat) throws TJException {
|
||||
setSourceImage(srcImage, width, pitch, height, pixelFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG compressor instance and associate the packed-pixel
|
||||
* source image stored in <code>srcImage</code> with the newly created
|
||||
* instance.
|
||||
*
|
||||
* @param srcImage see
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
|
||||
*
|
||||
* @param x see
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
|
||||
*
|
||||
* @param y see
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
|
||||
*
|
||||
* @param width see
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
|
||||
*
|
||||
* @param height see
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
|
||||
*/
|
||||
public TJCompressor(BufferedImage srcImage, int x, int y, int width,
|
||||
int height) throws TJException {
|
||||
setSourceImage(srcImage, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a packed-pixel RGB, grayscale, or CMYK source image with this
|
||||
* compressor instance.
|
||||
*
|
||||
* @param srcImage buffer containing a packed-pixel RGB, grayscale, or CMYK
|
||||
* source image to be compressed or encoded. This buffer is not modified.
|
||||
*
|
||||
* @param x x offset (in pixels) of the region in the source image from which
|
||||
* the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param y y offset (in pixels) of the region in the source image from which
|
||||
* the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param width width (in pixels) of the region in the source image from
|
||||
* which the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param pitch bytes per row in the source image. Normally this should be
|
||||
* <code>width *
|
||||
* </code>{@link TJ#getPixelSize TJ.getPixelSize}<code>(pixelFormat)</code>,
|
||||
* if the source image is unpadded. However, you can use this parameter to,
|
||||
* for instance, specify that the rows in the source image are padded to the
|
||||
* nearest multiple of 4 bytes or to compress/encode a JPEG or YUV image from
|
||||
* a region of a larger source image. You can also be clever and use this
|
||||
* parameter to skip rows, etc. Setting this parameter to 0 is the
|
||||
* equivalent of setting it to <code>width *
|
||||
* </code>{@link TJ#getPixelSize TJ.getPixelSize}<code>(pixelFormat)</code>.
|
||||
*
|
||||
* @param height height (in pixels) of the region in the source image from
|
||||
* which the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param pixelFormat pixel format of the source image (one of
|
||||
* {@link TJ#PF_RGB TJ.PF_*})
|
||||
*/
|
||||
public void setSourceImage(byte[] srcImage, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat)
|
||||
throws TJException {
|
||||
if (handle == 0) init();
|
||||
if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
|
||||
pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
|
||||
throw new IllegalArgumentException("Invalid argument in setSourceImage()");
|
||||
srcBuf = srcImage;
|
||||
srcWidth = width;
|
||||
if (pitch == 0)
|
||||
srcPitch = width * TJ.getPixelSize(pixelFormat);
|
||||
else
|
||||
srcPitch = pitch;
|
||||
srcHeight = height;
|
||||
srcPixelFormat = pixelFormat;
|
||||
srcX = x;
|
||||
srcY = y;
|
||||
srcBufInt = null;
|
||||
srcYUVImage = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(byte[], int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void setSourceImage(byte[] srcImage, int width, int pitch,
|
||||
int height, int pixelFormat) throws TJException {
|
||||
setSourceImage(srcImage, 0, 0, width, pitch, height, pixelFormat);
|
||||
srcX = srcY = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a packed-pixel RGB or grayscale source image with this
|
||||
* compressor instance.
|
||||
*
|
||||
* @param srcImage a <code>BufferedImage</code> instance containing a
|
||||
* packed-pixel RGB or grayscale source image to be compressed or encoded.
|
||||
* This image is not modified.
|
||||
*
|
||||
* @param x x offset (in pixels) of the region in the source image from which
|
||||
* the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param y y offset (in pixels) of the region in the source image from which
|
||||
* the JPEG or YUV image should be compressed/encoded
|
||||
*
|
||||
* @param width width (in pixels) of the region in the source image from
|
||||
* which the JPEG or YUV image should be compressed/encoded (0 = use the
|
||||
* width of the source image)
|
||||
*
|
||||
* @param height height (in pixels) of the region in the source image from
|
||||
* which the JPEG or YUV image should be compressed/encoded (0 = use the
|
||||
* height of the source image)
|
||||
*/
|
||||
public void setSourceImage(BufferedImage srcImage, int x, int y, int width,
|
||||
int height) throws TJException {
|
||||
if (handle == 0) init();
|
||||
if (srcImage == null || x < 0 || y < 0 || width < 0 || height < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in setSourceImage()");
|
||||
srcX = x;
|
||||
srcY = y;
|
||||
srcWidth = (width == 0) ? srcImage.getWidth() : width;
|
||||
srcHeight = (height == 0) ? srcImage.getHeight() : height;
|
||||
if (x + width > srcImage.getWidth() || y + height > srcImage.getHeight())
|
||||
throw new IllegalArgumentException("Compression region exceeds the bounds of the source image");
|
||||
|
||||
int pixelFormat;
|
||||
boolean intPixels = false;
|
||||
if (byteOrder == null)
|
||||
byteOrder = ByteOrder.nativeOrder();
|
||||
switch (srcImage.getType()) {
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
pixelFormat = TJ.PF_BGR; break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
pixelFormat = TJ.PF_XBGR; break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
pixelFormat = TJ.PF_GRAY; break;
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
pixelFormat = TJ.PF_XBGR;
|
||||
else
|
||||
pixelFormat = TJ.PF_RGBX;
|
||||
intPixels = true; break;
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
pixelFormat = TJ.PF_XRGB;
|
||||
else
|
||||
pixelFormat = TJ.PF_BGRX;
|
||||
intPixels = true; break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported BufferedImage format");
|
||||
}
|
||||
srcPixelFormat = pixelFormat;
|
||||
|
||||
WritableRaster wr = srcImage.getRaster();
|
||||
if (intPixels) {
|
||||
SinglePixelPackedSampleModel sm =
|
||||
(SinglePixelPackedSampleModel)srcImage.getSampleModel();
|
||||
srcStride = sm.getScanlineStride();
|
||||
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
|
||||
srcBufInt = db.getData();
|
||||
srcBuf = null;
|
||||
} else {
|
||||
ComponentSampleModel sm =
|
||||
(ComponentSampleModel)srcImage.getSampleModel();
|
||||
int pixelSize = sm.getPixelStride();
|
||||
if (pixelSize != TJ.getPixelSize(pixelFormat))
|
||||
throw new IllegalArgumentException("Inconsistency between pixel format and pixel size in BufferedImage");
|
||||
srcPitch = sm.getScanlineStride();
|
||||
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
|
||||
srcBuf = db.getData();
|
||||
srcBufInt = null;
|
||||
}
|
||||
srcYUVImage = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a planar YUV source image with this compressor instance.
|
||||
*
|
||||
* @param srcImage planar YUV source image to be compressed. This image is
|
||||
* not modified.
|
||||
*/
|
||||
public void setSourceImage(YUVImage srcImage) throws TJException {
|
||||
if (handle == 0) init();
|
||||
if (srcImage == null)
|
||||
throw new IllegalArgumentException("Invalid argument in setSourceImage()");
|
||||
srcYUVImage = srcImage;
|
||||
srcBuf = null;
|
||||
srcBufInt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the level of chrominance subsampling for subsequent compress/encode
|
||||
* operations. When pixels are converted from RGB to YCbCr (see
|
||||
* {@link TJ#CS_YCbCr}) or from CMYK to YCCK (see {@link TJ#CS_YCCK}) as part
|
||||
* of the JPEG compression process, some of the Cb and Cr (chrominance)
|
||||
* components can be discarded or averaged together to produce a smaller
|
||||
* image with little perceptible loss of image clarity. (The human eye is
|
||||
* more sensitive to small changes in brightness than to small changes in
|
||||
* color.) This is called "chrominance subsampling".
|
||||
* <p>
|
||||
* NOTE: This method has no effect when compressing a JPEG image from a
|
||||
* planar YUV source image. In that case, the level of chrominance
|
||||
* subsampling in the JPEG image is determined by the source image.
|
||||
* Furthermore, this method has no effect when encoding to a pre-allocated
|
||||
* {@link YUVImage} instance. In that case, the level of chrominance
|
||||
* subsampling is determined by the destination image.
|
||||
*
|
||||
* @param newSubsamp the level of chrominance subsampling to use in
|
||||
* subsequent compress/encode oeprations (one of
|
||||
* {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public void setSubsamp(int newSubsamp) {
|
||||
if (newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalArgumentException("Invalid argument in setSubsamp()");
|
||||
subsamp = newSubsamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JPEG image quality level for subsequent compress operations.
|
||||
*
|
||||
* @param quality the new JPEG image quality level (1 to 100, 1 = worst,
|
||||
* 100 = best)
|
||||
*/
|
||||
public void setJPEGQuality(int quality) {
|
||||
if (quality < 1 || quality > 100)
|
||||
throw new IllegalArgumentException("Invalid argument in setJPEGQuality()");
|
||||
jpegQuality = quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the packed-pixel or planar YUV source image associated with this
|
||||
* compressor instance and output a JPEG image to the given destination
|
||||
* buffer.
|
||||
*
|
||||
* @param dstBuf buffer that will receive the JPEG image. Use
|
||||
* {@link TJ#bufSize} to determine the maximum size for this buffer based on
|
||||
* the source image's width and height and the desired level of chrominance
|
||||
* subsampling.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void compress(byte[] dstBuf, int flags) throws TJException {
|
||||
if (dstBuf == null || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in compress()");
|
||||
if (srcBuf == null && srcBufInt == null && srcYUVImage == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (jpegQuality < 0)
|
||||
throw new IllegalStateException("JPEG Quality not set");
|
||||
if (subsamp < 0 && srcYUVImage == null)
|
||||
throw new IllegalStateException("Subsampling level not set");
|
||||
|
||||
if (srcYUVImage != null)
|
||||
compressedSize = compressFromYUV(srcYUVImage.getPlanes(),
|
||||
srcYUVImage.getOffsets(),
|
||||
srcYUVImage.getWidth(),
|
||||
srcYUVImage.getStrides(),
|
||||
srcYUVImage.getHeight(),
|
||||
srcYUVImage.getSubsamp(),
|
||||
dstBuf, jpegQuality, flags);
|
||||
else if (srcBuf != null) {
|
||||
if (srcX >= 0 && srcY >= 0)
|
||||
compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch,
|
||||
srcHeight, srcPixelFormat, dstBuf, subsamp,
|
||||
jpegQuality, flags);
|
||||
else
|
||||
compressedSize = compress(srcBuf, srcWidth, srcPitch, srcHeight,
|
||||
srcPixelFormat, dstBuf, subsamp, jpegQuality,
|
||||
flags);
|
||||
} else if (srcBufInt != null) {
|
||||
if (srcX >= 0 && srcY >= 0)
|
||||
compressedSize = compress(srcBufInt, srcX, srcY, srcWidth, srcStride,
|
||||
srcHeight, srcPixelFormat, dstBuf, subsamp,
|
||||
jpegQuality, flags);
|
||||
else
|
||||
compressedSize = compress(srcBufInt, srcWidth, srcStride, srcHeight,
|
||||
srcPixelFormat, dstBuf, subsamp, jpegQuality,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the packed-pixel or planar YUV source image associated with this
|
||||
* compressor instance and return a buffer containing a JPEG image.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a buffer containing a JPEG image. The length of this buffer will
|
||||
* not be equal to the size of the JPEG image. Use {@link
|
||||
* #getCompressedSize} to obtain the size of the JPEG image.
|
||||
*/
|
||||
public byte[] compress(int flags) throws TJException {
|
||||
byte[] buf;
|
||||
if (srcYUVImage != null) {
|
||||
buf = new byte[TJ.bufSize(srcYUVImage.getWidth(),
|
||||
srcYUVImage.getHeight(),
|
||||
srcYUVImage.getSubsamp())];
|
||||
} else {
|
||||
checkSourceImage();
|
||||
buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
|
||||
}
|
||||
compress(buf, flags);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #compress(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void compress(BufferedImage srcImage, byte[] dstBuf, int flags)
|
||||
throws TJException {
|
||||
setSourceImage(srcImage, 0, 0, 0, 0);
|
||||
compress(dstBuf, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #compress(int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] compress(BufferedImage srcImage, int flags)
|
||||
throws TJException {
|
||||
setSourceImage(srcImage, 0, 0, 0, 0);
|
||||
return compress(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the packed-pixel source image associated with this compressor
|
||||
* instance into a planar YUV image and store it in the given
|
||||
* {@link YUVImage} instance. This method performs color conversion (which
|
||||
* is accelerated in the libjpeg-turbo implementation) but does not execute
|
||||
* any of the other steps in the JPEG compression process. Encoding CMYK
|
||||
* source images into YUV images is not supported.
|
||||
*
|
||||
* @param dstImage {@link YUVImage} instance that will receive the planar YUV
|
||||
* image
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void encodeYUV(YUVImage dstImage, int flags) throws TJException {
|
||||
if (dstImage == null || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in encodeYUV()");
|
||||
if (srcBuf == null && srcBufInt == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (srcYUVImage != null)
|
||||
throw new IllegalStateException("Source image is not correct type");
|
||||
checkSubsampling();
|
||||
if (srcWidth != dstImage.getWidth() || srcHeight != dstImage.getHeight())
|
||||
throw new IllegalStateException("Destination image is the wrong size");
|
||||
|
||||
if (srcBufInt != null) {
|
||||
encodeYUV(srcBufInt, srcX, srcY, srcWidth, srcStride, srcHeight,
|
||||
srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
|
||||
dstImage.getStrides(), dstImage.getSubsamp(), flags);
|
||||
} else {
|
||||
encodeYUV(srcBuf, srcX, srcY, srcWidth, srcPitch, srcHeight,
|
||||
srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
|
||||
dstImage.getStrides(), dstImage.getSubsamp(), flags);
|
||||
}
|
||||
compressedSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #encodeYUV(YUVImage, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void encodeYUV(byte[] dstBuf, int flags) throws TJException {
|
||||
if (dstBuf == null)
|
||||
throw new IllegalArgumentException("Invalid argument in encodeYUV()");
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage dstYUVImage = new YUVImage(dstBuf, srcWidth, 4, srcHeight,
|
||||
subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the packed-pixel source image associated with this compressor
|
||||
* instance into a unified planar YUV image and return a {@link YUVImage}
|
||||
* instance containing the encoded image. This method performs color
|
||||
* conversion (which is accelerated in the libjpeg-turbo implementation) but
|
||||
* does not execute any of the other steps in the JPEG compression process.
|
||||
* Encoding CMYK source images into YUV images is not supported.
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n will cause each row in each plane of the
|
||||
* YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.)
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a {@link YUVImage} instance containing the unified planar YUV
|
||||
* encoded image
|
||||
*/
|
||||
public YUVImage encodeYUV(int align, int flags) throws TJException {
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
if (align < 1 || ((align & (align - 1)) != 0))
|
||||
throw new IllegalStateException("Invalid argument in encodeYUV()");
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, align, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the packed-pixel source image associated with this compressor
|
||||
* instance into separate Y, U (Cb), and V (Cr) image planes and return a
|
||||
* {@link YUVImage} instance containing the encoded image planes. This
|
||||
* method performs color conversion (which is accelerated in the
|
||||
* libjpeg-turbo implementation) but does not execute any of the other steps
|
||||
* in the JPEG compression process. Encoding CMYK source images into YUV
|
||||
* images is not supported.
|
||||
*
|
||||
* @param strides an array of integers, each specifying the number of bytes
|
||||
* per row in the corresponding plane of the YUV source image. Setting the
|
||||
* stride for any plane to 0 is the same as setting it to the plane width
|
||||
* (see {@link YUVImage}.) If <code>strides</code> is null, then the strides
|
||||
* for all planes will be set to their respective plane widths. You can
|
||||
* adjust the strides in order to add an arbitrary amount of row padding to
|
||||
* each plane.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a {@link YUVImage} instance containing the encoded image planes
|
||||
*/
|
||||
public YUVImage encodeYUV(int[] strides, int flags) throws TJException {
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, strides, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #encodeYUV(int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] encodeYUV(int flags) throws TJException {
|
||||
checkSourceImage();
|
||||
checkSubsampling();
|
||||
YUVImage dstYUVImage = new YUVImage(srcWidth, 4, srcHeight, subsamp);
|
||||
encodeYUV(dstYUVImage, flags);
|
||||
return dstYUVImage.getBuf();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #encodeYUV(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags)
|
||||
throws TJException {
|
||||
setSourceImage(srcImage, 0, 0, 0, 0);
|
||||
encodeYUV(dstBuf, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #setSourceImage(BufferedImage, int, int, int, int)} and
|
||||
* {@link #encodeYUV(int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] encodeYUV(BufferedImage srcImage, int flags)
|
||||
throws TJException {
|
||||
setSourceImage(srcImage, 0, 0, 0, 0);
|
||||
return encodeYUV(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the image (in bytes) generated by the most recent
|
||||
* compress operation.
|
||||
*
|
||||
* @return the size of the image (in bytes) generated by the most recent
|
||||
* compress operation.
|
||||
*/
|
||||
public int getCompressedSize() {
|
||||
return compressedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the native structures associated with this compressor instance.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws TJException {
|
||||
if (handle != 0)
|
||||
destroy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
close();
|
||||
} catch (TJException e) {
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
};
|
||||
|
||||
private native void init() throws TJException;
|
||||
|
||||
private native void destroy() throws TJException;
|
||||
|
||||
// JPEG size in bytes is returned
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native int compress(byte[] srcBuf, int width, int pitch,
|
||||
int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
|
||||
int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compress(byte[] srcBuf, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
|
||||
int jpegQual, int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native int compress(int[] srcBuf, int width, int stride,
|
||||
int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
|
||||
int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compress(int[] srcBuf, int x, int y, int width,
|
||||
int stride, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
|
||||
int jpegQual, int flags) throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native int compressFromYUV(byte[][] srcPlanes, int[] srcOffsets,
|
||||
int width, int[] srcStrides, int height, int subsamp, byte[] jpegBuf,
|
||||
int jpegQual, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native void encodeYUV(byte[] srcBuf, int width, int pitch,
|
||||
int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native void encodeYUV(byte[] srcBuf, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat, byte[][] dstPlanes,
|
||||
int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Deprecated
|
||||
private native void encodeYUV(int[] srcBuf, int width, int stride,
|
||||
int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
private native void encodeYUV(int[] srcBuf, int x, int y, int width,
|
||||
int srcStride, int height, int pixelFormat, byte[][] dstPlanes,
|
||||
int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
|
||||
throws TJException;
|
||||
|
||||
static {
|
||||
TJLoader.load();
|
||||
}
|
||||
|
||||
private void checkSourceImage() {
|
||||
if (srcWidth < 1 || srcHeight < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
}
|
||||
|
||||
private void checkSubsampling() {
|
||||
if (subsamp < 0)
|
||||
throw new IllegalStateException("Subsampling level not set");
|
||||
}
|
||||
|
||||
private long handle = 0;
|
||||
private byte[] srcBuf = null;
|
||||
private int[] srcBufInt = null;
|
||||
private int srcWidth = 0;
|
||||
private int srcHeight = 0;
|
||||
private int srcX = -1;
|
||||
private int srcY = -1;
|
||||
private int srcPitch = 0;
|
||||
private int srcStride = 0;
|
||||
private int srcPixelFormat = -1;
|
||||
private YUVImage srcYUVImage = null;
|
||||
private int subsamp = -1;
|
||||
private int jpegQuality = -1;
|
||||
private int compressedSize = 0;
|
||||
private ByteOrder byteOrder = null;
|
||||
}
|
||||
76
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
vendored
Normal file
76
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C)2011, 2013, 2023 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
* Custom filter callback interface
|
||||
*/
|
||||
public interface TJCustomFilter {
|
||||
|
||||
/**
|
||||
* A callback function that can be used to modify the DCT coefficients after
|
||||
* they are losslessly transformed but before they are transcoded to a new
|
||||
* JPEG image. This allows for custom filters or other transformations to be
|
||||
* applied in the frequency domain.
|
||||
*
|
||||
* @param coeffBuffer a buffer containing transformed DCT coefficients.
|
||||
* (NOTE: this buffer is not guaranteed to be valid once the callback
|
||||
* returns, so applications wishing to hand off the DCT coefficients to
|
||||
* another function or library should make a copy of them within the body of
|
||||
* the callback.)
|
||||
*
|
||||
* @param bufferRegion rectangle containing the width and height of
|
||||
* <code>coeffBuffer</code> as well as its offset relative to the component
|
||||
* plane. TurboJPEG implementations may choose to split each component plane
|
||||
* into multiple DCT coefficient buffers and call the callback function once
|
||||
* for each buffer.
|
||||
*
|
||||
* @param planeRegion rectangle containing the width and height of the
|
||||
* component plane to which <code>coeffBuffer</code> belongs
|
||||
*
|
||||
* @param componentID ID number of the component plane to which
|
||||
* <code>coeffBuffer</code> belongs. (Y, Cb, and Cr have, respectively, ID's
|
||||
* of 0, 1, and 2 in typical JPEG images.)
|
||||
*
|
||||
* @param transformID ID number of the transformed image to which
|
||||
* <code>coeffBuffer</code> belongs. This is the same as the index of the
|
||||
* transform in the <code>transforms</code> array that was passed to {@link
|
||||
* TJTransformer#transform TJTransformer.transform()}.
|
||||
*
|
||||
* @param transform a {@link TJTransform} instance that specifies the
|
||||
* parameters and/or cropping region for this transform
|
||||
*/
|
||||
void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
|
||||
Rectangle planeRegion, int componentID, int transformID,
|
||||
TJTransform transform)
|
||||
throws TJException;
|
||||
}
|
||||
953
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
vendored
Normal file
953
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
vendored
Normal file
@@ -0,0 +1,953 @@
|
||||
/*
|
||||
* Copyright (C)2011-2015, 2018, 2022-2023 D. R. Commander.
|
||||
* All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.awt.image.*;
|
||||
import java.nio.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* TurboJPEG decompressor
|
||||
*/
|
||||
public class TJDecompressor implements Closeable {
|
||||
|
||||
private static final String NO_ASSOC_ERROR =
|
||||
"No JPEG image is associated with this instance";
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG decompresssor instance.
|
||||
*/
|
||||
public TJDecompressor() throws TJException {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG decompressor instance and associate the JPEG source
|
||||
* image or "abbreviated table specification" (AKA "tables-only") datastream
|
||||
* stored in <code>jpegImage</code> with the newly created instance.
|
||||
*
|
||||
* @param jpegImage buffer containing a JPEG source image or tables-only
|
||||
* datastream. (The size of the JPEG image or datastream is assumed to be
|
||||
* the length of the array.) This buffer is not modified.
|
||||
*/
|
||||
public TJDecompressor(byte[] jpegImage) throws TJException {
|
||||
init();
|
||||
setSourceImage(jpegImage, jpegImage.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG decompressor instance and associate the JPEG source
|
||||
* image or "abbreviated table specification" (AKA "tables-only") datastream
|
||||
* of length <code>imageSize</code> bytes stored in <code>jpegImage</code>
|
||||
* with the newly created instance.
|
||||
*
|
||||
* @param jpegImage buffer containing a JPEG source image or tables-only
|
||||
* datastream. This buffer is not modified.
|
||||
*
|
||||
* @param imageSize size of the JPEG source image or tables-only datastream
|
||||
* (in bytes)
|
||||
*/
|
||||
public TJDecompressor(byte[] jpegImage, int imageSize) throws TJException {
|
||||
init();
|
||||
setSourceImage(jpegImage, imageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG decompressor instance and associate the planar YUV
|
||||
* source image stored in <code>yuvImage</code> with the newly created
|
||||
* instance.
|
||||
*
|
||||
* @param yuvImage {@link YUVImage} instance containing a planar YUV source
|
||||
* image to be decoded. This image is not modified.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJDecompressor(YUVImage yuvImage) throws TJException {
|
||||
init();
|
||||
setSourceImage(yuvImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate the JPEG image or "abbreviated table specification" (AKA
|
||||
* "tables-only") datastream of length <code>imageSize</code> bytes stored in
|
||||
* <code>jpegImage</code> with this decompressor instance. If
|
||||
* <code>jpegImage</code> contains a JPEG image, then this image will be used
|
||||
* as the source image for subsequent decompression operations. Passing a
|
||||
* tables-only datastream to this method primes the decompressor with
|
||||
* quantization and Huffman tables that can be used when decompressing
|
||||
* subsequent "abbreviated image" datastreams. This is useful, for instance,
|
||||
* when decompressing video streams in which all frames share the same
|
||||
* quantization and Huffman tables.
|
||||
*
|
||||
* @param jpegImage buffer containing a JPEG source image or tables-only
|
||||
* datastream. This buffer is not modified.
|
||||
*
|
||||
* @param imageSize size of the JPEG source image or tables-only datastream
|
||||
* (in bytes)
|
||||
*/
|
||||
public void setSourceImage(byte[] jpegImage, int imageSize)
|
||||
throws TJException {
|
||||
if (jpegImage == null || imageSize < 1)
|
||||
throw new IllegalArgumentException("Invalid argument in setSourceImage()");
|
||||
jpegBuf = jpegImage;
|
||||
jpegBufSize = imageSize;
|
||||
decompressHeader(jpegBuf, jpegBufSize);
|
||||
yuvImage = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setSourceImage(byte[], int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void setJPEGImage(byte[] jpegImage, int imageSize)
|
||||
throws TJException {
|
||||
setSourceImage(jpegImage, imageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate the specified planar YUV source image with this decompressor
|
||||
* instance. Subsequent decompression operations will decode this image into
|
||||
* a packed-pixel RGB or grayscale destination image.
|
||||
*
|
||||
* @param srcImage {@link YUVImage} instance containing a planar YUV source
|
||||
* image to be decoded. This image is not modified.
|
||||
*/
|
||||
public void setSourceImage(YUVImage srcImage) {
|
||||
if (srcImage == null)
|
||||
throw new IllegalArgumentException("Invalid argument in setSourceImage()");
|
||||
yuvImage = srcImage;
|
||||
jpegBuf = null;
|
||||
jpegBufSize = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the width of the source image (JPEG or YUV) associated with this
|
||||
* decompressor instance.
|
||||
*
|
||||
* @return the width of the source image (JPEG or YUV) associated with this
|
||||
* decompressor instance.
|
||||
*/
|
||||
public int getWidth() {
|
||||
if (yuvImage != null)
|
||||
return yuvImage.getWidth();
|
||||
if (jpegWidth < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return jpegWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of the source image (JPEG or YUV) associated with this
|
||||
* decompressor instance.
|
||||
*
|
||||
* @return the height of the source image (JPEG or YUV) associated with this
|
||||
* decompressor instance.
|
||||
*/
|
||||
public int getHeight() {
|
||||
if (yuvImage != null)
|
||||
return yuvImage.getHeight();
|
||||
if (jpegHeight < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return jpegHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the level of chrominance subsampling used in the source image
|
||||
* (JPEG or YUV) associated with this decompressor instance. See
|
||||
* {@link TJ#SAMP_444 TJ.SAMP_*}.
|
||||
*
|
||||
* @return the level of chrominance subsampling used in the source image
|
||||
* (JPEG or YUV) associated with this decompressor instance.
|
||||
*/
|
||||
public int getSubsamp() {
|
||||
if (yuvImage != null)
|
||||
return yuvImage.getSubsamp();
|
||||
if (jpegSubsamp < 0)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (jpegSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException("JPEG header information is invalid");
|
||||
return jpegSubsamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the colorspace used in the source image (JPEG or YUV) associated
|
||||
* with this decompressor instance. See {@link TJ#CS_RGB TJ.CS_*}. If the
|
||||
* source image is YUV, then this always returns {@link TJ#CS_YCbCr}.
|
||||
*
|
||||
* @return the colorspace used in the source image (JPEG or YUV) associated
|
||||
* with this decompressor instance.
|
||||
*/
|
||||
public int getColorspace() {
|
||||
if (yuvImage != null)
|
||||
return TJ.CS_YCbCr;
|
||||
if (jpegColorspace < 0)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (jpegColorspace >= TJ.NUMCS)
|
||||
throw new IllegalStateException("JPEG header information is invalid");
|
||||
return jpegColorspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JPEG buffer associated with this decompressor instance.
|
||||
*
|
||||
* @return the JPEG buffer associated with this decompressor instance.
|
||||
*/
|
||||
public byte[] getJPEGBuf() {
|
||||
if (jpegBuf == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return jpegBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the JPEG image (in bytes) associated with this
|
||||
* decompressor instance.
|
||||
*
|
||||
* @return the size of the JPEG image (in bytes) associated with this
|
||||
* decompressor instance.
|
||||
*/
|
||||
public int getJPEGSize() {
|
||||
if (jpegBufSize < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return jpegBufSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the largest scaled-down image that the TurboJPEG
|
||||
* decompressor can generate without exceeding the desired image width and
|
||||
* height.
|
||||
*
|
||||
* @param desiredWidth desired width (in pixels) of the decompressed image.
|
||||
* Setting this to 0 is the same as setting it to the width of the JPEG
|
||||
* image. (In other words, the width will not be considered when determining
|
||||
* the scaled image size.)
|
||||
*
|
||||
* @param desiredHeight desired height (in pixels) of the decompressed image.
|
||||
* Setting this to 0 is the same as setting it to the height of the JPEG
|
||||
* image. (In other words, the height will not be considered when
|
||||
* determining the scaled image size.)
|
||||
*
|
||||
* @return the width of the largest scaled-down image that the TurboJPEG
|
||||
* decompressor can generate without exceeding the desired image width and
|
||||
* height.
|
||||
*/
|
||||
public int getScaledWidth(int desiredWidth, int desiredHeight) {
|
||||
if (jpegWidth < 1 || jpegHeight < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (desiredWidth < 0 || desiredHeight < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in getScaledWidth()");
|
||||
TJScalingFactor[] sf = TJ.getScalingFactors();
|
||||
if (desiredWidth == 0)
|
||||
desiredWidth = jpegWidth;
|
||||
if (desiredHeight == 0)
|
||||
desiredHeight = jpegHeight;
|
||||
int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
|
||||
for (int i = 0; i < sf.length; i++) {
|
||||
scaledWidth = sf[i].getScaled(jpegWidth);
|
||||
scaledHeight = sf[i].getScaled(jpegHeight);
|
||||
if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
|
||||
break;
|
||||
}
|
||||
if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
|
||||
throw new IllegalArgumentException("Could not scale down to desired image dimensions");
|
||||
return scaledWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of the largest scaled-down image that the TurboJPEG
|
||||
* decompressor can generate without exceeding the desired image width and
|
||||
* height.
|
||||
*
|
||||
* @param desiredWidth desired width (in pixels) of the decompressed image.
|
||||
* Setting this to 0 is the same as setting it to the width of the JPEG
|
||||
* image. (In other words, the width will not be considered when determining
|
||||
* the scaled image size.)
|
||||
*
|
||||
* @param desiredHeight desired height (in pixels) of the decompressed image.
|
||||
* Setting this to 0 is the same as setting it to the height of the JPEG
|
||||
* image. (In other words, the height will not be considered when
|
||||
* determining the scaled image size.)
|
||||
*
|
||||
* @return the height of the largest scaled-down image that the TurboJPEG
|
||||
* decompressor can generate without exceeding the desired image width and
|
||||
* height.
|
||||
*/
|
||||
public int getScaledHeight(int desiredWidth, int desiredHeight) {
|
||||
if (jpegWidth < 1 || jpegHeight < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (desiredWidth < 0 || desiredHeight < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in getScaledHeight()");
|
||||
TJScalingFactor[] sf = TJ.getScalingFactors();
|
||||
if (desiredWidth == 0)
|
||||
desiredWidth = jpegWidth;
|
||||
if (desiredHeight == 0)
|
||||
desiredHeight = jpegHeight;
|
||||
int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
|
||||
for (int i = 0; i < sf.length; i++) {
|
||||
scaledWidth = sf[i].getScaled(jpegWidth);
|
||||
scaledHeight = sf[i].getScaled(jpegHeight);
|
||||
if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
|
||||
break;
|
||||
}
|
||||
if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
|
||||
throw new IllegalArgumentException("Could not scale down to desired image dimensions");
|
||||
return scaledHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image or decode the planar YUV source image
|
||||
* associated with this decompressor instance and output a packed-pixel
|
||||
* grayscale, RGB, or CMYK image to the given destination buffer.
|
||||
* <p>
|
||||
* NOTE: The destination image is fully recoverable if this method throws a
|
||||
* non-fatal {@link TJException} (unless
|
||||
* {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
|
||||
*
|
||||
* @param dstBuf buffer that will receive the packed-pixel
|
||||
* decompressed/decoded image. If the source image is a JPEG image, then
|
||||
* this buffer should normally be <code>pitch * scaledHeight</code> bytes in
|
||||
* size, where <code>scaledHeight</code> can be determined by calling
|
||||
* <code>scalingFactor.</code>{@link TJScalingFactor#getScaled getScaled}<code>(jpegHeight)</code>
|
||||
* with one of the scaling factors returned from {@link TJ#getScalingFactors}
|
||||
* or by calling {@link #getScaledHeight}. If the source image is a YUV
|
||||
* image, then this buffer should normally be <code>pitch * height</code>
|
||||
* bytes in size, where <code>height</code> is the height of the YUV image.
|
||||
* However, the buffer may also be larger than the dimensions of the source
|
||||
* image, in which case the <code>x</code>, <code>y</code>, and
|
||||
* <code>pitch</code> parameters can be used to specify the region into which
|
||||
* the source image should be decompressed/decoded.
|
||||
*
|
||||
* @param x x offset (in pixels) of the region in the destination image into
|
||||
* which the source image should be decompressed/decoded
|
||||
*
|
||||
* @param y y offset (in pixels) of the region in the destination image into
|
||||
* which the source image should be decompressed/decoded
|
||||
*
|
||||
* @param desiredWidth If the source image is a JPEG image, then this
|
||||
* specifies the desired width (in pixels) of the decompressed image (or
|
||||
* image region.) If the desired destination image dimensions are different
|
||||
* than the source image dimensions, then TurboJPEG will use scaling in the
|
||||
* JPEG decompressor to generate the largest possible image that will fit
|
||||
* within the desired dimensions. Setting this to 0 is the same as setting
|
||||
* it to the width of the JPEG image. (In other words, the width will not be
|
||||
* considered when determining the scaled image size.) This parameter is
|
||||
* ignored if the source image is a YUV image.
|
||||
*
|
||||
* @param pitch bytes per row in the destination image. Normally this should
|
||||
* be set to <code>scaledWidth *
|
||||
* </code>{@link TJ#getPixelSize TJ.getPixelSize}<code>(pixelFormat)</code>,
|
||||
* if the destination image will be unpadded. However, you can use this to,
|
||||
* for instance, pad each row of the destination image to the nearest
|
||||
* multiple of 4 bytes or to decompress/decode the source image into a region
|
||||
* of a larger image. NOTE: if the source image is a JPEG image, then
|
||||
* <code>scaledWidth</code> can be determined by calling
|
||||
* <code>scalingFactor.</code>{@link TJScalingFactor#getScaled getScaled}<code>(jpegWidth)</code>
|
||||
* or by calling {@link #getScaledWidth}. If the source image is a YUV
|
||||
* image, then <code>scaledWidth</code> is the width of the YUV image.
|
||||
* Setting this parameter to 0 is the equivalent of setting it to
|
||||
* <code>scaledWidth *
|
||||
* </code>{@link TJ#getPixelSize TJ.getPixelSize}<code>(pixelFormat)</code>.
|
||||
*
|
||||
* @param desiredHeight If the source image is a JPEG image, then this
|
||||
* specifies the desired height (in pixels) of the decompressed image (or
|
||||
* image region.) If the desired destination image dimensions are different
|
||||
* than the source image dimensions, then TurboJPEG will use scaling in the
|
||||
* JPEG decompressor to generate the largest possible image that will fit
|
||||
* within the desired dimensions. Setting this to 0 is the same as setting
|
||||
* it to the height of the JPEG image. (In other words, the height will not
|
||||
* be considered when determining the scaled image size.) This parameter is
|
||||
* ignored if the source image is a YUV image.
|
||||
*
|
||||
* @param pixelFormat pixel format of the decompressed/decoded image (one of
|
||||
* {@link TJ#PF_RGB TJ.PF_*})
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void decompress(byte[] dstBuf, int x, int y, int desiredWidth,
|
||||
int pitch, int desiredHeight, int pixelFormat,
|
||||
int flags) throws TJException {
|
||||
if (jpegBuf == null && yuvImage == null)
|
||||
throw new IllegalStateException("No source image is associated with this instance");
|
||||
if (dstBuf == null || x < 0 || y < 0 || pitch < 0 ||
|
||||
(yuvImage != null && (desiredWidth < 0 || desiredHeight < 0)) ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompress()");
|
||||
if (yuvImage != null)
|
||||
decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
|
||||
yuvImage.getStrides(), yuvImage.getSubsamp(), dstBuf, x, y,
|
||||
yuvImage.getWidth(), pitch, yuvImage.getHeight(), pixelFormat,
|
||||
flags);
|
||||
else {
|
||||
if (x > 0 || y > 0)
|
||||
decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, pitch,
|
||||
desiredHeight, pixelFormat, flags);
|
||||
else
|
||||
decompress(jpegBuf, jpegBufSize, dstBuf, desiredWidth, pitch,
|
||||
desiredHeight, pixelFormat, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void decompress(byte[] dstBuf, int desiredWidth, int pitch,
|
||||
int desiredHeight, int pixelFormat, int flags)
|
||||
throws TJException {
|
||||
decompress(dstBuf, 0, 0, desiredWidth, pitch, desiredHeight, pixelFormat,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image or decode the planar YUV source image
|
||||
* associated with this decompressor instance and return a buffer containing
|
||||
* the packed-pixel decompressed image.
|
||||
*
|
||||
* @param desiredWidth see
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)}
|
||||
* for description
|
||||
*
|
||||
* @param pitch see
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)}
|
||||
* for description
|
||||
*
|
||||
* @param desiredHeight see
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)}
|
||||
* for description
|
||||
*
|
||||
* @param pixelFormat pixel format of the decompressed image (one of
|
||||
* {@link TJ#PF_RGB TJ.PF_*})
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a buffer containing the packed-pixel decompressed image.
|
||||
*/
|
||||
public byte[] decompress(int desiredWidth, int pitch, int desiredHeight,
|
||||
int pixelFormat, int flags) throws TJException {
|
||||
if (pitch < 0 ||
|
||||
(yuvImage == null && (desiredWidth < 0 || desiredHeight < 0)) ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompress()");
|
||||
int pixelSize = TJ.getPixelSize(pixelFormat);
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
if (pitch == 0)
|
||||
pitch = scaledWidth * pixelSize;
|
||||
byte[] buf = new byte[pitch * scaledHeight];
|
||||
decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image associated with this decompressor
|
||||
* instance into a planar YUV image and store it in the given
|
||||
* {@link YUVImage} instance. This method performs JPEG decompression but
|
||||
* leaves out the color conversion step, so a planar YUV image is generated
|
||||
* instead of a packed-pixel image. This method cannot be used to decompress
|
||||
* JPEG source images with the CMYK or YCCK colorspace.
|
||||
* <p>
|
||||
* NOTE: The planar YUV destination image is fully recoverable if this method
|
||||
* throws a non-fatal {@link TJException} (unless
|
||||
* {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
|
||||
*
|
||||
* @param dstImage {@link YUVImage} instance that will receive the planar YUV
|
||||
* decompressed image. The level of subsampling specified in this
|
||||
* {@link YUVImage} instance must match that of the JPEG image, and the width
|
||||
* and height specified in the {@link YUVImage} instance must match one of
|
||||
* the scaled image sizes that the decompressor is capable of generating from
|
||||
* the JPEG source image.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void decompressToYUV(YUVImage dstImage, int flags)
|
||||
throws TJException {
|
||||
if (jpegBuf == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (dstImage == null || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
|
||||
int scaledWidth = getScaledWidth(dstImage.getWidth(),
|
||||
dstImage.getHeight());
|
||||
int scaledHeight = getScaledHeight(dstImage.getWidth(),
|
||||
dstImage.getHeight());
|
||||
if (scaledWidth != dstImage.getWidth() ||
|
||||
scaledHeight != dstImage.getHeight())
|
||||
throw new IllegalArgumentException("YUVImage dimensions do not match one of the scaled image sizes that the decompressor is capable of generating.");
|
||||
if (jpegSubsamp != dstImage.getSubsamp())
|
||||
throw new IllegalArgumentException("YUVImage subsampling level does not match that of the JPEG image");
|
||||
|
||||
decompressToYUV(jpegBuf, jpegBufSize, dstImage.getPlanes(),
|
||||
dstImage.getOffsets(), dstImage.getWidth(),
|
||||
dstImage.getStrides(), dstImage.getHeight(), flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #decompressToYUV(YUVImage, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public void decompressToYUV(byte[] dstBuf, int flags) throws TJException {
|
||||
YUVImage dstYUVImage = new YUVImage(dstBuf, jpegWidth, 4, jpegHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image associated with this decompressor
|
||||
* instance into a set of Y, U (Cb), and V (Cr) image planes and return a
|
||||
* {@link YUVImage} instance containing the decompressed image planes. This
|
||||
* method performs JPEG decompression but leaves out the color conversion
|
||||
* step, so a planar YUV image is generated instead of a packed-pixel image.
|
||||
* This method cannot be used to decompress JPEG source images with the CMYK
|
||||
* or YCCK colorspace.
|
||||
*
|
||||
* @param desiredWidth desired width (in pixels) of the YUV image. If the
|
||||
* desired image dimensions are different than the dimensions of the JPEG
|
||||
* image being decompressed, then TurboJPEG will use scaling in the JPEG
|
||||
* decompressor to generate the largest possible image that will fit within
|
||||
* the desired dimensions. Setting this to 0 is the same as setting it to
|
||||
* the width of the JPEG image. (In other words, the width will not be
|
||||
* considered when determining the scaled image size.)
|
||||
*
|
||||
* @param strides an array of integers, each specifying the number of bytes
|
||||
* per row in the corresponding plane of the YUV image. Setting the stride
|
||||
* for any plane to 0 is the same as setting it to the scaled plane width
|
||||
* (see {@link YUVImage}.) If <code>strides</code> is null, then the strides
|
||||
* for all planes will be set to their respective scaled plane widths. You
|
||||
* can adjust the strides in order to add an arbitrary amount of row padding
|
||||
* to each plane.
|
||||
*
|
||||
* @param desiredHeight desired height (in pixels) of the YUV image. If the
|
||||
* desired image dimensions are different than the dimensions of the JPEG
|
||||
* image being decompressed, then TurboJPEG will use scaling in the JPEG
|
||||
* decompressor to generate the largest possible image that will fit within
|
||||
* the desired dimensions. Setting this to 0 is the same as setting it to
|
||||
* the height of the JPEG image. (In other words, the height will not be
|
||||
* considered when determining the scaled image size.)
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a {@link YUVImage} instance containing the decompressed image
|
||||
* planes
|
||||
*/
|
||||
public YUVImage decompressToYUV(int desiredWidth, int[] strides,
|
||||
int desiredHeight,
|
||||
int flags) throws TJException {
|
||||
if (flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
|
||||
if (jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (jpegSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException("JPEG header information is invalid");
|
||||
if (yuvImage != null)
|
||||
throw new IllegalStateException("Source image is the wrong type");
|
||||
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
YUVImage dstYUVImage = new YUVImage(scaledWidth, null, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image associated with this decompressor
|
||||
* instance into a unified planar YUV image and return a {@link YUVImage}
|
||||
* instance containing the decompressed image. This method performs JPEG
|
||||
* decompression but leaves out the color conversion step, so a planar YUV
|
||||
* image is generated instead of a packed-pixel image. This method cannot be
|
||||
* used to decompress JPEG source images with the CMYK or YCCK colorspace.
|
||||
*
|
||||
* @param desiredWidth desired width (in pixels) of the YUV image. If the
|
||||
* desired image dimensions are different than the dimensions of the JPEG
|
||||
* image being decompressed, then TurboJPEG will use scaling in the JPEG
|
||||
* decompressor to generate the largest possible image that will fit within
|
||||
* the desired dimensions. Setting this to 0 is the same as setting it to
|
||||
* the width of the JPEG image. (In other words, the width will not be
|
||||
* considered when determining the scaled image size.)
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n will cause each row in each plane of the
|
||||
* YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.)
|
||||
*
|
||||
* @param desiredHeight desired height (in pixels) of the YUV image. If the
|
||||
* desired image dimensions are different than the dimensions of the JPEG
|
||||
* image being decompressed, then TurboJPEG will use scaling in the JPEG
|
||||
* decompressor to generate the largest possible image that will fit within
|
||||
* the desired dimensions. Setting this to 0 is the same as setting it to
|
||||
* the height of the JPEG image. (In other words, the height will not be
|
||||
* considered when determining the scaled image size.)
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a {@link YUVImage} instance containing the unified planar YUV
|
||||
* decompressed image
|
||||
*/
|
||||
public YUVImage decompressToYUV(int desiredWidth, int align,
|
||||
int desiredHeight, int flags)
|
||||
throws TJException {
|
||||
if (flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
|
||||
if (jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (jpegSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException("JPEG header information is invalid");
|
||||
if (yuvImage != null)
|
||||
throw new IllegalStateException("Source image is the wrong type");
|
||||
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
YUVImage dstYUVImage = new YUVImage(scaledWidth, align, scaledHeight,
|
||||
jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #decompressToYUV(int, int, int, int)} instead.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
@Deprecated
|
||||
public byte[] decompressToYUV(int flags) throws TJException {
|
||||
YUVImage dstYUVImage = new YUVImage(jpegWidth, 4, jpegHeight, jpegSubsamp);
|
||||
decompressToYUV(dstYUVImage, flags);
|
||||
return dstYUVImage.getBuf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image or decode the planar YUV source image
|
||||
* associated with this decompressor instance and output a packed-pixel
|
||||
* grayscale, RGB, or CMYK image to the given destination buffer.
|
||||
* <p>
|
||||
* NOTE: The destination image is fully recoverable if this method throws a
|
||||
* non-fatal {@link TJException} (unless
|
||||
* {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
|
||||
*
|
||||
* @param dstBuf buffer that will receive the packed-pixel
|
||||
* decompressed/decoded image. If the source image is a JPEG image, then
|
||||
* this buffer should normally be <code>stride * scaledHeight</code> pixels
|
||||
* in size, where <code>scaledHeight</code> can be determined by calling
|
||||
* <code>scalingFactor.</code>{@link TJScalingFactor#getScaled getScaled}<code>(jpegHeight)</code>
|
||||
* with one of the scaling factors returned from {@link TJ#getScalingFactors}
|
||||
* or by calling {@link #getScaledHeight}. If the source image is a YUV
|
||||
* image, then this buffer should normally be <code>stride * height</code>
|
||||
* pixels in size, where <code>height</code> is the height of the YUV image.
|
||||
* However, the buffer may also be larger than the dimensions of the JPEG
|
||||
* image, in which case the <code>x</code>, <code>y</code>, and
|
||||
* <code>stride</code> parameters can be used to specify the region into
|
||||
* which the source image should be decompressed.
|
||||
*
|
||||
* @param x x offset (in pixels) of the region in the destination image into
|
||||
* which the source image should be decompressed/decoded
|
||||
*
|
||||
* @param y y offset (in pixels) of the region in the destination image into
|
||||
* which the source image should be decompressed/decoded
|
||||
*
|
||||
* @param desiredWidth If the source image is a JPEG image, then this
|
||||
* specifies the desired width (in pixels) of the decompressed image (or
|
||||
* image region.) If the desired destination image dimensions are different
|
||||
* than the source image dimensions, then TurboJPEG will use scaling in the
|
||||
* JPEG decompressor to generate the largest possible image that will fit
|
||||
* within the desired dimensions. Setting this to 0 is the same as setting
|
||||
* it to the width of the JPEG image. (In other words, the width will not be
|
||||
* considered when determining the scaled image size.) This parameter is
|
||||
* ignored if the source image is a YUV image.
|
||||
*
|
||||
* @param stride pixels per row in the destination image. Normally this
|
||||
* should be set to <code>scaledWidth</code>, but you can use this to, for
|
||||
* instance, decompress the JPEG image into a region of a larger image.
|
||||
* NOTE: if the source image is a JPEG image, then <code>scaledWidth</code>
|
||||
* can be determined by calling
|
||||
* <code>scalingFactor.</code>{@link TJScalingFactor#getScaled getScaled}<code>(jpegWidth)</code>
|
||||
* or by calling {@link #getScaledWidth}. If the source image is a YUV
|
||||
* image, then <code>scaledWidth</code> is the width of the YUV image.
|
||||
* Setting this parameter to 0 is the equivalent of setting it to
|
||||
* <code>scaledWidth</code>.
|
||||
*
|
||||
* @param desiredHeight If the source image is a JPEG image, then this
|
||||
* specifies the desired height (in pixels) of the decompressed image (or
|
||||
* image region.) If the desired destination image dimensions are different
|
||||
* than the source image dimensions, then TurboJPEG will use scaling in the
|
||||
* JPEG decompressor to generate the largest possible image that will fit
|
||||
* within the desired dimensions. Setting this to 0 is the same as setting
|
||||
* it to the height of the JPEG image. (In other words, the height will not
|
||||
* be considered when determining the scaled image size.) This parameter is
|
||||
* ignored if the source image is a YUV image.
|
||||
*
|
||||
* @param pixelFormat pixel format of the decompressed image (one of
|
||||
* {@link TJ#PF_RGB TJ.PF_*})
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void decompress(int[] dstBuf, int x, int y, int desiredWidth,
|
||||
int stride, int desiredHeight, int pixelFormat,
|
||||
int flags) throws TJException {
|
||||
if (jpegBuf == null && yuvImage == null)
|
||||
throw new IllegalStateException("No source image is associated with this instance");
|
||||
if (dstBuf == null || x < 0 || y < 0 || stride < 0 ||
|
||||
(yuvImage != null && (desiredWidth < 0 || desiredHeight < 0)) ||
|
||||
pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompress()");
|
||||
if (yuvImage != null)
|
||||
decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
|
||||
yuvImage.getStrides(), yuvImage.getSubsamp(), dstBuf, x, y,
|
||||
yuvImage.getWidth(), stride, yuvImage.getHeight(), pixelFormat,
|
||||
flags);
|
||||
else
|
||||
decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, stride,
|
||||
desiredHeight, pixelFormat, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image or decode the planar YUV source image
|
||||
* associated with this decompressor instance and output a packed-pixel
|
||||
* decompressed/decoded image to the given <code>BufferedImage</code>
|
||||
* instance.
|
||||
* <p>
|
||||
* NOTE: The destination image is fully recoverable if this method throws a
|
||||
* non-fatal {@link TJException} (unless
|
||||
* {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
|
||||
*
|
||||
* @param dstImage a <code>BufferedImage</code> instance that will receive
|
||||
* the packed-pixel decompressed/decoded image. If the source image is a
|
||||
* JPEG image, then the width and height of the <code>BufferedImage</code>
|
||||
* instance must match one of the scaled image sizes that the decompressor is
|
||||
* capable of generating from the JPEG image. If the source image is a YUV
|
||||
* image, then the width and height of the <code>BufferedImage</code>
|
||||
* instance must match the width and height of the YUV image.
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void decompress(BufferedImage dstImage, int flags)
|
||||
throws TJException {
|
||||
if (dstImage == null || flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompress()");
|
||||
int desiredWidth = dstImage.getWidth();
|
||||
int desiredHeight = dstImage.getHeight();
|
||||
int scaledWidth, scaledHeight;
|
||||
|
||||
if (yuvImage != null) {
|
||||
if (desiredWidth != yuvImage.getWidth() ||
|
||||
desiredHeight != yuvImage.getHeight())
|
||||
throw new IllegalArgumentException("BufferedImage dimensions do not match the dimensions of the source image.");
|
||||
scaledWidth = yuvImage.getWidth();
|
||||
scaledHeight = yuvImage.getHeight();
|
||||
} else {
|
||||
scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
if (scaledWidth != desiredWidth || scaledHeight != desiredHeight)
|
||||
throw new IllegalArgumentException("BufferedImage dimensions do not match one of the scaled image sizes that the decompressor is capable of generating.");
|
||||
}
|
||||
int pixelFormat; boolean intPixels = false;
|
||||
if (byteOrder == null)
|
||||
byteOrder = ByteOrder.nativeOrder();
|
||||
switch (dstImage.getType()) {
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
pixelFormat = TJ.PF_BGR; break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
pixelFormat = TJ.PF_XBGR; break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
pixelFormat = TJ.PF_GRAY; break;
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
pixelFormat = TJ.PF_XBGR;
|
||||
else
|
||||
pixelFormat = TJ.PF_RGBX;
|
||||
intPixels = true; break;
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
pixelFormat = TJ.PF_XRGB;
|
||||
else
|
||||
pixelFormat = TJ.PF_BGRX;
|
||||
intPixels = true; break;
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN)
|
||||
pixelFormat = TJ.PF_ARGB;
|
||||
else
|
||||
pixelFormat = TJ.PF_BGRA;
|
||||
intPixels = true; break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported BufferedImage format");
|
||||
}
|
||||
WritableRaster wr = dstImage.getRaster();
|
||||
if (intPixels) {
|
||||
SinglePixelPackedSampleModel sm =
|
||||
(SinglePixelPackedSampleModel)dstImage.getSampleModel();
|
||||
int stride = sm.getScanlineStride();
|
||||
DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
|
||||
int[] buf = db.getData();
|
||||
if (yuvImage != null)
|
||||
decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
|
||||
yuvImage.getStrides(), yuvImage.getSubsamp(), buf, 0, 0,
|
||||
yuvImage.getWidth(), stride, yuvImage.getHeight(),
|
||||
pixelFormat, flags);
|
||||
else {
|
||||
if (jpegBuf == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
decompress(jpegBuf, jpegBufSize, buf, 0, 0, scaledWidth, stride,
|
||||
scaledHeight, pixelFormat, flags);
|
||||
}
|
||||
} else {
|
||||
ComponentSampleModel sm =
|
||||
(ComponentSampleModel)dstImage.getSampleModel();
|
||||
int pixelSize = sm.getPixelStride();
|
||||
if (pixelSize != TJ.getPixelSize(pixelFormat))
|
||||
throw new IllegalArgumentException("Inconsistency between pixel format and pixel size in BufferedImage");
|
||||
int pitch = sm.getScanlineStride();
|
||||
DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
|
||||
byte[] buf = db.getData();
|
||||
decompress(buf, 0, 0, scaledWidth, pitch, scaledHeight, pixelFormat,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the JPEG source image or decode the planar YUV source image
|
||||
* associated with this decompressor instance and return a
|
||||
* <code>BufferedImage</code> instance containing the packed-pixel
|
||||
* decompressed/decoded image.
|
||||
*
|
||||
* @param desiredWidth see
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)} for
|
||||
* description
|
||||
*
|
||||
* @param desiredHeight see
|
||||
* {@link #decompress(byte[], int, int, int, int, int, int, int)} for
|
||||
* description
|
||||
*
|
||||
* @param bufferedImageType the image type of the <code>BufferedImage</code>
|
||||
* instance that will be created (for instance,
|
||||
* <code>BufferedImage.TYPE_INT_RGB</code>)
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return a <code>BufferedImage</code> instance containing the packed-pixel
|
||||
* decompressed/decoded image.
|
||||
*/
|
||||
public BufferedImage decompress(int desiredWidth, int desiredHeight,
|
||||
int bufferedImageType, int flags)
|
||||
throws TJException {
|
||||
if ((yuvImage == null && (desiredWidth < 0 || desiredHeight < 0)) ||
|
||||
flags < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in decompress()");
|
||||
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
|
||||
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
|
||||
BufferedImage img = new BufferedImage(scaledWidth, scaledHeight,
|
||||
bufferedImageType);
|
||||
decompress(img, flags);
|
||||
return img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the native structures associated with this decompressor instance.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws TJException {
|
||||
if (handle != 0)
|
||||
destroy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
close();
|
||||
} catch (TJException e) {
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
};
|
||||
|
||||
private native void init() throws TJException;
|
||||
|
||||
private native void destroy() throws TJException;
|
||||
|
||||
private native void decompressHeader(byte[] srcBuf, int size)
|
||||
throws TJException;
|
||||
|
||||
@Deprecated
|
||||
private native void decompress(byte[] srcBuf, int size, byte[] dstBuf,
|
||||
int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
|
||||
throws TJException;
|
||||
|
||||
private native void decompress(byte[] srcBuf, int size, byte[] dstBuf, int x,
|
||||
int y, int desiredWidth, int pitch, int desiredHeight, int pixelFormat,
|
||||
int flags) throws TJException;
|
||||
|
||||
@Deprecated
|
||||
private native void decompress(byte[] srcBuf, int size, int[] dstBuf,
|
||||
int desiredWidth, int stride, int desiredHeight, int pixelFormat,
|
||||
int flags) throws TJException;
|
||||
|
||||
private native void decompress(byte[] srcBuf, int size, int[] dstBuf, int x,
|
||||
int y, int desiredWidth, int stride, int desiredHeight, int pixelFormat,
|
||||
int flags) throws TJException;
|
||||
|
||||
@Deprecated
|
||||
private native void decompressToYUV(byte[] srcBuf, int size, byte[] dstBuf,
|
||||
int flags) throws TJException;
|
||||
|
||||
private native void decompressToYUV(byte[] srcBuf, int size,
|
||||
byte[][] dstPlanes, int[] dstOffsets, int desiredWidth, int[] dstStrides,
|
||||
int desiredheight, int flags) throws TJException;
|
||||
|
||||
private native void decodeYUV(byte[][] srcPlanes, int[] srcOffsets,
|
||||
int[] srcStrides, int subsamp, byte[] dstBuf, int x, int y, int width,
|
||||
int pitch, int height, int pixelFormat, int flags) throws TJException;
|
||||
|
||||
private native void decodeYUV(byte[][] srcPlanes, int[] srcOffsets,
|
||||
int[] srcStrides, int subsamp, int[] dstBuf, int x, int y, int width,
|
||||
int stride, int height, int pixelFormat, int flags) throws TJException;
|
||||
|
||||
static {
|
||||
TJLoader.load();
|
||||
}
|
||||
|
||||
protected long handle = 0;
|
||||
protected byte[] jpegBuf = null;
|
||||
protected int jpegBufSize = 0;
|
||||
protected YUVImage yuvImage = null;
|
||||
protected int jpegWidth = 0;
|
||||
protected int jpegHeight = 0;
|
||||
protected int jpegSubsamp = -1;
|
||||
protected int jpegColorspace = -1;
|
||||
private ByteOrder byteOrder = null;
|
||||
}
|
||||
78
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java
vendored
Normal file
78
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
* Copyright (C)2017-2018 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocType")
|
||||
public class TJException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(String message, int code) {
|
||||
super(message);
|
||||
if (errorCode >= 0 && errorCode < TJ.NUMERR)
|
||||
errorCode = code;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
public TJException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the
|
||||
* last error.
|
||||
*
|
||||
* @return a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the
|
||||
* last error.
|
||||
*/
|
||||
public int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
private int errorCode = TJ.ERR_FATAL;
|
||||
}
|
||||
59
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-unix.java.in
vendored
Normal file
59
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-unix.java.in
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C)2011-2013, 2016, 2020 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
final class TJLoader {
|
||||
static void load() {
|
||||
try {
|
||||
System.loadLibrary("turbojpeg");
|
||||
} catch (java.lang.UnsatisfiedLinkError e) {
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.indexOf("mac") >= 0) {
|
||||
try {
|
||||
System.load("@CMAKE_INSTALL_FULL_LIBDIR@/libturbojpeg.dylib");
|
||||
} catch (java.lang.UnsatisfiedLinkError e2) {
|
||||
System.load("/usr/lib/libturbojpeg.dylib");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
System.load("@CMAKE_INSTALL_FULL_LIBDIR@/libturbojpeg.so");
|
||||
} catch (java.lang.UnsatisfiedLinkError e3) {
|
||||
String libdir = "@CMAKE_INSTALL_FULL_LIBDIR@";
|
||||
if (libdir.equals("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib64")) {
|
||||
System.load("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib32/libturbojpeg.so");
|
||||
} else if (libdir.equals("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib32")) {
|
||||
System.load("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib64/libturbojpeg.so");
|
||||
} else {
|
||||
throw e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-win.java.in
vendored
Normal file
35
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-win.java.in
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C)2011 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
final class TJLoader {
|
||||
static void load() {
|
||||
System.loadLibrary("@TURBOJPEG_DLL_NAME@");
|
||||
}
|
||||
}
|
||||
115
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java
vendored
Normal file
115
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C)2011, 2018 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
/**
|
||||
* Fractional scaling factor
|
||||
*/
|
||||
public class TJScalingFactor {
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG scaling factor instance.
|
||||
*
|
||||
* @param num numerator
|
||||
* @param denom denominator
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJScalingFactor(int num, int denom) {
|
||||
if (num < 1 || denom < 1)
|
||||
throw new IllegalArgumentException("Numerator and denominator must be >= 1");
|
||||
this.num = num;
|
||||
this.denom = denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numerator
|
||||
*
|
||||
* @return numerator
|
||||
*/
|
||||
public int getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns denominator
|
||||
*
|
||||
* @return denominator
|
||||
*/
|
||||
public int getDenom() {
|
||||
return denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scaled value of <code>dimension</code>. This function
|
||||
* performs the integer equivalent of
|
||||
* <code>ceil(dimension * scalingFactor)</code>.
|
||||
*
|
||||
* @param dimension width or height to multiply by this scaling factor
|
||||
*
|
||||
* @return the scaled value of <code>dimension</code>.
|
||||
*/
|
||||
public int getScaled(int dimension) {
|
||||
return (dimension * num + denom - 1) / denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true or false, depending on whether this instance and
|
||||
* <code>other</code> have the same numerator and denominator.
|
||||
*
|
||||
* @param other the scaling factor against which to compare this one
|
||||
*
|
||||
* @return true or false, depending on whether this instance and
|
||||
* <code>other</code> have the same numerator and denominator.
|
||||
*/
|
||||
public boolean equals(TJScalingFactor other) {
|
||||
return this.num == other.num && this.denom == other.denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true or false, depending on whether this instance is equal to
|
||||
* 1/1.
|
||||
*
|
||||
* @return true or false, depending on whether this instance is equal to
|
||||
* 1/1.
|
||||
*/
|
||||
public boolean isOne() {
|
||||
return num == 1 && denom == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Numerator
|
||||
*/
|
||||
private int num = 1;
|
||||
|
||||
/**
|
||||
* Denominator
|
||||
*/
|
||||
private int denom = 1;
|
||||
}
|
||||
227
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java
vendored
Normal file
227
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (C)2011, 2013, 2018, 2023 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Lossless transform parameters
|
||||
*/
|
||||
public class TJTransform extends Rectangle {
|
||||
|
||||
private static final long serialVersionUID = -127367705761430371L;
|
||||
|
||||
/**
|
||||
* The number of lossless transform operations
|
||||
*/
|
||||
public static final int NUMOP = 8;
|
||||
/**
|
||||
* Do not transform the position of the image pixels.
|
||||
*/
|
||||
public static final int OP_NONE = 0;
|
||||
/**
|
||||
* Flip (mirror) image horizontally. This transform is imperfect if there
|
||||
* are any partial MCU blocks on the right edge.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_HFLIP = 1;
|
||||
/**
|
||||
* Flip (mirror) image vertically. This transform is imperfect if there are
|
||||
* any partial MCU blocks on the bottom edge.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_VFLIP = 2;
|
||||
/**
|
||||
* Transpose image (flip/mirror along upper left to lower right axis). This
|
||||
* transform is always perfect.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_TRANSPOSE = 3;
|
||||
/**
|
||||
* Transverse transpose image (flip/mirror along upper right to lower left
|
||||
* axis). This transform is imperfect if there are any partial MCU blocks in
|
||||
* the image.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_TRANSVERSE = 4;
|
||||
/**
|
||||
* Rotate image clockwise by 90 degrees. This transform is imperfect if
|
||||
* there are any partial MCU blocks on the bottom edge.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_ROT90 = 5;
|
||||
/**
|
||||
* Rotate image 180 degrees. This transform is imperfect if there are any
|
||||
* partial MCU blocks in the image.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_ROT180 = 6;
|
||||
/**
|
||||
* Rotate image counter-clockwise by 90 degrees. This transform is imperfect
|
||||
* if there are any partial MCU blocks on the right edge.
|
||||
* @see #OPT_PERFECT
|
||||
*/
|
||||
public static final int OP_ROT270 = 7;
|
||||
|
||||
|
||||
/**
|
||||
* This option will cause {@link TJTransformer#transform
|
||||
* TJTransformer.transform()} to throw an exception if the transform is not
|
||||
* perfect. Lossless transforms operate on MCU blocks, whose size depends on
|
||||
* the level of chrominance subsampling used. If the image's width or height
|
||||
* is not evenly divisible by the MCU block size (see {@link TJ#getMCUWidth}
|
||||
* and {@link TJ#getMCUHeight}), then there will be partial MCU blocks on the
|
||||
* right and/or bottom edges. It is not possible to move these partial MCU
|
||||
* blocks to the top or left of the image, so any transform that would
|
||||
* require that is "imperfect." If this option is not specified, then any
|
||||
* partial MCU blocks that cannot be transformed will be left in place, which
|
||||
* will create odd-looking strips on the right or bottom edge of the image.
|
||||
*/
|
||||
public static final int OPT_PERFECT = 1;
|
||||
/**
|
||||
* This option will discard any partial MCU blocks that cannot be
|
||||
* transformed.
|
||||
*/
|
||||
public static final int OPT_TRIM = 2;
|
||||
/**
|
||||
* This option will enable lossless cropping.
|
||||
*/
|
||||
public static final int OPT_CROP = 4;
|
||||
/**
|
||||
* This option will discard the color data in the source image and produce a
|
||||
* grayscale destination image.
|
||||
*/
|
||||
public static final int OPT_GRAY = 8;
|
||||
/**
|
||||
* This option will prevent {@link TJTransformer#transform
|
||||
* TJTransformer.transform()} from outputting a JPEG image for this
|
||||
* particular transform. This can be used in conjunction with a custom
|
||||
* filter to capture the transformed DCT coefficients without transcoding
|
||||
* them.
|
||||
*/
|
||||
public static final int OPT_NOOUTPUT = 16;
|
||||
/**
|
||||
* This option will enable progressive entropy coding in the JPEG image
|
||||
* generated by this particular transform. Progressive entropy coding will
|
||||
* generally improve compression relative to baseline entropy coding (the
|
||||
* default), but it will reduce decompression performance considerably.
|
||||
*/
|
||||
public static final int OPT_PROGRESSIVE = 32;
|
||||
/**
|
||||
* This option will prevent {@link TJTransformer#transform
|
||||
* TJTransformer.transform()} from copying any extra markers (including EXIF
|
||||
* and ICC profile data) from the source image to the destination image.
|
||||
*/
|
||||
public static final int OPT_COPYNONE = 64;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new lossless transform instance.
|
||||
*/
|
||||
public TJTransform() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new lossless transform instance with the given parameters.
|
||||
*
|
||||
* @param x the left boundary of the cropping region. This must be evenly
|
||||
* divisible by the MCU block width (see {@link TJ#getMCUWidth})
|
||||
*
|
||||
* @param y the upper boundary of the cropping region. This must be evenly
|
||||
* divisible by the MCU block height (see {@link TJ#getMCUHeight})
|
||||
*
|
||||
* @param w the width of the cropping region. Setting this to 0 is the
|
||||
* equivalent of setting it to (width of the source JPEG image -
|
||||
* <code>x</code>).
|
||||
*
|
||||
* @param h the height of the cropping region. Setting this to 0 is the
|
||||
* equivalent of setting it to (height of the source JPEG image -
|
||||
* <code>y</code>).
|
||||
*
|
||||
* @param op one of the transform operations ({@link #OP_NONE OP_*})
|
||||
*
|
||||
* @param options the bitwise OR of one or more of the transform options
|
||||
* ({@link #OPT_PERFECT OPT_*})
|
||||
*
|
||||
* @param cf an instance of an object that implements the {@link
|
||||
* TJCustomFilter} interface, or null if no custom filter is needed
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJTransform(int x, int y, int w, int h, int op, int options,
|
||||
TJCustomFilter cf) {
|
||||
super(x, y, w, h);
|
||||
this.op = op;
|
||||
this.options = options;
|
||||
this.cf = cf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new lossless transform instance with the given parameters.
|
||||
*
|
||||
* @param r a <code>Rectangle</code> instance that specifies the cropping
|
||||
* region. See {@link
|
||||
* #TJTransform(int, int, int, int, int, int, TJCustomFilter)} for more
|
||||
* detail.
|
||||
*
|
||||
* @param op one of the transform operations ({@link #OP_NONE OP_*})
|
||||
*
|
||||
* @param options the bitwise OR of one or more of the transform options
|
||||
* ({@link #OPT_PERFECT OPT_*})
|
||||
*
|
||||
* @param cf an instance of an object that implements the {@link
|
||||
* TJCustomFilter} interface, or null if no custom filter is needed
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
public TJTransform(Rectangle r, int op, int options,
|
||||
TJCustomFilter cf) {
|
||||
super(r);
|
||||
this.op = op;
|
||||
this.options = options;
|
||||
this.cf = cf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform operation (one of {@link #OP_NONE OP_*})
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public int op = 0;
|
||||
|
||||
/**
|
||||
* Transform options (bitwise OR of one or more of
|
||||
* {@link #OPT_PERFECT OPT_*})
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public int options = 0;
|
||||
|
||||
/**
|
||||
* Custom filter instance
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VisibilityModifier")
|
||||
public TJCustomFilter cf = null;
|
||||
}
|
||||
167
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java
vendored
Normal file
167
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C)2011, 2013-2015, 2023 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
/**
|
||||
* TurboJPEG lossless transformer
|
||||
*/
|
||||
public class TJTransformer extends TJDecompressor {
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG lossless transformer instance.
|
||||
*/
|
||||
public TJTransformer() throws TJException {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG lossless transformer instance and associate the JPEG
|
||||
* source image stored in <code>jpegImage</code> with the newly created
|
||||
* instance.
|
||||
*
|
||||
* @param jpegImage buffer containing the JPEG source image to transform.
|
||||
* (The size of the JPEG image is assumed to be the length of the array.)
|
||||
* This buffer is not modified.
|
||||
*/
|
||||
public TJTransformer(byte[] jpegImage) throws TJException {
|
||||
init();
|
||||
setSourceImage(jpegImage, jpegImage.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TurboJPEG lossless transformer instance and associate the JPEG
|
||||
* source image of length <code>imageSize</code> bytes stored in
|
||||
* <code>jpegImage</code> with the newly created instance.
|
||||
*
|
||||
* @param jpegImage buffer containing the JPEG source image to transform.
|
||||
* This buffer is not modified.
|
||||
*
|
||||
* @param imageSize size of the JPEG source image (in bytes)
|
||||
*/
|
||||
public TJTransformer(byte[] jpegImage, int imageSize) throws TJException {
|
||||
init();
|
||||
setSourceImage(jpegImage, imageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Losslessly transform the JPEG source image associated with this
|
||||
* transformer instance into one or more JPEG images stored in the given
|
||||
* destination buffers. Lossless transforms work by moving the raw
|
||||
* coefficients from one JPEG image structure to another without altering the
|
||||
* values of the coefficients. While this is typically faster than
|
||||
* decompressing the image, transforming it, and re-compressing it, lossless
|
||||
* transforms are not free. Each lossless transform requires reading and
|
||||
* performing Huffman decoding on all of the coefficients in the source
|
||||
* image, regardless of the size of the destination image. Thus, this method
|
||||
* provides a means of generating multiple transformed images from the same
|
||||
* source or of applying multiple transformations simultaneously, in order to
|
||||
* eliminate the need to read the source coefficients multiple times.
|
||||
*
|
||||
* @param dstBufs an array of JPEG destination buffers.
|
||||
* <code>dstbufs[i]</code> will receive a JPEG image that has been
|
||||
* transformed using the parameters in <code>transforms[i]</code>. Use
|
||||
* {@link TJ#bufSize} to determine the maximum size for each buffer based on
|
||||
* the transformed or cropped width and height and the level of subsampling
|
||||
* used in the source image.
|
||||
*
|
||||
* @param transforms an array of {@link TJTransform} instances, each of
|
||||
* which specifies the transform parameters and/or cropping region for the
|
||||
* corresponding transformed JPEG image
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*/
|
||||
public void transform(byte[][] dstBufs, TJTransform[] transforms,
|
||||
int flags) throws TJException {
|
||||
if (jpegBuf == null)
|
||||
throw new IllegalStateException("JPEG buffer not initialized");
|
||||
transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Losslessly transform the JPEG source image associated with this
|
||||
* transformer instance and return an array of {@link TJDecompressor}
|
||||
* instances, each of which has a transformed JPEG image associated with it.
|
||||
*
|
||||
* @param transforms an array of {@link TJTransform} instances, each of
|
||||
* which specifies the transform parameters and/or cropping region for the
|
||||
* corresponding transformed JPEG image
|
||||
*
|
||||
* @param flags the bitwise OR of one or more of
|
||||
* {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
|
||||
*
|
||||
* @return an array of {@link TJDecompressor} instances, each of
|
||||
* which has a transformed JPEG image associated with it.
|
||||
*/
|
||||
public TJDecompressor[] transform(TJTransform[] transforms, int flags)
|
||||
throws TJException {
|
||||
byte[][] dstBufs = new byte[transforms.length][];
|
||||
if (jpegWidth < 1 || jpegHeight < 1)
|
||||
throw new IllegalStateException("JPEG buffer not initialized");
|
||||
for (int i = 0; i < transforms.length; i++) {
|
||||
int w = jpegWidth, h = jpegHeight;
|
||||
if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
|
||||
if (transforms[i].width != 0) w = transforms[i].width;
|
||||
if (transforms[i].height != 0) h = transforms[i].height;
|
||||
}
|
||||
dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)];
|
||||
}
|
||||
TJDecompressor[] tjd = new TJDecompressor[transforms.length];
|
||||
transform(dstBufs, transforms, flags);
|
||||
for (int i = 0; i < transforms.length; i++)
|
||||
tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
|
||||
return tjd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the sizes of the transformed JPEG images
|
||||
* (in bytes) generated by the most recent transform operation.
|
||||
*
|
||||
* @return an array containing the sizes of the transformed JPEG images
|
||||
* (in bytes) generated by the most recent transform operation.
|
||||
*/
|
||||
public int[] getTransformedSizes() {
|
||||
if (transformedSizes == null)
|
||||
throw new IllegalStateException("No image has been transformed yet");
|
||||
return transformedSizes;
|
||||
}
|
||||
|
||||
private native void init() throws TJException;
|
||||
|
||||
private native int[] transform(byte[] srcBuf, int srcSize, byte[][] dstBufs,
|
||||
TJTransform[] transforms, int flags) throws TJException;
|
||||
|
||||
static {
|
||||
TJLoader.load();
|
||||
}
|
||||
|
||||
private int[] transformedSizes = null;
|
||||
}
|
||||
452
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java
vendored
Normal file
452
android/extern/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright (C)2014, 2017, 2023 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the libjpeg-turbo Project nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.libjpegturbo.turbojpeg;
|
||||
|
||||
/**
|
||||
* This class encapsulates a planar YUV image and the metadata
|
||||
* associated with it. The TurboJPEG API allows both the JPEG compression and
|
||||
* decompression pipelines to be split into stages: YUV encode, compress from
|
||||
* YUV, decompress to YUV, and YUV decode. A <code>YUVImage</code> instance
|
||||
* serves as the destination image for YUV encode and decompress-to-YUV
|
||||
* operations and as the source image for compress-from-YUV and YUV decode
|
||||
* operations.
|
||||
* <p>
|
||||
* Technically, the JPEG format uses the YCbCr colorspace (which is technically
|
||||
* not a colorspace but a color transform), but per the convention of the
|
||||
* digital video community, the TurboJPEG API uses "YUV" to refer to an image
|
||||
* format consisting of Y, Cb, and Cr image planes.
|
||||
* <p>
|
||||
* Each plane is simply a 2D array of bytes, each byte representing the value
|
||||
* of one of the components (Y, Cb, or Cr) at a particular location in the
|
||||
* image. The width and height of each plane are determined by the image
|
||||
* width, height, and level of chrominance subsampling. The luminance plane
|
||||
* width is the image width padded to the nearest multiple of the horizontal
|
||||
* subsampling factor (1 in the case of 4:4:4, grayscale, or 4:4:0; 2 in the
|
||||
* case of 4:2:2 or 4:2:0; 4 in the case of 4:1:1.) Similarly, the luminance
|
||||
* plane height is the image height padded to the nearest multiple of the
|
||||
* vertical subsampling factor (1 in the case of 4:4:4, 4:2:2, grayscale, or
|
||||
* 4:1:1; 2 in the case of 4:2:0 or 4:4:0.) This is irrespective of any
|
||||
* additional padding that may be specified as an argument to the various
|
||||
* YUVImage methods. The chrominance plane width is equal to the luminance
|
||||
* plane width divided by the horizontal subsampling factor, and the
|
||||
* chrominance plane height is equal to the luminance plane height divided by
|
||||
* the vertical subsampling factor.
|
||||
* <p>
|
||||
* For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is
|
||||
* used, then the luminance plane would be 36 x 35 bytes, and each of the
|
||||
* chrominance planes would be 18 x 35 bytes. If you specify a row alignment
|
||||
* of 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes,
|
||||
* and each of the chrominance planes would be 20 x 35 bytes.
|
||||
*/
|
||||
public class YUVImage {
|
||||
|
||||
private static final String NO_ASSOC_ERROR =
|
||||
"No image data is associated with this instance";
|
||||
|
||||
/**
|
||||
* Create a new <code>YUVImage</code> instance backed by separate image
|
||||
* planes, and allocate memory for the image planes.
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image
|
||||
*
|
||||
* @param strides an array of integers, each specifying the number of bytes
|
||||
* per row in the corresponding plane of the YUV image. Setting the stride
|
||||
* for any plane to 0 is the same as setting it to the plane width (see
|
||||
* {@link YUVImage above}.) If <code>strides</code> is null, then the
|
||||
* strides for all planes will be set to their respective plane widths. When
|
||||
* using this constructor, the stride for each plane must be equal to or
|
||||
* greater than the plane width.
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling to be used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public YUVImage(int width, int[] strides, int height, int subsamp) {
|
||||
setBuf(null, null, width, strides, height, subsamp, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>YUVImage</code> instance backed by a unified buffer,
|
||||
* and allocate memory for the buffer.
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n specifies that each row in each plane of
|
||||
* the YUV image will be padded to the nearest multiple of n bytes
|
||||
* (1 = unpadded.)
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling to be used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public YUVImage(int width, int align, int height, int subsamp) {
|
||||
setBuf(new byte[TJ.bufSizeYUV(width, align, height, subsamp)], width,
|
||||
align, height, subsamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>YUVImage</code> instance from a set of existing image
|
||||
* planes.
|
||||
*
|
||||
* @param planes an array of buffers representing the Y, U (Cb), and V (Cr)
|
||||
* image planes (or just the Y plane, if the image is grayscale.) These
|
||||
* planes can be contiguous or non-contiguous in memory. Plane
|
||||
* <code>i</code> should be at least <code>offsets[i] + </code>
|
||||
* {@link TJ#planeSizeYUV TJ.planeSizeYUV}<code>(i, width, strides[i], height, subsamp)</code>
|
||||
* bytes in size.
|
||||
*
|
||||
* @param offsets If this <code>YUVImage</code> instance represents a
|
||||
* subregion of a larger image, then <code>offsets[i]</code> specifies the
|
||||
* offset (in bytes) of the subregion within plane <code>i</code> of the
|
||||
* larger image. Setting this to null is the same as setting the offsets for
|
||||
* all planes to 0.
|
||||
*
|
||||
* @param width width (in pixels) of the new YUV image (or subregion)
|
||||
*
|
||||
* @param strides an array of integers, each specifying the number of bytes
|
||||
* per row in the corresponding plane of the YUV image. Setting the stride
|
||||
* for any plane to 0 is the same as setting it to the plane width (see
|
||||
* {@link YUVImage above}.) If <code>strides</code> is null, then the
|
||||
* strides for all planes will be set to their respective plane widths. You
|
||||
* can adjust the strides in order to add an arbitrary amount of row padding
|
||||
* to each plane or to specify that this <code>YUVImage</code> instance is a
|
||||
* subregion of a larger image (in which case, <code>strides[i]</code> should
|
||||
* be set to the plane width of plane <code>i</code> in the larger image.)
|
||||
*
|
||||
* @param height height (in pixels) of the new YUV image (or subregion)
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public YUVImage(byte[][] planes, int[] offsets, int width, int[] strides,
|
||||
int height, int subsamp) {
|
||||
setBuf(planes, offsets, width, strides, height, subsamp, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new <code>YUVImage</code> instance from an existing unified
|
||||
* buffer.
|
||||
*
|
||||
* @param yuvImage buffer that contains or will receive a unified planar YUV
|
||||
* image. Use {@link TJ#bufSizeYUV} to determine the minimum size for this
|
||||
* buffer. The Y, U (Cb), and V (Cr) image planes are stored sequentially in
|
||||
* the buffer. (See {@link YUVImage above} for a description of the image
|
||||
* format.)
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n specifies that each row in each plane of
|
||||
* the YUV image will be padded to the nearest multiple of n bytes
|
||||
* (1 = unpadded.)
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public YUVImage(byte[] yuvImage, int width, int align, int height,
|
||||
int subsamp) {
|
||||
setBuf(yuvImage, width, align, height, subsamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a set of image planes to this <code>YUVImage</code> instance.
|
||||
*
|
||||
* @param planes an array of buffers representing the Y, U (Cb), and V (Cr)
|
||||
* image planes (or just the Y plane, if the image is grayscale.) These
|
||||
* planes can be contiguous or non-contiguous in memory. Plane
|
||||
* <code>i</code> should be at least <code>offsets[i] + </code>
|
||||
* {@link TJ#planeSizeYUV TJ.planeSizeYUV}<code>(i, width, strides[i], height, subsamp)</code>
|
||||
* bytes in size.
|
||||
*
|
||||
* @param offsets If this <code>YUVImage</code> instance represents a
|
||||
* subregion of a larger image, then <code>offsets[i]</code> specifies the
|
||||
* offset (in bytes) of the subregion within plane <code>i</code> of the
|
||||
* larger image. Setting this to null is the same as setting the offsets for
|
||||
* all planes to 0.
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image (or subregion)
|
||||
*
|
||||
* @param strides an array of integers, each specifying the number of bytes
|
||||
* per row in the corresponding plane of the YUV image. Setting the stride
|
||||
* for any plane to 0 is the same as setting it to the plane width (see
|
||||
* {@link YUVImage above}.) If <code>strides</code> is null, then the
|
||||
* strides for all planes will be set to their respective plane widths. You
|
||||
* can adjust the strides in order to add an arbitrary amount of row padding
|
||||
* to each plane or to specify that this <code>YUVImage</code> instance is a
|
||||
* subregion of a larger image (in which case, <code>strides[i]</code> should
|
||||
* be set to the plane width of plane <code>i</code> in the larger image.)
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image (or subregion)
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public void setBuf(byte[][] planes, int[] offsets, int width, int[] strides,
|
||||
int height, int subsamp) {
|
||||
setBuf(planes, offsets, width, strides, height, subsamp, false);
|
||||
}
|
||||
|
||||
private void setBuf(byte[][] planes, int[] offsets, int width, int[] strides,
|
||||
int height, int subsamp, boolean alloc) {
|
||||
if ((planes == null && !alloc) || width < 1 || height < 1 || subsamp < 0 ||
|
||||
subsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
|
||||
|
||||
int nc = (subsamp == TJ.SAMP_GRAY ? 1 : 3);
|
||||
if ((planes != null && planes.length != nc) ||
|
||||
(offsets != null && offsets.length != nc) ||
|
||||
(strides != null && strides.length != nc))
|
||||
throw new IllegalArgumentException("YUVImage::setBuf(): planes, offsets, or strides array is the wrong size");
|
||||
|
||||
if (planes == null)
|
||||
planes = new byte[nc][];
|
||||
if (offsets == null)
|
||||
offsets = new int[nc];
|
||||
if (strides == null)
|
||||
strides = new int[nc];
|
||||
|
||||
for (int i = 0; i < nc; i++) {
|
||||
int pw = TJ.planeWidth(i, width, subsamp);
|
||||
int ph = TJ.planeHeight(i, height, subsamp);
|
||||
int planeSize = TJ.planeSizeYUV(i, width, strides[i], height, subsamp);
|
||||
|
||||
if (strides[i] == 0)
|
||||
strides[i] = pw;
|
||||
if (alloc) {
|
||||
if (strides[i] < pw)
|
||||
throw new IllegalArgumentException("Stride must be >= plane width when allocating a new YUV image");
|
||||
planes[i] = new byte[strides[i] * ph];
|
||||
}
|
||||
if (planes[i] == null || offsets[i] < 0)
|
||||
throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
|
||||
if (strides[i] < 0 && offsets[i] - planeSize + pw < 0)
|
||||
throw new IllegalArgumentException("Stride for plane " + i +
|
||||
" would cause memory to be accessed below plane boundary");
|
||||
if (planes[i].length < offsets[i] + planeSize)
|
||||
throw new IllegalArgumentException("Image plane " + i +
|
||||
" is not large enough");
|
||||
}
|
||||
|
||||
yuvPlanes = planes;
|
||||
yuvOffsets = offsets;
|
||||
yuvWidth = width;
|
||||
yuvStrides = strides;
|
||||
yuvHeight = height;
|
||||
yuvSubsamp = subsamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a unified buffer to this <code>YUVImage</code> instance.
|
||||
*
|
||||
* @param yuvImage buffer that contains or will receive a unified planar YUV
|
||||
* image. Use {@link TJ#bufSizeYUV} to determine the minimum size for this
|
||||
* buffer. The Y, U (Cb), and V (Cr) image planes are stored sequentially in
|
||||
* the buffer. (See {@link YUVImage above} for a description of the image
|
||||
* format.)
|
||||
*
|
||||
* @param width width (in pixels) of the YUV image
|
||||
*
|
||||
* @param align row alignment (in bytes) of the YUV image (must be a power of
|
||||
* 2.) Setting this parameter to n specifies that each row in each plane of
|
||||
* the YUV image will be padded to the nearest multiple of n bytes
|
||||
* (1 = unpadded.)
|
||||
*
|
||||
* @param height height (in pixels) of the YUV image
|
||||
*
|
||||
* @param subsamp the level of chrominance subsampling used in the YUV
|
||||
* image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
|
||||
*/
|
||||
public void setBuf(byte[] yuvImage, int width, int align, int height,
|
||||
int subsamp) {
|
||||
if (yuvImage == null || width < 1 || align < 1 ||
|
||||
((align & (align - 1)) != 0) || height < 1 || subsamp < 0 ||
|
||||
subsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
|
||||
if (yuvImage.length < TJ.bufSizeYUV(width, align, height, subsamp))
|
||||
throw new IllegalArgumentException("YUV buffer is not large enough");
|
||||
|
||||
int nc = (subsamp == TJ.SAMP_GRAY ? 1 : 3);
|
||||
byte[][] planes = new byte[nc][];
|
||||
int[] strides = new int[nc];
|
||||
int[] offsets = new int[nc];
|
||||
|
||||
planes[0] = yuvImage;
|
||||
strides[0] = pad(TJ.planeWidth(0, width, subsamp), align);
|
||||
if (subsamp != TJ.SAMP_GRAY) {
|
||||
strides[1] = strides[2] = pad(TJ.planeWidth(1, width, subsamp), align);
|
||||
planes[1] = planes[2] = yuvImage;
|
||||
offsets[1] = offsets[0] +
|
||||
strides[0] * TJ.planeHeight(0, height, subsamp);
|
||||
offsets[2] = offsets[1] +
|
||||
strides[1] * TJ.planeHeight(1, height, subsamp);
|
||||
}
|
||||
|
||||
yuvAlign = align;
|
||||
setBuf(planes, offsets, width, strides, height, subsamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the YUV image (or subregion.)
|
||||
*
|
||||
* @return the width of the YUV image (or subregion)
|
||||
*/
|
||||
public int getWidth() {
|
||||
if (yuvWidth < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of the YUV image (or subregion.)
|
||||
*
|
||||
* @return the height of the YUV image (or subregion)
|
||||
*/
|
||||
public int getHeight() {
|
||||
if (yuvHeight < 1)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row alignment (in bytes) of the YUV buffer (if this image is
|
||||
* stored in a unified buffer rather than separate image planes.)
|
||||
*
|
||||
* @return the row alignment of the YUV buffer
|
||||
*/
|
||||
public int getPad() {
|
||||
if (yuvPlanes == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
if (yuvAlign < 1 || ((yuvAlign & (yuvAlign - 1)) != 0))
|
||||
throw new IllegalStateException("Image is not stored in a unified buffer");
|
||||
return yuvAlign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes per row of each plane in the YUV image.
|
||||
*
|
||||
* @return the number of bytes per row of each plane in the YUV image
|
||||
*/
|
||||
public int[] getStrides() {
|
||||
if (yuvStrides == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvStrides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offsets (in bytes) of each plane within the planes of a larger
|
||||
* YUV image.
|
||||
*
|
||||
* @return the offsets (in bytes) of each plane within the planes of a larger
|
||||
* YUV image
|
||||
*/
|
||||
public int[] getOffsets() {
|
||||
if (yuvOffsets == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvOffsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the level of chrominance subsampling used in the YUV image. See
|
||||
* {@link TJ#SAMP_444 TJ.SAMP_*}.
|
||||
*
|
||||
* @return the level of chrominance subsampling used in the YUV image
|
||||
*/
|
||||
public int getSubsamp() {
|
||||
if (yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvSubsamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the YUV image planes. If the image is stored in a unified buffer,
|
||||
* then all image planes will point to that buffer.
|
||||
*
|
||||
* @return the YUV image planes
|
||||
*/
|
||||
public byte[][] getPlanes() {
|
||||
if (yuvPlanes == null)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
return yuvPlanes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the YUV buffer (if this image is stored in a unified buffer rather
|
||||
* than separate image planes.)
|
||||
*
|
||||
* @return the YUV buffer
|
||||
*/
|
||||
public byte[] getBuf() {
|
||||
if (yuvPlanes == null || yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
int nc = (yuvSubsamp == TJ.SAMP_GRAY ? 1 : 3);
|
||||
for (int i = 1; i < nc; i++) {
|
||||
if (yuvPlanes[i] != yuvPlanes[0])
|
||||
throw new IllegalStateException("Image is not stored in a unified buffer");
|
||||
}
|
||||
return yuvPlanes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size (in bytes) of the YUV buffer (if this image is stored in
|
||||
* a unified buffer rather than separate image planes.)
|
||||
*
|
||||
* @return the size (in bytes) of the YUV buffer
|
||||
*/
|
||||
public int getSize() {
|
||||
if (yuvPlanes == null || yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
|
||||
throw new IllegalStateException(NO_ASSOC_ERROR);
|
||||
int nc = (yuvSubsamp == TJ.SAMP_GRAY ? 1 : 3);
|
||||
if (yuvAlign < 1)
|
||||
throw new IllegalStateException("Image is not stored in a unified buffer");
|
||||
for (int i = 1; i < nc; i++) {
|
||||
if (yuvPlanes[i] != yuvPlanes[0])
|
||||
throw new IllegalStateException("Image is not stored in a unified buffer");
|
||||
}
|
||||
return TJ.bufSizeYUV(yuvWidth, yuvAlign, yuvHeight, yuvSubsamp);
|
||||
}
|
||||
|
||||
private static int pad(int v, int p) {
|
||||
return (v + p - 1) & (~(p - 1));
|
||||
}
|
||||
|
||||
protected long handle = 0;
|
||||
protected byte[][] yuvPlanes = null;
|
||||
protected int[] yuvOffsets = null;
|
||||
protected int[] yuvStrides = null;
|
||||
protected int yuvAlign = 1;
|
||||
protected int yuvWidth = 0;
|
||||
protected int yuvHeight = 0;
|
||||
protected int yuvSubsamp = -1;
|
||||
}
|
||||
Reference in New Issue
Block a user