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