4 * Copyright (C) 1997-2001, Thomas G. Lane.
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_flip_h_no_crop (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
118 JDIMENSION x_crop_offset
,
119 jvirt_barray_ptr
*src_coef_arrays
)
120 /* Horizontal flip; done in-place, so no separate dest array is required.
121 * NB: this only works when y_crop_offset is zero.
124 JDIMENSION MCU_cols
, comp_width
, blk_x
, blk_y
, x_crop_blocks
;
129 jpeg_component_info
*compptr
;
131 /* Horizontal mirroring of DCT blocks is accomplished by swapping
132 * pairs of blocks in-place. Within a DCT block, we perform horizontal
133 * mirroring by changing the signs of odd-numbered columns.
134 * Partial iMCUs at the right edge are left untouched.
136 MCU_cols
= srcinfo
->image_width
/ (dstinfo
->max_h_samp_factor
* DCTSIZE
);
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 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
142 for (blk_y
= 0; blk_y
< compptr
->height_in_blocks
;
143 blk_y
+= compptr
->v_samp_factor
) {
144 buffer
= (*srcinfo
->mem
->access_virt_barray
)
145 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], blk_y
,
146 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
147 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
148 /* Do the mirroring */
149 for (blk_x
= 0; blk_x
* 2 < comp_width
; blk_x
++) {
150 ptr1
= buffer
[offset_y
][blk_x
];
151 ptr2
= buffer
[offset_y
][comp_width
- blk_x
- 1];
152 /* this unrolled loop doesn't need to know which row it's on... */
153 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
154 temp1
= *ptr1
; /* swap even column */
158 temp1
= *ptr1
; /* swap odd column with sign change */
164 if (x_crop_blocks
> 0) {
165 /* Now left-justify the portion of the data to be kept.
166 * We can't use a single jcopy_block_row() call because that routine
167 * depends on memcpy(), whose behavior is unspecified for overlapping
168 * source and destination areas. Sigh.
170 for (blk_x
= 0; blk_x
< compptr
->width_in_blocks
; blk_x
++) {
171 jcopy_block_row(buffer
[offset_y
] + blk_x
+ x_crop_blocks
,
172 buffer
[offset_y
] + blk_x
,
183 do_flip_h (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
184 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
185 jvirt_barray_ptr
*src_coef_arrays
,
186 jvirt_barray_ptr
*dst_coef_arrays
)
187 /* Horizontal flip in general cropping case */
189 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
190 JDIMENSION x_crop_blocks
, y_crop_blocks
;
192 JBLOCKARRAY src_buffer
, dst_buffer
;
193 JBLOCKROW src_row_ptr
, dst_row_ptr
;
194 JCOEFPTR src_ptr
, dst_ptr
;
195 jpeg_component_info
*compptr
;
197 /* Here we must output into a separate array because we can't touch
198 * different rows of a single virtual array simultaneously. Otherwise,
199 * this is essentially the same as the routine above.
201 MCU_cols
= srcinfo
->image_width
/ (dstinfo
->max_h_samp_factor
* DCTSIZE
);
203 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
204 compptr
= dstinfo
->comp_info
+ ci
;
205 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
206 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
207 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
208 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
209 dst_blk_y
+= compptr
->v_samp_factor
) {
210 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
211 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
212 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
213 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
214 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
215 dst_blk_y
+ y_crop_blocks
,
216 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
217 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
218 dst_row_ptr
= dst_buffer
[offset_y
];
219 src_row_ptr
= src_buffer
[offset_y
];
220 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
221 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
222 /* Do the mirrorable blocks */
223 dst_ptr
= dst_row_ptr
[dst_blk_x
];
224 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
225 /* this unrolled loop doesn't need to know which row it's on... */
226 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
227 *dst_ptr
++ = *src_ptr
++; /* copy even column */
228 *dst_ptr
++ = - *src_ptr
++; /* copy odd column with sign change */
231 /* Copy last partial block(s) verbatim */
232 jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
233 dst_row_ptr
+ dst_blk_x
,
244 do_flip_v (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
245 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
246 jvirt_barray_ptr
*src_coef_arrays
,
247 jvirt_barray_ptr
*dst_coef_arrays
)
250 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
251 JDIMENSION x_crop_blocks
, y_crop_blocks
;
252 int ci
, i
, j
, offset_y
;
253 JBLOCKARRAY src_buffer
, dst_buffer
;
254 JBLOCKROW src_row_ptr
, dst_row_ptr
;
255 JCOEFPTR src_ptr
, dst_ptr
;
256 jpeg_component_info
*compptr
;
258 /* We output into a separate array because we can't touch different
259 * rows of the source virtual array simultaneously. Otherwise, this
260 * is a pretty straightforward analog of horizontal flip.
261 * Within a DCT block, vertical mirroring is done by changing the signs
262 * of odd-numbered rows.
263 * Partial iMCUs at the bottom edge are copied verbatim.
265 MCU_rows
= srcinfo
->image_height
/ (dstinfo
->max_v_samp_factor
* DCTSIZE
);
267 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
268 compptr
= dstinfo
->comp_info
+ ci
;
269 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
270 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
271 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
272 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
273 dst_blk_y
+= compptr
->v_samp_factor
) {
274 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
275 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
276 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
277 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
278 /* Row is within the mirrorable area. */
279 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
280 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
281 comp_height
- y_crop_blocks
- dst_blk_y
-
282 (JDIMENSION
) compptr
->v_samp_factor
,
283 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
285 /* Bottom-edge blocks will be copied verbatim. */
286 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
287 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
288 dst_blk_y
+ y_crop_blocks
,
289 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
291 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
292 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
293 /* Row is within the mirrorable area. */
294 dst_row_ptr
= dst_buffer
[offset_y
];
295 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
296 src_row_ptr
+= x_crop_blocks
;
297 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
299 dst_ptr
= dst_row_ptr
[dst_blk_x
];
300 src_ptr
= src_row_ptr
[dst_blk_x
];
301 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
303 for (j
= 0; j
< DCTSIZE
; j
++)
304 *dst_ptr
++ = *src_ptr
++;
305 /* copy odd row with sign change */
306 for (j
= 0; j
< DCTSIZE
; j
++)
307 *dst_ptr
++ = - *src_ptr
++;
311 /* Just copy row verbatim. */
312 jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
313 dst_buffer
[offset_y
],
314 compptr
->width_in_blocks
);
323 do_transpose (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
324 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
325 jvirt_barray_ptr
*src_coef_arrays
,
326 jvirt_barray_ptr
*dst_coef_arrays
)
327 /* Transpose source into destination */
329 JDIMENSION dst_blk_x
, dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
330 int ci
, i
, j
, offset_x
, offset_y
;
331 JBLOCKARRAY src_buffer
, dst_buffer
;
332 JCOEFPTR src_ptr
, dst_ptr
;
333 jpeg_component_info
*compptr
;
335 /* Transposing pixels within a block just requires transposing the
337 * Partial iMCUs at the edges require no special treatment; we simply
338 * process all the available DCT blocks for every component.
340 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
341 compptr
= dstinfo
->comp_info
+ ci
;
342 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
343 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
344 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
345 dst_blk_y
+= compptr
->v_samp_factor
) {
346 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
347 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
348 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
349 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
350 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
351 dst_blk_x
+= compptr
->h_samp_factor
) {
352 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
353 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
354 dst_blk_x
+ x_crop_blocks
,
355 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
356 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
357 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
358 src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
+ y_crop_blocks
];
359 for (i
= 0; i
< DCTSIZE
; i
++)
360 for (j
= 0; j
< DCTSIZE
; j
++)
361 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
371 do_rot_90 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
372 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
373 jvirt_barray_ptr
*src_coef_arrays
,
374 jvirt_barray_ptr
*dst_coef_arrays
)
375 /* 90 degree rotation is equivalent to
376 * 1. Transposing the image;
377 * 2. Horizontal mirroring.
378 * These two steps are merged into a single processing routine.
381 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
382 JDIMENSION x_crop_blocks
, y_crop_blocks
;
383 int ci
, i
, j
, offset_x
, offset_y
;
384 JBLOCKARRAY src_buffer
, dst_buffer
;
385 JCOEFPTR src_ptr
, dst_ptr
;
386 jpeg_component_info
*compptr
;
388 /* Because of the horizontal mirror step, we can't process partial iMCUs
389 * at the (output) right edge properly. They just get transposed and
392 MCU_cols
= srcinfo
->image_height
/ (dstinfo
->max_h_samp_factor
* DCTSIZE
);
394 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
395 compptr
= dstinfo
->comp_info
+ ci
;
396 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
397 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
398 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
399 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
400 dst_blk_y
+= compptr
->v_samp_factor
) {
401 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
402 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
403 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
404 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
405 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
406 dst_blk_x
+= compptr
->h_samp_factor
) {
407 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
408 /* Block is within the mirrorable area. */
409 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
410 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
411 comp_width
- x_crop_blocks
- dst_blk_x
-
412 (JDIMENSION
) compptr
->h_samp_factor
,
413 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
415 /* Edge blocks are transposed but not mirrored. */
416 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
417 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
418 dst_blk_x
+ x_crop_blocks
,
419 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
421 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
422 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
423 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
424 /* Block is within the mirrorable area. */
425 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
426 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
427 for (i
= 0; i
< DCTSIZE
; i
++) {
428 for (j
= 0; j
< DCTSIZE
; j
++)
429 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
431 for (j
= 0; j
< DCTSIZE
; j
++)
432 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
435 /* Edge blocks are transposed but not mirrored. */
436 src_ptr
= src_buffer
[offset_x
]
437 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
438 for (i
= 0; i
< DCTSIZE
; i
++)
439 for (j
= 0; j
< DCTSIZE
; j
++)
440 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
451 do_rot_270 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
452 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
453 jvirt_barray_ptr
*src_coef_arrays
,
454 jvirt_barray_ptr
*dst_coef_arrays
)
455 /* 270 degree rotation is equivalent to
456 * 1. Horizontal mirroring;
457 * 2. Transposing the image.
458 * These two steps are merged into a single processing routine.
461 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
462 JDIMENSION x_crop_blocks
, y_crop_blocks
;
463 int ci
, i
, j
, offset_x
, offset_y
;
464 JBLOCKARRAY src_buffer
, dst_buffer
;
465 JCOEFPTR src_ptr
, dst_ptr
;
466 jpeg_component_info
*compptr
;
468 /* Because of the horizontal mirror step, we can't process partial iMCUs
469 * at the (output) bottom edge properly. They just get transposed and
472 MCU_rows
= srcinfo
->image_width
/ (dstinfo
->max_v_samp_factor
* DCTSIZE
);
474 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
475 compptr
= dstinfo
->comp_info
+ ci
;
476 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
477 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
478 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
479 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
480 dst_blk_y
+= compptr
->v_samp_factor
) {
481 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
482 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
483 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
484 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
485 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
486 dst_blk_x
+= compptr
->h_samp_factor
) {
487 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
488 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
489 dst_blk_x
+ x_crop_blocks
,
490 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
491 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
492 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
493 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
494 /* Block is within the mirrorable area. */
495 src_ptr
= src_buffer
[offset_x
]
496 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
497 for (i
= 0; i
< DCTSIZE
; i
++) {
498 for (j
= 0; j
< DCTSIZE
; j
++) {
499 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
501 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
505 /* Edge blocks are transposed but not mirrored. */
506 src_ptr
= src_buffer
[offset_x
]
507 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
508 for (i
= 0; i
< DCTSIZE
; i
++)
509 for (j
= 0; j
< DCTSIZE
; j
++)
510 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
521 do_rot_180 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
522 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
523 jvirt_barray_ptr
*src_coef_arrays
,
524 jvirt_barray_ptr
*dst_coef_arrays
)
525 /* 180 degree rotation is equivalent to
526 * 1. Vertical mirroring;
527 * 2. Horizontal mirroring.
528 * These two steps are merged into a single processing routine.
531 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
532 JDIMENSION x_crop_blocks
, y_crop_blocks
;
533 int ci
, i
, j
, offset_y
;
534 JBLOCKARRAY src_buffer
, dst_buffer
;
535 JBLOCKROW src_row_ptr
, dst_row_ptr
;
536 JCOEFPTR src_ptr
, dst_ptr
;
537 jpeg_component_info
*compptr
;
539 MCU_cols
= srcinfo
->image_width
/ (dstinfo
->max_h_samp_factor
* DCTSIZE
);
540 MCU_rows
= srcinfo
->image_height
/ (dstinfo
->max_v_samp_factor
* DCTSIZE
);
542 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
543 compptr
= dstinfo
->comp_info
+ ci
;
544 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
545 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
546 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
547 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
548 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
549 dst_blk_y
+= compptr
->v_samp_factor
) {
550 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
551 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
552 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
553 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
554 /* Row is within the vertically mirrorable area. */
555 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
556 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
557 comp_height
- y_crop_blocks
- dst_blk_y
-
558 (JDIMENSION
) compptr
->v_samp_factor
,
559 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
561 /* Bottom-edge rows are only mirrored horizontally. */
562 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
563 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
564 dst_blk_y
+ y_crop_blocks
,
565 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
567 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
568 dst_row_ptr
= dst_buffer
[offset_y
];
569 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
570 /* Row is within the mirrorable area. */
571 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
572 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
573 dst_ptr
= dst_row_ptr
[dst_blk_x
];
574 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
575 /* Process the blocks that can be mirrored both ways. */
576 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
577 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
578 /* For even row, negate every odd column. */
579 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
580 *dst_ptr
++ = *src_ptr
++;
581 *dst_ptr
++ = - *src_ptr
++;
583 /* For odd row, negate every even column. */
584 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
585 *dst_ptr
++ = - *src_ptr
++;
586 *dst_ptr
++ = *src_ptr
++;
590 /* Any remaining right-edge blocks are only mirrored vertically. */
591 src_ptr
= src_row_ptr
[x_crop_blocks
+ dst_blk_x
];
592 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
593 for (j
= 0; j
< DCTSIZE
; j
++)
594 *dst_ptr
++ = *src_ptr
++;
595 for (j
= 0; j
< DCTSIZE
; j
++)
596 *dst_ptr
++ = - *src_ptr
++;
601 /* Remaining rows are just mirrored horizontally. */
602 src_row_ptr
= src_buffer
[offset_y
];
603 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
604 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
605 /* Process the blocks that can be mirrored. */
606 dst_ptr
= dst_row_ptr
[dst_blk_x
];
607 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
608 for (i
= 0; i
< DCTSIZE2
; i
+= 2) {
609 *dst_ptr
++ = *src_ptr
++;
610 *dst_ptr
++ = - *src_ptr
++;
613 /* Any remaining right-edge blocks are only copied. */
614 jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
615 dst_row_ptr
+ dst_blk_x
,
627 do_transverse (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
628 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
629 jvirt_barray_ptr
*src_coef_arrays
,
630 jvirt_barray_ptr
*dst_coef_arrays
)
631 /* Transverse transpose is equivalent to
632 * 1. 180 degree rotation;
635 * 1. Horizontal mirroring;
637 * 3. Horizontal mirroring.
638 * These steps are merged into a single processing routine.
641 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
642 JDIMENSION x_crop_blocks
, y_crop_blocks
;
643 int ci
, i
, j
, offset_x
, offset_y
;
644 JBLOCKARRAY src_buffer
, dst_buffer
;
645 JCOEFPTR src_ptr
, dst_ptr
;
646 jpeg_component_info
*compptr
;
648 MCU_cols
= srcinfo
->image_height
/ (dstinfo
->max_h_samp_factor
* DCTSIZE
);
649 MCU_rows
= srcinfo
->image_width
/ (dstinfo
->max_v_samp_factor
* DCTSIZE
);
651 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
652 compptr
= dstinfo
->comp_info
+ ci
;
653 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
654 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
655 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
656 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
657 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
658 dst_blk_y
+= compptr
->v_samp_factor
) {
659 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
660 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
661 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
662 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
663 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
664 dst_blk_x
+= compptr
->h_samp_factor
) {
665 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
666 /* Block is within the mirrorable area. */
667 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
668 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
669 comp_width
- x_crop_blocks
- dst_blk_x
-
670 (JDIMENSION
) compptr
->h_samp_factor
,
671 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
673 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
674 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
675 dst_blk_x
+ x_crop_blocks
,
676 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
678 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
679 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
680 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
681 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
682 /* Block is within the mirrorable area. */
683 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
684 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
685 for (i
= 0; i
< DCTSIZE
; i
++) {
686 for (j
= 0; j
< DCTSIZE
; j
++) {
687 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
689 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
692 for (j
= 0; j
< DCTSIZE
; j
++) {
693 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
695 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
699 /* Right-edge blocks are mirrored in y only */
700 src_ptr
= src_buffer
[offset_x
]
701 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
702 for (i
= 0; i
< DCTSIZE
; i
++) {
703 for (j
= 0; j
< DCTSIZE
; j
++) {
704 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
706 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
711 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
712 /* Bottom-edge blocks are mirrored in x only */
713 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
714 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
715 for (i
= 0; i
< DCTSIZE
; i
++) {
716 for (j
= 0; j
< DCTSIZE
; j
++)
717 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
719 for (j
= 0; j
< DCTSIZE
; j
++)
720 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
723 /* At lower right corner, just transpose, no mirroring */
724 src_ptr
= src_buffer
[offset_x
]
725 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
726 for (i
= 0; i
< DCTSIZE
; i
++)
727 for (j
= 0; j
< DCTSIZE
; j
++)
728 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
739 /* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
740 * Returns TRUE if valid integer found, FALSE if not.
741 * *strptr is advanced over the digit string, and *result is set to its value.
745 jt_read_integer (const char ** strptr
, JDIMENSION
* result
)
747 const char * ptr
= *strptr
;
750 for (; isdigit(*ptr
); ptr
++) {
751 val
= val
* 10 + (JDIMENSION
) (*ptr
- '0');
755 return FALSE
; /* oops, no digits */
761 /* Parse a crop specification (written in X11 geometry style).
762 * The routine returns TRUE if the spec string is valid, FALSE if not.
764 * The crop spec string should have the format
765 * <width>x<height>{+-}<xoffset>{+-}<yoffset>
766 * where width, height, xoffset, and yoffset are unsigned integers.
767 * Each of the elements can be omitted to indicate a default value.
768 * (A weakness of this style is that it is not possible to omit xoffset
769 * while specifying yoffset, since they look alike.)
771 * This code is loosely based on XParseGeometry from the X11 distribution.
775 jtransform_parse_crop_spec (jpeg_transform_info
*info
, const char *spec
)
778 info
->crop_width_set
= JCROP_UNSET
;
779 info
->crop_height_set
= JCROP_UNSET
;
780 info
->crop_xoffset_set
= JCROP_UNSET
;
781 info
->crop_yoffset_set
= JCROP_UNSET
;
783 if (isdigit(*spec
)) {
785 if (! jt_read_integer(&spec
, &info
->crop_width
))
787 info
->crop_width_set
= JCROP_POS
;
789 if (*spec
== 'x' || *spec
== 'X') {
792 if (! jt_read_integer(&spec
, &info
->crop_height
))
794 info
->crop_height_set
= JCROP_POS
;
796 if (*spec
== '+' || *spec
== '-') {
798 info
->crop_xoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
800 if (! jt_read_integer(&spec
, &info
->crop_xoffset
))
803 if (*spec
== '+' || *spec
== '-') {
805 info
->crop_yoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
807 if (! jt_read_integer(&spec
, &info
->crop_yoffset
))
810 /* We had better have gotten to the end of the string. */
818 /* Trim off any partial iMCUs on the indicated destination edge */
821 trim_right_edge (jpeg_transform_info
*info
, JDIMENSION full_width
)
825 MCU_cols
= info
->output_width
/ (info
->max_h_samp_factor
* DCTSIZE
);
826 if (MCU_cols
> 0 && info
->x_crop_offset
+ MCU_cols
==
827 full_width
/ (info
->max_h_samp_factor
* DCTSIZE
))
828 info
->output_width
= MCU_cols
* (info
->max_h_samp_factor
* DCTSIZE
);
832 trim_bottom_edge (jpeg_transform_info
*info
, JDIMENSION full_height
)
836 MCU_rows
= info
->output_height
/ (info
->max_v_samp_factor
* DCTSIZE
);
837 if (MCU_rows
> 0 && info
->y_crop_offset
+ MCU_rows
==
838 full_height
/ (info
->max_v_samp_factor
* DCTSIZE
))
839 info
->output_height
= MCU_rows
* (info
->max_v_samp_factor
* DCTSIZE
);
843 /* Request any required workspace.
845 * This routine figures out the size that the output image will be
846 * (which implies that all the transform parameters must be set before
849 * We allocate the workspace virtual arrays from the source decompression
850 * object, so that all the arrays (both the original data and the workspace)
851 * will be taken into account while making memory management decisions.
852 * Hence, this routine must be called after jpeg_read_header (which reads
853 * the image dimensions) and before jpeg_read_coefficients (which realizes
854 * the source's virtual arrays).
858 jtransform_request_workspace (j_decompress_ptr srcinfo
,
859 jpeg_transform_info
*info
)
861 jvirt_barray_ptr
*coef_arrays
= NULL
;
862 boolean need_workspace
, transpose_it
;
863 jpeg_component_info
*compptr
;
864 JDIMENSION xoffset
, yoffset
, width_in_iMCUs
, height_in_iMCUs
;
865 JDIMENSION width_in_blocks
, height_in_blocks
;
866 int ci
, h_samp_factor
, v_samp_factor
;
868 /* Determine number of components in output image */
869 if (info
->force_grayscale
&&
870 srcinfo
->jpeg_color_space
== JCS_YCbCr
&&
871 srcinfo
->num_components
== 3) {
872 /* We'll only process the first component */
873 info
->num_components
= 1;
875 /* Process all the components */
876 info
->num_components
= srcinfo
->num_components
;
878 /* If there is only one output component, force the iMCU size to be 1;
879 * else use the source iMCU size. (This allows us to do the right thing
880 * when reducing color to grayscale, and also provides a handy way of
881 * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
884 switch (info
->transform
) {
885 case JXFORM_TRANSPOSE
:
886 case JXFORM_TRANSVERSE
:
889 info
->output_width
= srcinfo
->image_height
;
890 info
->output_height
= srcinfo
->image_width
;
891 if (info
->num_components
== 1) {
892 info
->max_h_samp_factor
= 1;
893 info
->max_v_samp_factor
= 1;
895 info
->max_h_samp_factor
= srcinfo
->max_v_samp_factor
;
896 info
->max_v_samp_factor
= srcinfo
->max_h_samp_factor
;
900 info
->output_width
= srcinfo
->image_width
;
901 info
->output_height
= srcinfo
->image_height
;
902 if (info
->num_components
== 1) {
903 info
->max_h_samp_factor
= 1;
904 info
->max_v_samp_factor
= 1;
906 info
->max_h_samp_factor
= srcinfo
->max_h_samp_factor
;
907 info
->max_v_samp_factor
= srcinfo
->max_v_samp_factor
;
912 /* If cropping has been requested, compute the crop area's position and
913 * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
916 /* Insert default values for unset crop parameters */
917 if (info
->crop_xoffset_set
== JCROP_UNSET
)
918 info
->crop_xoffset
= 0; /* default to +0 */
919 if (info
->crop_yoffset_set
== JCROP_UNSET
)
920 info
->crop_yoffset
= 0; /* default to +0 */
921 if (info
->crop_xoffset
>= info
->output_width
||
922 info
->crop_yoffset
>= info
->output_height
)
923 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
924 if (info
->crop_width_set
== JCROP_UNSET
)
925 info
->crop_width
= info
->output_width
- info
->crop_xoffset
;
926 if (info
->crop_height_set
== JCROP_UNSET
)
927 info
->crop_height
= info
->output_height
- info
->crop_yoffset
;
928 /* Ensure parameters are valid */
929 if (info
->crop_width
<= 0 || info
->crop_width
> info
->output_width
||
930 info
->crop_height
<= 0 || info
->crop_height
> info
->output_height
||
931 info
->crop_xoffset
> info
->output_width
- info
->crop_width
||
932 info
->crop_yoffset
> info
->output_height
- info
->crop_height
)
933 ERREXIT(srcinfo
, JERR_BAD_CROP_SPEC
);
934 /* Convert negative crop offsets into regular offsets */
935 if (info
->crop_xoffset_set
== JCROP_NEG
)
936 xoffset
= info
->output_width
- info
->crop_width
- info
->crop_xoffset
;
938 xoffset
= info
->crop_xoffset
;
939 if (info
->crop_yoffset_set
== JCROP_NEG
)
940 yoffset
= info
->output_height
- info
->crop_height
- info
->crop_yoffset
;
942 yoffset
= info
->crop_yoffset
;
943 /* Now adjust so that upper left corner falls at an iMCU boundary */
945 info
->crop_width
+ (xoffset
% (info
->max_h_samp_factor
* DCTSIZE
));
946 info
->output_height
=
947 info
->crop_height
+ (yoffset
% (info
->max_v_samp_factor
* DCTSIZE
));
948 /* Save x/y offsets measured in iMCUs */
949 info
->x_crop_offset
= xoffset
/ (info
->max_h_samp_factor
* DCTSIZE
);
950 info
->y_crop_offset
= yoffset
/ (info
->max_v_samp_factor
* DCTSIZE
);
952 info
->x_crop_offset
= 0;
953 info
->y_crop_offset
= 0;
956 /* Figure out whether we need workspace arrays,
957 * and if so whether they are transposed relative to the source.
959 need_workspace
= FALSE
;
960 transpose_it
= FALSE
;
961 switch (info
->transform
) {
963 if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0)
964 need_workspace
= TRUE
;
965 /* No workspace needed if neither cropping nor transforming */
969 trim_right_edge(info
, srcinfo
->image_width
);
970 if (info
->y_crop_offset
!= 0)
971 need_workspace
= TRUE
;
972 /* do_flip_h_no_crop doesn't need a workspace array */
976 trim_bottom_edge(info
, srcinfo
->image_height
);
977 /* Need workspace arrays having same dimensions as source image. */
978 need_workspace
= TRUE
;
980 case JXFORM_TRANSPOSE
:
981 /* transpose does NOT have to trim anything */
982 /* Need workspace arrays having transposed dimensions. */
983 need_workspace
= TRUE
;
986 case JXFORM_TRANSVERSE
:
988 trim_right_edge(info
, srcinfo
->image_height
);
989 trim_bottom_edge(info
, srcinfo
->image_width
);
991 /* Need workspace arrays having transposed dimensions. */
992 need_workspace
= TRUE
;
997 trim_right_edge(info
, srcinfo
->image_height
);
998 /* Need workspace arrays having transposed dimensions. */
999 need_workspace
= TRUE
;
1000 transpose_it
= TRUE
;
1002 case JXFORM_ROT_180
:
1004 trim_right_edge(info
, srcinfo
->image_width
);
1005 trim_bottom_edge(info
, srcinfo
->image_height
);
1007 /* Need workspace arrays having same dimensions as source image. */
1008 need_workspace
= TRUE
;
1010 case JXFORM_ROT_270
:
1012 trim_bottom_edge(info
, srcinfo
->image_width
);
1013 /* Need workspace arrays having transposed dimensions. */
1014 need_workspace
= TRUE
;
1015 transpose_it
= TRUE
;
1019 /* Allocate workspace if needed.
1020 * Note that we allocate arrays padded out to the next iMCU boundary,
1021 * so that transform routines need not worry about missing edge blocks.
1023 if (need_workspace
) {
1024 coef_arrays
= (jvirt_barray_ptr
*)
1025 (*srcinfo
->mem
->alloc_small
) ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
,
1026 SIZEOF(jvirt_barray_ptr
) * info
->num_components
);
1027 width_in_iMCUs
= (JDIMENSION
)
1028 jdiv_round_up((long) info
->output_width
,
1029 (long) (info
->max_h_samp_factor
* DCTSIZE
));
1030 height_in_iMCUs
= (JDIMENSION
)
1031 jdiv_round_up((long) info
->output_height
,
1032 (long) (info
->max_v_samp_factor
* DCTSIZE
));
1033 for (ci
= 0; ci
< info
->num_components
; ci
++) {
1034 compptr
= srcinfo
->comp_info
+ ci
;
1035 if (info
->num_components
== 1) {
1036 /* we're going to force samp factors to 1x1 in this case */
1037 h_samp_factor
= v_samp_factor
= 1;
1038 } else if (transpose_it
) {
1039 h_samp_factor
= compptr
->v_samp_factor
;
1040 v_samp_factor
= compptr
->h_samp_factor
;
1042 h_samp_factor
= compptr
->h_samp_factor
;
1043 v_samp_factor
= compptr
->v_samp_factor
;
1045 width_in_blocks
= width_in_iMCUs
* h_samp_factor
;
1046 height_in_blocks
= height_in_iMCUs
* v_samp_factor
;
1047 coef_arrays
[ci
] = (*srcinfo
->mem
->request_virt_barray
)
1048 ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
, FALSE
,
1049 width_in_blocks
, height_in_blocks
, (JDIMENSION
) v_samp_factor
);
1053 info
->workspace_coef_arrays
= coef_arrays
;
1057 /* Transpose destination image parameters */
1060 transpose_critical_parameters (j_compress_ptr dstinfo
)
1062 int tblno
, i
, j
, ci
, itemp
;
1063 jpeg_component_info
*compptr
;
1064 JQUANT_TBL
*qtblptr
;
1067 /* Transpose sampling factors */
1068 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
1069 compptr
= dstinfo
->comp_info
+ ci
;
1070 itemp
= compptr
->h_samp_factor
;
1071 compptr
->h_samp_factor
= compptr
->v_samp_factor
;
1072 compptr
->v_samp_factor
= itemp
;
1075 /* Transpose quantization tables */
1076 for (tblno
= 0; tblno
< NUM_QUANT_TBLS
; tblno
++) {
1077 qtblptr
= dstinfo
->quant_tbl_ptrs
[tblno
];
1078 if (qtblptr
!= NULL
) {
1079 for (i
= 0; i
< DCTSIZE
; i
++) {
1080 for (j
= 0; j
< i
; j
++) {
1081 qtemp
= qtblptr
->quantval
[i
*DCTSIZE
+j
];
1082 qtblptr
->quantval
[i
*DCTSIZE
+j
] = qtblptr
->quantval
[j
*DCTSIZE
+i
];
1083 qtblptr
->quantval
[j
*DCTSIZE
+i
] = qtemp
;
1091 /* Adjust Exif image parameters.
1093 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1097 adjust_exif_parameters (JOCTET FAR
* data
, unsigned int length
,
1098 JDIMENSION new_width
, JDIMENSION new_height
)
1100 boolean is_motorola
; /* Flag for byte order */
1101 unsigned int number_of_tags
, tagnum
;
1102 unsigned int firstoffset
, offset
;
1103 JDIMENSION new_value
;
1105 if (length
< 12) return; /* Length of an IFD entry */
1107 /* Discover byte order */
1108 if (GETJOCTET(data
[0]) == 0x49 && GETJOCTET(data
[1]) == 0x49)
1109 is_motorola
= FALSE
;
1110 else if (GETJOCTET(data
[0]) == 0x4D && GETJOCTET(data
[1]) == 0x4D)
1115 /* Check Tag Mark */
1117 if (GETJOCTET(data
[2]) != 0) return;
1118 if (GETJOCTET(data
[3]) != 0x2A) return;
1120 if (GETJOCTET(data
[3]) != 0) return;
1121 if (GETJOCTET(data
[2]) != 0x2A) return;
1124 /* Get first IFD offset (offset to IFD0) */
1126 if (GETJOCTET(data
[4]) != 0) return;
1127 if (GETJOCTET(data
[5]) != 0) return;
1128 firstoffset
= GETJOCTET(data
[6]);
1130 firstoffset
+= GETJOCTET(data
[7]);
1132 if (GETJOCTET(data
[7]) != 0) return;
1133 if (GETJOCTET(data
[6]) != 0) return;
1134 firstoffset
= GETJOCTET(data
[5]);
1136 firstoffset
+= GETJOCTET(data
[4]);
1138 if (firstoffset
> length
- 2) return; /* check end of data segment */
1140 /* Get the number of directory entries contained in this IFD */
1142 number_of_tags
= GETJOCTET(data
[firstoffset
]);
1143 number_of_tags
<<= 8;
1144 number_of_tags
+= GETJOCTET(data
[firstoffset
+1]);
1146 number_of_tags
= GETJOCTET(data
[firstoffset
+1]);
1147 number_of_tags
<<= 8;
1148 number_of_tags
+= GETJOCTET(data
[firstoffset
]);
1150 if (number_of_tags
== 0) return;
1153 /* Search for ExifSubIFD offset Tag in IFD0 */
1155 if (firstoffset
> length
- 12) return; /* check end of data segment */
1156 /* Get Tag number */
1158 tagnum
= GETJOCTET(data
[firstoffset
]);
1160 tagnum
+= GETJOCTET(data
[firstoffset
+1]);
1162 tagnum
= GETJOCTET(data
[firstoffset
+1]);
1164 tagnum
+= GETJOCTET(data
[firstoffset
]);
1166 if (tagnum
== 0x8769) break; /* found ExifSubIFD offset Tag */
1167 if (--number_of_tags
== 0) return;
1171 /* Get the ExifSubIFD offset */
1173 if (GETJOCTET(data
[firstoffset
+8]) != 0) return;
1174 if (GETJOCTET(data
[firstoffset
+9]) != 0) return;
1175 offset
= GETJOCTET(data
[firstoffset
+10]);
1177 offset
+= GETJOCTET(data
[firstoffset
+11]);
1179 if (GETJOCTET(data
[firstoffset
+11]) != 0) return;
1180 if (GETJOCTET(data
[firstoffset
+10]) != 0) return;
1181 offset
= GETJOCTET(data
[firstoffset
+9]);
1183 offset
+= GETJOCTET(data
[firstoffset
+8]);
1185 if (offset
> length
- 2) return; /* check end of data segment */
1187 /* Get the number of directory entries contained in this SubIFD */
1189 number_of_tags
= GETJOCTET(data
[offset
]);
1190 number_of_tags
<<= 8;
1191 number_of_tags
+= GETJOCTET(data
[offset
+1]);
1193 number_of_tags
= GETJOCTET(data
[offset
+1]);
1194 number_of_tags
<<= 8;
1195 number_of_tags
+= GETJOCTET(data
[offset
]);
1197 if (number_of_tags
< 2) return;
1200 /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1202 if (offset
> length
- 12) return; /* check end of data segment */
1203 /* Get Tag number */
1205 tagnum
= GETJOCTET(data
[offset
]);
1207 tagnum
+= GETJOCTET(data
[offset
+1]);
1209 tagnum
= GETJOCTET(data
[offset
+1]);
1211 tagnum
+= GETJOCTET(data
[offset
]);
1213 if (tagnum
== 0xA002 || tagnum
== 0xA003) {
1214 if (tagnum
== 0xA002)
1215 new_value
= new_width
; /* ExifImageWidth Tag */
1217 new_value
= new_height
; /* ExifImageHeight Tag */
1219 data
[offset
+2] = 0; /* Format = unsigned long (4 octets) */
1221 data
[offset
+4] = 0; /* Number Of Components = 1 */
1227 data
[offset
+10] = (JOCTET
)((new_value
>> 8) & 0xFF);
1228 data
[offset
+11] = (JOCTET
)(new_value
& 0xFF);
1230 data
[offset
+2] = 4; /* Format = unsigned long (4 octets) */
1232 data
[offset
+4] = 1; /* Number Of Components = 1 */
1236 data
[offset
+8] = (JOCTET
)(new_value
& 0xFF);
1237 data
[offset
+9] = (JOCTET
)((new_value
>> 8) & 0xFF);
1238 data
[offset
+10] = 0;
1239 data
[offset
+11] = 0;
1243 } while (--number_of_tags
);
1247 /* Adjust output image parameters as needed.
1249 * This must be called after jpeg_copy_critical_parameters()
1250 * and before jpeg_write_coefficients().
1252 * The return value is the set of virtual coefficient arrays to be written
1253 * (either the ones allocated by jtransform_request_workspace, or the
1254 * original source data arrays). The caller will need to pass this value
1255 * to jpeg_write_coefficients().
1258 GLOBAL(jvirt_barray_ptr
*)
1259 jtransform_adjust_parameters (j_decompress_ptr srcinfo
,
1260 j_compress_ptr dstinfo
,
1261 jvirt_barray_ptr
*src_coef_arrays
,
1262 jpeg_transform_info
*info
)
1264 /* If force-to-grayscale is requested, adjust destination parameters */
1265 if (info
->force_grayscale
) {
1266 /* First, ensure we have YCbCr or grayscale data, and that the source's
1267 * Y channel is full resolution. (No reasonable person would make Y
1268 * be less than full resolution, so actually coping with that case
1269 * isn't worth extra code space. But we check it to avoid crashing.)
1271 if (((dstinfo
->jpeg_color_space
== JCS_YCbCr
&&
1272 dstinfo
->num_components
== 3) ||
1273 (dstinfo
->jpeg_color_space
== JCS_GRAYSCALE
&&
1274 dstinfo
->num_components
== 1)) &&
1275 srcinfo
->comp_info
[0].h_samp_factor
== srcinfo
->max_h_samp_factor
&&
1276 srcinfo
->comp_info
[0].v_samp_factor
== srcinfo
->max_v_samp_factor
) {
1277 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1278 * properly. Among other things, it sets the target h_samp_factor &
1279 * v_samp_factor to 1, which typically won't match the source.
1280 * We have to preserve the source's quantization table number, however.
1282 int sv_quant_tbl_no
= dstinfo
->comp_info
[0].quant_tbl_no
;
1283 jpeg_set_colorspace(dstinfo
, JCS_GRAYSCALE
);
1284 dstinfo
->comp_info
[0].quant_tbl_no
= sv_quant_tbl_no
;
1286 /* Sorry, can't do it */
1287 ERREXIT(dstinfo
, JERR_CONVERSION_NOTIMPL
);
1289 } else if (info
->num_components
== 1) {
1290 /* For a single-component source, we force the destination sampling factors
1291 * to 1x1, with or without force_grayscale. This is useful because some
1292 * decoders choke on grayscale images with other sampling factors.
1294 dstinfo
->comp_info
[0].h_samp_factor
= 1;
1295 dstinfo
->comp_info
[0].v_samp_factor
= 1;
1298 /* Correct the destination's image dimensions as necessary
1299 * for crop and rotate/flip operations.
1301 dstinfo
->image_width
= info
->output_width
;
1302 dstinfo
->image_height
= info
->output_height
;
1304 /* Transpose destination image parameters */
1305 switch (info
->transform
) {
1306 case JXFORM_TRANSPOSE
:
1307 case JXFORM_TRANSVERSE
:
1309 case JXFORM_ROT_270
:
1310 transpose_critical_parameters(dstinfo
);
1314 /* Adjust Exif properties */
1315 if (srcinfo
->marker_list
!= NULL
&&
1316 srcinfo
->marker_list
->marker
== JPEG_APP0
+1 &&
1317 srcinfo
->marker_list
->data_length
>= 6 &&
1318 GETJOCTET(srcinfo
->marker_list
->data
[0]) == 0x45 &&
1319 GETJOCTET(srcinfo
->marker_list
->data
[1]) == 0x78 &&
1320 GETJOCTET(srcinfo
->marker_list
->data
[2]) == 0x69 &&
1321 GETJOCTET(srcinfo
->marker_list
->data
[3]) == 0x66 &&
1322 GETJOCTET(srcinfo
->marker_list
->data
[4]) == 0 &&
1323 GETJOCTET(srcinfo
->marker_list
->data
[5]) == 0) {
1324 /* Suppress output of JFIF marker */
1325 dstinfo
->write_JFIF_header
= FALSE
;
1326 /* Adjust Exif image parameters */
1327 if (dstinfo
->image_width
!= srcinfo
->image_width
||
1328 dstinfo
->image_height
!= srcinfo
->image_height
)
1329 /* Align data segment to start of TIFF structure for parsing */
1330 adjust_exif_parameters(srcinfo
->marker_list
->data
+ 6,
1331 srcinfo
->marker_list
->data_length
- 6,
1332 dstinfo
->image_width
, dstinfo
->image_height
);
1335 /* Return the appropriate output data set */
1336 if (info
->workspace_coef_arrays
!= NULL
)
1337 return info
->workspace_coef_arrays
;
1338 return src_coef_arrays
;
1342 /* Execute the actual transformation, if any.
1344 * This must be called *after* jpeg_write_coefficients, because it depends
1345 * on jpeg_write_coefficients to have computed subsidiary values such as
1346 * the per-component width and height fields in the destination object.
1348 * Note that some transformations will modify the source data arrays!
1352 jtransform_execute_transform (j_decompress_ptr srcinfo
,
1353 j_compress_ptr dstinfo
,
1354 jvirt_barray_ptr
*src_coef_arrays
,
1355 jpeg_transform_info
*info
)
1357 jvirt_barray_ptr
*dst_coef_arrays
= info
->workspace_coef_arrays
;
1359 /* Note: conditions tested here should match those in switch statement
1360 * in jtransform_request_workspace()
1362 switch (info
->transform
) {
1364 if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0)
1365 do_crop(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1366 src_coef_arrays
, dst_coef_arrays
);
1369 if (info
->y_crop_offset
!= 0)
1370 do_flip_h(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1371 src_coef_arrays
, dst_coef_arrays
);
1373 do_flip_h_no_crop(srcinfo
, dstinfo
, info
->x_crop_offset
,
1377 do_flip_v(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1378 src_coef_arrays
, dst_coef_arrays
);
1380 case JXFORM_TRANSPOSE
:
1381 do_transpose(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1382 src_coef_arrays
, dst_coef_arrays
);
1384 case JXFORM_TRANSVERSE
:
1385 do_transverse(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1386 src_coef_arrays
, dst_coef_arrays
);
1389 do_rot_90(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1390 src_coef_arrays
, dst_coef_arrays
);
1392 case JXFORM_ROT_180
:
1393 do_rot_180(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1394 src_coef_arrays
, dst_coef_arrays
);
1396 case JXFORM_ROT_270
:
1397 do_rot_270(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1398 src_coef_arrays
, dst_coef_arrays
);
1403 /* jtransform_perfect_transform
1405 * Determine whether lossless transformation is perfectly
1406 * possible for a specified image and transformation.
1409 * image_width, image_height: source image dimensions.
1410 * MCU_width, MCU_height: pixel dimensions of MCU.
1411 * transform: transformation identifier.
1412 * Parameter sources from initialized jpeg_struct
1413 * (after reading source header):
1414 * image_width = cinfo.image_width
1415 * image_height = cinfo.image_height
1416 * MCU_width = cinfo.max_h_samp_factor * DCTSIZE
1417 * MCU_height = cinfo.max_v_samp_factor * DCTSIZE
1419 * TRUE = perfect transformation possible
1420 * FALSE = perfect transformation not possible
1421 * (may use custom action then)
1425 jtransform_perfect_transform(JDIMENSION image_width
, JDIMENSION image_height
,
1426 int MCU_width
, int MCU_height
,
1427 JXFORM_CODE transform
)
1429 boolean result
= TRUE
; /* initialize TRUE */
1431 switch (transform
) {
1433 case JXFORM_ROT_270
:
1434 if (image_width
% (JDIMENSION
) MCU_width
)
1439 if (image_height
% (JDIMENSION
) MCU_height
)
1442 case JXFORM_TRANSVERSE
:
1443 case JXFORM_ROT_180
:
1444 if (image_width
% (JDIMENSION
) MCU_width
)
1446 if (image_height
% (JDIMENSION
) MCU_height
)
1454 #endif /* TRANSFORMS_SUPPORTED */
1457 /* Setup decompression object to save desired markers in memory.
1458 * This must be called before jpeg_read_header() to have the desired effect.
1462 jcopy_markers_setup (j_decompress_ptr srcinfo
, JCOPY_OPTION option
)
1464 #ifdef SAVE_MARKERS_SUPPORTED
1467 /* Save comments except under NONE option */
1468 if (option
!= JCOPYOPT_NONE
) {
1469 jpeg_save_markers(srcinfo
, JPEG_COM
, 0xFFFF);
1471 /* Save all types of APPn markers iff ALL option */
1472 if (option
== JCOPYOPT_ALL
) {
1473 for (m
= 0; m
< 16; m
++)
1474 jpeg_save_markers(srcinfo
, JPEG_APP0
+ m
, 0xFFFF);
1476 #endif /* SAVE_MARKERS_SUPPORTED */
1479 /* Copy markers saved in the given source object to the destination object.
1480 * This should be called just after jpeg_start_compress() or
1481 * jpeg_write_coefficients().
1482 * Note that those routines will have written the SOI, and also the
1483 * JFIF APP0 or Adobe APP14 markers if selected.
1487 jcopy_markers_execute (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
1488 JCOPY_OPTION option
)
1490 jpeg_saved_marker_ptr marker
;
1492 /* In the current implementation, we don't actually need to examine the
1493 * option flag here; we just copy everything that got saved.
1494 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1495 * if the encoder library already wrote one.
1497 for (marker
= srcinfo
->marker_list
; marker
!= NULL
; marker
= marker
->next
) {
1498 if (dstinfo
->write_JFIF_header
&&
1499 marker
->marker
== JPEG_APP0
&&
1500 marker
->data_length
>= 5 &&
1501 GETJOCTET(marker
->data
[0]) == 0x4A &&
1502 GETJOCTET(marker
->data
[1]) == 0x46 &&
1503 GETJOCTET(marker
->data
[2]) == 0x49 &&
1504 GETJOCTET(marker
->data
[3]) == 0x46 &&
1505 GETJOCTET(marker
->data
[4]) == 0)
1506 continue; /* reject duplicate JFIF */
1507 if (dstinfo
->write_Adobe_marker
&&
1508 marker
->marker
== JPEG_APP0
+14 &&
1509 marker
->data_length
>= 5 &&
1510 GETJOCTET(marker
->data
[0]) == 0x41 &&
1511 GETJOCTET(marker
->data
[1]) == 0x64 &&
1512 GETJOCTET(marker
->data
[2]) == 0x6F &&
1513 GETJOCTET(marker
->data
[3]) == 0x62 &&
1514 GETJOCTET(marker
->data
[4]) == 0x65)
1515 continue; /* reject duplicate Adobe */
1516 #ifdef NEED_FAR_POINTERS
1517 /* We could use jpeg_write_marker if the data weren't FAR... */
1520 jpeg_write_m_header(dstinfo
, marker
->marker
, marker
->data_length
);
1521 for (i
= 0; i
< marker
->data_length
; i
++)
1522 jpeg_write_m_byte(dstinfo
, marker
->data
[i
]);
1525 jpeg_write_marker(dstinfo
, marker
->marker
,
1526 marker
->data
, marker
->data_length
);