Hash :
9983840e
Author :
Date :
2024-08-31T12:41:13
TJ/xform: Check crop region against dest. image Lossless cropping is performed after other lossless transform operations, so the cropping region must be specified relative to the destination image dimensions and level of chrominance subsampling, not the source image dimensions and level of chrominance subsampling. More specifically, if the lossless transform operation swaps the X and Y axes, or if the image is converted to grayscale, then that changes the cropping region requirements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
/*
* Copyright (C)2011, 2013, 2018, 2022-2024 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 iMCUs 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 iMCUs 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 iMCUs 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 iMCUs 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 iMCUs 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 iMCUs on the right edge.
* @see #OPT_PERFECT
*/
public static final int OP_ROT270 = 7;
/**
* This option causes {@link TJTransformer#transform
* TJTransformer.transform()} to throw an exception if the transform is not
* perfect. Lossless transforms operate on iMCUs, the size of which depends
* on the level of chrominance subsampling used. If the image's width or
* height is not evenly divisible by the iMCU size (see {@link TJ#getMCUWidth
* TJ.getMCUWidth()} and {@link TJ#getMCUHeight TJ.getMCUHeight()}), then
* there will be partial iMCUs on the right and/or bottom edges. It is not
* possible to move these partial iMCUs 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 iMCUs 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 << 0);
/**
* Discard any partial iMCUs that cannot be transformed.
*/
public static final int OPT_TRIM = (1 << 1);
/**
* Enable lossless cropping.
*/
public static final int OPT_CROP = (1 << 2);
/**
* Discard the color data in the source image, and generate a grayscale
* destination image.
*/
public static final int OPT_GRAY = (1 << 3);
/**
* Do not generate a destination image. 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 = (1 << 4);
/**
* Generate a progressive destination image instead of a single-scan
* destination image. Progressive JPEG images generally have better
* compression ratios than single-scan JPEG images (much better if the image
* has large areas of solid color), but progressive JPEG decompression is
* considerably slower than single-scan JPEG decompression. Can be combined
* with {@link #OPT_ARITHMETIC}. Implies {@link #OPT_OPTIMIZE} unless
* {@link #OPT_ARITHMETIC} is also specified.
*/
public static final int OPT_PROGRESSIVE = (1 << 5);
/**
* Do not copy any extra markers (including EXIF and ICC profile data) from
* the source image to the destination image.
*/
public static final int OPT_COPYNONE = (1 << 6);
/**
* Enable arithmetic entropy coding in the destination image. Arithmetic
* entropy coding generally improves compression relative to Huffman entropy
* coding (the default), but it reduces decompression performance
* considerably. Can be combined with {@link #OPT_PROGRESSIVE}.
*/
public static final int OPT_ARITHMETIC = (1 << 7);
/**
* Enable Huffman table optimization for the destination image. Huffman
* table optimization improves compression slightly (generally 5% or less.)
*/
public static final int OPT_OPTIMIZE = (1 << 8);
/**
* 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 iMCU width (see {@link TJ#getMCUWidth TJ.getMCUWidth()})
* of the destination image.
*
* @param y the upper boundary of the cropping region. This must be evenly
* divisible by the iMCU height (see {@link TJ#getMCUHeight
* TJ.getMCUHeight()}) of the destination image.
*
* @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>java.awt.Rectangle</code> instance that specifies the
* cropping region. See
* {@link #TJTransform(int, int, int, int, int, int, TJCustomFilter)} for
* more details.
*
* @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;
}