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