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