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