/* * Copyright (C)2014 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; /** * This class encapsulates a YUV planar image buffer 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 YUVImage 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. *

* Technically, the JPEG format uses the YCbCr colorspace (which technically is * not a "colorspace" but rather 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. In this image * format, the Y, Cb (U), and Cr (V) planes are stored sequentially in the same * image buffer, and the size of each plane is determined by the image width, * height, line padding, and level of chrominance subsampling. If the * chrominance components are subsampled along the horizontal dimension, then * the width of the luminance plane would be padded to the nearest multiple of * 2 (same goes for the height of the luminance plane, if the chrominance * components are subsampled along the vertical dimension.) For instance, 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, for instance, a line padding 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 YUV buffer is associated with this instance"; /** * Create a YUVImage instance with a new image buffer. * * @param width width (in pixels) of the YUV image * * @param pad Each line of each plane in the YUV image buffer will be padded * to this number of bytes (must be a power of 2.) * * @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 pad, int height, int subsamp) throws Exception { setBuffer(new byte[TJ.bufSizeYUV(width, pad, height, subsamp)], width, pad, height, subsamp); } /** * Create a YUVImage instance from an existing YUV planar image * buffer. * * @param yuvImage image buffer that contains or will contain YUV planar * image data. See {@link YUVImage above} for a description of the image * format. You can use {@link TJ#bufSizeYUV} to determine the appropriate * size for this buffer. * * @param width width (in pixels) of the YUV image * * @param pad the line padding used in the YUV image buffer. For * instance, if each line in each plane of the buffer is padded to the * nearest multiple of 4 bytes, then pad should be set to 4. * * @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 pad, int height, int subsamp) throws Exception { setBuffer(yuvImage, width, pad, height, subsamp); } private void setBuffer(byte[] yuvImage, int width, int pad, int height, int subsamp) throws Exception { if (yuvImage == null || width < 1 || pad < 1 || ((pad & (pad - 1)) != 0) || height < 1 || subsamp < 0 || subsamp >= TJ.NUMSAMP) throw new Exception("Invalid argument in YUVImage()"); if (yuvImage.length != TJ.bufSizeYUV(width, pad, height, subsamp)) throw new Exception("YUV image buffer is the wrong size"); yuvBuf = yuvImage; yuvWidth = width; yuvPad = pad; yuvHeight = height; yuvSubsamp = subsamp; } /** * Returns the width of the YUV image. * * @return the width of the YUV image */ public int getWidth() throws Exception { if (yuvWidth < 1) throw new Exception(NO_ASSOC_ERROR); return yuvWidth; } /** * Returns the height of the YUV image. * * @return the height of the YUV image */ public int getHeight() throws Exception { if (yuvHeight < 1) throw new Exception(NO_ASSOC_ERROR); return yuvHeight; } /** * Returns the line padding used in the YUV image buffer. * * @return the line padding used in the YUV image buffer */ public int getPad() throws Exception { if (yuvPad < 1 || ((yuvPad & (yuvPad - 1)) != 0)) throw new Exception(NO_ASSOC_ERROR); return yuvPad; } /** * 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() throws Exception { if (yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP) throw new Exception(NO_ASSOC_ERROR); return yuvSubsamp; } /** * Returns the YUV image buffer * * @return the YUV image buffer */ public byte[] getBuf() throws Exception { if (yuvBuf == null) throw new Exception(NO_ASSOC_ERROR); return yuvBuf; } /** * Returns the size (in bytes) of the YUV image buffer * * @return the size (in bytes) of the YUV image buffer */ public int getSize() throws Exception { if (yuvBuf == null) throw new Exception(NO_ASSOC_ERROR); return yuvBuf.length; } protected long handle = 0; protected byte[] yuvBuf = null; protected int yuvPad = 0; protected int yuvWidth = 0; protected int yuvHeight = 0; protected int yuvSubsamp = -1; };