xref: /aosp_15_r20/external/libjpeg-turbo/transupp.h (revision dfc6aa5c1cfd4bc4e2018dc74aa96e29ee49c6da)
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