1*593dc095SDavid du Colombier /* 2*593dc095SDavid du Colombier * transupp.h 3*593dc095SDavid du Colombier * 4*593dc095SDavid du Colombier * Copyright (C) 1997, Thomas G. Lane. 5*593dc095SDavid du Colombier * This file is part of the Independent JPEG Group's software. 6*593dc095SDavid du Colombier * For conditions of distribution and use, see the accompanying README file. 7*593dc095SDavid du Colombier * 8*593dc095SDavid du Colombier * This file contains declarations for image transformation routines and 9*593dc095SDavid du Colombier * other utility code used by the jpegtran sample application. These are 10*593dc095SDavid du Colombier * NOT part of the core JPEG library. But we keep these routines separate 11*593dc095SDavid du Colombier * from jpegtran.c to ease the task of maintaining jpegtran-like programs 12*593dc095SDavid du Colombier * that have other user interfaces. 13*593dc095SDavid du Colombier * 14*593dc095SDavid du Colombier * NOTE: all the routines declared here have very specific requirements 15*593dc095SDavid du Colombier * about when they are to be executed during the reading and writing of the 16*593dc095SDavid du Colombier * source and destination files. See the comments in transupp.c, or see 17*593dc095SDavid du Colombier * jpegtran.c for an example of correct usage. 18*593dc095SDavid du Colombier */ 19*593dc095SDavid du Colombier 20*593dc095SDavid du Colombier /* If you happen not to want the image transform support, disable it here */ 21*593dc095SDavid du Colombier #ifndef TRANSFORMS_SUPPORTED 22*593dc095SDavid du Colombier #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ 23*593dc095SDavid du Colombier #endif 24*593dc095SDavid du Colombier 25*593dc095SDavid du Colombier /* Short forms of external names for systems with brain-damaged linkers. */ 26*593dc095SDavid du Colombier 27*593dc095SDavid du Colombier #ifdef NEED_SHORT_EXTERNAL_NAMES 28*593dc095SDavid du Colombier #define jtransform_request_workspace jTrRequest 29*593dc095SDavid du Colombier #define jtransform_adjust_parameters jTrAdjust 30*593dc095SDavid du Colombier #define jtransform_execute_transformation jTrExec 31*593dc095SDavid du Colombier #define jcopy_markers_setup jCMrkSetup 32*593dc095SDavid du Colombier #define jcopy_markers_execute jCMrkExec 33*593dc095SDavid du Colombier #endif /* NEED_SHORT_EXTERNAL_NAMES */ 34*593dc095SDavid du Colombier 35*593dc095SDavid du Colombier 36*593dc095SDavid du Colombier /* 37*593dc095SDavid du Colombier * Codes for supported types of image transformations. 38*593dc095SDavid du Colombier */ 39*593dc095SDavid du Colombier 40*593dc095SDavid du Colombier typedef enum { 41*593dc095SDavid du Colombier JXFORM_NONE, /* no transformation */ 42*593dc095SDavid du Colombier JXFORM_FLIP_H, /* horizontal flip */ 43*593dc095SDavid du Colombier JXFORM_FLIP_V, /* vertical flip */ 44*593dc095SDavid du Colombier JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ 45*593dc095SDavid du Colombier JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ 46*593dc095SDavid du Colombier JXFORM_ROT_90, /* 90-degree clockwise rotation */ 47*593dc095SDavid du Colombier JXFORM_ROT_180, /* 180-degree rotation */ 48*593dc095SDavid du Colombier JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ 49*593dc095SDavid du Colombier } JXFORM_CODE; 50*593dc095SDavid du Colombier 51*593dc095SDavid du Colombier /* 52*593dc095SDavid du Colombier * Although rotating and flipping data expressed as DCT coefficients is not 53*593dc095SDavid du Colombier * hard, there is an asymmetry in the JPEG format specification for images 54*593dc095SDavid du Colombier * whose dimensions aren't multiples of the iMCU size. The right and bottom 55*593dc095SDavid du Colombier * image edges are padded out to the next iMCU boundary with junk data; but 56*593dc095SDavid du Colombier * no padding is possible at the top and left edges. If we were to flip 57*593dc095SDavid du Colombier * the whole image including the pad data, then pad garbage would become 58*593dc095SDavid du Colombier * visible at the top and/or left, and real pixels would disappear into the 59*593dc095SDavid du Colombier * pad margins --- perhaps permanently, since encoders & decoders may not 60*593dc095SDavid du Colombier * bother to preserve DCT blocks that appear to be completely outside the 61*593dc095SDavid du Colombier * nominal image area. So, we have to exclude any partial iMCUs from the 62*593dc095SDavid du Colombier * basic transformation. 63*593dc095SDavid du Colombier * 64*593dc095SDavid du Colombier * Transpose is the only transformation that can handle partial iMCUs at the 65*593dc095SDavid du Colombier * right and bottom edges completely cleanly. flip_h can flip partial iMCUs 66*593dc095SDavid du Colombier * at the bottom, but leaves any partial iMCUs at the right edge untouched. 67*593dc095SDavid du Colombier * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. 68*593dc095SDavid du Colombier * The other transforms are defined as combinations of these basic transforms 69*593dc095SDavid du Colombier * and process edge blocks in a way that preserves the equivalence. 70*593dc095SDavid du Colombier * 71*593dc095SDavid du Colombier * The "trim" option causes untransformable partial iMCUs to be dropped; 72*593dc095SDavid du Colombier * this is not strictly lossless, but it usually gives the best-looking 73*593dc095SDavid du Colombier * result for odd-size images. Note that when this option is active, 74*593dc095SDavid du Colombier * the expected mathematical equivalences between the transforms may not hold. 75*593dc095SDavid du Colombier * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim 76*593dc095SDavid du Colombier * followed by -rot 180 -trim trims both edges.) 77*593dc095SDavid du Colombier * 78*593dc095SDavid du Colombier * We also offer a "force to grayscale" option, which simply discards the 79*593dc095SDavid du Colombier * chrominance channels of a YCbCr image. This is lossless in the sense that 80*593dc095SDavid du Colombier * the luminance channel is preserved exactly. It's not the same kind of 81*593dc095SDavid du Colombier * thing as the rotate/flip transformations, but it's convenient to handle it 82*593dc095SDavid du Colombier * as part of this package, mainly because the transformation routines have to 83*593dc095SDavid du Colombier * be aware of the option to know how many components to work on. 84*593dc095SDavid du Colombier */ 85*593dc095SDavid du Colombier 86*593dc095SDavid du Colombier typedef struct { 87*593dc095SDavid du Colombier /* Options: set by caller */ 88*593dc095SDavid du Colombier JXFORM_CODE transform; /* image transform operator */ 89*593dc095SDavid du Colombier boolean trim; /* if TRUE, trim partial MCUs as needed */ 90*593dc095SDavid du Colombier boolean force_grayscale; /* if TRUE, convert color image to grayscale */ 91*593dc095SDavid du Colombier 92*593dc095SDavid du Colombier /* Internal workspace: caller should not touch these */ 93*593dc095SDavid du Colombier int num_components; /* # of components in workspace */ 94*593dc095SDavid du Colombier jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ 95*593dc095SDavid du Colombier } jpeg_transform_info; 96*593dc095SDavid du Colombier 97*593dc095SDavid du Colombier 98*593dc095SDavid du Colombier #if TRANSFORMS_SUPPORTED 99*593dc095SDavid du Colombier 100*593dc095SDavid du Colombier /* Request any required workspace */ 101*593dc095SDavid du Colombier EXTERN(void) jtransform_request_workspace 102*593dc095SDavid du Colombier JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); 103*593dc095SDavid du Colombier /* Adjust output image parameters */ 104*593dc095SDavid du Colombier EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters 105*593dc095SDavid du Colombier JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 106*593dc095SDavid du Colombier jvirt_barray_ptr *src_coef_arrays, 107*593dc095SDavid du Colombier jpeg_transform_info *info)); 108*593dc095SDavid du Colombier /* Execute the actual transformation, if any */ 109*593dc095SDavid du Colombier EXTERN(void) jtransform_execute_transformation 110*593dc095SDavid du Colombier JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 111*593dc095SDavid du Colombier jvirt_barray_ptr *src_coef_arrays, 112*593dc095SDavid du Colombier jpeg_transform_info *info)); 113*593dc095SDavid du Colombier 114*593dc095SDavid du Colombier #endif /* TRANSFORMS_SUPPORTED */ 115*593dc095SDavid du Colombier 116*593dc095SDavid du Colombier 117*593dc095SDavid du Colombier /* 118*593dc095SDavid du Colombier * Support for copying optional markers from source to destination file. 119*593dc095SDavid du Colombier */ 120*593dc095SDavid du Colombier 121*593dc095SDavid du Colombier typedef enum { 122*593dc095SDavid du Colombier JCOPYOPT_NONE, /* copy no optional markers */ 123*593dc095SDavid du Colombier JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ 124*593dc095SDavid du Colombier JCOPYOPT_ALL /* copy all optional markers */ 125*593dc095SDavid du Colombier } JCOPY_OPTION; 126*593dc095SDavid du Colombier 127*593dc095SDavid du Colombier #define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ 128*593dc095SDavid du Colombier 129*593dc095SDavid du Colombier /* Setup decompression object to save desired markers in memory */ 130*593dc095SDavid du Colombier EXTERN(void) jcopy_markers_setup 131*593dc095SDavid du Colombier JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); 132*593dc095SDavid du Colombier /* Copy markers saved in the given source object to the destination object */ 133*593dc095SDavid du Colombier EXTERN(void) jcopy_markers_execute 134*593dc095SDavid du Colombier JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 135*593dc095SDavid du Colombier JCOPY_OPTION option)); 136