1*dfc6aa5cSAndroid Build Coastguard Worker /* 2*dfc6aa5cSAndroid Build Coastguard Worker * transupp.h 3*dfc6aa5cSAndroid Build Coastguard Worker * 4*dfc6aa5cSAndroid Build Coastguard Worker * This file was part of the Independent JPEG Group's software: 5*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding. 6*dfc6aa5cSAndroid Build Coastguard Worker * libjpeg-turbo Modifications: 7*dfc6aa5cSAndroid Build Coastguard Worker * Copyright (C) 2017, 2021, D. R. Commander. 8*dfc6aa5cSAndroid Build Coastguard Worker * For conditions of distribution and use, see the accompanying README.ijg 9*dfc6aa5cSAndroid Build Coastguard Worker * file. 10*dfc6aa5cSAndroid Build Coastguard Worker * 11*dfc6aa5cSAndroid Build Coastguard Worker * This file contains declarations for image transformation routines and 12*dfc6aa5cSAndroid Build Coastguard Worker * other utility code used by the jpegtran sample application. These are 13*dfc6aa5cSAndroid Build Coastguard Worker * NOT part of the core JPEG library. But we keep these routines separate 14*dfc6aa5cSAndroid Build Coastguard Worker * from jpegtran.c to ease the task of maintaining jpegtran-like programs 15*dfc6aa5cSAndroid Build Coastguard Worker * that have other user interfaces. 16*dfc6aa5cSAndroid Build Coastguard Worker * 17*dfc6aa5cSAndroid Build Coastguard Worker * NOTE: all the routines declared here have very specific requirements 18*dfc6aa5cSAndroid Build Coastguard Worker * about when they are to be executed during the reading and writing of the 19*dfc6aa5cSAndroid Build Coastguard Worker * source and destination files. See the comments in transupp.c, or see 20*dfc6aa5cSAndroid Build Coastguard Worker * jpegtran.c for an example of correct usage. 21*dfc6aa5cSAndroid Build Coastguard Worker */ 22*dfc6aa5cSAndroid Build Coastguard Worker 23*dfc6aa5cSAndroid Build Coastguard Worker /* If you happen not to want the image transform support, disable it here */ 24*dfc6aa5cSAndroid Build Coastguard Worker #ifndef TRANSFORMS_SUPPORTED 25*dfc6aa5cSAndroid Build Coastguard Worker #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ 26*dfc6aa5cSAndroid Build Coastguard Worker #endif 27*dfc6aa5cSAndroid Build Coastguard Worker 28*dfc6aa5cSAndroid Build Coastguard Worker /* 29*dfc6aa5cSAndroid Build Coastguard Worker * Although rotating and flipping data expressed as DCT coefficients is not 30*dfc6aa5cSAndroid Build Coastguard Worker * hard, there is an asymmetry in the JPEG format specification for images 31*dfc6aa5cSAndroid Build Coastguard Worker * whose dimensions aren't multiples of the iMCU size. The right and bottom 32*dfc6aa5cSAndroid Build Coastguard Worker * image edges are padded out to the next iMCU boundary with junk data; but 33*dfc6aa5cSAndroid Build Coastguard Worker * no padding is possible at the top and left edges. If we were to flip 34*dfc6aa5cSAndroid Build Coastguard Worker * the whole image including the pad data, then pad garbage would become 35*dfc6aa5cSAndroid Build Coastguard Worker * visible at the top and/or left, and real pixels would disappear into the 36*dfc6aa5cSAndroid Build Coastguard Worker * pad margins --- perhaps permanently, since encoders & decoders may not 37*dfc6aa5cSAndroid Build Coastguard Worker * bother to preserve DCT blocks that appear to be completely outside the 38*dfc6aa5cSAndroid Build Coastguard Worker * nominal image area. So, we have to exclude any partial iMCUs from the 39*dfc6aa5cSAndroid Build Coastguard Worker * basic transformation. 40*dfc6aa5cSAndroid Build Coastguard Worker * 41*dfc6aa5cSAndroid Build Coastguard Worker * Transpose is the only transformation that can handle partial iMCUs at the 42*dfc6aa5cSAndroid Build Coastguard Worker * right and bottom edges completely cleanly. flip_h can flip partial iMCUs 43*dfc6aa5cSAndroid Build Coastguard Worker * at the bottom, but leaves any partial iMCUs at the right edge untouched. 44*dfc6aa5cSAndroid Build Coastguard Worker * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. 45*dfc6aa5cSAndroid Build Coastguard Worker * The other transforms are defined as combinations of these basic transforms 46*dfc6aa5cSAndroid Build Coastguard Worker * and process edge blocks in a way that preserves the equivalence. 47*dfc6aa5cSAndroid Build Coastguard Worker * 48*dfc6aa5cSAndroid Build Coastguard Worker * The "trim" option causes untransformable partial iMCUs to be dropped; 49*dfc6aa5cSAndroid Build Coastguard Worker * this is not strictly lossless, but it usually gives the best-looking 50*dfc6aa5cSAndroid Build Coastguard Worker * result for odd-size images. Note that when this option is active, 51*dfc6aa5cSAndroid Build Coastguard Worker * the expected mathematical equivalences between the transforms may not hold. 52*dfc6aa5cSAndroid Build Coastguard Worker * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim 53*dfc6aa5cSAndroid Build Coastguard Worker * followed by -rot 180 -trim trims both edges.) 54*dfc6aa5cSAndroid Build Coastguard Worker * 55*dfc6aa5cSAndroid Build Coastguard Worker * We also offer a lossless-crop option, which discards data outside a given 56*dfc6aa5cSAndroid Build Coastguard Worker * image region but losslessly preserves what is inside. Like the rotate and 57*dfc6aa5cSAndroid Build Coastguard Worker * flip transforms, lossless crop is restricted by the JPEG format: the upper 58*dfc6aa5cSAndroid Build Coastguard Worker * left corner of the selected region must fall on an iMCU boundary. If this 59*dfc6aa5cSAndroid Build Coastguard Worker * does not hold for the given crop parameters, we silently move the upper left 60*dfc6aa5cSAndroid Build Coastguard Worker * corner up and/or left to make it so, simultaneously increasing the region 61*dfc6aa5cSAndroid Build Coastguard Worker * dimensions to keep the lower right crop corner unchanged. (Thus, the 62*dfc6aa5cSAndroid Build Coastguard Worker * output image covers at least the requested region, but may cover more.) 63*dfc6aa5cSAndroid Build Coastguard Worker * The adjustment of the region dimensions may be optionally disabled. 64*dfc6aa5cSAndroid Build Coastguard Worker * 65*dfc6aa5cSAndroid Build Coastguard Worker * A complementary lossless wipe option is provided to discard (gray out) data 66*dfc6aa5cSAndroid Build Coastguard Worker * inside a given image region while losslessly preserving what is outside. 67*dfc6aa5cSAndroid Build Coastguard Worker * A lossless drop option is also provided, which allows another JPEG image to 68*dfc6aa5cSAndroid Build Coastguard Worker * be inserted ("dropped") into the source image data at a given position, 69*dfc6aa5cSAndroid Build Coastguard Worker * replacing the existing image data at that position. Both the source image 70*dfc6aa5cSAndroid Build Coastguard Worker * and the drop image must have the same subsampling level. It is best if they 71*dfc6aa5cSAndroid Build Coastguard Worker * also have the same quantization (quality.) Otherwise, the quantization of 72*dfc6aa5cSAndroid Build Coastguard Worker * the output image will be adapted to accommodate the higher of the source 73*dfc6aa5cSAndroid Build Coastguard Worker * image quality and the drop image quality. The trim option can be used with 74*dfc6aa5cSAndroid Build Coastguard Worker * the drop option to requantize the drop image to match the source image. 75*dfc6aa5cSAndroid Build Coastguard Worker * 76*dfc6aa5cSAndroid Build Coastguard Worker * We also provide a lossless-resize option, which is kind of a lossless-crop 77*dfc6aa5cSAndroid Build Coastguard Worker * operation in the DCT coefficient block domain - it discards higher-order 78*dfc6aa5cSAndroid Build Coastguard Worker * coefficients and losslessly preserves lower-order coefficients of a 79*dfc6aa5cSAndroid Build Coastguard Worker * sub-block. 80*dfc6aa5cSAndroid Build Coastguard Worker * 81*dfc6aa5cSAndroid Build Coastguard Worker * Rotate/flip transform, resize, and crop can be requested together in a 82*dfc6aa5cSAndroid Build Coastguard Worker * single invocation. The crop is applied last --- that is, the crop region 83*dfc6aa5cSAndroid Build Coastguard Worker * is specified in terms of the destination image after transform/resize. 84*dfc6aa5cSAndroid Build Coastguard Worker * 85*dfc6aa5cSAndroid Build Coastguard Worker * We also offer a "force to grayscale" option, which simply discards the 86*dfc6aa5cSAndroid Build Coastguard Worker * chrominance channels of a YCbCr image. This is lossless in the sense that 87*dfc6aa5cSAndroid Build Coastguard Worker * the luminance channel is preserved exactly. It's not the same kind of 88*dfc6aa5cSAndroid Build Coastguard Worker * thing as the rotate/flip transformations, but it's convenient to handle it 89*dfc6aa5cSAndroid Build Coastguard Worker * as part of this package, mainly because the transformation routines have to 90*dfc6aa5cSAndroid Build Coastguard Worker * be aware of the option to know how many components to work on. 91*dfc6aa5cSAndroid Build Coastguard Worker */ 92*dfc6aa5cSAndroid Build Coastguard Worker 93*dfc6aa5cSAndroid Build Coastguard Worker 94*dfc6aa5cSAndroid Build Coastguard Worker /* 95*dfc6aa5cSAndroid Build Coastguard Worker * Codes for supported types of image transformations. 96*dfc6aa5cSAndroid Build Coastguard Worker */ 97*dfc6aa5cSAndroid Build Coastguard Worker 98*dfc6aa5cSAndroid Build Coastguard Worker typedef enum { 99*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_NONE, /* no transformation */ 100*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_FLIP_H, /* horizontal flip */ 101*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_FLIP_V, /* vertical flip */ 102*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ 103*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ 104*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_ROT_90, /* 90-degree clockwise rotation */ 105*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_ROT_180, /* 180-degree rotation */ 106*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_ROT_270, /* 270-degree clockwise (or 90 ccw) */ 107*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_WIPE, /* wipe */ 108*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_DROP /* drop */ 109*dfc6aa5cSAndroid Build Coastguard Worker } JXFORM_CODE; 110*dfc6aa5cSAndroid Build Coastguard Worker 111*dfc6aa5cSAndroid Build Coastguard Worker /* 112*dfc6aa5cSAndroid Build Coastguard Worker * Codes for crop parameters, which can individually be unspecified, 113*dfc6aa5cSAndroid Build Coastguard Worker * positive or negative for xoffset or yoffset, 114*dfc6aa5cSAndroid Build Coastguard Worker * positive or force or reflect for width or height. 115*dfc6aa5cSAndroid Build Coastguard Worker */ 116*dfc6aa5cSAndroid Build Coastguard Worker 117*dfc6aa5cSAndroid Build Coastguard Worker typedef enum { 118*dfc6aa5cSAndroid Build Coastguard Worker JCROP_UNSET, 119*dfc6aa5cSAndroid Build Coastguard Worker JCROP_POS, 120*dfc6aa5cSAndroid Build Coastguard Worker JCROP_NEG, 121*dfc6aa5cSAndroid Build Coastguard Worker JCROP_FORCE, 122*dfc6aa5cSAndroid Build Coastguard Worker JCROP_REFLECT 123*dfc6aa5cSAndroid Build Coastguard Worker } JCROP_CODE; 124*dfc6aa5cSAndroid Build Coastguard Worker 125*dfc6aa5cSAndroid Build Coastguard Worker /* 126*dfc6aa5cSAndroid Build Coastguard Worker * Transform parameters struct. 127*dfc6aa5cSAndroid Build Coastguard Worker * NB: application must not change any elements of this struct after 128*dfc6aa5cSAndroid Build Coastguard Worker * calling jtransform_request_workspace. 129*dfc6aa5cSAndroid Build Coastguard Worker */ 130*dfc6aa5cSAndroid Build Coastguard Worker 131*dfc6aa5cSAndroid Build Coastguard Worker typedef struct { 132*dfc6aa5cSAndroid Build Coastguard Worker /* Options: set by caller */ 133*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_CODE transform; /* image transform operator */ 134*dfc6aa5cSAndroid Build Coastguard Worker boolean perfect; /* if TRUE, fail if partial MCUs are requested */ 135*dfc6aa5cSAndroid Build Coastguard Worker boolean trim; /* if TRUE, trim partial MCUs as needed */ 136*dfc6aa5cSAndroid Build Coastguard Worker boolean force_grayscale; /* if TRUE, convert color image to grayscale */ 137*dfc6aa5cSAndroid Build Coastguard Worker boolean crop; /* if TRUE, crop or wipe source image, or drop */ 138*dfc6aa5cSAndroid Build Coastguard Worker boolean slow_hflip; /* For best performance, the JXFORM_FLIP_H transform 139*dfc6aa5cSAndroid Build Coastguard Worker normally modifies the source coefficients in place. 140*dfc6aa5cSAndroid Build Coastguard Worker Setting this to TRUE will instead use a slower, 141*dfc6aa5cSAndroid Build Coastguard Worker double-buffered algorithm, which leaves the source 142*dfc6aa5cSAndroid Build Coastguard Worker coefficients in tact (necessary if other transformed 143*dfc6aa5cSAndroid Build Coastguard Worker images must be generated from the same set of 144*dfc6aa5cSAndroid Build Coastguard Worker coefficients. */ 145*dfc6aa5cSAndroid Build Coastguard Worker 146*dfc6aa5cSAndroid Build Coastguard Worker /* Crop parameters: application need not set these unless crop is TRUE. 147*dfc6aa5cSAndroid Build Coastguard Worker * These can be filled in by jtransform_parse_crop_spec(). 148*dfc6aa5cSAndroid Build Coastguard Worker */ 149*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION crop_width; /* Width of selected region */ 150*dfc6aa5cSAndroid Build Coastguard Worker JCROP_CODE crop_width_set; /* (force-disables adjustment) */ 151*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION crop_height; /* Height of selected region */ 152*dfc6aa5cSAndroid Build Coastguard Worker JCROP_CODE crop_height_set; /* (force-disables adjustment) */ 153*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION crop_xoffset; /* X offset of selected region */ 154*dfc6aa5cSAndroid Build Coastguard Worker JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */ 155*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION crop_yoffset; /* Y offset of selected region */ 156*dfc6aa5cSAndroid Build Coastguard Worker JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */ 157*dfc6aa5cSAndroid Build Coastguard Worker 158*dfc6aa5cSAndroid Build Coastguard Worker /* Drop parameters: set by caller for drop request */ 159*dfc6aa5cSAndroid Build Coastguard Worker j_decompress_ptr drop_ptr; 160*dfc6aa5cSAndroid Build Coastguard Worker jvirt_barray_ptr *drop_coef_arrays; 161*dfc6aa5cSAndroid Build Coastguard Worker 162*dfc6aa5cSAndroid Build Coastguard Worker /* Internal workspace: caller should not touch these */ 163*dfc6aa5cSAndroid Build Coastguard Worker int num_components; /* # of components in workspace */ 164*dfc6aa5cSAndroid Build Coastguard Worker jvirt_barray_ptr *workspace_coef_arrays; /* workspace for transformations */ 165*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION output_width; /* cropped destination dimensions */ 166*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION output_height; 167*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */ 168*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION y_crop_offset; 169*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION drop_width; /* drop/wipe dimensions measured in iMCUs */ 170*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION drop_height; 171*dfc6aa5cSAndroid Build Coastguard Worker int iMCU_sample_width; /* destination iMCU size */ 172*dfc6aa5cSAndroid Build Coastguard Worker int iMCU_sample_height; 173*dfc6aa5cSAndroid Build Coastguard Worker } jpeg_transform_info; 174*dfc6aa5cSAndroid Build Coastguard Worker 175*dfc6aa5cSAndroid Build Coastguard Worker 176*dfc6aa5cSAndroid Build Coastguard Worker #if TRANSFORMS_SUPPORTED 177*dfc6aa5cSAndroid Build Coastguard Worker 178*dfc6aa5cSAndroid Build Coastguard Worker /* Parse a crop specification (written in X11 geometry style) */ 179*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(boolean) jtransform_parse_crop_spec(jpeg_transform_info *info, 180*dfc6aa5cSAndroid Build Coastguard Worker const char *spec); 181*dfc6aa5cSAndroid Build Coastguard Worker /* Request any required workspace */ 182*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(boolean) jtransform_request_workspace(j_decompress_ptr srcinfo, 183*dfc6aa5cSAndroid Build Coastguard Worker jpeg_transform_info *info); 184*dfc6aa5cSAndroid Build Coastguard Worker /* Adjust output image parameters */ 185*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters 186*dfc6aa5cSAndroid Build Coastguard Worker (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 187*dfc6aa5cSAndroid Build Coastguard Worker jvirt_barray_ptr *src_coef_arrays, jpeg_transform_info *info); 188*dfc6aa5cSAndroid Build Coastguard Worker /* Execute the actual transformation, if any */ 189*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(void) jtransform_execute_transform(j_decompress_ptr srcinfo, 190*dfc6aa5cSAndroid Build Coastguard Worker j_compress_ptr dstinfo, 191*dfc6aa5cSAndroid Build Coastguard Worker jvirt_barray_ptr *src_coef_arrays, 192*dfc6aa5cSAndroid Build Coastguard Worker jpeg_transform_info *info); 193*dfc6aa5cSAndroid Build Coastguard Worker /* Determine whether lossless transformation is perfectly 194*dfc6aa5cSAndroid Build Coastguard Worker * possible for a specified image and transformation. 195*dfc6aa5cSAndroid Build Coastguard Worker */ 196*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(boolean) jtransform_perfect_transform(JDIMENSION image_width, 197*dfc6aa5cSAndroid Build Coastguard Worker JDIMENSION image_height, 198*dfc6aa5cSAndroid Build Coastguard Worker int MCU_width, int MCU_height, 199*dfc6aa5cSAndroid Build Coastguard Worker JXFORM_CODE transform); 200*dfc6aa5cSAndroid Build Coastguard Worker 201*dfc6aa5cSAndroid Build Coastguard Worker /* jtransform_execute_transform used to be called 202*dfc6aa5cSAndroid Build Coastguard Worker * jtransform_execute_transformation, but some compilers complain about 203*dfc6aa5cSAndroid Build Coastguard Worker * routine names that long. This macro is here to avoid breaking any 204*dfc6aa5cSAndroid Build Coastguard Worker * old source code that uses the original name... 205*dfc6aa5cSAndroid Build Coastguard Worker */ 206*dfc6aa5cSAndroid Build Coastguard Worker #define jtransform_execute_transformation jtransform_execute_transform 207*dfc6aa5cSAndroid Build Coastguard Worker 208*dfc6aa5cSAndroid Build Coastguard Worker #endif /* TRANSFORMS_SUPPORTED */ 209*dfc6aa5cSAndroid Build Coastguard Worker 210*dfc6aa5cSAndroid Build Coastguard Worker 211*dfc6aa5cSAndroid Build Coastguard Worker /* 212*dfc6aa5cSAndroid Build Coastguard Worker * Support for copying optional markers from source to destination file. 213*dfc6aa5cSAndroid Build Coastguard Worker */ 214*dfc6aa5cSAndroid Build Coastguard Worker 215*dfc6aa5cSAndroid Build Coastguard Worker typedef enum { 216*dfc6aa5cSAndroid Build Coastguard Worker JCOPYOPT_NONE, /* copy no optional markers */ 217*dfc6aa5cSAndroid Build Coastguard Worker JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ 218*dfc6aa5cSAndroid Build Coastguard Worker JCOPYOPT_ALL, /* copy all optional markers */ 219*dfc6aa5cSAndroid Build Coastguard Worker JCOPYOPT_ALL_EXCEPT_ICC, /* copy all optional markers except APP2 */ 220*dfc6aa5cSAndroid Build Coastguard Worker JCOPYOPT_ICC /* copy only ICC profile (APP2) markers */ 221*dfc6aa5cSAndroid Build Coastguard Worker } JCOPY_OPTION; 222*dfc6aa5cSAndroid Build Coastguard Worker 223*dfc6aa5cSAndroid Build Coastguard Worker #define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ 224*dfc6aa5cSAndroid Build Coastguard Worker 225*dfc6aa5cSAndroid Build Coastguard Worker /* Setup decompression object to save desired markers in memory */ 226*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(void) jcopy_markers_setup(j_decompress_ptr srcinfo, 227*dfc6aa5cSAndroid Build Coastguard Worker JCOPY_OPTION option); 228*dfc6aa5cSAndroid Build Coastguard Worker /* Copy markers saved in the given source object to the destination object */ 229*dfc6aa5cSAndroid Build Coastguard Worker EXTERN(void) jcopy_markers_execute(j_decompress_ptr srcinfo, 230*dfc6aa5cSAndroid Build Coastguard Worker j_compress_ptr dstinfo, 231*dfc6aa5cSAndroid Build Coastguard Worker JCOPY_OPTION option); 232