4 * Copyright (C) 1997-2013, Thomas G. Lane, Guido Vollbeding.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
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
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
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().
18 #define JPEG_INTERNALS
22 #include "transupp.h" /* My own external interface */
23 #include <ctype.h> /* to declare isdigit() */
26 #if TRANSFORMS_SUPPORTED
29 * Lossless image transformation routines. These routines work on DCT
30 * coefficient arrays and thus do not require any lossy decompression
31 * or recompression of the image.
32 * Thanks to Guido Vollbeding for the initial design and code of this feature,
33 * and to Ben Jackson for introducing the cropping feature.
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
37 * fastest option for images larger than main memory.
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
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
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
45 * if the image is larger than main memory.
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
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
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.
54 * Some notes about the operating environment of the individual transform
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
58 * source's memory manager.
59 * 2. The destination's component count should be used. It may be smaller
60 * than the source's when forcing to grayscale.
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,
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
65 * trimmed values but the source's will be untrimmed.
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
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
70 * passed to the transform routines are measured in iMCU blocks of the
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
74 * source buffer it is an undocumented property of jdcoefct.c.
79 do_crop (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
80 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
81 jvirt_barray_ptr
*src_coef_arrays
,
82 jvirt_barray_ptr
*dst_coef_arrays
)
83 /* Crop. This is only used when no rotate/flip is requested with the crop. */
85 JDIMENSION dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
87 JBLOCKARRAY src_buffer
, dst_buffer
;
88 jpeg_component_info
*compptr
;
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.
93 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
94 compptr
= dstinfo
->comp_info
+ ci
;
95 x_crop_blocks
= x_crop_offset
* compptr
->h_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
;
98 dst_blk_y
+= compptr
->v_samp_factor
) {
99 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
100 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
101 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
102 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
103 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
104 dst_blk_y
+ y_crop_blocks
,
105 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
106 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
107 jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
108 dst_buffer
[offset_y
],
109 compptr
->width_in_blocks
);
117 do_crop_ext (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
118 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
119 jvirt_barray_ptr
*src_coef_arrays
,
120 jvirt_barray_ptr
*dst_coef_arrays
)
121 /* Crop. This is only used when no rotate/flip is requested with the crop.
122 * Extension: If the destination size is larger than the source, we fill in
123 * the extra area with zero (neutral gray). Note we also have to zero partial
124 * iMCUs at the right and bottom edge of the source image area in this case.
127 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
;
128 JDIMENSION dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
130 JBLOCKARRAY src_buffer
, dst_buffer
;
131 jpeg_component_info
*compptr
;
133 MCU_cols
= srcinfo
->output_width
/
134 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
135 MCU_rows
= srcinfo
->output_height
/
136 (dstinfo
->max_v_samp_factor
* dstinfo
->min_DCT_v_scaled_size
);
138 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
139 compptr
= dstinfo
->comp_info
+ ci
;
140 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
141 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
142 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
143 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
144 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
145 dst_blk_y
+= compptr
->v_samp_factor
) {
146 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
147 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
148 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
149 if (dstinfo
->jpeg_height
> srcinfo
->output_height
) {
150 if (dst_blk_y
< y_crop_blocks
||
151 dst_blk_y
>= comp_height
+ y_crop_blocks
) {
152 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
153 FMEMZERO(dst_buffer
[offset_y
],
154 compptr
->width_in_blocks
* SIZEOF(JBLOCK
));
158 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
159 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
160 dst_blk_y
- y_crop_blocks
,
161 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
163 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
164 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
165 dst_blk_y
+ y_crop_blocks
,
166 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
168 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
169 if (dstinfo
->jpeg_width
> srcinfo
->output_width
) {
170 if (x_crop_blocks
> 0) {
171 FMEMZERO(dst_buffer
[offset_y
],
172 x_crop_blocks
* SIZEOF(JBLOCK
));
174 jcopy_block_row(src_buffer
[offset_y
],
175 dst_buffer
[offset_y
] + x_crop_blocks
,
177 if (compptr
->width_in_blocks
> comp_width
+ x_crop_blocks
) {
178 FMEMZERO(dst_buffer
[offset_y
] +
179 comp_width
+ x_crop_blocks
,
180 (compptr
->width_in_blocks
-
181 comp_width
- x_crop_blocks
) * SIZEOF(JBLOCK
));
184 jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
185 dst_buffer
[offset_y
],
186 compptr
->width_in_blocks
);
195 do_wipe (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
196 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
197 jvirt_barray_ptr
*src_coef_arrays
,
198 JDIMENSION drop_width
, JDIMENSION drop_height
)
199 /* Wipe - drop content of specified area, fill with zero (neutral gray) */
201 JDIMENSION comp_width
, comp_height
;
202 JDIMENSION blk_y
, x_wipe_blocks
, y_wipe_blocks
;
205 jpeg_component_info
*compptr
;
207 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
208 compptr
= dstinfo
->comp_info
+ ci
;
209 comp_width
= drop_width
* compptr
->h_samp_factor
;
210 comp_height
= drop_height
* compptr
->v_samp_factor
;
211 x_wipe_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
212 y_wipe_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
213 for (blk_y
= 0; blk_y
< comp_height
; blk_y
+= compptr
->v_samp_factor
) {
214 buffer
= (*srcinfo
->mem
->access_virt_barray
)
215 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], blk_y
+ y_wipe_blocks
,
216 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
217 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
218 FMEMZERO(buffer
[offset_y
] + x_wipe_blocks
,
219 comp_width
* SIZEOF(JBLOCK
));
227 do_flip_h_no_crop (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
228 JDIMENSION x_crop_offset
,
229 jvirt_barray_ptr
*src_coef_arrays
)
230 /* Horizontal flip; done in-place, so no separate dest array is required.
231 * NB: this only works when y_crop_offset is zero.
234 JDIMENSION MCU_cols
, comp_width
, blk_x
, blk_y
, x_crop_blocks
;
239 jpeg_component_info
*compptr
;
241 /* Horizontal mirroring of DCT blocks is accomplished by swapping
242 * pairs of blocks in-place. Within a DCT block, we perform horizontal
243 * mirroring by changing the signs of odd-numbered columns.
244 * Partial iMCUs at the right edge are left untouched.
246 MCU_cols
= srcinfo
->output_width
/
247 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
249 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
250 compptr
= dstinfo
->comp_info
+ ci
;
251 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
252 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
253 for (blk_y
= 0; blk_y
< compptr
->height_in_blocks
;
254 blk_y
+= compptr
->v_samp_factor
) {
255 buffer
= (*srcinfo
->mem
->access_virt_barray
)
256 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], blk_y
,
257 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
258 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
259 /* Do the mirroring */
260 for (blk_x
= 0; blk_x
* 2 < comp_width
; blk_x
++) {
261 ptr1
= buffer
[offset_y
][blk_x
];
262 ptr2
= buffer
[offset_y
][comp_width
- blk_x
- 1];
263 /* this unrolled loop doesn't need to know which row it's on... */
264 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
265 temp1
= *ptr1
; /* swap even column */
269 temp1
= *ptr1
; /* swap odd column with sign change */
275 if (x_crop_blocks
> 0) {
276 /* Now left-justify the portion of the data to be kept.
277 * We can't use a single jcopy_block_row() call because that routine
278 * depends on memcpy(), whose behavior is unspecified for overlapping
279 * source and destination areas. Sigh.
281 for (blk_x
= 0; blk_x
< compptr
->width_in_blocks
; blk_x
++) {
282 jcopy_block_row(buffer
[offset_y
] + blk_x
+ x_crop_blocks
,
283 buffer
[offset_y
] + blk_x
,
294 do_flip_h (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
295 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
296 jvirt_barray_ptr
*src_coef_arrays
,
297 jvirt_barray_ptr
*dst_coef_arrays
)
298 /* Horizontal flip in general cropping case */
300 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
301 JDIMENSION x_crop_blocks
, y_crop_blocks
;
303 JBLOCKARRAY src_buffer
, dst_buffer
;
304 JBLOCKROW src_row_ptr
, dst_row_ptr
;
305 JCOEFPTR src_ptr
, dst_ptr
;
306 jpeg_component_info
*compptr
;
308 /* Here we must output into a separate array because we can't touch
309 * different rows of a single virtual array simultaneously. Otherwise,
310 * this is essentially the same as the routine above.
312 MCU_cols
= srcinfo
->output_width
/
313 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
315 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
316 compptr
= dstinfo
->comp_info
+ ci
;
317 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
318 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
319 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
320 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
321 dst_blk_y
+= compptr
->v_samp_factor
) {
322 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
323 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
324 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
325 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
326 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
327 dst_blk_y
+ y_crop_blocks
,
328 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
329 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
330 dst_row_ptr
= dst_buffer
[offset_y
];
331 src_row_ptr
= src_buffer
[offset_y
];
332 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
333 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
334 /* Do the mirrorable blocks */
335 dst_ptr
= dst_row_ptr
[dst_blk_x
];
336 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
337 /* this unrolled loop doesn't need to know which row it's on... */
338 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
339 *dst_ptr
++ = *src_ptr
++; /* copy even column */
340 *dst_ptr
++ = - *src_ptr
++; /* copy odd column with sign change */
343 /* Copy last partial block(s) verbatim */
344 jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
345 dst_row_ptr
+ dst_blk_x
,
356 do_flip_v (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
357 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
358 jvirt_barray_ptr
*src_coef_arrays
,
359 jvirt_barray_ptr
*dst_coef_arrays
)
362 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
363 JDIMENSION x_crop_blocks
, y_crop_blocks
;
364 int ci
, i
, j
, offset_y
;
365 JBLOCKARRAY src_buffer
, dst_buffer
;
366 JBLOCKROW src_row_ptr
, dst_row_ptr
;
367 JCOEFPTR src_ptr
, dst_ptr
;
368 jpeg_component_info
*compptr
;
370 /* We output into a separate array because we can't touch different
371 * rows of the source virtual array simultaneously. Otherwise, this
372 * is a pretty straightforward analog of horizontal flip.
373 * Within a DCT block, vertical mirroring is done by changing the signs
374 * of odd-numbered rows.
375 * Partial iMCUs at the bottom edge are copied verbatim.
377 MCU_rows
= srcinfo
->output_height
/
378 (dstinfo
->max_v_samp_factor
* dstinfo
->min_DCT_v_scaled_size
);
380 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
381 compptr
= dstinfo
->comp_info
+ ci
;
382 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
383 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
384 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
385 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
386 dst_blk_y
+= compptr
->v_samp_factor
) {
387 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
388 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
389 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
390 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
391 /* Row is within the mirrorable area. */
392 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
393 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
394 comp_height
- y_crop_blocks
- dst_blk_y
-
395 (JDIMENSION
) compptr
->v_samp_factor
,
396 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
398 /* Bottom-edge blocks will be copied verbatim. */
399 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
400 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
401 dst_blk_y
+ y_crop_blocks
,
402 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
404 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
405 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
406 /* Row is within the mirrorable area. */
407 dst_row_ptr
= dst_buffer
[offset_y
];
408 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
409 src_row_ptr
+= x_crop_blocks
;
410 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
412 dst_ptr
= dst_row_ptr
[dst_blk_x
];
413 src_ptr
= src_row_ptr
[dst_blk_x
];
414 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
416 for (j
= 0; j
< DCTSIZE
; j
++)
417 *dst_ptr
++ = *src_ptr
++;
418 /* copy odd row with sign change */
419 for (j
= 0; j
< DCTSIZE
; j
++)
420 *dst_ptr
++ = - *src_ptr
++;
424 /* Just copy row verbatim. */
425 jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
426 dst_buffer
[offset_y
],
427 compptr
->width_in_blocks
);
436 do_transpose (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
437 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
438 jvirt_barray_ptr
*src_coef_arrays
,
439 jvirt_barray_ptr
*dst_coef_arrays
)
440 /* Transpose source into destination */
442 JDIMENSION dst_blk_x
, dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
443 int ci
, i
, j
, offset_x
, offset_y
;
444 JBLOCKARRAY src_buffer
, dst_buffer
;
445 JCOEFPTR src_ptr
, dst_ptr
;
446 jpeg_component_info
*compptr
;
448 /* Transposing pixels within a block just requires transposing the
450 * Partial iMCUs at the edges require no special treatment; we simply
451 * process all the available DCT blocks for every component.
453 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
454 compptr
= dstinfo
->comp_info
+ ci
;
455 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
456 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
457 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
458 dst_blk_y
+= compptr
->v_samp_factor
) {
459 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
460 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
461 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
462 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
463 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
464 dst_blk_x
+= compptr
->h_samp_factor
) {
465 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
466 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
467 dst_blk_x
+ x_crop_blocks
,
468 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
469 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
470 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
471 src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
+ y_crop_blocks
];
472 for (i
= 0; i
< DCTSIZE
; i
++)
473 for (j
= 0; j
< DCTSIZE
; j
++)
474 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
484 do_rot_90 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
485 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
486 jvirt_barray_ptr
*src_coef_arrays
,
487 jvirt_barray_ptr
*dst_coef_arrays
)
488 /* 90 degree rotation is equivalent to
489 * 1. Transposing the image;
490 * 2. Horizontal mirroring.
491 * These two steps are merged into a single processing routine.
494 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
495 JDIMENSION x_crop_blocks
, y_crop_blocks
;
496 int ci
, i
, j
, offset_x
, offset_y
;
497 JBLOCKARRAY src_buffer
, dst_buffer
;
498 JCOEFPTR src_ptr
, dst_ptr
;
499 jpeg_component_info
*compptr
;
501 /* Because of the horizontal mirror step, we can't process partial iMCUs
502 * at the (output) right edge properly. They just get transposed and
505 MCU_cols
= srcinfo
->output_height
/
506 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
508 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
509 compptr
= dstinfo
->comp_info
+ ci
;
510 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
511 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
512 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
513 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
514 dst_blk_y
+= compptr
->v_samp_factor
) {
515 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
516 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
517 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
518 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
519 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
520 dst_blk_x
+= compptr
->h_samp_factor
) {
521 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
522 /* Block is within the mirrorable area. */
523 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
524 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
525 comp_width
- x_crop_blocks
- dst_blk_x
-
526 (JDIMENSION
) compptr
->h_samp_factor
,
527 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
529 /* Edge blocks are transposed but not mirrored. */
530 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
531 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
532 dst_blk_x
+ x_crop_blocks
,
533 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
535 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
536 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
537 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
538 /* Block is within the mirrorable area. */
539 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
540 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
541 for (i
= 0; i
< DCTSIZE
; i
++) {
542 for (j
= 0; j
< DCTSIZE
; j
++)
543 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
545 for (j
= 0; j
< DCTSIZE
; j
++)
546 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
549 /* Edge blocks are transposed but not mirrored. */
550 src_ptr
= src_buffer
[offset_x
]
551 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
552 for (i
= 0; i
< DCTSIZE
; i
++)
553 for (j
= 0; j
< DCTSIZE
; j
++)
554 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
565 do_rot_270 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
566 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
567 jvirt_barray_ptr
*src_coef_arrays
,
568 jvirt_barray_ptr
*dst_coef_arrays
)
569 /* 270 degree rotation is equivalent to
570 * 1. Horizontal mirroring;
571 * 2. Transposing the image.
572 * These two steps are merged into a single processing routine.
575 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
576 JDIMENSION x_crop_blocks
, y_crop_blocks
;
577 int ci
, i
, j
, offset_x
, offset_y
;
578 JBLOCKARRAY src_buffer
, dst_buffer
;
579 JCOEFPTR src_ptr
, dst_ptr
;
580 jpeg_component_info
*compptr
;
582 /* Because of the horizontal mirror step, we can't process partial iMCUs
583 * at the (output) bottom edge properly. They just get transposed and
586 MCU_rows
= srcinfo
->output_width
/
587 (dstinfo
->max_v_samp_factor
* dstinfo
->min_DCT_v_scaled_size
);
589 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
590 compptr
= dstinfo
->comp_info
+ ci
;
591 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
592 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
593 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
594 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
595 dst_blk_y
+= compptr
->v_samp_factor
) {
596 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
597 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
598 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
599 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
600 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
601 dst_blk_x
+= compptr
->h_samp_factor
) {
602 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
603 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
604 dst_blk_x
+ x_crop_blocks
,
605 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
606 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
607 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
608 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
609 /* Block is within the mirrorable area. */
610 src_ptr
= src_buffer
[offset_x
]
611 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
612 for (i
= 0; i
< DCTSIZE
; i
++) {
613 for (j
= 0; j
< DCTSIZE
; j
++) {
614 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
616 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
620 /* Edge blocks are transposed but not mirrored. */
621 src_ptr
= src_buffer
[offset_x
]
622 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
623 for (i
= 0; i
< DCTSIZE
; i
++)
624 for (j
= 0; j
< DCTSIZE
; j
++)
625 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
636 do_rot_180 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
637 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
638 jvirt_barray_ptr
*src_coef_arrays
,
639 jvirt_barray_ptr
*dst_coef_arrays
)
640 /* 180 degree rotation is equivalent to
641 * 1. Vertical mirroring;
642 * 2. Horizontal mirroring.
643 * These two steps are merged into a single processing routine.
646 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
647 JDIMENSION x_crop_blocks
, y_crop_blocks
;
648 int ci
, i
, j
, offset_y
;
649 JBLOCKARRAY src_buffer
, dst_buffer
;
650 JBLOCKROW src_row_ptr
, dst_row_ptr
;
651 JCOEFPTR src_ptr
, dst_ptr
;
652 jpeg_component_info
*compptr
;
654 MCU_cols
= srcinfo
->output_width
/
655 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
656 MCU_rows
= srcinfo
->output_height
/
657 (dstinfo
->max_v_samp_factor
* dstinfo
->min_DCT_v_scaled_size
);
659 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
660 compptr
= dstinfo
->comp_info
+ ci
;
661 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
662 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
663 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
664 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
665 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
666 dst_blk_y
+= compptr
->v_samp_factor
) {
667 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
668 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
669 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
670 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
671 /* Row is within the vertically mirrorable area. */
672 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
673 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
674 comp_height
- y_crop_blocks
- dst_blk_y
-
675 (JDIMENSION
) compptr
->v_samp_factor
,
676 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
678 /* Bottom-edge rows are only mirrored horizontally. */
679 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
680 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
681 dst_blk_y
+ y_crop_blocks
,
682 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
684 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
685 dst_row_ptr
= dst_buffer
[offset_y
];
686 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
687 /* Row is within the mirrorable area. */
688 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
689 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
690 dst_ptr
= dst_row_ptr
[dst_blk_x
];
691 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
692 /* Process the blocks that can be mirrored both ways. */
693 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
694 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
695 /* For even row, negate every odd column. */
696 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
697 *dst_ptr
++ = *src_ptr
++;
698 *dst_ptr
++ = - *src_ptr
++;
700 /* For odd row, negate every even column. */
701 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
702 *dst_ptr
++ = - *src_ptr
++;
703 *dst_ptr
++ = *src_ptr
++;
707 /* Any remaining right-edge blocks are only mirrored vertically. */
708 src_ptr
= src_row_ptr
[x_crop_blocks
+ dst_blk_x
];
709 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
710 for (j
= 0; j
< DCTSIZE
; j
++)
711 *dst_ptr
++ = *src_ptr
++;
712 for (j
= 0; j
< DCTSIZE
; j
++)
713 *dst_ptr
++ = - *src_ptr
++;
718 /* Remaining rows are just mirrored horizontally. */
719 src_row_ptr
= src_buffer
[offset_y
];
720 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
721 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
722 /* Process the blocks that can be mirrored. */
723 dst_ptr
= dst_row_ptr
[dst_blk_x
];
724 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
725 for (i
= 0; i
< DCTSIZE2
; i
+= 2) {
726 *dst_ptr
++ = *src_ptr
++;
727 *dst_ptr
++ = - *src_ptr
++;
730 /* Any remaining right-edge blocks are only copied. */
731 jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
732 dst_row_ptr
+ dst_blk_x
,
744 do_transverse (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
745 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
746 jvirt_barray_ptr
*src_coef_arrays
,
747 jvirt_barray_ptr
*dst_coef_arrays
)
748 /* Transverse transpose is equivalent to
749 * 1. 180 degree rotation;
752 * 1. Horizontal mirroring;
754 * 3. Horizontal mirroring.
755 * These steps are merged into a single processing routine.
758 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
759 JDIMENSION x_crop_blocks
, y_crop_blocks
;
760 int ci
, i
, j
, offset_x
, offset_y
;
761 JBLOCKARRAY src_buffer
, dst_buffer
;
762 JCOEFPTR src_ptr
, dst_ptr
;
763 jpeg_component_info
*compptr
;
765 MCU_cols
= srcinfo
->output_height
/
766 (dstinfo
->max_h_samp_factor
* dstinfo
->min_DCT_h_scaled_size
);
767 MCU_rows
= srcinfo
->output_width
/
768 (dstinfo
->max_v_samp_factor
* dstinfo
->min_DCT_v_scaled_size
);
770 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
771 compptr
= dstinfo
->comp_info
+ ci
;
772 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
773 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
774 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
775 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
776 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
777 dst_blk_y
+= compptr
->v_samp_factor
) {
778 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
779 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
780 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
781 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
782 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
783 dst_blk_x
+= compptr
->h_samp_factor
) {
784 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
785 /* Block is within the mirrorable area. */
786 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
787 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
788 comp_width
- x_crop_blocks
- dst_blk_x
-
789 (JDIMENSION
) compptr
->h_samp_factor
,
790 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
792 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
793 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
794 dst_blk_x
+ x_crop_blocks
,
795 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
797 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
798 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
799 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
800 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
801 /* Block is within the mirrorable area. */
802 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
803 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
804 for (i
= 0; i
< DCTSIZE
; i
++) {
805 for (j
= 0; j
< DCTSIZE
; j
++) {
806 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
808 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
811 for (j
= 0; j
< DCTSIZE
; j
++) {
812 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
814 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
818 /* Right-edge blocks are mirrored in y only */
819 src_ptr
= src_buffer
[offset_x
]
820 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
821 for (i
= 0; i
< DCTSIZE
; i
++) {
822 for (j
= 0; j
< DCTSIZE
; j
++) {
823 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
825 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
830 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
831 /* Bottom-edge blocks are mirrored in x only */
832 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
833 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
834 for (i
= 0; i
< DCTSIZE
; i
++) {
835 for (j
= 0; j
< DCTSIZE
; j
++)
836 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
838 for (j
= 0; j
< DCTSIZE
; j
++)
839 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
842 /* At lower right corner, just transpose, no mirroring */
843 src_ptr
= src_buffer
[offset_x
]
844 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
845 for (i
= 0; i
< DCTSIZE
; i
++)
846 for (j
= 0; j
< DCTSIZE
; j
++)
847 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
858 /* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
859 * Returns TRUE if valid integer found, FALSE if not.
860 * *strptr is advanced over the digit string, and *result is set to its value.
864 jt_read_integer (const char ** strptr
, JDIMENSION
* result
)
866 const char * ptr
= *strptr
;
869 for (; isdigit(*ptr
); ptr
++) {
870 val
= val
* 10 + (JDIMENSION
) (*ptr
- '0');
874 return FALSE
; /* oops, no digits */
880 /* Parse a crop specification (written in X11 geometry style).
881 * The routine returns TRUE if the spec string is valid, FALSE if not.
883 * The crop spec string should have the format
884 * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
885 * where width, height, xoffset, and yoffset are unsigned integers.
886 * Each of the elements can be omitted to indicate a default value.
887 * (A weakness of this style is that it is not possible to omit xoffset
888 * while specifying yoffset, since they look alike.)
890 * This code is loosely based on XParseGeometry from the X11 distribution.
894 jtransform_parse_crop_spec (jpeg_transform_info
*info
, const char *spec
)
897 info
->crop_width_set
= JCROP_UNSET
;
898 info
->crop_height_set
= JCROP_UNSET
;
899 info
->crop_xoffset_set
= JCROP_UNSET
;
900 info
->crop_yoffset_set
= JCROP_UNSET
;
902 if (isdigit(*spec
)) {
904 if (! jt_read_integer(&spec
, &info
->crop_width
))
906 if (*spec
== 'f' || *spec
== 'F') {
908 info
->crop_width_set
= JCROP_FORCE
;
910 info
->crop_width_set
= JCROP_POS
;
912 if (*spec
== 'x' || *spec
== 'X') {
915 if (! jt_read_integer(&spec
, &info
->crop_height
))
917 if (*spec
== 'f' || *spec
== 'F') {
919 info
->crop_height_set
= JCROP_FORCE
;
921 info
->crop_height_set
= JCROP_POS
;
923 if (*spec
== '+' || *spec
== '-') {
925 info
->crop_xoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
927 if (! jt_read_integer(&spec
, &info
->crop_xoffset
))
930 if (*spec
== '+' || *spec
== '-') {
932 info
->crop_yoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
934 if (! jt_read_integer(&spec
, &info
->crop_yoffset
))
937 /* We had better have gotten to the end of the string. */
945 /* Trim off any partial iMCUs on the indicated destination edge */
948 trim_right_edge (jpeg_transform_info
*info
, JDIMENSION full_width
)
952 MCU_cols
= info
->output_width
/ info
->iMCU_sample_width
;
953 if (MCU_cols
> 0 && info
->x_crop_offset
+ MCU_cols
==
954 full_width
/ info
->iMCU_sample_width
)
955 info
->output_width
= MCU_cols
* info
->iMCU_sample_width
;
959 trim_bottom_edge (jpeg_transform_info
*info
, JDIMENSION full_height
)
963 MCU_rows
= info
->output_height
/ info
->iMCU_sample_height
;
964 if (MCU_rows
> 0 && info
->y_crop_offset
+ MCU_rows
==
965 full_height
/ info
->iMCU_sample_height
)
966 info
->output_height
= MCU_rows
* info
->iMCU_sample_height
;
970 /* Request any required workspace.
972 * This routine figures out the size that the output image will be
973 * (which implies that all the transform parameters must be set before
976 * We allocate the workspace virtual arrays from the source decompression
977 * object, so that all the arrays (both the original data and the workspace)
978 * will be taken into account while making memory management decisions.
979 * Hence, this routine must be called after jpeg_read_header (which reads
980 * the image dimensions) and before jpeg_read_coefficients (which realizes
981 * the source's virtual arrays).
983 * This function returns FALSE right away if -perfect is given
984 * and transformation is not perfect. Otherwise returns TRUE.
988 jtransform_request_workspace (j_decompress_ptr srcinfo
,
989 jpeg_transform_info
*info
)
991 jvirt_barray_ptr
*coef_arrays
;
992 boolean need_workspace
, transpose_it
;
993 jpeg_component_info
*compptr
;
994 JDIMENSION xoffset
, yoffset
;
995 JDIMENSION width_in_iMCUs
, height_in_iMCUs
;
996 JDIMENSION width_in_blocks
, height_in_blocks
;
997 int ci
, h_samp_factor
, v_samp_factor
;
999 /* Determine number of components in output image */
1000 if (info
->force_grayscale
&&
1001 (srcinfo
->jpeg_color_space
== JCS_YCbCr
||
1002 srcinfo
->jpeg_color_space
== JCS_BG_YCC
) &&
1003 srcinfo
->num_components
== 3)
1004 /* We'll only process the first component */
1005 info
->num_components
= 1;
1007 /* Process all the components */
1008 info
->num_components
= srcinfo
->num_components
;
1010 /* Compute output image dimensions and related values. */
1011 jpeg_core_output_dimensions(srcinfo
);
1013 /* Return right away if -perfect is given and transformation is not perfect.
1015 if (info
->perfect
) {
1016 if (info
->num_components
== 1) {
1017 if (!jtransform_perfect_transform(srcinfo
->output_width
,
1018 srcinfo
->output_height
,
1019 srcinfo
->min_DCT_h_scaled_size
,
1020 srcinfo
->min_DCT_v_scaled_size
,
1024 if (!jtransform_perfect_transform(srcinfo
->output_width
,
1025 srcinfo
->output_height
,
1026 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size
,
1027 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size
,
1033 /* If there is only one output component, force the iMCU size to be 1;
1034 * else use the source iMCU size. (This allows us to do the right thing
1035 * when reducing color to grayscale, and also provides a handy way of
1036 * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
1038 switch (info
->transform
) {
1039 case JXFORM_TRANSPOSE
:
1040 case JXFORM_TRANSVERSE
:
1042 case JXFORM_ROT_270
:
1043 info
->output_width
= srcinfo
->output_height
;
1044 info
->output_height
= srcinfo
->output_width
;
1045 if (info
->num_components
== 1) {
1046 info
->iMCU_sample_width
= srcinfo
->min_DCT_v_scaled_size
;
1047 info
->iMCU_sample_height
= srcinfo
->min_DCT_h_scaled_size
;
1049 info
->iMCU_sample_width
=
1050 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size
;
1051 info
->iMCU_sample_height
=
1052 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size
;
1056 info
->output_width
= srcinfo
->output_width
;
1057 info
->output_height
= srcinfo
->output_height
;
1058 if (info
->num_components
== 1) {
1059 info
->iMCU_sample_width
= srcinfo
->min_DCT_h_scaled_size
;
1060 info
->iMCU_sample_height
= srcinfo
->min_DCT_v_scaled_size
;
1062 info
->iMCU_sample_width
=
1063 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size
;
1064 info
->iMCU_sample_height
=
1065 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size
;
1070 /* If cropping has been requested, compute the crop area's position and
1071 * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
1074 /* Insert default values for unset crop parameters */
1075 if (info
->crop_xoffset_set
== JCROP_UNSET
)
1076 info
->crop_xoffset
= 0; /* default to +0 */
1077 if (info
->crop_yoffset_set
== JCROP_UNSET
)
1078 info
->crop_yoffset
= 0; /* default to +0 */
1079 if (info
->crop_width_set
== JCROP_UNSET
) {
1080 if (info
->crop_xoffset
>= info
->output_width
)
1081 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1082 info
->crop_width
= info
->output_width
- info
->crop_xoffset
;
1084 /* Check for crop extension */
1085 if (info
->crop_width
> info
->output_width
) {
1086 /* Crop extension does not work when transforming! */
1087 if (info
->transform
!= JXFORM_NONE
||
1088 info
->crop_xoffset
>= info
->crop_width
||
1089 info
->crop_xoffset
> info
->crop_width
- info
->output_width
)
1090 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1092 if (info
->crop_xoffset
>= info
->output_width
||
1093 info
->crop_width
<= 0 ||
1094 info
->crop_xoffset
> info
->output_width
- info
->crop_width
)
1095 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1098 if (info
->crop_height_set
== JCROP_UNSET
) {
1099 if (info
->crop_yoffset
>= info
->output_height
)
1100 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1101 info
->crop_height
= info
->output_height
- info
->crop_yoffset
;
1103 /* Check for crop extension */
1104 if (info
->crop_height
> info
->output_height
) {
1105 /* Crop extension does not work when transforming! */
1106 if (info
->transform
!= JXFORM_NONE
||
1107 info
->crop_yoffset
>= info
->crop_height
||
1108 info
->crop_yoffset
> info
->crop_height
- info
->output_height
)
1109 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1111 if (info
->crop_yoffset
>= info
->output_height
||
1112 info
->crop_height
<= 0 ||
1113 info
->crop_yoffset
> info
->output_height
- info
->crop_height
)
1114 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
1117 /* Convert negative crop offsets into regular offsets */
1118 if (info
->crop_xoffset_set
!= JCROP_NEG
)
1119 xoffset
= info
->crop_xoffset
;
1120 else if (info
->crop_width
> info
->output_width
) /* crop extension */
1121 xoffset
= info
->crop_width
- info
->output_width
- info
->crop_xoffset
;
1123 xoffset
= info
->output_width
- info
->crop_width
- info
->crop_xoffset
;
1124 if (info
->crop_yoffset_set
!= JCROP_NEG
)
1125 yoffset
= info
->crop_yoffset
;
1126 else if (info
->crop_height
> info
->output_height
) /* crop extension */
1127 yoffset
= info
->crop_height
- info
->output_height
- info
->crop_yoffset
;
1129 yoffset
= info
->output_height
- info
->crop_height
- info
->crop_yoffset
;
1130 /* Now adjust so that upper left corner falls at an iMCU boundary */
1131 if (info
->transform
== JXFORM_WIPE
) {
1132 /* Ensure the effective wipe region will cover the requested */
1133 info
->drop_width
= (JDIMENSION
) jdiv_round_up
1134 ((long) (info
->crop_width
+ (xoffset
% info
->iMCU_sample_width
)),
1135 (long) info
->iMCU_sample_width
);
1136 info
->drop_height
= (JDIMENSION
) jdiv_round_up
1137 ((long) (info
->crop_height
+ (yoffset
% info
->iMCU_sample_height
)),
1138 (long) info
->iMCU_sample_height
);
1140 /* Ensure the effective crop region will cover the requested */
1141 if (info
->crop_width_set
== JCROP_FORCE
||
1142 info
->crop_width
> info
->output_width
)
1143 info
->output_width
= info
->crop_width
;
1145 info
->output_width
=
1146 info
->crop_width
+ (xoffset
% info
->iMCU_sample_width
);
1147 if (info
->crop_height_set
== JCROP_FORCE
||
1148 info
->crop_height
> info
->output_height
)
1149 info
->output_height
= info
->crop_height
;
1151 info
->output_height
=
1152 info
->crop_height
+ (yoffset
% info
->iMCU_sample_height
);
1154 /* Save x/y offsets measured in iMCUs */
1155 info
->x_crop_offset
= xoffset
/ info
->iMCU_sample_width
;
1156 info
->y_crop_offset
= yoffset
/ info
->iMCU_sample_height
;
1158 info
->x_crop_offset
= 0;
1159 info
->y_crop_offset
= 0;
1162 /* Figure out whether we need workspace arrays,
1163 * and if so whether they are transposed relative to the source.
1165 need_workspace
= FALSE
;
1166 transpose_it
= FALSE
;
1167 switch (info
->transform
) {
1169 if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0 ||
1170 info
->output_width
> srcinfo
->output_width
||
1171 info
->output_height
> srcinfo
->output_height
)
1172 need_workspace
= TRUE
;
1173 /* No workspace needed if neither cropping nor transforming */
1177 trim_right_edge(info
, srcinfo
->output_width
);
1178 if (info
->y_crop_offset
!= 0)
1179 need_workspace
= TRUE
;
1180 /* do_flip_h_no_crop doesn't need a workspace array */
1184 trim_bottom_edge(info
, srcinfo
->output_height
);
1185 /* Need workspace arrays having same dimensions as source image. */
1186 need_workspace
= TRUE
;
1188 case JXFORM_TRANSPOSE
:
1189 /* transpose does NOT have to trim anything */
1190 /* Need workspace arrays having transposed dimensions. */
1191 need_workspace
= TRUE
;
1192 transpose_it
= TRUE
;
1194 case JXFORM_TRANSVERSE
:
1196 trim_right_edge(info
, srcinfo
->output_height
);
1197 trim_bottom_edge(info
, srcinfo
->output_width
);
1199 /* Need workspace arrays having transposed dimensions. */
1200 need_workspace
= TRUE
;
1201 transpose_it
= TRUE
;
1205 trim_right_edge(info
, srcinfo
->output_height
);
1206 /* Need workspace arrays having transposed dimensions. */
1207 need_workspace
= TRUE
;
1208 transpose_it
= TRUE
;
1210 case JXFORM_ROT_180
:
1212 trim_right_edge(info
, srcinfo
->output_width
);
1213 trim_bottom_edge(info
, srcinfo
->output_height
);
1215 /* Need workspace arrays having same dimensions as source image. */
1216 need_workspace
= TRUE
;
1218 case JXFORM_ROT_270
:
1220 trim_bottom_edge(info
, srcinfo
->output_width
);
1221 /* Need workspace arrays having transposed dimensions. */
1222 need_workspace
= TRUE
;
1223 transpose_it
= TRUE
;
1229 /* Allocate workspace if needed.
1230 * Note that we allocate arrays padded out to the next iMCU boundary,
1231 * so that transform routines need not worry about missing edge blocks.
1233 if (need_workspace
) {
1234 coef_arrays
= (jvirt_barray_ptr
*)
1235 (*srcinfo
->mem
->alloc_small
) ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
,
1236 SIZEOF(jvirt_barray_ptr
) * info
->num_components
);
1237 width_in_iMCUs
= (JDIMENSION
)
1238 jdiv_round_up((long) info
->output_width
,
1239 (long) info
->iMCU_sample_width
);
1240 height_in_iMCUs
= (JDIMENSION
)
1241 jdiv_round_up((long) info
->output_height
,
1242 (long) info
->iMCU_sample_height
);
1243 for (ci
= 0; ci
< info
->num_components
; ci
++) {
1244 compptr
= srcinfo
->comp_info
+ ci
;
1245 if (info
->num_components
== 1) {
1246 /* we're going to force samp factors to 1x1 in this case */
1247 h_samp_factor
= v_samp_factor
= 1;
1248 } else if (transpose_it
) {
1249 h_samp_factor
= compptr
->v_samp_factor
;
1250 v_samp_factor
= compptr
->h_samp_factor
;
1252 h_samp_factor
= compptr
->h_samp_factor
;
1253 v_samp_factor
= compptr
->v_samp_factor
;
1255 width_in_blocks
= width_in_iMCUs
* h_samp_factor
;
1256 height_in_blocks
= height_in_iMCUs
* v_samp_factor
;
1257 coef_arrays
[ci
] = (*srcinfo
->mem
->request_virt_barray
)
1258 ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
, FALSE
,
1259 width_in_blocks
, height_in_blocks
, (JDIMENSION
) v_samp_factor
);
1261 info
->workspace_coef_arrays
= coef_arrays
;
1263 info
->workspace_coef_arrays
= NULL
;
1269 /* Transpose destination image parameters */
1272 transpose_critical_parameters (j_compress_ptr dstinfo
)
1274 int tblno
, i
, j
, ci
, itemp
;
1275 jpeg_component_info
*compptr
;
1276 JQUANT_TBL
*qtblptr
;
1280 /* Transpose image dimensions */
1281 jtemp
= dstinfo
->image_width
;
1282 dstinfo
->image_width
= dstinfo
->image_height
;
1283 dstinfo
->image_height
= jtemp
;
1284 itemp
= dstinfo
->min_DCT_h_scaled_size
;
1285 dstinfo
->min_DCT_h_scaled_size
= dstinfo
->min_DCT_v_scaled_size
;
1286 dstinfo
->min_DCT_v_scaled_size
= itemp
;
1288 /* Transpose sampling factors */
1289 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
1290 compptr
= dstinfo
->comp_info
+ ci
;
1291 itemp
= compptr
->h_samp_factor
;
1292 compptr
->h_samp_factor
= compptr
->v_samp_factor
;
1293 compptr
->v_samp_factor
= itemp
;
1296 /* Transpose quantization tables */
1297 for (tblno
= 0; tblno
< NUM_QUANT_TBLS
; tblno
++) {
1298 qtblptr
= dstinfo
->quant_tbl_ptrs
[tblno
];
1299 if (qtblptr
!= NULL
) {
1300 for (i
= 0; i
< DCTSIZE
; i
++) {
1301 for (j
= 0; j
< i
; j
++) {
1302 qtemp
= qtblptr
->quantval
[i
*DCTSIZE
+j
];
1303 qtblptr
->quantval
[i
*DCTSIZE
+j
] = qtblptr
->quantval
[j
*DCTSIZE
+i
];
1304 qtblptr
->quantval
[j
*DCTSIZE
+i
] = qtemp
;
1312 /* Adjust Exif image parameters.
1314 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1318 adjust_exif_parameters (JOCTET FAR
* data
, unsigned int length
,
1319 JDIMENSION new_width
, JDIMENSION new_height
)
1321 boolean is_motorola
; /* Flag for byte order */
1322 unsigned int number_of_tags
, tagnum
;
1323 unsigned int firstoffset
, offset
;
1324 JDIMENSION new_value
;
1326 if (length
< 12) return; /* Length of an IFD entry */
1328 /* Discover byte order */
1329 if (GETJOCTET(data
[0]) == 0x49 && GETJOCTET(data
[1]) == 0x49)
1330 is_motorola
= FALSE
;
1331 else if (GETJOCTET(data
[0]) == 0x4D && GETJOCTET(data
[1]) == 0x4D)
1336 /* Check Tag Mark */
1338 if (GETJOCTET(data
[2]) != 0) return;
1339 if (GETJOCTET(data
[3]) != 0x2A) return;
1341 if (GETJOCTET(data
[3]) != 0) return;
1342 if (GETJOCTET(data
[2]) != 0x2A) return;
1345 /* Get first IFD offset (offset to IFD0) */
1347 if (GETJOCTET(data
[4]) != 0) return;
1348 if (GETJOCTET(data
[5]) != 0) return;
1349 firstoffset
= GETJOCTET(data
[6]);
1351 firstoffset
+= GETJOCTET(data
[7]);
1353 if (GETJOCTET(data
[7]) != 0) return;
1354 if (GETJOCTET(data
[6]) != 0) return;
1355 firstoffset
= GETJOCTET(data
[5]);
1357 firstoffset
+= GETJOCTET(data
[4]);
1359 if (firstoffset
> length
- 2) return; /* check end of data segment */
1361 /* Get the number of directory entries contained in this IFD */
1363 number_of_tags
= GETJOCTET(data
[firstoffset
]);
1364 number_of_tags
<<= 8;
1365 number_of_tags
+= GETJOCTET(data
[firstoffset
+1]);
1367 number_of_tags
= GETJOCTET(data
[firstoffset
+1]);
1368 number_of_tags
<<= 8;
1369 number_of_tags
+= GETJOCTET(data
[firstoffset
]);
1371 if (number_of_tags
== 0) return;
1374 /* Search for ExifSubIFD offset Tag in IFD0 */
1376 if (firstoffset
> length
- 12) return; /* check end of data segment */
1377 /* Get Tag number */
1379 tagnum
= GETJOCTET(data
[firstoffset
]);
1381 tagnum
+= GETJOCTET(data
[firstoffset
+1]);
1383 tagnum
= GETJOCTET(data
[firstoffset
+1]);
1385 tagnum
+= GETJOCTET(data
[firstoffset
]);
1387 if (tagnum
== 0x8769) break; /* found ExifSubIFD offset Tag */
1388 if (--number_of_tags
== 0) return;
1392 /* Get the ExifSubIFD offset */
1394 if (GETJOCTET(data
[firstoffset
+8]) != 0) return;
1395 if (GETJOCTET(data
[firstoffset
+9]) != 0) return;
1396 offset
= GETJOCTET(data
[firstoffset
+10]);
1398 offset
+= GETJOCTET(data
[firstoffset
+11]);
1400 if (GETJOCTET(data
[firstoffset
+11]) != 0) return;
1401 if (GETJOCTET(data
[firstoffset
+10]) != 0) return;
1402 offset
= GETJOCTET(data
[firstoffset
+9]);
1404 offset
+= GETJOCTET(data
[firstoffset
+8]);
1406 if (offset
> length
- 2) return; /* check end of data segment */
1408 /* Get the number of directory entries contained in this SubIFD */
1410 number_of_tags
= GETJOCTET(data
[offset
]);
1411 number_of_tags
<<= 8;
1412 number_of_tags
+= GETJOCTET(data
[offset
+1]);
1414 number_of_tags
= GETJOCTET(data
[offset
+1]);
1415 number_of_tags
<<= 8;
1416 number_of_tags
+= GETJOCTET(data
[offset
]);
1418 if (number_of_tags
< 2) return;
1421 /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1423 if (offset
> length
- 12) return; /* check end of data segment */
1424 /* Get Tag number */
1426 tagnum
= GETJOCTET(data
[offset
]);
1428 tagnum
+= GETJOCTET(data
[offset
+1]);
1430 tagnum
= GETJOCTET(data
[offset
+1]);
1432 tagnum
+= GETJOCTET(data
[offset
]);
1434 if (tagnum
== 0xA002 || tagnum
== 0xA003) {
1435 if (tagnum
== 0xA002)
1436 new_value
= new_width
; /* ExifImageWidth Tag */
1438 new_value
= new_height
; /* ExifImageHeight Tag */
1440 data
[offset
+2] = 0; /* Format = unsigned long (4 octets) */
1442 data
[offset
+4] = 0; /* Number Of Components = 1 */
1448 data
[offset
+10] = (JOCTET
)((new_value
>> 8) & 0xFF);
1449 data
[offset
+11] = (JOCTET
)(new_value
& 0xFF);
1451 data
[offset
+2] = 4; /* Format = unsigned long (4 octets) */
1453 data
[offset
+4] = 1; /* Number Of Components = 1 */
1457 data
[offset
+8] = (JOCTET
)(new_value
& 0xFF);
1458 data
[offset
+9] = (JOCTET
)((new_value
>> 8) & 0xFF);
1459 data
[offset
+10] = 0;
1460 data
[offset
+11] = 0;
1464 } while (--number_of_tags
);
1468 /* Adjust output image parameters as needed.
1470 * This must be called after jpeg_copy_critical_parameters()
1471 * and before jpeg_write_coefficients().
1473 * The return value is the set of virtual coefficient arrays to be written
1474 * (either the ones allocated by jtransform_request_workspace, or the
1475 * original source data arrays). The caller will need to pass this value
1476 * to jpeg_write_coefficients().
1479 GLOBAL(jvirt_barray_ptr
*)
1480 jtransform_adjust_parameters (j_decompress_ptr srcinfo
,
1481 j_compress_ptr dstinfo
,
1482 jvirt_barray_ptr
*src_coef_arrays
,
1483 jpeg_transform_info
*info
)
1485 /* If force-to-grayscale is requested, adjust destination parameters */
1486 if (info
->force_grayscale
) {
1487 /* First, ensure we have YCC or grayscale data, and that the source's
1488 * Y channel is full resolution. (No reasonable person would make Y
1489 * be less than full resolution, so actually coping with that case
1490 * isn't worth extra code space. But we check it to avoid crashing.)
1492 if ((((dstinfo
->jpeg_color_space
== JCS_YCbCr
||
1493 dstinfo
->jpeg_color_space
== JCS_BG_YCC
) &&
1494 dstinfo
->num_components
== 3) ||
1495 (dstinfo
->jpeg_color_space
== JCS_GRAYSCALE
&&
1496 dstinfo
->num_components
== 1)) &&
1497 srcinfo
->comp_info
[0].h_samp_factor
== srcinfo
->max_h_samp_factor
&&
1498 srcinfo
->comp_info
[0].v_samp_factor
== srcinfo
->max_v_samp_factor
) {
1499 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1500 * properly. Among other things, it sets the target h_samp_factor &
1501 * v_samp_factor to 1, which typically won't match the source.
1502 * We have to preserve the source's quantization table number, however.
1504 int sv_quant_tbl_no
= dstinfo
->comp_info
[0].quant_tbl_no
;
1505 jpeg_set_colorspace(dstinfo
, JCS_GRAYSCALE
);
1506 dstinfo
->comp_info
[0].quant_tbl_no
= sv_quant_tbl_no
;
1508 /* Sorry, can't do it */
1509 ERREXIT(dstinfo
, JERR_CONVERSION_NOTIMPL
);
1511 } else if (info
->num_components
== 1) {
1512 /* For a single-component source, we force the destination sampling factors
1513 * to 1x1, with or without force_grayscale. This is useful because some
1514 * decoders choke on grayscale images with other sampling factors.
1516 dstinfo
->comp_info
[0].h_samp_factor
= 1;
1517 dstinfo
->comp_info
[0].v_samp_factor
= 1;
1520 /* Correct the destination's image dimensions as necessary
1521 * for rotate/flip, resize, and crop operations.
1523 dstinfo
->jpeg_width
= info
->output_width
;
1524 dstinfo
->jpeg_height
= info
->output_height
;
1526 /* Transpose destination image parameters */
1527 switch (info
->transform
) {
1528 case JXFORM_TRANSPOSE
:
1529 case JXFORM_TRANSVERSE
:
1531 case JXFORM_ROT_270
:
1532 transpose_critical_parameters(dstinfo
);
1538 /* Adjust Exif properties */
1539 if (srcinfo
->marker_list
!= NULL
&&
1540 srcinfo
->marker_list
->marker
== JPEG_APP0
+1 &&
1541 srcinfo
->marker_list
->data_length
>= 6 &&
1542 GETJOCTET(srcinfo
->marker_list
->data
[0]) == 0x45 &&
1543 GETJOCTET(srcinfo
->marker_list
->data
[1]) == 0x78 &&
1544 GETJOCTET(srcinfo
->marker_list
->data
[2]) == 0x69 &&
1545 GETJOCTET(srcinfo
->marker_list
->data
[3]) == 0x66 &&
1546 GETJOCTET(srcinfo
->marker_list
->data
[4]) == 0 &&
1547 GETJOCTET(srcinfo
->marker_list
->data
[5]) == 0) {
1548 /* Suppress output of JFIF marker */
1549 dstinfo
->write_JFIF_header
= FALSE
;
1550 /* Adjust Exif image parameters */
1551 if (dstinfo
->jpeg_width
!= srcinfo
->image_width
||
1552 dstinfo
->jpeg_height
!= srcinfo
->image_height
)
1553 /* Align data segment to start of TIFF structure for parsing */
1554 adjust_exif_parameters(srcinfo
->marker_list
->data
+ 6,
1555 srcinfo
->marker_list
->data_length
- 6,
1556 dstinfo
->jpeg_width
, dstinfo
->jpeg_height
);
1559 /* Return the appropriate output data set */
1560 if (info
->workspace_coef_arrays
!= NULL
)
1561 return info
->workspace_coef_arrays
;
1562 return src_coef_arrays
;
1566 /* Execute the actual transformation, if any.
1568 * This must be called *after* jpeg_write_coefficients, because it depends
1569 * on jpeg_write_coefficients to have computed subsidiary values such as
1570 * the per-component width and height fields in the destination object.
1572 * Note that some transformations will modify the source data arrays!
1576 jtransform_execute_transform (j_decompress_ptr srcinfo
,
1577 j_compress_ptr dstinfo
,
1578 jvirt_barray_ptr
*src_coef_arrays
,
1579 jpeg_transform_info
*info
)
1581 jvirt_barray_ptr
*dst_coef_arrays
= info
->workspace_coef_arrays
;
1583 /* Note: conditions tested here should match those in switch statement
1584 * in jtransform_request_workspace()
1586 switch (info
->transform
) {
1588 if (info
->output_width
> srcinfo
->output_width
||
1589 info
->output_height
> srcinfo
->output_height
)
1590 do_crop_ext(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1591 src_coef_arrays
, dst_coef_arrays
);
1592 else if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0)
1593 do_crop(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1594 src_coef_arrays
, dst_coef_arrays
);
1597 if (info
->y_crop_offset
!= 0)
1598 do_flip_h(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1599 src_coef_arrays
, dst_coef_arrays
);
1601 do_flip_h_no_crop(srcinfo
, dstinfo
, info
->x_crop_offset
,
1605 do_flip_v(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1606 src_coef_arrays
, dst_coef_arrays
);
1608 case JXFORM_TRANSPOSE
:
1609 do_transpose(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1610 src_coef_arrays
, dst_coef_arrays
);
1612 case JXFORM_TRANSVERSE
:
1613 do_transverse(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1614 src_coef_arrays
, dst_coef_arrays
);
1617 do_rot_90(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1618 src_coef_arrays
, dst_coef_arrays
);
1620 case JXFORM_ROT_180
:
1621 do_rot_180(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1622 src_coef_arrays
, dst_coef_arrays
);
1624 case JXFORM_ROT_270
:
1625 do_rot_270(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1626 src_coef_arrays
, dst_coef_arrays
);
1629 do_wipe(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1630 src_coef_arrays
, info
->drop_width
, info
->drop_height
);
1635 /* jtransform_perfect_transform
1637 * Determine whether lossless transformation is perfectly
1638 * possible for a specified image and transformation.
1641 * image_width, image_height: source image dimensions.
1642 * MCU_width, MCU_height: pixel dimensions of MCU.
1643 * transform: transformation identifier.
1644 * Parameter sources from initialized jpeg_struct
1645 * (after reading source header):
1646 * image_width = cinfo.image_width
1647 * image_height = cinfo.image_height
1648 * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
1649 * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
1651 * TRUE = perfect transformation possible
1652 * FALSE = perfect transformation not possible
1653 * (may use custom action then)
1657 jtransform_perfect_transform(JDIMENSION image_width
, JDIMENSION image_height
,
1658 int MCU_width
, int MCU_height
,
1659 JXFORM_CODE transform
)
1661 boolean result
= TRUE
; /* initialize TRUE */
1663 switch (transform
) {
1665 case JXFORM_ROT_270
:
1666 if (image_width
% (JDIMENSION
) MCU_width
)
1671 if (image_height
% (JDIMENSION
) MCU_height
)
1674 case JXFORM_TRANSVERSE
:
1675 case JXFORM_ROT_180
:
1676 if (image_width
% (JDIMENSION
) MCU_width
)
1678 if (image_height
% (JDIMENSION
) MCU_height
)
1688 #endif /* TRANSFORMS_SUPPORTED */
1691 /* Setup decompression object to save desired markers in memory.
1692 * This must be called before jpeg_read_header() to have the desired effect.
1696 jcopy_markers_setup (j_decompress_ptr srcinfo
, JCOPY_OPTION option
)
1698 #ifdef SAVE_MARKERS_SUPPORTED
1701 /* Save comments except under NONE option */
1702 if (option
!= JCOPYOPT_NONE
) {
1703 jpeg_save_markers(srcinfo
, JPEG_COM
, 0xFFFF);
1705 /* Save all types of APPn markers iff ALL option */
1706 if (option
== JCOPYOPT_ALL
) {
1707 for (m
= 0; m
< 16; m
++)
1708 jpeg_save_markers(srcinfo
, JPEG_APP0
+ m
, 0xFFFF);
1710 #endif /* SAVE_MARKERS_SUPPORTED */
1713 /* Copy markers saved in the given source object to the destination object.
1714 * This should be called just after jpeg_start_compress() or
1715 * jpeg_write_coefficients().
1716 * Note that those routines will have written the SOI, and also the
1717 * JFIF APP0 or Adobe APP14 markers if selected.
1721 jcopy_markers_execute (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
1722 JCOPY_OPTION option
)
1724 jpeg_saved_marker_ptr marker
;
1726 /* In the current implementation, we don't actually need to examine the
1727 * option flag here; we just copy everything that got saved.
1728 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1729 * if the encoder library already wrote one.
1731 for (marker
= srcinfo
->marker_list
; marker
!= NULL
; marker
= marker
->next
) {
1732 if (dstinfo
->write_JFIF_header
&&
1733 marker
->marker
== JPEG_APP0
&&
1734 marker
->data_length
>= 5 &&
1735 GETJOCTET(marker
->data
[0]) == 0x4A &&
1736 GETJOCTET(marker
->data
[1]) == 0x46 &&
1737 GETJOCTET(marker
->data
[2]) == 0x49 &&
1738 GETJOCTET(marker
->data
[3]) == 0x46 &&
1739 GETJOCTET(marker
->data
[4]) == 0)
1740 continue; /* reject duplicate JFIF */
1741 if (dstinfo
->write_Adobe_marker
&&
1742 marker
->marker
== JPEG_APP0
+14 &&
1743 marker
->data_length
>= 5 &&
1744 GETJOCTET(marker
->data
[0]) == 0x41 &&
1745 GETJOCTET(marker
->data
[1]) == 0x64 &&
1746 GETJOCTET(marker
->data
[2]) == 0x6F &&
1747 GETJOCTET(marker
->data
[3]) == 0x62 &&
1748 GETJOCTET(marker
->data
[4]) == 0x65)
1749 continue; /* reject duplicate Adobe */
1750 #ifdef NEED_FAR_POINTERS
1751 /* We could use jpeg_write_marker if the data weren't FAR... */
1754 jpeg_write_m_header(dstinfo
, marker
->marker
, marker
->data_length
);
1755 for (i
= 0; i
< marker
->data_length
; i
++)
1756 jpeg_write_m_byte(dstinfo
, marker
->data
[i
]);
1759 jpeg_write_marker(dstinfo
, marker
->marker
,
1760 marker
->data
, marker
->data_length
);