aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c3194
1 files changed, 1597 insertions, 1597 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c b/libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c
index fe34a3a..016f383 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c
+++ b/libraries/irrlicht-1.8/source/Irrlicht/jpeglib/transupp.c
@@ -1,1597 +1,1597 @@
1/* 1/*
2 * transupp.c 2 * transupp.c
3 * 3 *
4 * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding. 4 * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
5 * This file is part of the Independent JPEG Group's software. 5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file. 6 * For conditions of distribution and use, see the accompanying README file.
7 * 7 *
8 * This file contains image transformation routines and other utility code 8 * This file contains image transformation routines and other utility code
9 * used by the jpegtran sample application. These are NOT part of the core 9 * used by the jpegtran sample application. These are NOT part of the core
10 * JPEG library. But we keep these routines separate from jpegtran.c to 10 * JPEG library. But we keep these routines separate from jpegtran.c to
11 * ease the task of maintaining jpegtran-like programs that have other user 11 * ease the task of maintaining jpegtran-like programs that have other user
12 * interfaces. 12 * interfaces.
13 */ 13 */
14 14
15/* Although this file really shouldn't have access to the library internals, 15/* Although this file really shouldn't have access to the library internals,
16 * it's helpful to let it call jround_up() and jcopy_block_row(). 16 * it's helpful to let it call jround_up() and jcopy_block_row().
17 */ 17 */
18#define JPEG_INTERNALS 18#define JPEG_INTERNALS
19 19
20#include "jinclude.h" 20#include "jinclude.h"
21#include "jpeglib.h" 21#include "jpeglib.h"
22#include "transupp.h" /* My own external interface */ 22#include "transupp.h" /* My own external interface */
23#include <ctype.h> /* to declare isdigit() */ 23#include <ctype.h> /* to declare isdigit() */
24 24
25 25
26#if TRANSFORMS_SUPPORTED 26#if TRANSFORMS_SUPPORTED
27 27
28/* 28/*
29 * Lossless image transformation routines. These routines work on DCT 29 * Lossless image transformation routines. These routines work on DCT
30 * coefficient arrays and thus do not require any lossy decompression 30 * coefficient arrays and thus do not require any lossy decompression
31 * or recompression of the image. 31 * or recompression of the image.
32 * Thanks to Guido Vollbeding for the initial design and code of this feature, 32 * Thanks to Guido Vollbeding for the initial design and code of this feature,
33 * and to Ben Jackson for introducing the cropping feature. 33 * and to Ben Jackson for introducing the cropping feature.
34 * 34 *
35 * Horizontal flipping is done in-place, using a single top-to-bottom 35 * Horizontal flipping is done in-place, using a single top-to-bottom
36 * pass through the virtual source array. It will thus be much the 36 * pass through the virtual source array. It will thus be much the
37 * fastest option for images larger than main memory. 37 * fastest option for images larger than main memory.
38 * 38 *
39 * The other routines require a set of destination virtual arrays, so they 39 * The other routines require a set of destination virtual arrays, so they
40 * need twice as much memory as jpegtran normally does. The destination 40 * need twice as much memory as jpegtran normally does. The destination
41 * arrays are always written in normal scan order (top to bottom) because 41 * arrays are always written in normal scan order (top to bottom) because
42 * the virtual array manager expects this. The source arrays will be scanned 42 * the virtual array manager expects this. The source arrays will be scanned
43 * in the corresponding order, which means multiple passes through the source 43 * in the corresponding order, which means multiple passes through the source
44 * arrays for most of the transforms. That could result in much thrashing 44 * arrays for most of the transforms. That could result in much thrashing
45 * if the image is larger than main memory. 45 * if the image is larger than main memory.
46 * 46 *
47 * If cropping or trimming is involved, the destination arrays may be smaller 47 * If cropping or trimming is involved, the destination arrays may be smaller
48 * than the source arrays. Note it is not possible to do horizontal flip 48 * than the source arrays. Note it is not possible to do horizontal flip
49 * in-place when a nonzero Y crop offset is specified, since we'd have to move 49 * in-place when a nonzero Y crop offset is specified, since we'd have to move
50 * data from one block row to another but the virtual array manager doesn't 50 * data from one block row to another but the virtual array manager doesn't
51 * guarantee we can touch more than one row at a time. So in that case, 51 * guarantee we can touch more than one row at a time. So in that case,
52 * we have to use a separate destination array. 52 * we have to use a separate destination array.
53 * 53 *
54 * Some notes about the operating environment of the individual transform 54 * Some notes about the operating environment of the individual transform
55 * routines: 55 * routines:
56 * 1. Both the source and destination virtual arrays are allocated from the 56 * 1. Both the source and destination virtual arrays are allocated from the
57 * source JPEG object, and therefore should be manipulated by calling the 57 * source JPEG object, and therefore should be manipulated by calling the
58 * source's memory manager. 58 * source's memory manager.
59 * 2. The destination's component count should be used. It may be smaller 59 * 2. The destination's component count should be used. It may be smaller
60 * than the source's when forcing to grayscale. 60 * than the source's when forcing to grayscale.
61 * 3. Likewise the destination's sampling factors should be used. When 61 * 3. Likewise the destination's sampling factors should be used. When
62 * forcing to grayscale the destination's sampling factors will be all 1, 62 * forcing to grayscale the destination's sampling factors will be all 1,
63 * and we may as well take that as the effective iMCU size. 63 * and we may as well take that as the effective iMCU size.
64 * 4. When "trim" is in effect, the destination's dimensions will be the 64 * 4. When "trim" is in effect, the destination's dimensions will be the
65 * trimmed values but the source's will be untrimmed. 65 * trimmed values but the source's will be untrimmed.
66 * 5. When "crop" is in effect, the destination's dimensions will be the 66 * 5. When "crop" is in effect, the destination's dimensions will be the
67 * cropped values but the source's will be uncropped. Each transform 67 * cropped values but the source's will be uncropped. Each transform
68 * routine is responsible for picking up source data starting at the 68 * routine is responsible for picking up source data starting at the
69 * correct X and Y offset for the crop region. (The X and Y offsets 69 * correct X and Y offset for the crop region. (The X and Y offsets
70 * passed to the transform routines are measured in iMCU blocks of the 70 * passed to the transform routines are measured in iMCU blocks of the
71 * destination.) 71 * destination.)
72 * 6. All the routines assume that the source and destination buffers are 72 * 6. All the routines assume that the source and destination buffers are
73 * padded out to a full iMCU boundary. This is true, although for the 73 * padded out to a full iMCU boundary. This is true, although for the
74 * source buffer it is an undocumented property of jdcoefct.c. 74 * source buffer it is an undocumented property of jdcoefct.c.
75 */ 75 */
76 76
77 77
78LOCAL(void) 78LOCAL(void)
79do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 79do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
80 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 80 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
81 jvirt_barray_ptr *src_coef_arrays, 81 jvirt_barray_ptr *src_coef_arrays,
82 jvirt_barray_ptr *dst_coef_arrays) 82 jvirt_barray_ptr *dst_coef_arrays)
83/* Crop. This is only used when no rotate/flip is requested with the crop. */ 83/* Crop. This is only used when no rotate/flip is requested with the crop. */
84{ 84{
85 JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks; 85 JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
86 int ci, offset_y; 86 int ci, offset_y;
87 JBLOCKARRAY src_buffer, dst_buffer; 87 JBLOCKARRAY src_buffer, dst_buffer;
88 jpeg_component_info *compptr; 88 jpeg_component_info *compptr;
89 89
90 /* We simply have to copy the right amount of data (the destination's 90 /* We simply have to copy the right amount of data (the destination's
91 * image size) starting at the given X and Y offsets in the source. 91 * image size) starting at the given X and Y offsets in the source.
92 */ 92 */
93 for (ci = 0; ci < dstinfo->num_components; ci++) { 93 for (ci = 0; ci < dstinfo->num_components; ci++) {
94 compptr = dstinfo->comp_info + ci; 94 compptr = dstinfo->comp_info + ci;
95 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 95 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
96 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 96 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
97 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 97 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
98 dst_blk_y += compptr->v_samp_factor) { 98 dst_blk_y += compptr->v_samp_factor) {
99 dst_buffer = (*srcinfo->mem->access_virt_barray) 99 dst_buffer = (*srcinfo->mem->access_virt_barray)
100 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 100 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
101 (JDIMENSION) compptr->v_samp_factor, TRUE); 101 (JDIMENSION) compptr->v_samp_factor, TRUE);
102 src_buffer = (*srcinfo->mem->access_virt_barray) 102 src_buffer = (*srcinfo->mem->access_virt_barray)
103 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 103 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
104 dst_blk_y + y_crop_blocks, 104 dst_blk_y + y_crop_blocks,
105 (JDIMENSION) compptr->v_samp_factor, FALSE); 105 (JDIMENSION) compptr->v_samp_factor, FALSE);
106 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 106 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
107 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, 107 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
108 dst_buffer[offset_y], 108 dst_buffer[offset_y],
109 compptr->width_in_blocks); 109 compptr->width_in_blocks);
110 } 110 }
111 } 111 }
112 } 112 }
113} 113}
114 114
115 115
116LOCAL(void) 116LOCAL(void)
117do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 117do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
118 JDIMENSION x_crop_offset, 118 JDIMENSION x_crop_offset,
119 jvirt_barray_ptr *src_coef_arrays) 119 jvirt_barray_ptr *src_coef_arrays)
120/* Horizontal flip; done in-place, so no separate dest array is required. 120/* Horizontal flip; done in-place, so no separate dest array is required.
121 * NB: this only works when y_crop_offset is zero. 121 * NB: this only works when y_crop_offset is zero.
122 */ 122 */
123{ 123{
124 JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks; 124 JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
125 int ci, k, offset_y; 125 int ci, k, offset_y;
126 JBLOCKARRAY buffer; 126 JBLOCKARRAY buffer;
127 JCOEFPTR ptr1, ptr2; 127 JCOEFPTR ptr1, ptr2;
128 JCOEF temp1, temp2; 128 JCOEF temp1, temp2;
129 jpeg_component_info *compptr; 129 jpeg_component_info *compptr;
130 130
131 /* Horizontal mirroring of DCT blocks is accomplished by swapping 131 /* Horizontal mirroring of DCT blocks is accomplished by swapping
132 * pairs of blocks in-place. Within a DCT block, we perform horizontal 132 * pairs of blocks in-place. Within a DCT block, we perform horizontal
133 * mirroring by changing the signs of odd-numbered columns. 133 * mirroring by changing the signs of odd-numbered columns.
134 * Partial iMCUs at the right edge are left untouched. 134 * Partial iMCUs at the right edge are left untouched.
135 */ 135 */
136 MCU_cols = srcinfo->output_width / 136 MCU_cols = srcinfo->output_width /
137 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size); 137 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
138 138
139 for (ci = 0; ci < dstinfo->num_components; ci++) { 139 for (ci = 0; ci < dstinfo->num_components; ci++) {
140 compptr = dstinfo->comp_info + ci; 140 compptr = dstinfo->comp_info + ci;
141 comp_width = MCU_cols * compptr->h_samp_factor; 141 comp_width = MCU_cols * compptr->h_samp_factor;
142 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 142 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
143 for (blk_y = 0; blk_y < compptr->height_in_blocks; 143 for (blk_y = 0; blk_y < compptr->height_in_blocks;
144 blk_y += compptr->v_samp_factor) { 144 blk_y += compptr->v_samp_factor) {
145 buffer = (*srcinfo->mem->access_virt_barray) 145 buffer = (*srcinfo->mem->access_virt_barray)
146 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, 146 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
147 (JDIMENSION) compptr->v_samp_factor, TRUE); 147 (JDIMENSION) compptr->v_samp_factor, TRUE);
148 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 148 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
149 /* Do the mirroring */ 149 /* Do the mirroring */
150 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { 150 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
151 ptr1 = buffer[offset_y][blk_x]; 151 ptr1 = buffer[offset_y][blk_x];
152 ptr2 = buffer[offset_y][comp_width - blk_x - 1]; 152 ptr2 = buffer[offset_y][comp_width - blk_x - 1];
153 /* this unrolled loop doesn't need to know which row it's on... */ 153 /* this unrolled loop doesn't need to know which row it's on... */
154 for (k = 0; k < DCTSIZE2; k += 2) { 154 for (k = 0; k < DCTSIZE2; k += 2) {
155 temp1 = *ptr1; /* swap even column */ 155 temp1 = *ptr1; /* swap even column */
156 temp2 = *ptr2; 156 temp2 = *ptr2;
157 *ptr1++ = temp2; 157 *ptr1++ = temp2;
158 *ptr2++ = temp1; 158 *ptr2++ = temp1;
159 temp1 = *ptr1; /* swap odd column with sign change */ 159 temp1 = *ptr1; /* swap odd column with sign change */
160 temp2 = *ptr2; 160 temp2 = *ptr2;
161 *ptr1++ = -temp2; 161 *ptr1++ = -temp2;
162 *ptr2++ = -temp1; 162 *ptr2++ = -temp1;
163 } 163 }
164 } 164 }
165 if (x_crop_blocks > 0) { 165 if (x_crop_blocks > 0) {
166 /* Now left-justify the portion of the data to be kept. 166 /* Now left-justify the portion of the data to be kept.
167 * We can't use a single jcopy_block_row() call because that routine 167 * We can't use a single jcopy_block_row() call because that routine
168 * depends on memcpy(), whose behavior is unspecified for overlapping 168 * depends on memcpy(), whose behavior is unspecified for overlapping
169 * source and destination areas. Sigh. 169 * source and destination areas. Sigh.
170 */ 170 */
171 for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { 171 for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
172 jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks, 172 jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
173 buffer[offset_y] + blk_x, 173 buffer[offset_y] + blk_x,
174 (JDIMENSION) 1); 174 (JDIMENSION) 1);
175 } 175 }
176 } 176 }
177 } 177 }
178 } 178 }
179 } 179 }
180} 180}
181 181
182 182
183LOCAL(void) 183LOCAL(void)
184do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 184do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
185 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 185 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
186 jvirt_barray_ptr *src_coef_arrays, 186 jvirt_barray_ptr *src_coef_arrays,
187 jvirt_barray_ptr *dst_coef_arrays) 187 jvirt_barray_ptr *dst_coef_arrays)
188/* Horizontal flip in general cropping case */ 188/* Horizontal flip in general cropping case */
189{ 189{
190 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 190 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
191 JDIMENSION x_crop_blocks, y_crop_blocks; 191 JDIMENSION x_crop_blocks, y_crop_blocks;
192 int ci, k, offset_y; 192 int ci, k, offset_y;
193 JBLOCKARRAY src_buffer, dst_buffer; 193 JBLOCKARRAY src_buffer, dst_buffer;
194 JBLOCKROW src_row_ptr, dst_row_ptr; 194 JBLOCKROW src_row_ptr, dst_row_ptr;
195 JCOEFPTR src_ptr, dst_ptr; 195 JCOEFPTR src_ptr, dst_ptr;
196 jpeg_component_info *compptr; 196 jpeg_component_info *compptr;
197 197
198 /* Here we must output into a separate array because we can't touch 198 /* Here we must output into a separate array because we can't touch
199 * different rows of a single virtual array simultaneously. Otherwise, 199 * different rows of a single virtual array simultaneously. Otherwise,
200 * this is essentially the same as the routine above. 200 * this is essentially the same as the routine above.
201 */ 201 */
202 MCU_cols = srcinfo->output_width / 202 MCU_cols = srcinfo->output_width /
203 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size); 203 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
204 204
205 for (ci = 0; ci < dstinfo->num_components; ci++) { 205 for (ci = 0; ci < dstinfo->num_components; ci++) {
206 compptr = dstinfo->comp_info + ci; 206 compptr = dstinfo->comp_info + ci;
207 comp_width = MCU_cols * compptr->h_samp_factor; 207 comp_width = MCU_cols * compptr->h_samp_factor;
208 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 208 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
209 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 209 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
210 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 210 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
211 dst_blk_y += compptr->v_samp_factor) { 211 dst_blk_y += compptr->v_samp_factor) {
212 dst_buffer = (*srcinfo->mem->access_virt_barray) 212 dst_buffer = (*srcinfo->mem->access_virt_barray)
213 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 213 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
214 (JDIMENSION) compptr->v_samp_factor, TRUE); 214 (JDIMENSION) compptr->v_samp_factor, TRUE);
215 src_buffer = (*srcinfo->mem->access_virt_barray) 215 src_buffer = (*srcinfo->mem->access_virt_barray)
216 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 216 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
217 dst_blk_y + y_crop_blocks, 217 dst_blk_y + y_crop_blocks,
218 (JDIMENSION) compptr->v_samp_factor, FALSE); 218 (JDIMENSION) compptr->v_samp_factor, FALSE);
219 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 219 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
220 dst_row_ptr = dst_buffer[offset_y]; 220 dst_row_ptr = dst_buffer[offset_y];
221 src_row_ptr = src_buffer[offset_y]; 221 src_row_ptr = src_buffer[offset_y];
222 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 222 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
223 if (x_crop_blocks + dst_blk_x < comp_width) { 223 if (x_crop_blocks + dst_blk_x < comp_width) {
224 /* Do the mirrorable blocks */ 224 /* Do the mirrorable blocks */
225 dst_ptr = dst_row_ptr[dst_blk_x]; 225 dst_ptr = dst_row_ptr[dst_blk_x];
226 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 226 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
227 /* this unrolled loop doesn't need to know which row it's on... */ 227 /* this unrolled loop doesn't need to know which row it's on... */
228 for (k = 0; k < DCTSIZE2; k += 2) { 228 for (k = 0; k < DCTSIZE2; k += 2) {
229 *dst_ptr++ = *src_ptr++; /* copy even column */ 229 *dst_ptr++ = *src_ptr++; /* copy even column */
230 *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */ 230 *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
231 } 231 }
232 } else { 232 } else {
233 /* Copy last partial block(s) verbatim */ 233 /* Copy last partial block(s) verbatim */
234 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, 234 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
235 dst_row_ptr + dst_blk_x, 235 dst_row_ptr + dst_blk_x,
236 (JDIMENSION) 1); 236 (JDIMENSION) 1);
237 } 237 }
238 } 238 }
239 } 239 }
240 } 240 }
241 } 241 }
242} 242}
243 243
244 244
245LOCAL(void) 245LOCAL(void)
246do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 246do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
247 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 247 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
248 jvirt_barray_ptr *src_coef_arrays, 248 jvirt_barray_ptr *src_coef_arrays,
249 jvirt_barray_ptr *dst_coef_arrays) 249 jvirt_barray_ptr *dst_coef_arrays)
250/* Vertical flip */ 250/* Vertical flip */
251{ 251{
252 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 252 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
253 JDIMENSION x_crop_blocks, y_crop_blocks; 253 JDIMENSION x_crop_blocks, y_crop_blocks;
254 int ci, i, j, offset_y; 254 int ci, i, j, offset_y;
255 JBLOCKARRAY src_buffer, dst_buffer; 255 JBLOCKARRAY src_buffer, dst_buffer;
256 JBLOCKROW src_row_ptr, dst_row_ptr; 256 JBLOCKROW src_row_ptr, dst_row_ptr;
257 JCOEFPTR src_ptr, dst_ptr; 257 JCOEFPTR src_ptr, dst_ptr;
258 jpeg_component_info *compptr; 258 jpeg_component_info *compptr;
259 259
260 /* We output into a separate array because we can't touch different 260 /* We output into a separate array because we can't touch different
261 * rows of the source virtual array simultaneously. Otherwise, this 261 * rows of the source virtual array simultaneously. Otherwise, this
262 * is a pretty straightforward analog of horizontal flip. 262 * is a pretty straightforward analog of horizontal flip.
263 * Within a DCT block, vertical mirroring is done by changing the signs 263 * Within a DCT block, vertical mirroring is done by changing the signs
264 * of odd-numbered rows. 264 * of odd-numbered rows.
265 * Partial iMCUs at the bottom edge are copied verbatim. 265 * Partial iMCUs at the bottom edge are copied verbatim.
266 */ 266 */
267 MCU_rows = srcinfo->output_height / 267 MCU_rows = srcinfo->output_height /
268 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size); 268 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
269 269
270 for (ci = 0; ci < dstinfo->num_components; ci++) { 270 for (ci = 0; ci < dstinfo->num_components; ci++) {
271 compptr = dstinfo->comp_info + ci; 271 compptr = dstinfo->comp_info + ci;
272 comp_height = MCU_rows * compptr->v_samp_factor; 272 comp_height = MCU_rows * compptr->v_samp_factor;
273 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 273 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
274 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 274 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
275 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 275 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
276 dst_blk_y += compptr->v_samp_factor) { 276 dst_blk_y += compptr->v_samp_factor) {
277 dst_buffer = (*srcinfo->mem->access_virt_barray) 277 dst_buffer = (*srcinfo->mem->access_virt_barray)
278 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 278 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
279 (JDIMENSION) compptr->v_samp_factor, TRUE); 279 (JDIMENSION) compptr->v_samp_factor, TRUE);
280 if (y_crop_blocks + dst_blk_y < comp_height) { 280 if (y_crop_blocks + dst_blk_y < comp_height) {
281 /* Row is within the mirrorable area. */ 281 /* Row is within the mirrorable area. */
282 src_buffer = (*srcinfo->mem->access_virt_barray) 282 src_buffer = (*srcinfo->mem->access_virt_barray)
283 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 283 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
284 comp_height - y_crop_blocks - dst_blk_y - 284 comp_height - y_crop_blocks - dst_blk_y -
285 (JDIMENSION) compptr->v_samp_factor, 285 (JDIMENSION) compptr->v_samp_factor,
286 (JDIMENSION) compptr->v_samp_factor, FALSE); 286 (JDIMENSION) compptr->v_samp_factor, FALSE);
287 } else { 287 } else {
288 /* Bottom-edge blocks will be copied verbatim. */ 288 /* Bottom-edge blocks will be copied verbatim. */
289 src_buffer = (*srcinfo->mem->access_virt_barray) 289 src_buffer = (*srcinfo->mem->access_virt_barray)
290 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 290 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
291 dst_blk_y + y_crop_blocks, 291 dst_blk_y + y_crop_blocks,
292 (JDIMENSION) compptr->v_samp_factor, FALSE); 292 (JDIMENSION) compptr->v_samp_factor, FALSE);
293 } 293 }
294 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 294 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
295 if (y_crop_blocks + dst_blk_y < comp_height) { 295 if (y_crop_blocks + dst_blk_y < comp_height) {
296 /* Row is within the mirrorable area. */ 296 /* Row is within the mirrorable area. */
297 dst_row_ptr = dst_buffer[offset_y]; 297 dst_row_ptr = dst_buffer[offset_y];
298 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 298 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
299 src_row_ptr += x_crop_blocks; 299 src_row_ptr += x_crop_blocks;
300 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 300 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
301 dst_blk_x++) { 301 dst_blk_x++) {
302 dst_ptr = dst_row_ptr[dst_blk_x]; 302 dst_ptr = dst_row_ptr[dst_blk_x];
303 src_ptr = src_row_ptr[dst_blk_x]; 303 src_ptr = src_row_ptr[dst_blk_x];
304 for (i = 0; i < DCTSIZE; i += 2) { 304 for (i = 0; i < DCTSIZE; i += 2) {
305 /* copy even row */ 305 /* copy even row */
306 for (j = 0; j < DCTSIZE; j++) 306 for (j = 0; j < DCTSIZE; j++)
307 *dst_ptr++ = *src_ptr++; 307 *dst_ptr++ = *src_ptr++;
308 /* copy odd row with sign change */ 308 /* copy odd row with sign change */
309 for (j = 0; j < DCTSIZE; j++) 309 for (j = 0; j < DCTSIZE; j++)
310 *dst_ptr++ = - *src_ptr++; 310 *dst_ptr++ = - *src_ptr++;
311 } 311 }
312 } 312 }
313 } else { 313 } else {
314 /* Just copy row verbatim. */ 314 /* Just copy row verbatim. */
315 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, 315 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
316 dst_buffer[offset_y], 316 dst_buffer[offset_y],
317 compptr->width_in_blocks); 317 compptr->width_in_blocks);
318 } 318 }
319 } 319 }
320 } 320 }
321 } 321 }
322} 322}
323 323
324 324
325LOCAL(void) 325LOCAL(void)
326do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 326do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
327 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 327 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
328 jvirt_barray_ptr *src_coef_arrays, 328 jvirt_barray_ptr *src_coef_arrays,
329 jvirt_barray_ptr *dst_coef_arrays) 329 jvirt_barray_ptr *dst_coef_arrays)
330/* Transpose source into destination */ 330/* Transpose source into destination */
331{ 331{
332 JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks; 332 JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
333 int ci, i, j, offset_x, offset_y; 333 int ci, i, j, offset_x, offset_y;
334 JBLOCKARRAY src_buffer, dst_buffer; 334 JBLOCKARRAY src_buffer, dst_buffer;
335 JCOEFPTR src_ptr, dst_ptr; 335 JCOEFPTR src_ptr, dst_ptr;
336 jpeg_component_info *compptr; 336 jpeg_component_info *compptr;
337 337
338 /* Transposing pixels within a block just requires transposing the 338 /* Transposing pixels within a block just requires transposing the
339 * DCT coefficients. 339 * DCT coefficients.
340 * Partial iMCUs at the edges require no special treatment; we simply 340 * Partial iMCUs at the edges require no special treatment; we simply
341 * process all the available DCT blocks for every component. 341 * process all the available DCT blocks for every component.
342 */ 342 */
343 for (ci = 0; ci < dstinfo->num_components; ci++) { 343 for (ci = 0; ci < dstinfo->num_components; ci++) {
344 compptr = dstinfo->comp_info + ci; 344 compptr = dstinfo->comp_info + ci;
345 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 345 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
346 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 346 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
347 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 347 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
348 dst_blk_y += compptr->v_samp_factor) { 348 dst_blk_y += compptr->v_samp_factor) {
349 dst_buffer = (*srcinfo->mem->access_virt_barray) 349 dst_buffer = (*srcinfo->mem->access_virt_barray)
350 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 350 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
351 (JDIMENSION) compptr->v_samp_factor, TRUE); 351 (JDIMENSION) compptr->v_samp_factor, TRUE);
352 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 352 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
353 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 353 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
354 dst_blk_x += compptr->h_samp_factor) { 354 dst_blk_x += compptr->h_samp_factor) {
355 src_buffer = (*srcinfo->mem->access_virt_barray) 355 src_buffer = (*srcinfo->mem->access_virt_barray)
356 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 356 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
357 dst_blk_x + x_crop_blocks, 357 dst_blk_x + x_crop_blocks,
358 (JDIMENSION) compptr->h_samp_factor, FALSE); 358 (JDIMENSION) compptr->h_samp_factor, FALSE);
359 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 359 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
360 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 360 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
361 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks]; 361 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
362 for (i = 0; i < DCTSIZE; i++) 362 for (i = 0; i < DCTSIZE; i++)
363 for (j = 0; j < DCTSIZE; j++) 363 for (j = 0; j < DCTSIZE; j++)
364 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 364 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
365 } 365 }
366 } 366 }
367 } 367 }
368 } 368 }
369 } 369 }
370} 370}
371 371
372 372
373LOCAL(void) 373LOCAL(void)
374do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 374do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
375 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 375 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
376 jvirt_barray_ptr *src_coef_arrays, 376 jvirt_barray_ptr *src_coef_arrays,
377 jvirt_barray_ptr *dst_coef_arrays) 377 jvirt_barray_ptr *dst_coef_arrays)
378/* 90 degree rotation is equivalent to 378/* 90 degree rotation is equivalent to
379 * 1. Transposing the image; 379 * 1. Transposing the image;
380 * 2. Horizontal mirroring. 380 * 2. Horizontal mirroring.
381 * These two steps are merged into a single processing routine. 381 * These two steps are merged into a single processing routine.
382 */ 382 */
383{ 383{
384 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 384 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
385 JDIMENSION x_crop_blocks, y_crop_blocks; 385 JDIMENSION x_crop_blocks, y_crop_blocks;
386 int ci, i, j, offset_x, offset_y; 386 int ci, i, j, offset_x, offset_y;
387 JBLOCKARRAY src_buffer, dst_buffer; 387 JBLOCKARRAY src_buffer, dst_buffer;
388 JCOEFPTR src_ptr, dst_ptr; 388 JCOEFPTR src_ptr, dst_ptr;
389 jpeg_component_info *compptr; 389 jpeg_component_info *compptr;
390 390
391 /* Because of the horizontal mirror step, we can't process partial iMCUs 391 /* Because of the horizontal mirror step, we can't process partial iMCUs
392 * at the (output) right edge properly. They just get transposed and 392 * at the (output) right edge properly. They just get transposed and
393 * not mirrored. 393 * not mirrored.
394 */ 394 */
395 MCU_cols = srcinfo->output_height / 395 MCU_cols = srcinfo->output_height /
396 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size); 396 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
397 397
398 for (ci = 0; ci < dstinfo->num_components; ci++) { 398 for (ci = 0; ci < dstinfo->num_components; ci++) {
399 compptr = dstinfo->comp_info + ci; 399 compptr = dstinfo->comp_info + ci;
400 comp_width = MCU_cols * compptr->h_samp_factor; 400 comp_width = MCU_cols * compptr->h_samp_factor;
401 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 401 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
402 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 402 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
403 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 403 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
404 dst_blk_y += compptr->v_samp_factor) { 404 dst_blk_y += compptr->v_samp_factor) {
405 dst_buffer = (*srcinfo->mem->access_virt_barray) 405 dst_buffer = (*srcinfo->mem->access_virt_barray)
406 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 406 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
407 (JDIMENSION) compptr->v_samp_factor, TRUE); 407 (JDIMENSION) compptr->v_samp_factor, TRUE);
408 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 408 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
409 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 409 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
410 dst_blk_x += compptr->h_samp_factor) { 410 dst_blk_x += compptr->h_samp_factor) {
411 if (x_crop_blocks + dst_blk_x < comp_width) { 411 if (x_crop_blocks + dst_blk_x < comp_width) {
412 /* Block is within the mirrorable area. */ 412 /* Block is within the mirrorable area. */
413 src_buffer = (*srcinfo->mem->access_virt_barray) 413 src_buffer = (*srcinfo->mem->access_virt_barray)
414 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 414 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
415 comp_width - x_crop_blocks - dst_blk_x - 415 comp_width - x_crop_blocks - dst_blk_x -
416 (JDIMENSION) compptr->h_samp_factor, 416 (JDIMENSION) compptr->h_samp_factor,
417 (JDIMENSION) compptr->h_samp_factor, FALSE); 417 (JDIMENSION) compptr->h_samp_factor, FALSE);
418 } else { 418 } else {
419 /* Edge blocks are transposed but not mirrored. */ 419 /* Edge blocks are transposed but not mirrored. */
420 src_buffer = (*srcinfo->mem->access_virt_barray) 420 src_buffer = (*srcinfo->mem->access_virt_barray)
421 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 421 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
422 dst_blk_x + x_crop_blocks, 422 dst_blk_x + x_crop_blocks,
423 (JDIMENSION) compptr->h_samp_factor, FALSE); 423 (JDIMENSION) compptr->h_samp_factor, FALSE);
424 } 424 }
425 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 425 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
426 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 426 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
427 if (x_crop_blocks + dst_blk_x < comp_width) { 427 if (x_crop_blocks + dst_blk_x < comp_width) {
428 /* Block is within the mirrorable area. */ 428 /* Block is within the mirrorable area. */
429 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 429 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
430 [dst_blk_y + offset_y + y_crop_blocks]; 430 [dst_blk_y + offset_y + y_crop_blocks];
431 for (i = 0; i < DCTSIZE; i++) { 431 for (i = 0; i < DCTSIZE; i++) {
432 for (j = 0; j < DCTSIZE; j++) 432 for (j = 0; j < DCTSIZE; j++)
433 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 433 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
434 i++; 434 i++;
435 for (j = 0; j < DCTSIZE; j++) 435 for (j = 0; j < DCTSIZE; j++)
436 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 436 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
437 } 437 }
438 } else { 438 } else {
439 /* Edge blocks are transposed but not mirrored. */ 439 /* Edge blocks are transposed but not mirrored. */
440 src_ptr = src_buffer[offset_x] 440 src_ptr = src_buffer[offset_x]
441 [dst_blk_y + offset_y + y_crop_blocks]; 441 [dst_blk_y + offset_y + y_crop_blocks];
442 for (i = 0; i < DCTSIZE; i++) 442 for (i = 0; i < DCTSIZE; i++)
443 for (j = 0; j < DCTSIZE; j++) 443 for (j = 0; j < DCTSIZE; j++)
444 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 444 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
445 } 445 }
446 } 446 }
447 } 447 }
448 } 448 }
449 } 449 }
450 } 450 }
451} 451}
452 452
453 453
454LOCAL(void) 454LOCAL(void)
455do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 455do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
456 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 456 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
457 jvirt_barray_ptr *src_coef_arrays, 457 jvirt_barray_ptr *src_coef_arrays,
458 jvirt_barray_ptr *dst_coef_arrays) 458 jvirt_barray_ptr *dst_coef_arrays)
459/* 270 degree rotation is equivalent to 459/* 270 degree rotation is equivalent to
460 * 1. Horizontal mirroring; 460 * 1. Horizontal mirroring;
461 * 2. Transposing the image. 461 * 2. Transposing the image.
462 * These two steps are merged into a single processing routine. 462 * These two steps are merged into a single processing routine.
463 */ 463 */
464{ 464{
465 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 465 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
466 JDIMENSION x_crop_blocks, y_crop_blocks; 466 JDIMENSION x_crop_blocks, y_crop_blocks;
467 int ci, i, j, offset_x, offset_y; 467 int ci, i, j, offset_x, offset_y;
468 JBLOCKARRAY src_buffer, dst_buffer; 468 JBLOCKARRAY src_buffer, dst_buffer;
469 JCOEFPTR src_ptr, dst_ptr; 469 JCOEFPTR src_ptr, dst_ptr;
470 jpeg_component_info *compptr; 470 jpeg_component_info *compptr;
471 471
472 /* Because of the horizontal mirror step, we can't process partial iMCUs 472 /* Because of the horizontal mirror step, we can't process partial iMCUs
473 * at the (output) bottom edge properly. They just get transposed and 473 * at the (output) bottom edge properly. They just get transposed and
474 * not mirrored. 474 * not mirrored.
475 */ 475 */
476 MCU_rows = srcinfo->output_width / 476 MCU_rows = srcinfo->output_width /
477 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size); 477 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
478 478
479 for (ci = 0; ci < dstinfo->num_components; ci++) { 479 for (ci = 0; ci < dstinfo->num_components; ci++) {
480 compptr = dstinfo->comp_info + ci; 480 compptr = dstinfo->comp_info + ci;
481 comp_height = MCU_rows * compptr->v_samp_factor; 481 comp_height = MCU_rows * compptr->v_samp_factor;
482 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 482 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
483 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 483 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
484 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 484 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
485 dst_blk_y += compptr->v_samp_factor) { 485 dst_blk_y += compptr->v_samp_factor) {
486 dst_buffer = (*srcinfo->mem->access_virt_barray) 486 dst_buffer = (*srcinfo->mem->access_virt_barray)
487 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 487 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
488 (JDIMENSION) compptr->v_samp_factor, TRUE); 488 (JDIMENSION) compptr->v_samp_factor, TRUE);
489 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 489 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
490 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 490 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
491 dst_blk_x += compptr->h_samp_factor) { 491 dst_blk_x += compptr->h_samp_factor) {
492 src_buffer = (*srcinfo->mem->access_virt_barray) 492 src_buffer = (*srcinfo->mem->access_virt_barray)
493 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 493 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
494 dst_blk_x + x_crop_blocks, 494 dst_blk_x + x_crop_blocks,
495 (JDIMENSION) compptr->h_samp_factor, FALSE); 495 (JDIMENSION) compptr->h_samp_factor, FALSE);
496 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 496 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
497 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 497 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
498 if (y_crop_blocks + dst_blk_y < comp_height) { 498 if (y_crop_blocks + dst_blk_y < comp_height) {
499 /* Block is within the mirrorable area. */ 499 /* Block is within the mirrorable area. */
500 src_ptr = src_buffer[offset_x] 500 src_ptr = src_buffer[offset_x]
501 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 501 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
502 for (i = 0; i < DCTSIZE; i++) { 502 for (i = 0; i < DCTSIZE; i++) {
503 for (j = 0; j < DCTSIZE; j++) { 503 for (j = 0; j < DCTSIZE; j++) {
504 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 504 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
505 j++; 505 j++;
506 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 506 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
507 } 507 }
508 } 508 }
509 } else { 509 } else {
510 /* Edge blocks are transposed but not mirrored. */ 510 /* Edge blocks are transposed but not mirrored. */
511 src_ptr = src_buffer[offset_x] 511 src_ptr = src_buffer[offset_x]
512 [dst_blk_y + offset_y + y_crop_blocks]; 512 [dst_blk_y + offset_y + y_crop_blocks];
513 for (i = 0; i < DCTSIZE; i++) 513 for (i = 0; i < DCTSIZE; i++)
514 for (j = 0; j < DCTSIZE; j++) 514 for (j = 0; j < DCTSIZE; j++)
515 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 515 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
516 } 516 }
517 } 517 }
518 } 518 }
519 } 519 }
520 } 520 }
521 } 521 }
522} 522}
523 523
524 524
525LOCAL(void) 525LOCAL(void)
526do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 526do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
527 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 527 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
528 jvirt_barray_ptr *src_coef_arrays, 528 jvirt_barray_ptr *src_coef_arrays,
529 jvirt_barray_ptr *dst_coef_arrays) 529 jvirt_barray_ptr *dst_coef_arrays)
530/* 180 degree rotation is equivalent to 530/* 180 degree rotation is equivalent to
531 * 1. Vertical mirroring; 531 * 1. Vertical mirroring;
532 * 2. Horizontal mirroring. 532 * 2. Horizontal mirroring.
533 * These two steps are merged into a single processing routine. 533 * These two steps are merged into a single processing routine.
534 */ 534 */
535{ 535{
536 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 536 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
537 JDIMENSION x_crop_blocks, y_crop_blocks; 537 JDIMENSION x_crop_blocks, y_crop_blocks;
538 int ci, i, j, offset_y; 538 int ci, i, j, offset_y;
539 JBLOCKARRAY src_buffer, dst_buffer; 539 JBLOCKARRAY src_buffer, dst_buffer;
540 JBLOCKROW src_row_ptr, dst_row_ptr; 540 JBLOCKROW src_row_ptr, dst_row_ptr;
541 JCOEFPTR src_ptr, dst_ptr; 541 JCOEFPTR src_ptr, dst_ptr;
542 jpeg_component_info *compptr; 542 jpeg_component_info *compptr;
543 543
544 MCU_cols = srcinfo->output_width / 544 MCU_cols = srcinfo->output_width /
545 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size); 545 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
546 MCU_rows = srcinfo->output_height / 546 MCU_rows = srcinfo->output_height /
547 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size); 547 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
548 548
549 for (ci = 0; ci < dstinfo->num_components; ci++) { 549 for (ci = 0; ci < dstinfo->num_components; ci++) {
550 compptr = dstinfo->comp_info + ci; 550 compptr = dstinfo->comp_info + ci;
551 comp_width = MCU_cols * compptr->h_samp_factor; 551 comp_width = MCU_cols * compptr->h_samp_factor;
552 comp_height = MCU_rows * compptr->v_samp_factor; 552 comp_height = MCU_rows * compptr->v_samp_factor;
553 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 553 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
554 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 554 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
555 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 555 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
556 dst_blk_y += compptr->v_samp_factor) { 556 dst_blk_y += compptr->v_samp_factor) {
557 dst_buffer = (*srcinfo->mem->access_virt_barray) 557 dst_buffer = (*srcinfo->mem->access_virt_barray)
558 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 558 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
559 (JDIMENSION) compptr->v_samp_factor, TRUE); 559 (JDIMENSION) compptr->v_samp_factor, TRUE);
560 if (y_crop_blocks + dst_blk_y < comp_height) { 560 if (y_crop_blocks + dst_blk_y < comp_height) {
561 /* Row is within the vertically mirrorable area. */ 561 /* Row is within the vertically mirrorable area. */
562 src_buffer = (*srcinfo->mem->access_virt_barray) 562 src_buffer = (*srcinfo->mem->access_virt_barray)
563 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 563 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
564 comp_height - y_crop_blocks - dst_blk_y - 564 comp_height - y_crop_blocks - dst_blk_y -
565 (JDIMENSION) compptr->v_samp_factor, 565 (JDIMENSION) compptr->v_samp_factor,
566 (JDIMENSION) compptr->v_samp_factor, FALSE); 566 (JDIMENSION) compptr->v_samp_factor, FALSE);
567 } else { 567 } else {
568 /* Bottom-edge rows are only mirrored horizontally. */ 568 /* Bottom-edge rows are only mirrored horizontally. */
569 src_buffer = (*srcinfo->mem->access_virt_barray) 569 src_buffer = (*srcinfo->mem->access_virt_barray)
570 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 570 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
571 dst_blk_y + y_crop_blocks, 571 dst_blk_y + y_crop_blocks,
572 (JDIMENSION) compptr->v_samp_factor, FALSE); 572 (JDIMENSION) compptr->v_samp_factor, FALSE);
573 } 573 }
574 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 574 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
575 dst_row_ptr = dst_buffer[offset_y]; 575 dst_row_ptr = dst_buffer[offset_y];
576 if (y_crop_blocks + dst_blk_y < comp_height) { 576 if (y_crop_blocks + dst_blk_y < comp_height) {
577 /* Row is within the mirrorable area. */ 577 /* Row is within the mirrorable area. */
578 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 578 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
579 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 579 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
580 dst_ptr = dst_row_ptr[dst_blk_x]; 580 dst_ptr = dst_row_ptr[dst_blk_x];
581 if (x_crop_blocks + dst_blk_x < comp_width) { 581 if (x_crop_blocks + dst_blk_x < comp_width) {
582 /* Process the blocks that can be mirrored both ways. */ 582 /* Process the blocks that can be mirrored both ways. */
583 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 583 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
584 for (i = 0; i < DCTSIZE; i += 2) { 584 for (i = 0; i < DCTSIZE; i += 2) {
585 /* For even row, negate every odd column. */ 585 /* For even row, negate every odd column. */
586 for (j = 0; j < DCTSIZE; j += 2) { 586 for (j = 0; j < DCTSIZE; j += 2) {
587 *dst_ptr++ = *src_ptr++; 587 *dst_ptr++ = *src_ptr++;
588 *dst_ptr++ = - *src_ptr++; 588 *dst_ptr++ = - *src_ptr++;
589 } 589 }
590 /* For odd row, negate every even column. */ 590 /* For odd row, negate every even column. */
591 for (j = 0; j < DCTSIZE; j += 2) { 591 for (j = 0; j < DCTSIZE; j += 2) {
592 *dst_ptr++ = - *src_ptr++; 592 *dst_ptr++ = - *src_ptr++;
593 *dst_ptr++ = *src_ptr++; 593 *dst_ptr++ = *src_ptr++;
594 } 594 }
595 } 595 }
596 } else { 596 } else {
597 /* Any remaining right-edge blocks are only mirrored vertically. */ 597 /* Any remaining right-edge blocks are only mirrored vertically. */
598 src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x]; 598 src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
599 for (i = 0; i < DCTSIZE; i += 2) { 599 for (i = 0; i < DCTSIZE; i += 2) {
600 for (j = 0; j < DCTSIZE; j++) 600 for (j = 0; j < DCTSIZE; j++)
601 *dst_ptr++ = *src_ptr++; 601 *dst_ptr++ = *src_ptr++;
602 for (j = 0; j < DCTSIZE; j++) 602 for (j = 0; j < DCTSIZE; j++)
603 *dst_ptr++ = - *src_ptr++; 603 *dst_ptr++ = - *src_ptr++;
604 } 604 }
605 } 605 }
606 } 606 }
607 } else { 607 } else {
608 /* Remaining rows are just mirrored horizontally. */ 608 /* Remaining rows are just mirrored horizontally. */
609 src_row_ptr = src_buffer[offset_y]; 609 src_row_ptr = src_buffer[offset_y];
610 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 610 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
611 if (x_crop_blocks + dst_blk_x < comp_width) { 611 if (x_crop_blocks + dst_blk_x < comp_width) {
612 /* Process the blocks that can be mirrored. */ 612 /* Process the blocks that can be mirrored. */
613 dst_ptr = dst_row_ptr[dst_blk_x]; 613 dst_ptr = dst_row_ptr[dst_blk_x];
614 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 614 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
615 for (i = 0; i < DCTSIZE2; i += 2) { 615 for (i = 0; i < DCTSIZE2; i += 2) {
616 *dst_ptr++ = *src_ptr++; 616 *dst_ptr++ = *src_ptr++;
617 *dst_ptr++ = - *src_ptr++; 617 *dst_ptr++ = - *src_ptr++;
618 } 618 }
619 } else { 619 } else {
620 /* Any remaining right-edge blocks are only copied. */ 620 /* Any remaining right-edge blocks are only copied. */
621 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, 621 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
622 dst_row_ptr + dst_blk_x, 622 dst_row_ptr + dst_blk_x,
623 (JDIMENSION) 1); 623 (JDIMENSION) 1);
624 } 624 }
625 } 625 }
626 } 626 }
627 } 627 }
628 } 628 }
629 } 629 }
630} 630}
631 631
632 632
633LOCAL(void) 633LOCAL(void)
634do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 634do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
635 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 635 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
636 jvirt_barray_ptr *src_coef_arrays, 636 jvirt_barray_ptr *src_coef_arrays,
637 jvirt_barray_ptr *dst_coef_arrays) 637 jvirt_barray_ptr *dst_coef_arrays)
638/* Transverse transpose is equivalent to 638/* Transverse transpose is equivalent to
639 * 1. 180 degree rotation; 639 * 1. 180 degree rotation;
640 * 2. Transposition; 640 * 2. Transposition;
641 * or 641 * or
642 * 1. Horizontal mirroring; 642 * 1. Horizontal mirroring;
643 * 2. Transposition; 643 * 2. Transposition;
644 * 3. Horizontal mirroring. 644 * 3. Horizontal mirroring.
645 * These steps are merged into a single processing routine. 645 * These steps are merged into a single processing routine.
646 */ 646 */
647{ 647{
648 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 648 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
649 JDIMENSION x_crop_blocks, y_crop_blocks; 649 JDIMENSION x_crop_blocks, y_crop_blocks;
650 int ci, i, j, offset_x, offset_y; 650 int ci, i, j, offset_x, offset_y;
651 JBLOCKARRAY src_buffer, dst_buffer; 651 JBLOCKARRAY src_buffer, dst_buffer;
652 JCOEFPTR src_ptr, dst_ptr; 652 JCOEFPTR src_ptr, dst_ptr;
653 jpeg_component_info *compptr; 653 jpeg_component_info *compptr;
654 654
655 MCU_cols = srcinfo->output_height / 655 MCU_cols = srcinfo->output_height /
656 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size); 656 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
657 MCU_rows = srcinfo->output_width / 657 MCU_rows = srcinfo->output_width /
658 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size); 658 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
659 659
660 for (ci = 0; ci < dstinfo->num_components; ci++) { 660 for (ci = 0; ci < dstinfo->num_components; ci++) {
661 compptr = dstinfo->comp_info + ci; 661 compptr = dstinfo->comp_info + ci;
662 comp_width = MCU_cols * compptr->h_samp_factor; 662 comp_width = MCU_cols * compptr->h_samp_factor;
663 comp_height = MCU_rows * compptr->v_samp_factor; 663 comp_height = MCU_rows * compptr->v_samp_factor;
664 x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 664 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
665 y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 665 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
666 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 666 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
667 dst_blk_y += compptr->v_samp_factor) { 667 dst_blk_y += compptr->v_samp_factor) {
668 dst_buffer = (*srcinfo->mem->access_virt_barray) 668 dst_buffer = (*srcinfo->mem->access_virt_barray)
669 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 669 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
670 (JDIMENSION) compptr->v_samp_factor, TRUE); 670 (JDIMENSION) compptr->v_samp_factor, TRUE);
671 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 671 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
672 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 672 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
673 dst_blk_x += compptr->h_samp_factor) { 673 dst_blk_x += compptr->h_samp_factor) {
674 if (x_crop_blocks + dst_blk_x < comp_width) { 674 if (x_crop_blocks + dst_blk_x < comp_width) {
675 /* Block is within the mirrorable area. */ 675 /* Block is within the mirrorable area. */
676 src_buffer = (*srcinfo->mem->access_virt_barray) 676 src_buffer = (*srcinfo->mem->access_virt_barray)
677 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 677 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
678 comp_width - x_crop_blocks - dst_blk_x - 678 comp_width - x_crop_blocks - dst_blk_x -
679 (JDIMENSION) compptr->h_samp_factor, 679 (JDIMENSION) compptr->h_samp_factor,
680 (JDIMENSION) compptr->h_samp_factor, FALSE); 680 (JDIMENSION) compptr->h_samp_factor, FALSE);
681 } else { 681 } else {
682 src_buffer = (*srcinfo->mem->access_virt_barray) 682 src_buffer = (*srcinfo->mem->access_virt_barray)
683 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 683 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
684 dst_blk_x + x_crop_blocks, 684 dst_blk_x + x_crop_blocks,
685 (JDIMENSION) compptr->h_samp_factor, FALSE); 685 (JDIMENSION) compptr->h_samp_factor, FALSE);
686 } 686 }
687 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 687 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
688 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 688 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
689 if (y_crop_blocks + dst_blk_y < comp_height) { 689 if (y_crop_blocks + dst_blk_y < comp_height) {
690 if (x_crop_blocks + dst_blk_x < comp_width) { 690 if (x_crop_blocks + dst_blk_x < comp_width) {
691 /* Block is within the mirrorable area. */ 691 /* Block is within the mirrorable area. */
692 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 692 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
693 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 693 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
694 for (i = 0; i < DCTSIZE; i++) { 694 for (i = 0; i < DCTSIZE; i++) {
695 for (j = 0; j < DCTSIZE; j++) { 695 for (j = 0; j < DCTSIZE; j++) {
696 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 696 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
697 j++; 697 j++;
698 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 698 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
699 } 699 }
700 i++; 700 i++;
701 for (j = 0; j < DCTSIZE; j++) { 701 for (j = 0; j < DCTSIZE; j++) {
702 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 702 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
703 j++; 703 j++;
704 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 704 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
705 } 705 }
706 } 706 }
707 } else { 707 } else {
708 /* Right-edge blocks are mirrored in y only */ 708 /* Right-edge blocks are mirrored in y only */
709 src_ptr = src_buffer[offset_x] 709 src_ptr = src_buffer[offset_x]
710 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 710 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
711 for (i = 0; i < DCTSIZE; i++) { 711 for (i = 0; i < DCTSIZE; i++) {
712 for (j = 0; j < DCTSIZE; j++) { 712 for (j = 0; j < DCTSIZE; j++) {
713 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 713 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
714 j++; 714 j++;
715 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 715 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
716 } 716 }
717 } 717 }
718 } 718 }
719 } else { 719 } else {
720 if (x_crop_blocks + dst_blk_x < comp_width) { 720 if (x_crop_blocks + dst_blk_x < comp_width) {
721 /* Bottom-edge blocks are mirrored in x only */ 721 /* Bottom-edge blocks are mirrored in x only */
722 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 722 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
723 [dst_blk_y + offset_y + y_crop_blocks]; 723 [dst_blk_y + offset_y + y_crop_blocks];
724 for (i = 0; i < DCTSIZE; i++) { 724 for (i = 0; i < DCTSIZE; i++) {
725 for (j = 0; j < DCTSIZE; j++) 725 for (j = 0; j < DCTSIZE; j++)
726 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 726 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
727 i++; 727 i++;
728 for (j = 0; j < DCTSIZE; j++) 728 for (j = 0; j < DCTSIZE; j++)
729 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 729 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
730 } 730 }
731 } else { 731 } else {
732 /* At lower right corner, just transpose, no mirroring */ 732 /* At lower right corner, just transpose, no mirroring */
733 src_ptr = src_buffer[offset_x] 733 src_ptr = src_buffer[offset_x]
734 [dst_blk_y + offset_y + y_crop_blocks]; 734 [dst_blk_y + offset_y + y_crop_blocks];
735 for (i = 0; i < DCTSIZE; i++) 735 for (i = 0; i < DCTSIZE; i++)
736 for (j = 0; j < DCTSIZE; j++) 736 for (j = 0; j < DCTSIZE; j++)
737 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 737 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
738 } 738 }
739 } 739 }
740 } 740 }
741 } 741 }
742 } 742 }
743 } 743 }
744 } 744 }
745} 745}
746 746
747 747
748/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec. 748/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
749 * Returns TRUE if valid integer found, FALSE if not. 749 * Returns TRUE if valid integer found, FALSE if not.
750 * *strptr is advanced over the digit string, and *result is set to its value. 750 * *strptr is advanced over the digit string, and *result is set to its value.
751 */ 751 */
752 752
753LOCAL(boolean) 753LOCAL(boolean)
754jt_read_integer (const char ** strptr, JDIMENSION * result) 754jt_read_integer (const char ** strptr, JDIMENSION * result)
755{ 755{
756 const char * ptr = *strptr; 756 const char * ptr = *strptr;
757 JDIMENSION val = 0; 757 JDIMENSION val = 0;
758 758
759 for (; isdigit(*ptr); ptr++) { 759 for (; isdigit(*ptr); ptr++) {
760 val = val * 10 + (JDIMENSION) (*ptr - '0'); 760 val = val * 10 + (JDIMENSION) (*ptr - '0');
761 } 761 }
762 *result = val; 762 *result = val;
763 if (ptr == *strptr) 763 if (ptr == *strptr)
764 return FALSE; /* oops, no digits */ 764 return FALSE; /* oops, no digits */
765 *strptr = ptr; 765 *strptr = ptr;
766 return TRUE; 766 return TRUE;
767} 767}
768 768
769 769
770/* Parse a crop specification (written in X11 geometry style). 770/* Parse a crop specification (written in X11 geometry style).
771 * The routine returns TRUE if the spec string is valid, FALSE if not. 771 * The routine returns TRUE if the spec string is valid, FALSE if not.
772 * 772 *
773 * The crop spec string should have the format 773 * The crop spec string should have the format
774 * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset> 774 * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
775 * where width, height, xoffset, and yoffset are unsigned integers. 775 * where width, height, xoffset, and yoffset are unsigned integers.
776 * Each of the elements can be omitted to indicate a default value. 776 * Each of the elements can be omitted to indicate a default value.
777 * (A weakness of this style is that it is not possible to omit xoffset 777 * (A weakness of this style is that it is not possible to omit xoffset
778 * while specifying yoffset, since they look alike.) 778 * while specifying yoffset, since they look alike.)
779 * 779 *
780 * This code is loosely based on XParseGeometry from the X11 distribution. 780 * This code is loosely based on XParseGeometry from the X11 distribution.
781 */ 781 */
782 782
783GLOBAL(boolean) 783GLOBAL(boolean)
784jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec) 784jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
785{ 785{
786 info->crop = FALSE; 786 info->crop = FALSE;
787 info->crop_width_set = JCROP_UNSET; 787 info->crop_width_set = JCROP_UNSET;
788 info->crop_height_set = JCROP_UNSET; 788 info->crop_height_set = JCROP_UNSET;
789 info->crop_xoffset_set = JCROP_UNSET; 789 info->crop_xoffset_set = JCROP_UNSET;
790 info->crop_yoffset_set = JCROP_UNSET; 790 info->crop_yoffset_set = JCROP_UNSET;
791 791
792 if (isdigit(*spec)) { 792 if (isdigit(*spec)) {
793 /* fetch width */ 793 /* fetch width */
794 if (! jt_read_integer(&spec, &info->crop_width)) 794 if (! jt_read_integer(&spec, &info->crop_width))
795 return FALSE; 795 return FALSE;
796 if (*spec == 'f' || *spec == 'F') { 796 if (*spec == 'f' || *spec == 'F') {
797 spec++; 797 spec++;
798 info->crop_width_set = JCROP_FORCE; 798 info->crop_width_set = JCROP_FORCE;
799 } else 799 } else
800 info->crop_width_set = JCROP_POS; 800 info->crop_width_set = JCROP_POS;
801 } 801 }
802 if (*spec == 'x' || *spec == 'X') { 802 if (*spec == 'x' || *spec == 'X') {
803 /* fetch height */ 803 /* fetch height */
804 spec++; 804 spec++;
805 if (! jt_read_integer(&spec, &info->crop_height)) 805 if (! jt_read_integer(&spec, &info->crop_height))
806 return FALSE; 806 return FALSE;
807 if (*spec == 'f' || *spec == 'F') { 807 if (*spec == 'f' || *spec == 'F') {
808 spec++; 808 spec++;
809 info->crop_height_set = JCROP_FORCE; 809 info->crop_height_set = JCROP_FORCE;
810 } else 810 } else
811 info->crop_height_set = JCROP_POS; 811 info->crop_height_set = JCROP_POS;
812 } 812 }
813 if (*spec == '+' || *spec == '-') { 813 if (*spec == '+' || *spec == '-') {
814 /* fetch xoffset */ 814 /* fetch xoffset */
815 info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; 815 info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
816 spec++; 816 spec++;
817 if (! jt_read_integer(&spec, &info->crop_xoffset)) 817 if (! jt_read_integer(&spec, &info->crop_xoffset))
818 return FALSE; 818 return FALSE;
819 } 819 }
820 if (*spec == '+' || *spec == '-') { 820 if (*spec == '+' || *spec == '-') {
821 /* fetch yoffset */ 821 /* fetch yoffset */
822 info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; 822 info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
823 spec++; 823 spec++;
824 if (! jt_read_integer(&spec, &info->crop_yoffset)) 824 if (! jt_read_integer(&spec, &info->crop_yoffset))
825 return FALSE; 825 return FALSE;
826 } 826 }
827 /* We had better have gotten to the end of the string. */ 827 /* We had better have gotten to the end of the string. */
828 if (*spec != '\0') 828 if (*spec != '\0')
829 return FALSE; 829 return FALSE;
830 info->crop = TRUE; 830 info->crop = TRUE;
831 return TRUE; 831 return TRUE;
832} 832}
833 833
834 834
835/* Trim off any partial iMCUs on the indicated destination edge */ 835/* Trim off any partial iMCUs on the indicated destination edge */
836 836
837LOCAL(void) 837LOCAL(void)
838trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width) 838trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
839{ 839{
840 JDIMENSION MCU_cols; 840 JDIMENSION MCU_cols;
841 841
842 MCU_cols = info->output_width / info->iMCU_sample_width; 842 MCU_cols = info->output_width / info->iMCU_sample_width;
843 if (MCU_cols > 0 && info->x_crop_offset + MCU_cols == 843 if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
844 full_width / info->iMCU_sample_width) 844 full_width / info->iMCU_sample_width)
845 info->output_width = MCU_cols * info->iMCU_sample_width; 845 info->output_width = MCU_cols * info->iMCU_sample_width;
846} 846}
847 847
848LOCAL(void) 848LOCAL(void)
849trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height) 849trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
850{ 850{
851 JDIMENSION MCU_rows; 851 JDIMENSION MCU_rows;
852 852
853 MCU_rows = info->output_height / info->iMCU_sample_height; 853 MCU_rows = info->output_height / info->iMCU_sample_height;
854 if (MCU_rows > 0 && info->y_crop_offset + MCU_rows == 854 if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
855 full_height / info->iMCU_sample_height) 855 full_height / info->iMCU_sample_height)
856 info->output_height = MCU_rows * info->iMCU_sample_height; 856 info->output_height = MCU_rows * info->iMCU_sample_height;
857} 857}
858 858
859 859
860/* Request any required workspace. 860/* Request any required workspace.
861 * 861 *
862 * This routine figures out the size that the output image will be 862 * This routine figures out the size that the output image will be
863 * (which implies that all the transform parameters must be set before 863 * (which implies that all the transform parameters must be set before
864 * it is called). 864 * it is called).
865 * 865 *
866 * We allocate the workspace virtual arrays from the source decompression 866 * We allocate the workspace virtual arrays from the source decompression
867 * object, so that all the arrays (both the original data and the workspace) 867 * object, so that all the arrays (both the original data and the workspace)
868 * will be taken into account while making memory management decisions. 868 * will be taken into account while making memory management decisions.
869 * Hence, this routine must be called after jpeg_read_header (which reads 869 * Hence, this routine must be called after jpeg_read_header (which reads
870 * the image dimensions) and before jpeg_read_coefficients (which realizes 870 * the image dimensions) and before jpeg_read_coefficients (which realizes
871 * the source's virtual arrays). 871 * the source's virtual arrays).
872 * 872 *
873 * This function returns FALSE right away if -perfect is given 873 * This function returns FALSE right away if -perfect is given
874 * and transformation is not perfect. Otherwise returns TRUE. 874 * and transformation is not perfect. Otherwise returns TRUE.
875 */ 875 */
876 876
877GLOBAL(boolean) 877GLOBAL(boolean)
878jtransform_request_workspace (j_decompress_ptr srcinfo, 878jtransform_request_workspace (j_decompress_ptr srcinfo,
879 jpeg_transform_info *info) 879 jpeg_transform_info *info)
880{ 880{
881 jvirt_barray_ptr *coef_arrays; 881 jvirt_barray_ptr *coef_arrays;
882 boolean need_workspace, transpose_it; 882 boolean need_workspace, transpose_it;
883 jpeg_component_info *compptr; 883 jpeg_component_info *compptr;
884 JDIMENSION xoffset, yoffset; 884 JDIMENSION xoffset, yoffset;
885 JDIMENSION width_in_iMCUs, height_in_iMCUs; 885 JDIMENSION width_in_iMCUs, height_in_iMCUs;
886 JDIMENSION width_in_blocks, height_in_blocks; 886 JDIMENSION width_in_blocks, height_in_blocks;
887 int ci, h_samp_factor, v_samp_factor; 887 int ci, h_samp_factor, v_samp_factor;
888 888
889 /* Determine number of components in output image */ 889 /* Determine number of components in output image */
890 if (info->force_grayscale && 890 if (info->force_grayscale &&
891 srcinfo->jpeg_color_space == JCS_YCbCr && 891 srcinfo->jpeg_color_space == JCS_YCbCr &&
892 srcinfo->num_components == 3) 892 srcinfo->num_components == 3)
893 /* We'll only process the first component */ 893 /* We'll only process the first component */
894 info->num_components = 1; 894 info->num_components = 1;
895 else 895 else
896 /* Process all the components */ 896 /* Process all the components */
897 info->num_components = srcinfo->num_components; 897 info->num_components = srcinfo->num_components;
898 898
899 /* Compute output image dimensions and related values. */ 899 /* Compute output image dimensions and related values. */
900 jpeg_core_output_dimensions(srcinfo); 900 jpeg_core_output_dimensions(srcinfo);
901 901
902 /* Return right away if -perfect is given and transformation is not perfect. 902 /* Return right away if -perfect is given and transformation is not perfect.
903 */ 903 */
904 if (info->perfect) { 904 if (info->perfect) {
905 if (info->num_components == 1) { 905 if (info->num_components == 1) {
906 if (!jtransform_perfect_transform(srcinfo->output_width, 906 if (!jtransform_perfect_transform(srcinfo->output_width,
907 srcinfo->output_height, 907 srcinfo->output_height,
908 srcinfo->min_DCT_h_scaled_size, 908 srcinfo->min_DCT_h_scaled_size,
909 srcinfo->min_DCT_v_scaled_size, 909 srcinfo->min_DCT_v_scaled_size,
910 info->transform)) 910 info->transform))
911 return FALSE; 911 return FALSE;
912 } else { 912 } else {
913 if (!jtransform_perfect_transform(srcinfo->output_width, 913 if (!jtransform_perfect_transform(srcinfo->output_width,
914 srcinfo->output_height, 914 srcinfo->output_height,
915 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size, 915 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size,
916 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size, 916 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size,
917 info->transform)) 917 info->transform))
918 return FALSE; 918 return FALSE;
919 } 919 }
920 } 920 }
921 921
922 /* If there is only one output component, force the iMCU size to be 1; 922 /* If there is only one output component, force the iMCU size to be 1;
923 * else use the source iMCU size. (This allows us to do the right thing 923 * else use the source iMCU size. (This allows us to do the right thing
924 * when reducing color to grayscale, and also provides a handy way of 924 * when reducing color to grayscale, and also provides a handy way of
925 * cleaning up "funny" grayscale images whose sampling factors are not 1x1.) 925 * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
926 */ 926 */
927 switch (info->transform) { 927 switch (info->transform) {
928 case JXFORM_TRANSPOSE: 928 case JXFORM_TRANSPOSE:
929 case JXFORM_TRANSVERSE: 929 case JXFORM_TRANSVERSE:
930 case JXFORM_ROT_90: 930 case JXFORM_ROT_90:
931 case JXFORM_ROT_270: 931 case JXFORM_ROT_270:
932 info->output_width = srcinfo->output_height; 932 info->output_width = srcinfo->output_height;
933 info->output_height = srcinfo->output_width; 933 info->output_height = srcinfo->output_width;
934 if (info->num_components == 1) { 934 if (info->num_components == 1) {
935 info->iMCU_sample_width = srcinfo->min_DCT_v_scaled_size; 935 info->iMCU_sample_width = srcinfo->min_DCT_v_scaled_size;
936 info->iMCU_sample_height = srcinfo->min_DCT_h_scaled_size; 936 info->iMCU_sample_height = srcinfo->min_DCT_h_scaled_size;
937 } else { 937 } else {
938 info->iMCU_sample_width = 938 info->iMCU_sample_width =
939 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size; 939 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size;
940 info->iMCU_sample_height = 940 info->iMCU_sample_height =
941 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size; 941 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size;
942 } 942 }
943 break; 943 break;
944 default: 944 default:
945 info->output_width = srcinfo->output_width; 945 info->output_width = srcinfo->output_width;
946 info->output_height = srcinfo->output_height; 946 info->output_height = srcinfo->output_height;
947 if (info->num_components == 1) { 947 if (info->num_components == 1) {
948 info->iMCU_sample_width = srcinfo->min_DCT_h_scaled_size; 948 info->iMCU_sample_width = srcinfo->min_DCT_h_scaled_size;
949 info->iMCU_sample_height = srcinfo->min_DCT_v_scaled_size; 949 info->iMCU_sample_height = srcinfo->min_DCT_v_scaled_size;
950 } else { 950 } else {
951 info->iMCU_sample_width = 951 info->iMCU_sample_width =
952 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size; 952 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size;
953 info->iMCU_sample_height = 953 info->iMCU_sample_height =
954 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size; 954 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size;
955 } 955 }
956 break; 956 break;
957 } 957 }
958 958
959 /* If cropping has been requested, compute the crop area's position and 959 /* If cropping has been requested, compute the crop area's position and
960 * dimensions, ensuring that its upper left corner falls at an iMCU boundary. 960 * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
961 */ 961 */
962 if (info->crop) { 962 if (info->crop) {
963 /* Insert default values for unset crop parameters */ 963 /* Insert default values for unset crop parameters */
964 if (info->crop_xoffset_set == JCROP_UNSET) 964 if (info->crop_xoffset_set == JCROP_UNSET)
965 info->crop_xoffset = 0; /* default to +0 */ 965 info->crop_xoffset = 0; /* default to +0 */
966 if (info->crop_yoffset_set == JCROP_UNSET) 966 if (info->crop_yoffset_set == JCROP_UNSET)
967 info->crop_yoffset = 0; /* default to +0 */ 967 info->crop_yoffset = 0; /* default to +0 */
968 if (info->crop_xoffset >= info->output_width || 968 if (info->crop_xoffset >= info->output_width ||
969 info->crop_yoffset >= info->output_height) 969 info->crop_yoffset >= info->output_height)
970 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); 970 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
971 if (info->crop_width_set == JCROP_UNSET) 971 if (info->crop_width_set == JCROP_UNSET)
972 info->crop_width = info->output_width - info->crop_xoffset; 972 info->crop_width = info->output_width - info->crop_xoffset;
973 if (info->crop_height_set == JCROP_UNSET) 973 if (info->crop_height_set == JCROP_UNSET)
974 info->crop_height = info->output_height - info->crop_yoffset; 974 info->crop_height = info->output_height - info->crop_yoffset;
975 /* Ensure parameters are valid */ 975 /* Ensure parameters are valid */
976 if (info->crop_width <= 0 || info->crop_width > info->output_width || 976 if (info->crop_width <= 0 || info->crop_width > info->output_width ||
977 info->crop_height <= 0 || info->crop_height > info->output_height || 977 info->crop_height <= 0 || info->crop_height > info->output_height ||
978 info->crop_xoffset > info->output_width - info->crop_width || 978 info->crop_xoffset > info->output_width - info->crop_width ||
979 info->crop_yoffset > info->output_height - info->crop_height) 979 info->crop_yoffset > info->output_height - info->crop_height)
980 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); 980 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
981 /* Convert negative crop offsets into regular offsets */ 981 /* Convert negative crop offsets into regular offsets */
982 if (info->crop_xoffset_set == JCROP_NEG) 982 if (info->crop_xoffset_set == JCROP_NEG)
983 xoffset = info->output_width - info->crop_width - info->crop_xoffset; 983 xoffset = info->output_width - info->crop_width - info->crop_xoffset;
984 else 984 else
985 xoffset = info->crop_xoffset; 985 xoffset = info->crop_xoffset;
986 if (info->crop_yoffset_set == JCROP_NEG) 986 if (info->crop_yoffset_set == JCROP_NEG)
987 yoffset = info->output_height - info->crop_height - info->crop_yoffset; 987 yoffset = info->output_height - info->crop_height - info->crop_yoffset;
988 else 988 else
989 yoffset = info->crop_yoffset; 989 yoffset = info->crop_yoffset;
990 /* Now adjust so that upper left corner falls at an iMCU boundary */ 990 /* Now adjust so that upper left corner falls at an iMCU boundary */
991 if (info->crop_width_set == JCROP_FORCE) 991 if (info->crop_width_set == JCROP_FORCE)
992 info->output_width = info->crop_width; 992 info->output_width = info->crop_width;
993 else 993 else
994 info->output_width = 994 info->output_width =
995 info->crop_width + (xoffset % info->iMCU_sample_width); 995 info->crop_width + (xoffset % info->iMCU_sample_width);
996 if (info->crop_height_set == JCROP_FORCE) 996 if (info->crop_height_set == JCROP_FORCE)
997 info->output_height = info->crop_height; 997 info->output_height = info->crop_height;
998 else 998 else
999 info->output_height = 999 info->output_height =
1000 info->crop_height + (yoffset % info->iMCU_sample_height); 1000 info->crop_height + (yoffset % info->iMCU_sample_height);
1001 /* Save x/y offsets measured in iMCUs */ 1001 /* Save x/y offsets measured in iMCUs */
1002 info->x_crop_offset = xoffset / info->iMCU_sample_width; 1002 info->x_crop_offset = xoffset / info->iMCU_sample_width;
1003 info->y_crop_offset = yoffset / info->iMCU_sample_height; 1003 info->y_crop_offset = yoffset / info->iMCU_sample_height;
1004 } else { 1004 } else {
1005 info->x_crop_offset = 0; 1005 info->x_crop_offset = 0;
1006 info->y_crop_offset = 0; 1006 info->y_crop_offset = 0;
1007 } 1007 }
1008 1008
1009 /* Figure out whether we need workspace arrays, 1009 /* Figure out whether we need workspace arrays,
1010 * and if so whether they are transposed relative to the source. 1010 * and if so whether they are transposed relative to the source.
1011 */ 1011 */
1012 need_workspace = FALSE; 1012 need_workspace = FALSE;
1013 transpose_it = FALSE; 1013 transpose_it = FALSE;
1014 switch (info->transform) { 1014 switch (info->transform) {
1015 case JXFORM_NONE: 1015 case JXFORM_NONE:
1016 if (info->x_crop_offset != 0 || info->y_crop_offset != 0) 1016 if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1017 need_workspace = TRUE; 1017 need_workspace = TRUE;
1018 /* No workspace needed if neither cropping nor transforming */ 1018 /* No workspace needed if neither cropping nor transforming */
1019 break; 1019 break;
1020 case JXFORM_FLIP_H: 1020 case JXFORM_FLIP_H:
1021 if (info->trim) 1021 if (info->trim)
1022 trim_right_edge(info, srcinfo->output_width); 1022 trim_right_edge(info, srcinfo->output_width);
1023 if (info->y_crop_offset != 0) 1023 if (info->y_crop_offset != 0)
1024 need_workspace = TRUE; 1024 need_workspace = TRUE;
1025 /* do_flip_h_no_crop doesn't need a workspace array */ 1025 /* do_flip_h_no_crop doesn't need a workspace array */
1026 break; 1026 break;
1027 case JXFORM_FLIP_V: 1027 case JXFORM_FLIP_V:
1028 if (info->trim) 1028 if (info->trim)
1029 trim_bottom_edge(info, srcinfo->output_height); 1029 trim_bottom_edge(info, srcinfo->output_height);
1030 /* Need workspace arrays having same dimensions as source image. */ 1030 /* Need workspace arrays having same dimensions as source image. */
1031 need_workspace = TRUE; 1031 need_workspace = TRUE;
1032 break; 1032 break;
1033 case JXFORM_TRANSPOSE: 1033 case JXFORM_TRANSPOSE:
1034 /* transpose does NOT have to trim anything */ 1034 /* transpose does NOT have to trim anything */
1035 /* Need workspace arrays having transposed dimensions. */ 1035 /* Need workspace arrays having transposed dimensions. */
1036 need_workspace = TRUE; 1036 need_workspace = TRUE;
1037 transpose_it = TRUE; 1037 transpose_it = TRUE;
1038 break; 1038 break;
1039 case JXFORM_TRANSVERSE: 1039 case JXFORM_TRANSVERSE:
1040 if (info->trim) { 1040 if (info->trim) {
1041 trim_right_edge(info, srcinfo->output_height); 1041 trim_right_edge(info, srcinfo->output_height);
1042 trim_bottom_edge(info, srcinfo->output_width); 1042 trim_bottom_edge(info, srcinfo->output_width);
1043 } 1043 }
1044 /* Need workspace arrays having transposed dimensions. */ 1044 /* Need workspace arrays having transposed dimensions. */
1045 need_workspace = TRUE; 1045 need_workspace = TRUE;
1046 transpose_it = TRUE; 1046 transpose_it = TRUE;
1047 break; 1047 break;
1048 case JXFORM_ROT_90: 1048 case JXFORM_ROT_90:
1049 if (info->trim) 1049 if (info->trim)
1050 trim_right_edge(info, srcinfo->output_height); 1050 trim_right_edge(info, srcinfo->output_height);
1051 /* Need workspace arrays having transposed dimensions. */ 1051 /* Need workspace arrays having transposed dimensions. */
1052 need_workspace = TRUE; 1052 need_workspace = TRUE;
1053 transpose_it = TRUE; 1053 transpose_it = TRUE;
1054 break; 1054 break;
1055 case JXFORM_ROT_180: 1055 case JXFORM_ROT_180:
1056 if (info->trim) { 1056 if (info->trim) {
1057 trim_right_edge(info, srcinfo->output_width); 1057 trim_right_edge(info, srcinfo->output_width);
1058 trim_bottom_edge(info, srcinfo->output_height); 1058 trim_bottom_edge(info, srcinfo->output_height);
1059 } 1059 }
1060 /* Need workspace arrays having same dimensions as source image. */ 1060 /* Need workspace arrays having same dimensions as source image. */
1061 need_workspace = TRUE; 1061 need_workspace = TRUE;
1062 break; 1062 break;
1063 case JXFORM_ROT_270: 1063 case JXFORM_ROT_270:
1064 if (info->trim) 1064 if (info->trim)
1065 trim_bottom_edge(info, srcinfo->output_width); 1065 trim_bottom_edge(info, srcinfo->output_width);
1066 /* Need workspace arrays having transposed dimensions. */ 1066 /* Need workspace arrays having transposed dimensions. */
1067 need_workspace = TRUE; 1067 need_workspace = TRUE;
1068 transpose_it = TRUE; 1068 transpose_it = TRUE;
1069 break; 1069 break;
1070 } 1070 }
1071 1071
1072 /* Allocate workspace if needed. 1072 /* Allocate workspace if needed.
1073 * Note that we allocate arrays padded out to the next iMCU boundary, 1073 * Note that we allocate arrays padded out to the next iMCU boundary,
1074 * so that transform routines need not worry about missing edge blocks. 1074 * so that transform routines need not worry about missing edge blocks.
1075 */ 1075 */
1076 if (need_workspace) { 1076 if (need_workspace) {
1077 coef_arrays = (jvirt_barray_ptr *) 1077 coef_arrays = (jvirt_barray_ptr *)
1078 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 1078 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1079 SIZEOF(jvirt_barray_ptr) * info->num_components); 1079 SIZEOF(jvirt_barray_ptr) * info->num_components);
1080 width_in_iMCUs = (JDIMENSION) 1080 width_in_iMCUs = (JDIMENSION)
1081 jdiv_round_up((long) info->output_width, 1081 jdiv_round_up((long) info->output_width,
1082 (long) info->iMCU_sample_width); 1082 (long) info->iMCU_sample_width);
1083 height_in_iMCUs = (JDIMENSION) 1083 height_in_iMCUs = (JDIMENSION)
1084 jdiv_round_up((long) info->output_height, 1084 jdiv_round_up((long) info->output_height,
1085 (long) info->iMCU_sample_height); 1085 (long) info->iMCU_sample_height);
1086 for (ci = 0; ci < info->num_components; ci++) { 1086 for (ci = 0; ci < info->num_components; ci++) {
1087 compptr = srcinfo->comp_info + ci; 1087 compptr = srcinfo->comp_info + ci;
1088 if (info->num_components == 1) { 1088 if (info->num_components == 1) {
1089 /* we're going to force samp factors to 1x1 in this case */ 1089 /* we're going to force samp factors to 1x1 in this case */
1090 h_samp_factor = v_samp_factor = 1; 1090 h_samp_factor = v_samp_factor = 1;
1091 } else if (transpose_it) { 1091 } else if (transpose_it) {
1092 h_samp_factor = compptr->v_samp_factor; 1092 h_samp_factor = compptr->v_samp_factor;
1093 v_samp_factor = compptr->h_samp_factor; 1093 v_samp_factor = compptr->h_samp_factor;
1094 } else { 1094 } else {
1095 h_samp_factor = compptr->h_samp_factor; 1095 h_samp_factor = compptr->h_samp_factor;
1096 v_samp_factor = compptr->v_samp_factor; 1096 v_samp_factor = compptr->v_samp_factor;
1097 } 1097 }
1098 width_in_blocks = width_in_iMCUs * h_samp_factor; 1098 width_in_blocks = width_in_iMCUs * h_samp_factor;
1099 height_in_blocks = height_in_iMCUs * v_samp_factor; 1099 height_in_blocks = height_in_iMCUs * v_samp_factor;
1100 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 1100 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1101 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 1101 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
1102 width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor); 1102 width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
1103 } 1103 }
1104 info->workspace_coef_arrays = coef_arrays; 1104 info->workspace_coef_arrays = coef_arrays;
1105 } else 1105 } else
1106 info->workspace_coef_arrays = NULL; 1106 info->workspace_coef_arrays = NULL;
1107 1107
1108 return TRUE; 1108 return TRUE;
1109} 1109}
1110 1110
1111 1111
1112/* Transpose destination image parameters */ 1112/* Transpose destination image parameters */
1113 1113
1114LOCAL(void) 1114LOCAL(void)
1115transpose_critical_parameters (j_compress_ptr dstinfo) 1115transpose_critical_parameters (j_compress_ptr dstinfo)
1116{ 1116{
1117 int tblno, i, j, ci, itemp; 1117 int tblno, i, j, ci, itemp;
1118 jpeg_component_info *compptr; 1118 jpeg_component_info *compptr;
1119 JQUANT_TBL *qtblptr; 1119 JQUANT_TBL *qtblptr;
1120 JDIMENSION jtemp; 1120 JDIMENSION jtemp;
1121 UINT16 qtemp; 1121 UINT16 qtemp;
1122 1122
1123 /* Transpose image dimensions */ 1123 /* Transpose image dimensions */
1124 jtemp = dstinfo->image_width; 1124 jtemp = dstinfo->image_width;
1125 dstinfo->image_width = dstinfo->image_height; 1125 dstinfo->image_width = dstinfo->image_height;
1126 dstinfo->image_height = jtemp; 1126 dstinfo->image_height = jtemp;
1127 itemp = dstinfo->min_DCT_h_scaled_size; 1127 itemp = dstinfo->min_DCT_h_scaled_size;
1128 dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size; 1128 dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
1129 dstinfo->min_DCT_v_scaled_size = itemp; 1129 dstinfo->min_DCT_v_scaled_size = itemp;
1130 1130
1131 /* Transpose sampling factors */ 1131 /* Transpose sampling factors */
1132 for (ci = 0; ci < dstinfo->num_components; ci++) { 1132 for (ci = 0; ci < dstinfo->num_components; ci++) {
1133 compptr = dstinfo->comp_info + ci; 1133 compptr = dstinfo->comp_info + ci;
1134 itemp = compptr->h_samp_factor; 1134 itemp = compptr->h_samp_factor;
1135 compptr->h_samp_factor = compptr->v_samp_factor; 1135 compptr->h_samp_factor = compptr->v_samp_factor;
1136 compptr->v_samp_factor = itemp; 1136 compptr->v_samp_factor = itemp;
1137 } 1137 }
1138 1138
1139 /* Transpose quantization tables */ 1139 /* Transpose quantization tables */
1140 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { 1140 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
1141 qtblptr = dstinfo->quant_tbl_ptrs[tblno]; 1141 qtblptr = dstinfo->quant_tbl_ptrs[tblno];
1142 if (qtblptr != NULL) { 1142 if (qtblptr != NULL) {
1143 for (i = 0; i < DCTSIZE; i++) { 1143 for (i = 0; i < DCTSIZE; i++) {
1144 for (j = 0; j < i; j++) { 1144 for (j = 0; j < i; j++) {
1145 qtemp = qtblptr->quantval[i*DCTSIZE+j]; 1145 qtemp = qtblptr->quantval[i*DCTSIZE+j];
1146 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; 1146 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
1147 qtblptr->quantval[j*DCTSIZE+i] = qtemp; 1147 qtblptr->quantval[j*DCTSIZE+i] = qtemp;
1148 } 1148 }
1149 } 1149 }
1150 } 1150 }
1151 } 1151 }
1152} 1152}
1153 1153
1154 1154
1155/* Adjust Exif image parameters. 1155/* Adjust Exif image parameters.
1156 * 1156 *
1157 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. 1157 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1158 */ 1158 */
1159 1159
1160LOCAL(void) 1160LOCAL(void)
1161adjust_exif_parameters (JOCTET FAR * data, unsigned int length, 1161adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
1162 JDIMENSION new_width, JDIMENSION new_height) 1162 JDIMENSION new_width, JDIMENSION new_height)
1163{ 1163{
1164 boolean is_motorola; /* Flag for byte order */ 1164 boolean is_motorola; /* Flag for byte order */
1165 unsigned int number_of_tags, tagnum; 1165 unsigned int number_of_tags, tagnum;
1166 unsigned int firstoffset, offset; 1166 unsigned int firstoffset, offset;
1167 JDIMENSION new_value; 1167 JDIMENSION new_value;
1168 1168
1169 if (length < 12) return; /* Length of an IFD entry */ 1169 if (length < 12) return; /* Length of an IFD entry */
1170 1170
1171 /* Discover byte order */ 1171 /* Discover byte order */
1172 if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) 1172 if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
1173 is_motorola = FALSE; 1173 is_motorola = FALSE;
1174 else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) 1174 else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
1175 is_motorola = TRUE; 1175 is_motorola = TRUE;
1176 else 1176 else
1177 return; 1177 return;
1178 1178
1179 /* Check Tag Mark */ 1179 /* Check Tag Mark */
1180 if (is_motorola) { 1180 if (is_motorola) {
1181 if (GETJOCTET(data[2]) != 0) return; 1181 if (GETJOCTET(data[2]) != 0) return;
1182 if (GETJOCTET(data[3]) != 0x2A) return; 1182 if (GETJOCTET(data[3]) != 0x2A) return;
1183 } else { 1183 } else {
1184 if (GETJOCTET(data[3]) != 0) return; 1184 if (GETJOCTET(data[3]) != 0) return;
1185 if (GETJOCTET(data[2]) != 0x2A) return; 1185 if (GETJOCTET(data[2]) != 0x2A) return;
1186 } 1186 }
1187 1187
1188 /* Get first IFD offset (offset to IFD0) */ 1188 /* Get first IFD offset (offset to IFD0) */
1189 if (is_motorola) { 1189 if (is_motorola) {
1190 if (GETJOCTET(data[4]) != 0) return; 1190 if (GETJOCTET(data[4]) != 0) return;
1191 if (GETJOCTET(data[5]) != 0) return; 1191 if (GETJOCTET(data[5]) != 0) return;
1192 firstoffset = GETJOCTET(data[6]); 1192 firstoffset = GETJOCTET(data[6]);
1193 firstoffset <<= 8; 1193 firstoffset <<= 8;
1194 firstoffset += GETJOCTET(data[7]); 1194 firstoffset += GETJOCTET(data[7]);
1195 } else { 1195 } else {
1196 if (GETJOCTET(data[7]) != 0) return; 1196 if (GETJOCTET(data[7]) != 0) return;
1197 if (GETJOCTET(data[6]) != 0) return; 1197 if (GETJOCTET(data[6]) != 0) return;
1198 firstoffset = GETJOCTET(data[5]); 1198 firstoffset = GETJOCTET(data[5]);
1199 firstoffset <<= 8; 1199 firstoffset <<= 8;
1200 firstoffset += GETJOCTET(data[4]); 1200 firstoffset += GETJOCTET(data[4]);
1201 } 1201 }
1202 if (firstoffset > length - 2) return; /* check end of data segment */ 1202 if (firstoffset > length - 2) return; /* check end of data segment */
1203 1203
1204 /* Get the number of directory entries contained in this IFD */ 1204 /* Get the number of directory entries contained in this IFD */
1205 if (is_motorola) { 1205 if (is_motorola) {
1206 number_of_tags = GETJOCTET(data[firstoffset]); 1206 number_of_tags = GETJOCTET(data[firstoffset]);
1207 number_of_tags <<= 8; 1207 number_of_tags <<= 8;
1208 number_of_tags += GETJOCTET(data[firstoffset+1]); 1208 number_of_tags += GETJOCTET(data[firstoffset+1]);
1209 } else { 1209 } else {
1210 number_of_tags = GETJOCTET(data[firstoffset+1]); 1210 number_of_tags = GETJOCTET(data[firstoffset+1]);
1211 number_of_tags <<= 8; 1211 number_of_tags <<= 8;
1212 number_of_tags += GETJOCTET(data[firstoffset]); 1212 number_of_tags += GETJOCTET(data[firstoffset]);
1213 } 1213 }
1214 if (number_of_tags == 0) return; 1214 if (number_of_tags == 0) return;
1215 firstoffset += 2; 1215 firstoffset += 2;
1216 1216
1217 /* Search for ExifSubIFD offset Tag in IFD0 */ 1217 /* Search for ExifSubIFD offset Tag in IFD0 */
1218 for (;;) { 1218 for (;;) {
1219 if (firstoffset > length - 12) return; /* check end of data segment */ 1219 if (firstoffset > length - 12) return; /* check end of data segment */
1220 /* Get Tag number */ 1220 /* Get Tag number */
1221 if (is_motorola) { 1221 if (is_motorola) {
1222 tagnum = GETJOCTET(data[firstoffset]); 1222 tagnum = GETJOCTET(data[firstoffset]);
1223 tagnum <<= 8; 1223 tagnum <<= 8;
1224 tagnum += GETJOCTET(data[firstoffset+1]); 1224 tagnum += GETJOCTET(data[firstoffset+1]);
1225 } else { 1225 } else {
1226 tagnum = GETJOCTET(data[firstoffset+1]); 1226 tagnum = GETJOCTET(data[firstoffset+1]);
1227 tagnum <<= 8; 1227 tagnum <<= 8;
1228 tagnum += GETJOCTET(data[firstoffset]); 1228 tagnum += GETJOCTET(data[firstoffset]);
1229 } 1229 }
1230 if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */ 1230 if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
1231 if (--number_of_tags == 0) return; 1231 if (--number_of_tags == 0) return;
1232 firstoffset += 12; 1232 firstoffset += 12;
1233 } 1233 }
1234 1234
1235 /* Get the ExifSubIFD offset */ 1235 /* Get the ExifSubIFD offset */
1236 if (is_motorola) { 1236 if (is_motorola) {
1237 if (GETJOCTET(data[firstoffset+8]) != 0) return; 1237 if (GETJOCTET(data[firstoffset+8]) != 0) return;
1238 if (GETJOCTET(data[firstoffset+9]) != 0) return; 1238 if (GETJOCTET(data[firstoffset+9]) != 0) return;
1239 offset = GETJOCTET(data[firstoffset+10]); 1239 offset = GETJOCTET(data[firstoffset+10]);
1240 offset <<= 8; 1240 offset <<= 8;
1241 offset += GETJOCTET(data[firstoffset+11]); 1241 offset += GETJOCTET(data[firstoffset+11]);
1242 } else { 1242 } else {
1243 if (GETJOCTET(data[firstoffset+11]) != 0) return; 1243 if (GETJOCTET(data[firstoffset+11]) != 0) return;
1244 if (GETJOCTET(data[firstoffset+10]) != 0) return; 1244 if (GETJOCTET(data[firstoffset+10]) != 0) return;
1245 offset = GETJOCTET(data[firstoffset+9]); 1245 offset = GETJOCTET(data[firstoffset+9]);
1246 offset <<= 8; 1246 offset <<= 8;
1247 offset += GETJOCTET(data[firstoffset+8]); 1247 offset += GETJOCTET(data[firstoffset+8]);
1248 } 1248 }
1249 if (offset > length - 2) return; /* check end of data segment */ 1249 if (offset > length - 2) return; /* check end of data segment */
1250 1250
1251 /* Get the number of directory entries contained in this SubIFD */ 1251 /* Get the number of directory entries contained in this SubIFD */
1252 if (is_motorola) { 1252 if (is_motorola) {
1253 number_of_tags = GETJOCTET(data[offset]); 1253 number_of_tags = GETJOCTET(data[offset]);
1254 number_of_tags <<= 8; 1254 number_of_tags <<= 8;
1255 number_of_tags += GETJOCTET(data[offset+1]); 1255 number_of_tags += GETJOCTET(data[offset+1]);
1256 } else { 1256 } else {
1257 number_of_tags = GETJOCTET(data[offset+1]); 1257 number_of_tags = GETJOCTET(data[offset+1]);
1258 number_of_tags <<= 8; 1258 number_of_tags <<= 8;
1259 number_of_tags += GETJOCTET(data[offset]); 1259 number_of_tags += GETJOCTET(data[offset]);
1260 } 1260 }
1261 if (number_of_tags < 2) return; 1261 if (number_of_tags < 2) return;
1262 offset += 2; 1262 offset += 2;
1263 1263
1264 /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ 1264 /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1265 do { 1265 do {
1266 if (offset > length - 12) return; /* check end of data segment */ 1266 if (offset > length - 12) return; /* check end of data segment */
1267 /* Get Tag number */ 1267 /* Get Tag number */
1268 if (is_motorola) { 1268 if (is_motorola) {
1269 tagnum = GETJOCTET(data[offset]); 1269 tagnum = GETJOCTET(data[offset]);
1270 tagnum <<= 8; 1270 tagnum <<= 8;
1271 tagnum += GETJOCTET(data[offset+1]); 1271 tagnum += GETJOCTET(data[offset+1]);
1272 } else { 1272 } else {
1273 tagnum = GETJOCTET(data[offset+1]); 1273 tagnum = GETJOCTET(data[offset+1]);
1274 tagnum <<= 8; 1274 tagnum <<= 8;
1275 tagnum += GETJOCTET(data[offset]); 1275 tagnum += GETJOCTET(data[offset]);
1276 } 1276 }
1277 if (tagnum == 0xA002 || tagnum == 0xA003) { 1277 if (tagnum == 0xA002 || tagnum == 0xA003) {
1278 if (tagnum == 0xA002) 1278 if (tagnum == 0xA002)
1279 new_value = new_width; /* ExifImageWidth Tag */ 1279 new_value = new_width; /* ExifImageWidth Tag */
1280 else 1280 else
1281 new_value = new_height; /* ExifImageHeight Tag */ 1281 new_value = new_height; /* ExifImageHeight Tag */
1282 if (is_motorola) { 1282 if (is_motorola) {
1283 data[offset+2] = 0; /* Format = unsigned long (4 octets) */ 1283 data[offset+2] = 0; /* Format = unsigned long (4 octets) */
1284 data[offset+3] = 4; 1284 data[offset+3] = 4;
1285 data[offset+4] = 0; /* Number Of Components = 1 */ 1285 data[offset+4] = 0; /* Number Of Components = 1 */
1286 data[offset+5] = 0; 1286 data[offset+5] = 0;
1287 data[offset+6] = 0; 1287 data[offset+6] = 0;
1288 data[offset+7] = 1; 1288 data[offset+7] = 1;
1289 data[offset+8] = 0; 1289 data[offset+8] = 0;
1290 data[offset+9] = 0; 1290 data[offset+9] = 0;
1291 data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); 1291 data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
1292 data[offset+11] = (JOCTET)(new_value & 0xFF); 1292 data[offset+11] = (JOCTET)(new_value & 0xFF);
1293 } else { 1293 } else {
1294 data[offset+2] = 4; /* Format = unsigned long (4 octets) */ 1294 data[offset+2] = 4; /* Format = unsigned long (4 octets) */
1295 data[offset+3] = 0; 1295 data[offset+3] = 0;
1296 data[offset+4] = 1; /* Number Of Components = 1 */ 1296 data[offset+4] = 1; /* Number Of Components = 1 */
1297 data[offset+5] = 0; 1297 data[offset+5] = 0;
1298 data[offset+6] = 0; 1298 data[offset+6] = 0;
1299 data[offset+7] = 0; 1299 data[offset+7] = 0;
1300 data[offset+8] = (JOCTET)(new_value & 0xFF); 1300 data[offset+8] = (JOCTET)(new_value & 0xFF);
1301 data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); 1301 data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
1302 data[offset+10] = 0; 1302 data[offset+10] = 0;
1303 data[offset+11] = 0; 1303 data[offset+11] = 0;
1304 } 1304 }
1305 } 1305 }
1306 offset += 12; 1306 offset += 12;
1307 } while (--number_of_tags); 1307 } while (--number_of_tags);
1308} 1308}
1309 1309
1310 1310
1311/* Adjust output image parameters as needed. 1311/* Adjust output image parameters as needed.
1312 * 1312 *
1313 * This must be called after jpeg_copy_critical_parameters() 1313 * This must be called after jpeg_copy_critical_parameters()
1314 * and before jpeg_write_coefficients(). 1314 * and before jpeg_write_coefficients().
1315 * 1315 *
1316 * The return value is the set of virtual coefficient arrays to be written 1316 * The return value is the set of virtual coefficient arrays to be written
1317 * (either the ones allocated by jtransform_request_workspace, or the 1317 * (either the ones allocated by jtransform_request_workspace, or the
1318 * original source data arrays). The caller will need to pass this value 1318 * original source data arrays). The caller will need to pass this value
1319 * to jpeg_write_coefficients(). 1319 * to jpeg_write_coefficients().
1320 */ 1320 */
1321 1321
1322GLOBAL(jvirt_barray_ptr *) 1322GLOBAL(jvirt_barray_ptr *)
1323jtransform_adjust_parameters (j_decompress_ptr srcinfo, 1323jtransform_adjust_parameters (j_decompress_ptr srcinfo,
1324 j_compress_ptr dstinfo, 1324 j_compress_ptr dstinfo,
1325 jvirt_barray_ptr *src_coef_arrays, 1325 jvirt_barray_ptr *src_coef_arrays,
1326 jpeg_transform_info *info) 1326 jpeg_transform_info *info)
1327{ 1327{
1328 /* If force-to-grayscale is requested, adjust destination parameters */ 1328 /* If force-to-grayscale is requested, adjust destination parameters */
1329 if (info->force_grayscale) { 1329 if (info->force_grayscale) {
1330 /* First, ensure we have YCbCr or grayscale data, and that the source's 1330 /* First, ensure we have YCbCr or grayscale data, and that the source's
1331 * Y channel is full resolution. (No reasonable person would make Y 1331 * Y channel is full resolution. (No reasonable person would make Y
1332 * be less than full resolution, so actually coping with that case 1332 * be less than full resolution, so actually coping with that case
1333 * isn't worth extra code space. But we check it to avoid crashing.) 1333 * isn't worth extra code space. But we check it to avoid crashing.)
1334 */ 1334 */
1335 if (((dstinfo->jpeg_color_space == JCS_YCbCr && 1335 if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
1336 dstinfo->num_components == 3) || 1336 dstinfo->num_components == 3) ||
1337 (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 1337 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
1338 dstinfo->num_components == 1)) && 1338 dstinfo->num_components == 1)) &&
1339 srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor && 1339 srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
1340 srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) { 1340 srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
1341 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 1341 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1342 * properly. Among other things, it sets the target h_samp_factor & 1342 * properly. Among other things, it sets the target h_samp_factor &
1343 * v_samp_factor to 1, which typically won't match the source. 1343 * v_samp_factor to 1, which typically won't match the source.
1344 * We have to preserve the source's quantization table number, however. 1344 * We have to preserve the source's quantization table number, however.
1345 */ 1345 */
1346 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; 1346 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
1347 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); 1347 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
1348 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; 1348 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
1349 } else { 1349 } else {
1350 /* Sorry, can't do it */ 1350 /* Sorry, can't do it */
1351 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); 1351 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
1352 } 1352 }
1353 } else if (info->num_components == 1) { 1353 } else if (info->num_components == 1) {
1354 /* For a single-component source, we force the destination sampling factors 1354 /* For a single-component source, we force the destination sampling factors
1355 * to 1x1, with or without force_grayscale. This is useful because some 1355 * to 1x1, with or without force_grayscale. This is useful because some
1356 * decoders choke on grayscale images with other sampling factors. 1356 * decoders choke on grayscale images with other sampling factors.
1357 */ 1357 */
1358 dstinfo->comp_info[0].h_samp_factor = 1; 1358 dstinfo->comp_info[0].h_samp_factor = 1;
1359 dstinfo->comp_info[0].v_samp_factor = 1; 1359 dstinfo->comp_info[0].v_samp_factor = 1;
1360 } 1360 }
1361 1361
1362 /* Correct the destination's image dimensions as necessary 1362 /* Correct the destination's image dimensions as necessary
1363 * for rotate/flip, resize, and crop operations. 1363 * for rotate/flip, resize, and crop operations.
1364 */ 1364 */
1365 dstinfo->jpeg_width = info->output_width; 1365 dstinfo->jpeg_width = info->output_width;
1366 dstinfo->jpeg_height = info->output_height; 1366 dstinfo->jpeg_height = info->output_height;
1367 1367
1368 /* Transpose destination image parameters */ 1368 /* Transpose destination image parameters */
1369 switch (info->transform) { 1369 switch (info->transform) {
1370 case JXFORM_TRANSPOSE: 1370 case JXFORM_TRANSPOSE:
1371 case JXFORM_TRANSVERSE: 1371 case JXFORM_TRANSVERSE:
1372 case JXFORM_ROT_90: 1372 case JXFORM_ROT_90:
1373 case JXFORM_ROT_270: 1373 case JXFORM_ROT_270:
1374 transpose_critical_parameters(dstinfo); 1374 transpose_critical_parameters(dstinfo);
1375 break; 1375 break;
1376 default: 1376 default:
1377 break; 1377 break;
1378 } 1378 }
1379 1379
1380 /* Adjust Exif properties */ 1380 /* Adjust Exif properties */
1381 if (srcinfo->marker_list != NULL && 1381 if (srcinfo->marker_list != NULL &&
1382 srcinfo->marker_list->marker == JPEG_APP0+1 && 1382 srcinfo->marker_list->marker == JPEG_APP0+1 &&
1383 srcinfo->marker_list->data_length >= 6 && 1383 srcinfo->marker_list->data_length >= 6 &&
1384 GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 && 1384 GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
1385 GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 && 1385 GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
1386 GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 && 1386 GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
1387 GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 && 1387 GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
1388 GETJOCTET(srcinfo->marker_list->data[4]) == 0 && 1388 GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
1389 GETJOCTET(srcinfo->marker_list->data[5]) == 0) { 1389 GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
1390 /* Suppress output of JFIF marker */ 1390 /* Suppress output of JFIF marker */
1391 dstinfo->write_JFIF_header = FALSE; 1391 dstinfo->write_JFIF_header = FALSE;
1392 /* Adjust Exif image parameters */ 1392 /* Adjust Exif image parameters */
1393 if (dstinfo->jpeg_width != srcinfo->image_width || 1393 if (dstinfo->jpeg_width != srcinfo->image_width ||
1394 dstinfo->jpeg_height != srcinfo->image_height) 1394 dstinfo->jpeg_height != srcinfo->image_height)
1395 /* Align data segment to start of TIFF structure for parsing */ 1395 /* Align data segment to start of TIFF structure for parsing */
1396 adjust_exif_parameters(srcinfo->marker_list->data + 6, 1396 adjust_exif_parameters(srcinfo->marker_list->data + 6,
1397 srcinfo->marker_list->data_length - 6, 1397 srcinfo->marker_list->data_length - 6,
1398 dstinfo->jpeg_width, dstinfo->jpeg_height); 1398 dstinfo->jpeg_width, dstinfo->jpeg_height);
1399 } 1399 }
1400 1400
1401 /* Return the appropriate output data set */ 1401 /* Return the appropriate output data set */
1402 if (info->workspace_coef_arrays != NULL) 1402 if (info->workspace_coef_arrays != NULL)
1403 return info->workspace_coef_arrays; 1403 return info->workspace_coef_arrays;
1404 return src_coef_arrays; 1404 return src_coef_arrays;
1405} 1405}
1406 1406
1407 1407
1408/* Execute the actual transformation, if any. 1408/* Execute the actual transformation, if any.
1409 * 1409 *
1410 * This must be called *after* jpeg_write_coefficients, because it depends 1410 * This must be called *after* jpeg_write_coefficients, because it depends
1411 * on jpeg_write_coefficients to have computed subsidiary values such as 1411 * on jpeg_write_coefficients to have computed subsidiary values such as
1412 * the per-component width and height fields in the destination object. 1412 * the per-component width and height fields in the destination object.
1413 * 1413 *
1414 * Note that some transformations will modify the source data arrays! 1414 * Note that some transformations will modify the source data arrays!
1415 */ 1415 */
1416 1416
1417GLOBAL(void) 1417GLOBAL(void)
1418jtransform_execute_transform (j_decompress_ptr srcinfo, 1418jtransform_execute_transform (j_decompress_ptr srcinfo,
1419 j_compress_ptr dstinfo, 1419 j_compress_ptr dstinfo,
1420 jvirt_barray_ptr *src_coef_arrays, 1420 jvirt_barray_ptr *src_coef_arrays,
1421 jpeg_transform_info *info) 1421 jpeg_transform_info *info)
1422{ 1422{
1423 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; 1423 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
1424 1424
1425 /* Note: conditions tested here should match those in switch statement 1425 /* Note: conditions tested here should match those in switch statement
1426 * in jtransform_request_workspace() 1426 * in jtransform_request_workspace()
1427 */ 1427 */
1428 switch (info->transform) { 1428 switch (info->transform) {
1429 case JXFORM_NONE: 1429 case JXFORM_NONE:
1430 if (info->x_crop_offset != 0 || info->y_crop_offset != 0) 1430 if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1431 do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1431 do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1432 src_coef_arrays, dst_coef_arrays); 1432 src_coef_arrays, dst_coef_arrays);
1433 break; 1433 break;
1434 case JXFORM_FLIP_H: 1434 case JXFORM_FLIP_H:
1435 if (info->y_crop_offset != 0) 1435 if (info->y_crop_offset != 0)
1436 do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1436 do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1437 src_coef_arrays, dst_coef_arrays); 1437 src_coef_arrays, dst_coef_arrays);
1438 else 1438 else
1439 do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset, 1439 do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
1440 src_coef_arrays); 1440 src_coef_arrays);
1441 break; 1441 break;
1442 case JXFORM_FLIP_V: 1442 case JXFORM_FLIP_V:
1443 do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1443 do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1444 src_coef_arrays, dst_coef_arrays); 1444 src_coef_arrays, dst_coef_arrays);
1445 break; 1445 break;
1446 case JXFORM_TRANSPOSE: 1446 case JXFORM_TRANSPOSE:
1447 do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1447 do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1448 src_coef_arrays, dst_coef_arrays); 1448 src_coef_arrays, dst_coef_arrays);
1449 break; 1449 break;
1450 case JXFORM_TRANSVERSE: 1450 case JXFORM_TRANSVERSE:
1451 do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1451 do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1452 src_coef_arrays, dst_coef_arrays); 1452 src_coef_arrays, dst_coef_arrays);
1453 break; 1453 break;
1454 case JXFORM_ROT_90: 1454 case JXFORM_ROT_90:
1455 do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1455 do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1456 src_coef_arrays, dst_coef_arrays); 1456 src_coef_arrays, dst_coef_arrays);
1457 break; 1457 break;
1458 case JXFORM_ROT_180: 1458 case JXFORM_ROT_180:
1459 do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1459 do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1460 src_coef_arrays, dst_coef_arrays); 1460 src_coef_arrays, dst_coef_arrays);
1461 break; 1461 break;
1462 case JXFORM_ROT_270: 1462 case JXFORM_ROT_270:
1463 do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1463 do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1464 src_coef_arrays, dst_coef_arrays); 1464 src_coef_arrays, dst_coef_arrays);
1465 break; 1465 break;
1466 } 1466 }
1467} 1467}
1468 1468
1469/* jtransform_perfect_transform 1469/* jtransform_perfect_transform
1470 * 1470 *
1471 * Determine whether lossless transformation is perfectly 1471 * Determine whether lossless transformation is perfectly
1472 * possible for a specified image and transformation. 1472 * possible for a specified image and transformation.
1473 * 1473 *
1474 * Inputs: 1474 * Inputs:
1475 * image_width, image_height: source image dimensions. 1475 * image_width, image_height: source image dimensions.
1476 * MCU_width, MCU_height: pixel dimensions of MCU. 1476 * MCU_width, MCU_height: pixel dimensions of MCU.
1477 * transform: transformation identifier. 1477 * transform: transformation identifier.
1478 * Parameter sources from initialized jpeg_struct 1478 * Parameter sources from initialized jpeg_struct
1479 * (after reading source header): 1479 * (after reading source header):
1480 * image_width = cinfo.image_width 1480 * image_width = cinfo.image_width
1481 * image_height = cinfo.image_height 1481 * image_height = cinfo.image_height
1482 * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size 1482 * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
1483 * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size 1483 * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
1484 * Result: 1484 * Result:
1485 * TRUE = perfect transformation possible 1485 * TRUE = perfect transformation possible
1486 * FALSE = perfect transformation not possible 1486 * FALSE = perfect transformation not possible
1487 * (may use custom action then) 1487 * (may use custom action then)
1488 */ 1488 */
1489 1489
1490GLOBAL(boolean) 1490GLOBAL(boolean)
1491jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height, 1491jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
1492 int MCU_width, int MCU_height, 1492 int MCU_width, int MCU_height,
1493 JXFORM_CODE transform) 1493 JXFORM_CODE transform)
1494{ 1494{
1495 boolean result = TRUE; /* initialize TRUE */ 1495 boolean result = TRUE; /* initialize TRUE */
1496 1496
1497 switch (transform) { 1497 switch (transform) {
1498 case JXFORM_FLIP_H: 1498 case JXFORM_FLIP_H:
1499 case JXFORM_ROT_270: 1499 case JXFORM_ROT_270:
1500 if (image_width % (JDIMENSION) MCU_width) 1500 if (image_width % (JDIMENSION) MCU_width)
1501 result = FALSE; 1501 result = FALSE;
1502 break; 1502 break;
1503 case JXFORM_FLIP_V: 1503 case JXFORM_FLIP_V:
1504 case JXFORM_ROT_90: 1504 case JXFORM_ROT_90:
1505 if (image_height % (JDIMENSION) MCU_height) 1505 if (image_height % (JDIMENSION) MCU_height)
1506 result = FALSE; 1506 result = FALSE;
1507 break; 1507 break;
1508 case JXFORM_TRANSVERSE: 1508 case JXFORM_TRANSVERSE:
1509 case JXFORM_ROT_180: 1509 case JXFORM_ROT_180:
1510 if (image_width % (JDIMENSION) MCU_width) 1510 if (image_width % (JDIMENSION) MCU_width)
1511 result = FALSE; 1511 result = FALSE;
1512 if (image_height % (JDIMENSION) MCU_height) 1512 if (image_height % (JDIMENSION) MCU_height)
1513 result = FALSE; 1513 result = FALSE;
1514 break; 1514 break;
1515 default: 1515 default:
1516 break; 1516 break;
1517 } 1517 }
1518 1518
1519 return result; 1519 return result;
1520} 1520}
1521 1521
1522#endif /* TRANSFORMS_SUPPORTED */ 1522#endif /* TRANSFORMS_SUPPORTED */
1523 1523
1524 1524
1525/* Setup decompression object to save desired markers in memory. 1525/* Setup decompression object to save desired markers in memory.
1526 * This must be called before jpeg_read_header() to have the desired effect. 1526 * This must be called before jpeg_read_header() to have the desired effect.
1527 */ 1527 */
1528 1528
1529GLOBAL(void) 1529GLOBAL(void)
1530jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) 1530jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
1531{ 1531{
1532#ifdef SAVE_MARKERS_SUPPORTED 1532#ifdef SAVE_MARKERS_SUPPORTED
1533 int m; 1533 int m;
1534 1534
1535 /* Save comments except under NONE option */ 1535 /* Save comments except under NONE option */
1536 if (option != JCOPYOPT_NONE) { 1536 if (option != JCOPYOPT_NONE) {
1537 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); 1537 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
1538 } 1538 }
1539 /* Save all types of APPn markers iff ALL option */ 1539 /* Save all types of APPn markers iff ALL option */
1540 if (option == JCOPYOPT_ALL) { 1540 if (option == JCOPYOPT_ALL) {
1541 for (m = 0; m < 16; m++) 1541 for (m = 0; m < 16; m++)
1542 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); 1542 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
1543 } 1543 }
1544#endif /* SAVE_MARKERS_SUPPORTED */ 1544#endif /* SAVE_MARKERS_SUPPORTED */
1545} 1545}
1546 1546
1547/* Copy markers saved in the given source object to the destination object. 1547/* Copy markers saved in the given source object to the destination object.
1548 * This should be called just after jpeg_start_compress() or 1548 * This should be called just after jpeg_start_compress() or
1549 * jpeg_write_coefficients(). 1549 * jpeg_write_coefficients().
1550 * Note that those routines will have written the SOI, and also the 1550 * Note that those routines will have written the SOI, and also the
1551 * JFIF APP0 or Adobe APP14 markers if selected. 1551 * JFIF APP0 or Adobe APP14 markers if selected.
1552 */ 1552 */
1553 1553
1554GLOBAL(void) 1554GLOBAL(void)
1555jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 1555jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1556 JCOPY_OPTION option) 1556 JCOPY_OPTION option)
1557{ 1557{
1558 jpeg_saved_marker_ptr marker; 1558 jpeg_saved_marker_ptr marker;
1559 1559
1560 /* In the current implementation, we don't actually need to examine the 1560 /* In the current implementation, we don't actually need to examine the
1561 * option flag here; we just copy everything that got saved. 1561 * option flag here; we just copy everything that got saved.
1562 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers 1562 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1563 * if the encoder library already wrote one. 1563 * if the encoder library already wrote one.
1564 */ 1564 */
1565 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { 1565 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
1566 if (dstinfo->write_JFIF_header && 1566 if (dstinfo->write_JFIF_header &&
1567 marker->marker == JPEG_APP0 && 1567 marker->marker == JPEG_APP0 &&
1568 marker->data_length >= 5 && 1568 marker->data_length >= 5 &&
1569 GETJOCTET(marker->data[0]) == 0x4A && 1569 GETJOCTET(marker->data[0]) == 0x4A &&
1570 GETJOCTET(marker->data[1]) == 0x46 && 1570 GETJOCTET(marker->data[1]) == 0x46 &&
1571 GETJOCTET(marker->data[2]) == 0x49 && 1571 GETJOCTET(marker->data[2]) == 0x49 &&
1572 GETJOCTET(marker->data[3]) == 0x46 && 1572 GETJOCTET(marker->data[3]) == 0x46 &&
1573 GETJOCTET(marker->data[4]) == 0) 1573 GETJOCTET(marker->data[4]) == 0)
1574 continue; /* reject duplicate JFIF */ 1574 continue; /* reject duplicate JFIF */
1575 if (dstinfo->write_Adobe_marker && 1575 if (dstinfo->write_Adobe_marker &&
1576 marker->marker == JPEG_APP0+14 && 1576 marker->marker == JPEG_APP0+14 &&
1577 marker->data_length >= 5 && 1577 marker->data_length >= 5 &&
1578 GETJOCTET(marker->data[0]) == 0x41 && 1578 GETJOCTET(marker->data[0]) == 0x41 &&
1579 GETJOCTET(marker->data[1]) == 0x64 && 1579 GETJOCTET(marker->data[1]) == 0x64 &&
1580 GETJOCTET(marker->data[2]) == 0x6F && 1580 GETJOCTET(marker->data[2]) == 0x6F &&
1581 GETJOCTET(marker->data[3]) == 0x62 && 1581 GETJOCTET(marker->data[3]) == 0x62 &&
1582 GETJOCTET(marker->data[4]) == 0x65) 1582 GETJOCTET(marker->data[4]) == 0x65)
1583 continue; /* reject duplicate Adobe */ 1583 continue; /* reject duplicate Adobe */
1584#ifdef NEED_FAR_POINTERS 1584#ifdef NEED_FAR_POINTERS
1585 /* We could use jpeg_write_marker if the data weren't FAR... */ 1585 /* We could use jpeg_write_marker if the data weren't FAR... */
1586 { 1586 {
1587 unsigned int i; 1587 unsigned int i;
1588 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); 1588 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
1589 for (i = 0; i < marker->data_length; i++) 1589 for (i = 0; i < marker->data_length; i++)
1590 jpeg_write_m_byte(dstinfo, marker->data[i]); 1590 jpeg_write_m_byte(dstinfo, marker->data[i]);
1591 } 1591 }
1592#else 1592#else
1593 jpeg_write_marker(dstinfo, marker->marker, 1593 jpeg_write_marker(dstinfo, marker->marker,
1594 marker->data, marker->data_length); 1594 marker->data, marker->data_length);
1595#endif 1595#endif
1596 } 1596 }
1597} 1597}