4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
7 * Copyright (C) 2010, D. R. Commander.
8 * For conditions of distribution and use, see the accompanying README file.
10 * This file contains image transformation routines and other utility code
11 * used by the jpegtran sample application. These are NOT part of the core
12 * JPEG library. But we keep these routines separate from jpegtran.c to
13 * ease the task of maintaining jpegtran-like programs that have other user
17 #include <sal/config.h>
22 #include "transupp.h" /* My own external interface */
25 /* Definition of jdiv_round_up is copied here from jutils.c in jpeg-8c.tar.gz,
26 just as the rest of this file appears to be copied here from transupp.c in
29 jdiv_round_up (long a
, long b
)
30 /* Compute a/b rounded up to next integer, ie, ceil(a/b) */
31 /* Assumes a >= 0, b > 0 */
33 return (a
+ b
- 1) / b
;
36 #if JPEG_LIB_VERSION >= 70
37 #define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
38 #define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
40 #define dstinfo_min_DCT_h_scaled_size DCTSIZE
41 #define dstinfo_min_DCT_v_scaled_size DCTSIZE
45 #if TRANSFORMS_SUPPORTED
48 * Lossless image transformation routines. These routines work on DCT
49 * coefficient arrays and thus do not require any lossy decompression
50 * or recompression of the image.
51 * Thanks to Guido Vollbeding for the initial design and code of this feature,
52 * and to Ben Jackson for introducing the cropping feature.
54 * Horizontal flipping is done in-place, using a single top-to-bottom
55 * pass through the virtual source array. It will thus be much the
56 * fastest option for images larger than main memory.
58 * The other routines require a set of destination virtual arrays, so they
59 * need twice as much memory as jpegtran normally does. The destination
60 * arrays are always written in normal scan order (top to bottom) because
61 * the virtual array manager expects this. The source arrays will be scanned
62 * in the corresponding order, which means multiple passes through the source
63 * arrays for most of the transforms. That could result in much thrashing
64 * if the image is larger than main memory.
66 * If cropping or trimming is involved, the destination arrays may be smaller
67 * than the source arrays. Note it is not possible to do horizontal flip
68 * in-place when a nonzero Y crop offset is specified, since we'd have to move
69 * data from one block row to another but the virtual array manager doesn't
70 * guarantee we can touch more than one row at a time. So in that case,
71 * we have to use a separate destination array.
73 * Some notes about the operating environment of the individual transform
75 * 1. Both the source and destination virtual arrays are allocated from the
76 * source JPEG object, and therefore should be manipulated by calling the
77 * source's memory manager.
78 * 2. The destination's component count should be used. It may be smaller
79 * than the source's when forcing to grayscale.
80 * 3. Likewise the destination's sampling factors should be used. When
81 * forcing to grayscale the destination's sampling factors will be all 1,
82 * and we may as well take that as the effective iMCU size.
83 * 4. When "trim" is in effect, the destination's dimensions will be the
84 * trimmed values but the source's will be untrimmed.
85 * 5. When "crop" is in effect, the destination's dimensions will be the
86 * cropped values but the source's will be uncropped. Each transform
87 * routine is responsible for picking up source data starting at the
88 * correct X and Y offset for the crop region. (The X and Y offsets
89 * passed to the transform routines are measured in iMCU blocks of the
91 * 6. All the routines assume that the source and destination buffers are
92 * padded out to a full iMCU boundary. This is true, although for the
93 * source buffer it is an undocumented property of jdcoefct.c.
96 static void lcl_jcopy_block_row (JBLOCKROW input_row
, JBLOCKROW output_row
, JDIMENSION num_blocks
)
97 /* Copy a row of coefficient blocks from one place to another. */
100 FMEMCOPY(output_row
, input_row
, num_blocks
* (DCTSIZE2
* SIZEOF(JCOEF
)));
102 JCOEFPTR inptr
, outptr
;
105 inptr
= (JCOEFPTR
) input_row
;
106 outptr
= (JCOEFPTR
) output_row
;
107 for (count
= (long) num_blocks
* DCTSIZE2
; count
> 0; count
--) {
108 *outptr
++ = *inptr
++;
114 do_crop (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
115 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
116 jvirt_barray_ptr
*src_coef_arrays
,
117 jvirt_barray_ptr
*dst_coef_arrays
)
118 /* Crop. This is only used when no rotate/flip is requested with the crop. */
120 JDIMENSION dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
122 JBLOCKARRAY src_buffer
, dst_buffer
;
123 jpeg_component_info
*compptr
;
125 /* We simply have to copy the right amount of data (the destination's
126 * image size) starting at the given X and Y offsets in the source.
128 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
129 compptr
= dstinfo
->comp_info
+ ci
;
130 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
131 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
132 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
133 dst_blk_y
+= compptr
->v_samp_factor
) {
134 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
135 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
136 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
137 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
138 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
139 dst_blk_y
+ y_crop_blocks
,
140 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
141 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
142 lcl_jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
143 dst_buffer
[offset_y
],
144 compptr
->width_in_blocks
);
152 do_flip_h_no_crop (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
153 JDIMENSION x_crop_offset
,
154 jvirt_barray_ptr
*src_coef_arrays
)
155 /* Horizontal flip; done in-place, so no separate dest array is required.
156 * NB: this only works when y_crop_offset is zero.
159 JDIMENSION MCU_cols
, comp_width
, blk_x
, blk_y
, x_crop_blocks
;
164 jpeg_component_info
*compptr
;
166 /* Horizontal mirroring of DCT blocks is accomplished by swapping
167 * pairs of blocks in-place. Within a DCT block, we perform horizontal
168 * mirroring by changing the signs of odd-numbered columns.
169 * Partial iMCUs at the right edge are left untouched.
171 MCU_cols
= srcinfo
->output_width
/
172 (dstinfo
->max_h_samp_factor
* dstinfo_min_DCT_h_scaled_size
);
174 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
175 compptr
= dstinfo
->comp_info
+ ci
;
176 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
177 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
178 for (blk_y
= 0; blk_y
< compptr
->height_in_blocks
;
179 blk_y
+= compptr
->v_samp_factor
) {
180 buffer
= (*srcinfo
->mem
->access_virt_barray
)
181 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], blk_y
,
182 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
183 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
184 /* Do the mirroring */
185 for (blk_x
= 0; blk_x
* 2 < comp_width
; blk_x
++) {
186 ptr1
= buffer
[offset_y
][blk_x
];
187 ptr2
= buffer
[offset_y
][comp_width
- blk_x
- 1];
188 /* this unrolled loop doesn't need to know which row it's on... */
189 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
190 temp1
= *ptr1
; /* swap even column */
194 temp1
= *ptr1
; /* swap odd column with sign change */
200 if (x_crop_blocks
> 0) {
201 /* Now left-justify the portion of the data to be kept.
202 * We can't use a single lcl_jcopy_block_row() call because that routine
203 * depends on memcpy(), whose behavior is unspecified for overlapping
204 * source and destination areas. Sigh.
206 for (blk_x
= 0; blk_x
< compptr
->width_in_blocks
; blk_x
++) {
207 lcl_jcopy_block_row(buffer
[offset_y
] + blk_x
+ x_crop_blocks
,
208 buffer
[offset_y
] + blk_x
,
219 do_flip_h (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
220 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
221 jvirt_barray_ptr
*src_coef_arrays
,
222 jvirt_barray_ptr
*dst_coef_arrays
)
223 /* Horizontal flip in general cropping case */
225 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
226 JDIMENSION x_crop_blocks
, y_crop_blocks
;
228 JBLOCKARRAY src_buffer
, dst_buffer
;
229 JBLOCKROW src_row_ptr
, dst_row_ptr
;
230 JCOEFPTR src_ptr
, dst_ptr
;
231 jpeg_component_info
*compptr
;
233 /* Here we must output into a separate array because we can't touch
234 * different rows of a single virtual array simultaneously. Otherwise,
235 * this is essentially the same as the routine above.
237 MCU_cols
= srcinfo
->output_width
/
238 (dstinfo
->max_h_samp_factor
* dstinfo_min_DCT_h_scaled_size
);
240 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
241 compptr
= dstinfo
->comp_info
+ ci
;
242 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
243 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
244 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
245 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
246 dst_blk_y
+= compptr
->v_samp_factor
) {
247 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
248 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
249 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
250 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
251 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
252 dst_blk_y
+ y_crop_blocks
,
253 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
254 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
255 dst_row_ptr
= dst_buffer
[offset_y
];
256 src_row_ptr
= src_buffer
[offset_y
];
257 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
258 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
259 /* Do the mirrorable blocks */
260 dst_ptr
= dst_row_ptr
[dst_blk_x
];
261 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
262 /* this unrolled loop doesn't need to know which row it's on... */
263 for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
264 *dst_ptr
++ = *src_ptr
++; /* copy even column */
265 *dst_ptr
++ = - *src_ptr
++; /* copy odd column with sign change */
268 /* Copy last partial block(s) verbatim */
269 lcl_jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
270 dst_row_ptr
+ dst_blk_x
,
281 do_flip_v (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
282 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
283 jvirt_barray_ptr
*src_coef_arrays
,
284 jvirt_barray_ptr
*dst_coef_arrays
)
287 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
288 JDIMENSION x_crop_blocks
, y_crop_blocks
;
289 int ci
, i
, j
, offset_y
;
290 JBLOCKARRAY src_buffer
, dst_buffer
;
291 JBLOCKROW src_row_ptr
, dst_row_ptr
;
292 JCOEFPTR src_ptr
, dst_ptr
;
293 jpeg_component_info
*compptr
;
295 /* We output into a separate array because we can't touch different
296 * rows of the source virtual array simultaneously. Otherwise, this
297 * is a pretty straightforward analog of horizontal flip.
298 * Within a DCT block, vertical mirroring is done by changing the signs
299 * of odd-numbered rows.
300 * Partial iMCUs at the bottom edge are copied verbatim.
302 MCU_rows
= srcinfo
->output_height
/
303 (dstinfo
->max_v_samp_factor
* dstinfo_min_DCT_v_scaled_size
);
305 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
306 compptr
= dstinfo
->comp_info
+ ci
;
307 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
308 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
309 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
310 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
311 dst_blk_y
+= compptr
->v_samp_factor
) {
312 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
313 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
314 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
315 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
316 /* Row is within the mirrorable area. */
317 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
318 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
319 comp_height
- y_crop_blocks
- dst_blk_y
-
320 (JDIMENSION
) compptr
->v_samp_factor
,
321 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
323 /* Bottom-edge blocks will be copied verbatim. */
324 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
325 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
326 dst_blk_y
+ y_crop_blocks
,
327 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
329 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
330 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
331 /* Row is within the mirrorable area. */
332 dst_row_ptr
= dst_buffer
[offset_y
];
333 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
334 src_row_ptr
+= x_crop_blocks
;
335 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
337 dst_ptr
= dst_row_ptr
[dst_blk_x
];
338 src_ptr
= src_row_ptr
[dst_blk_x
];
339 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
341 for (j
= 0; j
< DCTSIZE
; j
++)
342 *dst_ptr
++ = *src_ptr
++;
343 /* copy odd row with sign change */
344 for (j
= 0; j
< DCTSIZE
; j
++)
345 *dst_ptr
++ = - *src_ptr
++;
349 /* Just copy row verbatim. */
350 lcl_jcopy_block_row(src_buffer
[offset_y
] + x_crop_blocks
,
351 dst_buffer
[offset_y
],
352 compptr
->width_in_blocks
);
361 do_transpose (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
362 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
363 jvirt_barray_ptr
*src_coef_arrays
,
364 jvirt_barray_ptr
*dst_coef_arrays
)
365 /* Transpose source into destination */
367 JDIMENSION dst_blk_x
, dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
368 int ci
, i
, j
, offset_x
, offset_y
;
369 JBLOCKARRAY src_buffer
, dst_buffer
;
370 JCOEFPTR src_ptr
, dst_ptr
;
371 jpeg_component_info
*compptr
;
373 /* Transposing pixels within a block just requires transposing the
375 * Partial iMCUs at the edges require no special treatment; we simply
376 * process all the available DCT blocks for every component.
378 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
379 compptr
= dstinfo
->comp_info
+ ci
;
380 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
381 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
382 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
383 dst_blk_y
+= compptr
->v_samp_factor
) {
384 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
385 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
386 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
387 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
388 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
389 dst_blk_x
+= compptr
->h_samp_factor
) {
390 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
391 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
392 dst_blk_x
+ x_crop_blocks
,
393 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
394 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
395 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
396 src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
+ y_crop_blocks
];
397 for (i
= 0; i
< DCTSIZE
; i
++)
398 for (j
= 0; j
< DCTSIZE
; j
++)
399 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
409 do_rot_90 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
410 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
411 jvirt_barray_ptr
*src_coef_arrays
,
412 jvirt_barray_ptr
*dst_coef_arrays
)
413 /* 90 degree rotation is equivalent to
414 * 1. Transposing the image;
415 * 2. Horizontal mirroring.
416 * These two steps are merged into a single processing routine.
419 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
420 JDIMENSION x_crop_blocks
, y_crop_blocks
;
421 int ci
, i
, j
, offset_x
, offset_y
;
422 JBLOCKARRAY src_buffer
, dst_buffer
;
423 JCOEFPTR src_ptr
, dst_ptr
;
424 jpeg_component_info
*compptr
;
426 /* Because of the horizontal mirror step, we can't process partial iMCUs
427 * at the (output) right edge properly. They just get transposed and
430 MCU_cols
= srcinfo
->output_height
/
431 (dstinfo
->max_h_samp_factor
* dstinfo_min_DCT_h_scaled_size
);
433 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
434 compptr
= dstinfo
->comp_info
+ ci
;
435 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
436 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
437 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
438 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
439 dst_blk_y
+= compptr
->v_samp_factor
) {
440 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
441 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
442 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
443 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
444 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
445 dst_blk_x
+= compptr
->h_samp_factor
) {
446 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
447 /* Block is within the mirrorable area. */
448 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
449 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
450 comp_width
- x_crop_blocks
- dst_blk_x
-
451 (JDIMENSION
) compptr
->h_samp_factor
,
452 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
454 /* Edge blocks are transposed but not mirrored. */
455 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
456 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
457 dst_blk_x
+ x_crop_blocks
,
458 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
460 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
461 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
462 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
463 /* Block is within the mirrorable area. */
464 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
465 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
466 for (i
= 0; i
< DCTSIZE
; i
++) {
467 for (j
= 0; j
< DCTSIZE
; j
++)
468 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
470 for (j
= 0; j
< DCTSIZE
; j
++)
471 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
474 /* Edge blocks are transposed but not mirrored. */
475 src_ptr
= src_buffer
[offset_x
]
476 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
477 for (i
= 0; i
< DCTSIZE
; i
++)
478 for (j
= 0; j
< DCTSIZE
; j
++)
479 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
490 do_rot_270 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
491 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
492 jvirt_barray_ptr
*src_coef_arrays
,
493 jvirt_barray_ptr
*dst_coef_arrays
)
494 /* 270 degree rotation is equivalent to
495 * 1. Horizontal mirroring;
496 * 2. Transposing the image.
497 * These two steps are merged into a single processing routine.
500 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
501 JDIMENSION x_crop_blocks
, y_crop_blocks
;
502 int ci
, i
, j
, offset_x
, offset_y
;
503 JBLOCKARRAY src_buffer
, dst_buffer
;
504 JCOEFPTR src_ptr
, dst_ptr
;
505 jpeg_component_info
*compptr
;
507 /* Because of the horizontal mirror step, we can't process partial iMCUs
508 * at the (output) bottom edge properly. They just get transposed and
511 MCU_rows
= srcinfo
->output_width
/
512 (dstinfo
->max_v_samp_factor
* dstinfo_min_DCT_v_scaled_size
);
514 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
515 compptr
= dstinfo
->comp_info
+ ci
;
516 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
517 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
518 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
519 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
520 dst_blk_y
+= compptr
->v_samp_factor
) {
521 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
522 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
523 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
524 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
525 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
526 dst_blk_x
+= compptr
->h_samp_factor
) {
527 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
528 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
529 dst_blk_x
+ x_crop_blocks
,
530 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
531 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
532 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
533 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
534 /* Block is within the mirrorable area. */
535 src_ptr
= src_buffer
[offset_x
]
536 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
537 for (i
= 0; i
< DCTSIZE
; i
++) {
538 for (j
= 0; j
< DCTSIZE
; j
++) {
539 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
541 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
545 /* Edge blocks are transposed but not mirrored. */
546 src_ptr
= src_buffer
[offset_x
]
547 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
548 for (i
= 0; i
< DCTSIZE
; i
++)
549 for (j
= 0; j
< DCTSIZE
; j
++)
550 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
561 do_rot_180 (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
562 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
563 jvirt_barray_ptr
*src_coef_arrays
,
564 jvirt_barray_ptr
*dst_coef_arrays
)
565 /* 180 degree rotation is equivalent to
566 * 1. Vertical mirroring;
567 * 2. Horizontal mirroring.
568 * These two steps are merged into a single processing routine.
571 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
572 JDIMENSION x_crop_blocks
, y_crop_blocks
;
573 int ci
, i
, j
, offset_y
;
574 JBLOCKARRAY src_buffer
, dst_buffer
;
575 JBLOCKROW src_row_ptr
, dst_row_ptr
;
576 JCOEFPTR src_ptr
, dst_ptr
;
577 jpeg_component_info
*compptr
;
579 MCU_cols
= srcinfo
->output_width
/
580 (dstinfo
->max_h_samp_factor
* dstinfo_min_DCT_h_scaled_size
);
581 MCU_rows
= srcinfo
->output_height
/
582 (dstinfo
->max_v_samp_factor
* dstinfo_min_DCT_v_scaled_size
);
584 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
585 compptr
= dstinfo
->comp_info
+ ci
;
586 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
587 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
588 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
589 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
590 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
591 dst_blk_y
+= compptr
->v_samp_factor
) {
592 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
593 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
594 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
595 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
596 /* Row is within the vertically mirrorable area. */
597 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
598 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
599 comp_height
- y_crop_blocks
- dst_blk_y
-
600 (JDIMENSION
) compptr
->v_samp_factor
,
601 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
603 /* Bottom-edge rows are only mirrored horizontally. */
604 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
605 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
606 dst_blk_y
+ y_crop_blocks
,
607 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
609 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
610 dst_row_ptr
= dst_buffer
[offset_y
];
611 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
612 /* Row is within the mirrorable area. */
613 src_row_ptr
= src_buffer
[compptr
->v_samp_factor
- offset_y
- 1];
614 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
615 dst_ptr
= dst_row_ptr
[dst_blk_x
];
616 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
617 /* Process the blocks that can be mirrored both ways. */
618 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
619 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
620 /* For even row, negate every odd column. */
621 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
622 *dst_ptr
++ = *src_ptr
++;
623 *dst_ptr
++ = - *src_ptr
++;
625 /* For odd row, negate every even column. */
626 for (j
= 0; j
< DCTSIZE
; j
+= 2) {
627 *dst_ptr
++ = - *src_ptr
++;
628 *dst_ptr
++ = *src_ptr
++;
632 /* Any remaining right-edge blocks are only mirrored vertically. */
633 src_ptr
= src_row_ptr
[x_crop_blocks
+ dst_blk_x
];
634 for (i
= 0; i
< DCTSIZE
; i
+= 2) {
635 for (j
= 0; j
< DCTSIZE
; j
++)
636 *dst_ptr
++ = *src_ptr
++;
637 for (j
= 0; j
< DCTSIZE
; j
++)
638 *dst_ptr
++ = - *src_ptr
++;
643 /* Remaining rows are just mirrored horizontally. */
644 src_row_ptr
= src_buffer
[offset_y
];
645 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
; dst_blk_x
++) {
646 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
647 /* Process the blocks that can be mirrored. */
648 dst_ptr
= dst_row_ptr
[dst_blk_x
];
649 src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
650 for (i
= 0; i
< DCTSIZE2
; i
+= 2) {
651 *dst_ptr
++ = *src_ptr
++;
652 *dst_ptr
++ = - *src_ptr
++;
655 /* Any remaining right-edge blocks are only copied. */
656 lcl_jcopy_block_row(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
657 dst_row_ptr
+ dst_blk_x
,
669 do_transverse (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
670 JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
671 jvirt_barray_ptr
*src_coef_arrays
,
672 jvirt_barray_ptr
*dst_coef_arrays
)
673 /* Transverse transpose is equivalent to
674 * 1. 180 degree rotation;
677 * 1. Horizontal mirroring;
679 * 3. Horizontal mirroring.
680 * These steps are merged into a single processing routine.
683 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
684 JDIMENSION x_crop_blocks
, y_crop_blocks
;
685 int ci
, i
, j
, offset_x
, offset_y
;
686 JBLOCKARRAY src_buffer
, dst_buffer
;
687 JCOEFPTR src_ptr
, dst_ptr
;
688 jpeg_component_info
*compptr
;
690 MCU_cols
= srcinfo
->output_height
/
691 (dstinfo
->max_h_samp_factor
* dstinfo_min_DCT_h_scaled_size
);
692 MCU_rows
= srcinfo
->output_width
/
693 (dstinfo
->max_v_samp_factor
* dstinfo_min_DCT_v_scaled_size
);
695 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
696 compptr
= dstinfo
->comp_info
+ ci
;
697 comp_width
= MCU_cols
* compptr
->h_samp_factor
;
698 comp_height
= MCU_rows
* compptr
->v_samp_factor
;
699 x_crop_blocks
= x_crop_offset
* compptr
->h_samp_factor
;
700 y_crop_blocks
= y_crop_offset
* compptr
->v_samp_factor
;
701 for (dst_blk_y
= 0; dst_blk_y
< compptr
->height_in_blocks
;
702 dst_blk_y
+= compptr
->v_samp_factor
) {
703 dst_buffer
= (*srcinfo
->mem
->access_virt_barray
)
704 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
705 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
706 for (offset_y
= 0; offset_y
< compptr
->v_samp_factor
; offset_y
++) {
707 for (dst_blk_x
= 0; dst_blk_x
< compptr
->width_in_blocks
;
708 dst_blk_x
+= compptr
->h_samp_factor
) {
709 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
710 /* Block is within the mirrorable area. */
711 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
712 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
713 comp_width
- x_crop_blocks
- dst_blk_x
-
714 (JDIMENSION
) compptr
->h_samp_factor
,
715 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
717 src_buffer
= (*srcinfo
->mem
->access_virt_barray
)
718 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
719 dst_blk_x
+ x_crop_blocks
,
720 (JDIMENSION
) compptr
->h_samp_factor
, FALSE
);
722 for (offset_x
= 0; offset_x
< compptr
->h_samp_factor
; offset_x
++) {
723 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
724 if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
725 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
726 /* Block is within the mirrorable area. */
727 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
728 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
729 for (i
= 0; i
< DCTSIZE
; i
++) {
730 for (j
= 0; j
< DCTSIZE
; j
++) {
731 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
733 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
736 for (j
= 0; j
< DCTSIZE
; j
++) {
737 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
739 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
743 /* Right-edge blocks are mirrored in y only */
744 src_ptr
= src_buffer
[offset_x
]
745 [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
746 for (i
= 0; i
< DCTSIZE
; i
++) {
747 for (j
= 0; j
< DCTSIZE
; j
++) {
748 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
750 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
755 if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
756 /* Bottom-edge blocks are mirrored in x only */
757 src_ptr
= src_buffer
[compptr
->h_samp_factor
- offset_x
- 1]
758 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
759 for (i
= 0; i
< DCTSIZE
; i
++) {
760 for (j
= 0; j
< DCTSIZE
; j
++)
761 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
763 for (j
= 0; j
< DCTSIZE
; j
++)
764 dst_ptr
[j
*DCTSIZE
+i
] = -src_ptr
[i
*DCTSIZE
+j
];
767 /* At lower right corner, just transpose, no mirroring */
768 src_ptr
= src_buffer
[offset_x
]
769 [dst_blk_y
+ offset_y
+ y_crop_blocks
];
770 for (i
= 0; i
< DCTSIZE
; i
++)
771 for (j
= 0; j
< DCTSIZE
; j
++)
772 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
783 /* Trim off any partial iMCUs on the indicated destination edge */
786 trim_right_edge (jpeg_transform_info
*info
, JDIMENSION full_width
)
790 MCU_cols
= info
->output_width
/ info
->iMCU_sample_width
;
791 if (MCU_cols
> 0 && info
->x_crop_offset
+ MCU_cols
==
792 full_width
/ info
->iMCU_sample_width
)
793 info
->output_width
= MCU_cols
* info
->iMCU_sample_width
;
797 trim_bottom_edge (jpeg_transform_info
*info
, JDIMENSION full_height
)
801 MCU_rows
= info
->output_height
/ info
->iMCU_sample_height
;
802 if (MCU_rows
> 0 && info
->y_crop_offset
+ MCU_rows
==
803 full_height
/ info
->iMCU_sample_height
)
804 info
->output_height
= MCU_rows
* info
->iMCU_sample_height
;
808 /* Request any required workspace.
810 * This routine figures out the size that the output image will be
811 * (which implies that all the transform parameters must be set before
814 * We allocate the workspace virtual arrays from the source decompression
815 * object, so that all the arrays (both the original data and the workspace)
816 * will be taken into account while making memory management decisions.
817 * Hence, this routine must be called after jpeg_read_header (which reads
818 * the image dimensions) and before jpeg_read_coefficients (which realizes
819 * the source's virtual arrays).
821 * This function returns FALSE right away if -perfect is given
822 * and transformation is not perfect. Otherwise returns TRUE.
826 jtransform_request_workspace (j_decompress_ptr srcinfo
,
827 jpeg_transform_info
*info
)
829 jvirt_barray_ptr
*coef_arrays
;
830 boolean need_workspace
, transpose_it
;
831 jpeg_component_info
*compptr
;
832 JDIMENSION xoffset
, yoffset
;
833 JDIMENSION width_in_iMCUs
, height_in_iMCUs
;
834 JDIMENSION width_in_blocks
, height_in_blocks
;
835 int ci
, h_samp_factor
, v_samp_factor
;
837 /* Determine number of components in output image */
838 if (info
->force_grayscale
&&
839 srcinfo
->jpeg_color_space
== JCS_YCbCr
&&
840 srcinfo
->num_components
== 3)
841 /* We'll only process the first component */
842 info
->num_components
= 1;
844 /* Process all the components */
845 info
->num_components
= srcinfo
->num_components
;
847 /* Compute output image dimensions and related values. */
848 #if JPEG_LIB_VERSION >= 80
849 jpeg_core_output_dimensions(srcinfo
);
851 srcinfo
->output_width
= srcinfo
->image_width
;
852 srcinfo
->output_height
= srcinfo
->image_height
;
855 /* Return right away if -perfect is given and transformation is not perfect.
858 if (info
->num_components
== 1) {
859 if (!jtransform_perfect_transform(srcinfo
->output_width
,
860 srcinfo
->output_height
,
861 srcinfo
->min_DCT_h_scaled_size_
,
862 srcinfo
->min_DCT_v_scaled_size_
,
866 if (!jtransform_perfect_transform(srcinfo
->output_width
,
867 srcinfo
->output_height
,
868 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size_
,
869 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size_
,
875 /* If there is only one output component, force the iMCU size to be 1;
876 * else use the source iMCU size. (This allows us to do the right thing
877 * when reducing color to grayscale, and also provides a handy way of
878 * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
880 switch (info
->transform
) {
881 case JXFORM_TRANSPOSE
:
882 case JXFORM_TRANSVERSE
:
885 info
->output_width
= srcinfo
->output_height
;
886 info
->output_height
= srcinfo
->output_width
;
887 if (info
->num_components
== 1) {
888 info
->iMCU_sample_width
= srcinfo
->min_DCT_v_scaled_size_
;
889 info
->iMCU_sample_height
= srcinfo
->min_DCT_h_scaled_size_
;
891 info
->iMCU_sample_width
=
892 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size_
;
893 info
->iMCU_sample_height
=
894 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size_
;
898 info
->output_width
= srcinfo
->output_width
;
899 info
->output_height
= srcinfo
->output_height
;
900 if (info
->num_components
== 1) {
901 info
->iMCU_sample_width
= srcinfo
->min_DCT_h_scaled_size_
;
902 info
->iMCU_sample_height
= srcinfo
->min_DCT_v_scaled_size_
;
904 info
->iMCU_sample_width
=
905 srcinfo
->max_h_samp_factor
* srcinfo
->min_DCT_h_scaled_size_
;
906 info
->iMCU_sample_height
=
907 srcinfo
->max_v_samp_factor
* srcinfo
->min_DCT_v_scaled_size_
;
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_CONVERSION_NOTIMPL
);
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_CONVERSION_NOTIMPL
);
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 */
944 if (info
->crop_width_set
== JCROP_FORCE
)
945 info
->output_width
= info
->crop_width
;
948 info
->crop_width
+ (xoffset
% info
->iMCU_sample_width
);
949 if (info
->crop_height_set
== JCROP_FORCE
)
950 info
->output_height
= info
->crop_height
;
952 info
->output_height
=
953 info
->crop_height
+ (yoffset
% info
->iMCU_sample_height
);
954 /* Save x/y offsets measured in iMCUs */
955 info
->x_crop_offset
= xoffset
/ info
->iMCU_sample_width
;
956 info
->y_crop_offset
= yoffset
/ info
->iMCU_sample_height
;
958 info
->x_crop_offset
= 0;
959 info
->y_crop_offset
= 0;
962 /* Figure out whether we need workspace arrays,
963 * and if so whether they are transposed relative to the source.
965 need_workspace
= FALSE
;
966 transpose_it
= FALSE
;
967 switch (info
->transform
) {
969 if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0)
970 need_workspace
= TRUE
;
971 /* No workspace needed if neither cropping nor transforming */
975 trim_right_edge(info
, srcinfo
->output_width
);
976 if (info
->y_crop_offset
!= 0 || info
->slow_hflip
)
977 need_workspace
= TRUE
;
978 /* do_flip_h_no_crop doesn't need a workspace array */
982 trim_bottom_edge(info
, srcinfo
->output_height
);
983 /* Need workspace arrays having same dimensions as source image. */
984 need_workspace
= TRUE
;
986 case JXFORM_TRANSPOSE
:
987 /* transpose does NOT have to trim anything */
988 /* Need workspace arrays having transposed dimensions. */
989 need_workspace
= TRUE
;
992 case JXFORM_TRANSVERSE
:
994 trim_right_edge(info
, srcinfo
->output_height
);
995 trim_bottom_edge(info
, srcinfo
->output_width
);
997 /* Need workspace arrays having transposed dimensions. */
998 need_workspace
= TRUE
;
1003 trim_right_edge(info
, srcinfo
->output_height
);
1004 /* Need workspace arrays having transposed dimensions. */
1005 need_workspace
= TRUE
;
1006 transpose_it
= TRUE
;
1008 case JXFORM_ROT_180
:
1010 trim_right_edge(info
, srcinfo
->output_width
);
1011 trim_bottom_edge(info
, srcinfo
->output_height
);
1013 /* Need workspace arrays having same dimensions as source image. */
1014 need_workspace
= TRUE
;
1016 case JXFORM_ROT_270
:
1018 trim_bottom_edge(info
, srcinfo
->output_width
);
1019 /* Need workspace arrays having transposed dimensions. */
1020 need_workspace
= TRUE
;
1021 transpose_it
= TRUE
;
1025 /* Allocate workspace if needed.
1026 * Note that we allocate arrays padded out to the next iMCU boundary,
1027 * so that transform routines need not worry about missing edge blocks.
1029 if (need_workspace
) {
1030 coef_arrays
= (jvirt_barray_ptr
*)
1031 (*srcinfo
->mem
->alloc_small
) ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
,
1032 SIZEOF(jvirt_barray_ptr
) * info
->num_components
);
1033 width_in_iMCUs
= (JDIMENSION
)
1034 jdiv_round_up((long) info
->output_width
,
1035 (long) info
->iMCU_sample_width
);
1036 height_in_iMCUs
= (JDIMENSION
)
1037 jdiv_round_up((long) info
->output_height
,
1038 (long) info
->iMCU_sample_height
);
1039 for (ci
= 0; ci
< info
->num_components
; ci
++) {
1040 compptr
= srcinfo
->comp_info
+ ci
;
1041 if (info
->num_components
== 1) {
1042 /* we're going to force samp factors to 1x1 in this case */
1043 h_samp_factor
= v_samp_factor
= 1;
1044 } else if (transpose_it
) {
1045 h_samp_factor
= compptr
->v_samp_factor
;
1046 v_samp_factor
= compptr
->h_samp_factor
;
1048 h_samp_factor
= compptr
->h_samp_factor
;
1049 v_samp_factor
= compptr
->v_samp_factor
;
1051 width_in_blocks
= width_in_iMCUs
* h_samp_factor
;
1052 height_in_blocks
= height_in_iMCUs
* v_samp_factor
;
1053 coef_arrays
[ci
] = (*srcinfo
->mem
->request_virt_barray
)
1054 ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
, FALSE
,
1055 width_in_blocks
, height_in_blocks
, (JDIMENSION
) v_samp_factor
);
1057 info
->workspace_coef_arrays
= coef_arrays
;
1059 info
->workspace_coef_arrays
= NULL
;
1065 /* Transpose destination image parameters */
1068 transpose_critical_parameters (j_compress_ptr dstinfo
)
1070 int tblno
, i
, j
, ci
, itemp
;
1071 jpeg_component_info
*compptr
;
1072 JQUANT_TBL
*qtblptr
;
1076 /* Transpose image dimensions */
1077 jtemp
= dstinfo
->image_width
;
1078 dstinfo
->image_width
= dstinfo
->image_height
;
1079 dstinfo
->image_height
= jtemp
;
1080 #if JPEG_LIB_VERSION >= 70
1081 itemp
= dstinfo
->min_DCT_h_scaled_size
;
1082 dstinfo
->min_DCT_h_scaled_size
= dstinfo
->min_DCT_v_scaled_size
;
1083 dstinfo
->min_DCT_v_scaled_size
= itemp
;
1086 /* Transpose sampling factors */
1087 for (ci
= 0; ci
< dstinfo
->num_components
; ci
++) {
1088 compptr
= dstinfo
->comp_info
+ ci
;
1089 itemp
= compptr
->h_samp_factor
;
1090 compptr
->h_samp_factor
= compptr
->v_samp_factor
;
1091 compptr
->v_samp_factor
= itemp
;
1094 /* Transpose quantization tables */
1095 for (tblno
= 0; tblno
< NUM_QUANT_TBLS
; tblno
++) {
1096 qtblptr
= dstinfo
->quant_tbl_ptrs
[tblno
];
1097 if (qtblptr
!= NULL
) {
1098 for (i
= 0; i
< DCTSIZE
; i
++) {
1099 for (j
= 0; j
< i
; j
++) {
1100 qtemp
= qtblptr
->quantval
[i
*DCTSIZE
+j
];
1101 qtblptr
->quantval
[i
*DCTSIZE
+j
] = qtblptr
->quantval
[j
*DCTSIZE
+i
];
1102 qtblptr
->quantval
[j
*DCTSIZE
+i
] = qtemp
;
1110 /* Adjust Exif image parameters.
1112 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1115 #if JPEG_LIB_VERSION >= 70
1117 adjust_exif_parameters (JOCTET FAR
* data
, unsigned int length
,
1118 JDIMENSION new_width
, JDIMENSION new_height
)
1120 boolean is_motorola
; /* Flag for byte order */
1121 unsigned int number_of_tags
, tagnum
;
1122 unsigned int firstoffset
, offset
;
1123 JDIMENSION new_value
;
1125 if (length
< 12) return; /* Length of an IFD entry */
1127 /* Discover byte order */
1128 if (GETJOCTET(data
[0]) == 0x49 && GETJOCTET(data
[1]) == 0x49)
1129 is_motorola
= FALSE
;
1130 else if (GETJOCTET(data
[0]) == 0x4D && GETJOCTET(data
[1]) == 0x4D)
1135 /* Check Tag Mark */
1137 if (GETJOCTET(data
[2]) != 0) return;
1138 if (GETJOCTET(data
[3]) != 0x2A) return;
1140 if (GETJOCTET(data
[3]) != 0) return;
1141 if (GETJOCTET(data
[2]) != 0x2A) return;
1144 /* Get first IFD offset (offset to IFD0) */
1146 if (GETJOCTET(data
[4]) != 0) return;
1147 if (GETJOCTET(data
[5]) != 0) return;
1148 firstoffset
= GETJOCTET(data
[6]);
1150 firstoffset
+= GETJOCTET(data
[7]);
1152 if (GETJOCTET(data
[7]) != 0) return;
1153 if (GETJOCTET(data
[6]) != 0) return;
1154 firstoffset
= GETJOCTET(data
[5]);
1156 firstoffset
+= GETJOCTET(data
[4]);
1158 if (firstoffset
> length
- 2) return; /* check end of data segment */
1160 /* Get the number of directory entries contained in this IFD */
1162 number_of_tags
= GETJOCTET(data
[firstoffset
]);
1163 number_of_tags
<<= 8;
1164 number_of_tags
+= GETJOCTET(data
[firstoffset
+1]);
1166 number_of_tags
= GETJOCTET(data
[firstoffset
+1]);
1167 number_of_tags
<<= 8;
1168 number_of_tags
+= GETJOCTET(data
[firstoffset
]);
1170 if (number_of_tags
== 0) return;
1173 /* Search for ExifSubIFD offset Tag in IFD0 */
1175 if (firstoffset
> length
- 12) return; /* check end of data segment */
1176 /* Get Tag number */
1178 tagnum
= GETJOCTET(data
[firstoffset
]);
1180 tagnum
+= GETJOCTET(data
[firstoffset
+1]);
1182 tagnum
= GETJOCTET(data
[firstoffset
+1]);
1184 tagnum
+= GETJOCTET(data
[firstoffset
]);
1186 if (tagnum
== 0x8769) break; /* found ExifSubIFD offset Tag */
1187 if (--number_of_tags
== 0) return;
1191 /* Get the ExifSubIFD offset */
1193 if (GETJOCTET(data
[firstoffset
+8]) != 0) return;
1194 if (GETJOCTET(data
[firstoffset
+9]) != 0) return;
1195 offset
= GETJOCTET(data
[firstoffset
+10]);
1197 offset
+= GETJOCTET(data
[firstoffset
+11]);
1199 if (GETJOCTET(data
[firstoffset
+11]) != 0) return;
1200 if (GETJOCTET(data
[firstoffset
+10]) != 0) return;
1201 offset
= GETJOCTET(data
[firstoffset
+9]);
1203 offset
+= GETJOCTET(data
[firstoffset
+8]);
1205 if (offset
> length
- 2) return; /* check end of data segment */
1207 /* Get the number of directory entries contained in this SubIFD */
1209 number_of_tags
= GETJOCTET(data
[offset
]);
1210 number_of_tags
<<= 8;
1211 number_of_tags
+= GETJOCTET(data
[offset
+1]);
1213 number_of_tags
= GETJOCTET(data
[offset
+1]);
1214 number_of_tags
<<= 8;
1215 number_of_tags
+= GETJOCTET(data
[offset
]);
1217 if (number_of_tags
< 2) return;
1220 /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1222 if (offset
> length
- 12) return; /* check end of data segment */
1223 /* Get Tag number */
1225 tagnum
= GETJOCTET(data
[offset
]);
1227 tagnum
+= GETJOCTET(data
[offset
+1]);
1229 tagnum
= GETJOCTET(data
[offset
+1]);
1231 tagnum
+= GETJOCTET(data
[offset
]);
1233 if (tagnum
== 0xA002 || tagnum
== 0xA003) {
1234 if (tagnum
== 0xA002)
1235 new_value
= new_width
; /* ExifImageWidth Tag */
1237 new_value
= new_height
; /* ExifImageHeight Tag */
1239 data
[offset
+2] = 0; /* Format = unsigned long (4 octets) */
1241 data
[offset
+4] = 0; /* Number Of Components = 1 */
1247 data
[offset
+10] = (JOCTET
)((new_value
>> 8) & 0xFF);
1248 data
[offset
+11] = (JOCTET
)(new_value
& 0xFF);
1250 data
[offset
+2] = 4; /* Format = unsigned long (4 octets) */
1252 data
[offset
+4] = 1; /* Number Of Components = 1 */
1256 data
[offset
+8] = (JOCTET
)(new_value
& 0xFF);
1257 data
[offset
+9] = (JOCTET
)((new_value
>> 8) & 0xFF);
1258 data
[offset
+10] = 0;
1259 data
[offset
+11] = 0;
1263 } while (--number_of_tags
);
1268 /* Adjust output image parameters as needed.
1270 * This must be called after jpeg_copy_critical_parameters()
1271 * and before jpeg_write_coefficients().
1273 * The return value is the set of virtual coefficient arrays to be written
1274 * (either the ones allocated by jtransform_request_workspace, or the
1275 * original source data arrays). The caller will need to pass this value
1276 * to jpeg_write_coefficients().
1279 GLOBAL(jvirt_barray_ptr
*)
1280 jtransform_adjust_parameters (j_decompress_ptr srcinfo
,
1281 j_compress_ptr dstinfo
,
1282 jvirt_barray_ptr
*src_coef_arrays
,
1283 jpeg_transform_info
*info
)
1285 /* If force-to-grayscale is requested, adjust destination parameters */
1286 if (info
->force_grayscale
) {
1287 /* First, ensure we have YCbCr or grayscale data, and that the source's
1288 * Y channel is full resolution. (No reasonable person would make Y
1289 * be less than full resolution, so actually coping with that case
1290 * isn't worth extra code space. But we check it to avoid crashing.)
1292 if (((dstinfo
->jpeg_color_space
== JCS_YCbCr
&&
1293 dstinfo
->num_components
== 3) ||
1294 (dstinfo
->jpeg_color_space
== JCS_GRAYSCALE
&&
1295 dstinfo
->num_components
== 1)) &&
1296 srcinfo
->comp_info
[0].h_samp_factor
== srcinfo
->max_h_samp_factor
&&
1297 srcinfo
->comp_info
[0].v_samp_factor
== srcinfo
->max_v_samp_factor
) {
1298 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1299 * properly. Among other things, it sets the target h_samp_factor &
1300 * v_samp_factor to 1, which typically won't match the source.
1301 * We have to preserve the source's quantization table number, however.
1303 int sv_quant_tbl_no
= dstinfo
->comp_info
[0].quant_tbl_no
;
1304 jpeg_set_colorspace(dstinfo
, JCS_GRAYSCALE
);
1305 dstinfo
->comp_info
[0].quant_tbl_no
= sv_quant_tbl_no
;
1307 /* Sorry, can't do it */
1308 ERREXIT(dstinfo
, JERR_CONVERSION_NOTIMPL
);
1310 } else if (info
->num_components
== 1) {
1311 /* For a single-component source, we force the destination sampling factors
1312 * to 1x1, with or without force_grayscale. This is useful because some
1313 * decoders choke on grayscale images with other sampling factors.
1315 dstinfo
->comp_info
[0].h_samp_factor
= 1;
1316 dstinfo
->comp_info
[0].v_samp_factor
= 1;
1319 /* Correct the destination's image dimensions as necessary
1320 * for rotate/flip, resize, and crop operations.
1322 #if JPEG_LIB_VERSION >= 70
1323 dstinfo
->jpeg_width
= info
->output_width
;
1324 dstinfo
->jpeg_height
= info
->output_height
;
1327 /* Transpose destination image parameters */
1328 switch (info
->transform
) {
1329 case JXFORM_TRANSPOSE
:
1330 case JXFORM_TRANSVERSE
:
1332 case JXFORM_ROT_270
:
1333 #if JPEG_LIB_VERSION < 70
1334 dstinfo
->image_width
= info
->output_height
;
1335 dstinfo
->image_height
= info
->output_width
;
1337 transpose_critical_parameters(dstinfo
);
1340 #if JPEG_LIB_VERSION < 70
1341 dstinfo
->image_width
= info
->output_width
;
1342 dstinfo
->image_height
= info
->output_height
;
1347 /* Adjust Exif properties */
1348 if (srcinfo
->marker_list
!= NULL
&&
1349 srcinfo
->marker_list
->marker
== JPEG_APP0
+1 &&
1350 srcinfo
->marker_list
->data_length
>= 6 &&
1351 GETJOCTET(srcinfo
->marker_list
->data
[0]) == 0x45 &&
1352 GETJOCTET(srcinfo
->marker_list
->data
[1]) == 0x78 &&
1353 GETJOCTET(srcinfo
->marker_list
->data
[2]) == 0x69 &&
1354 GETJOCTET(srcinfo
->marker_list
->data
[3]) == 0x66 &&
1355 GETJOCTET(srcinfo
->marker_list
->data
[4]) == 0 &&
1356 GETJOCTET(srcinfo
->marker_list
->data
[5]) == 0) {
1357 /* Suppress output of JFIF marker */
1358 dstinfo
->write_JFIF_header
= FALSE
;
1359 #if JPEG_LIB_VERSION >= 70
1360 /* Adjust Exif image parameters */
1361 if (dstinfo
->jpeg_width
!= srcinfo
->image_width
||
1362 dstinfo
->jpeg_height
!= srcinfo
->image_height
)
1363 /* Align data segment to start of TIFF structure for parsing */
1364 adjust_exif_parameters(srcinfo
->marker_list
->data
+ 6,
1365 srcinfo
->marker_list
->data_length
- 6,
1366 dstinfo
->jpeg_width
, dstinfo
->jpeg_height
);
1370 /* Return the appropriate output data set */
1371 if (info
->workspace_coef_arrays
!= NULL
)
1372 return info
->workspace_coef_arrays
;
1373 return src_coef_arrays
;
1377 /* Execute the actual transformation, if any.
1379 * This must be called *after* jpeg_write_coefficients, because it depends
1380 * on jpeg_write_coefficients to have computed subsidiary values such as
1381 * the per-component width and height fields in the destination object.
1383 * Note that some transformations will modify the source data arrays!
1387 jtransform_execute_transform (j_decompress_ptr srcinfo
,
1388 j_compress_ptr dstinfo
,
1389 jvirt_barray_ptr
*src_coef_arrays
,
1390 jpeg_transform_info
*info
)
1392 jvirt_barray_ptr
*dst_coef_arrays
= info
->workspace_coef_arrays
;
1394 /* Note: conditions tested here should match those in switch statement
1395 * in jtransform_request_workspace()
1397 switch (info
->transform
) {
1399 if (info
->x_crop_offset
!= 0 || info
->y_crop_offset
!= 0)
1400 do_crop(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1401 src_coef_arrays
, dst_coef_arrays
);
1404 if (info
->y_crop_offset
!= 0 || info
->slow_hflip
)
1405 do_flip_h(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1406 src_coef_arrays
, dst_coef_arrays
);
1408 do_flip_h_no_crop(srcinfo
, dstinfo
, info
->x_crop_offset
,
1412 do_flip_v(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1413 src_coef_arrays
, dst_coef_arrays
);
1415 case JXFORM_TRANSPOSE
:
1416 do_transpose(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1417 src_coef_arrays
, dst_coef_arrays
);
1419 case JXFORM_TRANSVERSE
:
1420 do_transverse(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1421 src_coef_arrays
, dst_coef_arrays
);
1424 do_rot_90(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1425 src_coef_arrays
, dst_coef_arrays
);
1427 case JXFORM_ROT_180
:
1428 do_rot_180(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1429 src_coef_arrays
, dst_coef_arrays
);
1431 case JXFORM_ROT_270
:
1432 do_rot_270(srcinfo
, dstinfo
, info
->x_crop_offset
, info
->y_crop_offset
,
1433 src_coef_arrays
, dst_coef_arrays
);
1438 /* jtransform_perfect_transform
1440 * Determine whether lossless transformation is perfectly
1441 * possible for a specified image and transformation.
1444 * image_width, image_height: source image dimensions.
1445 * MCU_width, MCU_height: pixel dimensions of MCU.
1446 * transform: transformation identifier.
1447 * Parameter sources from initialized jpeg_struct
1448 * (after reading source header):
1449 * image_width = cinfo.image_width
1450 * image_height = cinfo.image_height
1451 * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
1452 * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
1454 * TRUE = perfect transformation possible
1455 * FALSE = perfect transformation not possible
1456 * (may use custom action then)
1460 jtransform_perfect_transform(JDIMENSION image_width
, JDIMENSION image_height
,
1461 int MCU_width
, int MCU_height
,
1462 JXFORM_CODE transform
)
1464 boolean result
= TRUE
; /* initialize TRUE */
1466 switch (transform
) {
1468 case JXFORM_ROT_270
:
1469 if (image_width
% (JDIMENSION
) MCU_width
)
1474 if (image_height
% (JDIMENSION
) MCU_height
)
1477 case JXFORM_TRANSVERSE
:
1478 case JXFORM_ROT_180
:
1479 if (image_width
% (JDIMENSION
) MCU_width
)
1481 if (image_height
% (JDIMENSION
) MCU_height
)
1491 #endif /* TRANSFORMS_SUPPORTED */
1494 /* Setup decompression object to save desired markers in memory.
1495 * This must be called before jpeg_read_header() to have the desired effect.
1499 jcopy_markers_setup (j_decompress_ptr srcinfo
, JCOPY_OPTION option
)
1501 #ifdef SAVE_MARKERS_SUPPORTED
1504 /* Save comments except under NONE option */
1505 if (option
!= JCOPYOPT_NONE
) {
1506 jpeg_save_markers(srcinfo
, JPEG_COM
, 0xFFFF);
1508 /* Save all types of APPn markers iff ALL option */
1509 if (option
== JCOPYOPT_ALL
) {
1510 for (m
= 0; m
< 16; m
++)
1511 jpeg_save_markers(srcinfo
, JPEG_APP0
+ m
, 0xFFFF);
1514 (void) srcinfo
; (void) option
;
1515 #endif /* SAVE_MARKERS_SUPPORTED */
1518 /* Copy markers saved in the given source object to the destination object.
1519 * This should be called just after jpeg_start_compress() or
1520 * jpeg_write_coefficients().
1521 * Note that those routines will have written the SOI, and also the
1522 * JFIF APP0 or Adobe APP14 markers if selected.
1526 jcopy_markers_execute (j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
1527 JCOPY_OPTION option
)
1529 jpeg_saved_marker_ptr marker
;
1531 /* In the current implementation, we don't actually need to examine the
1532 * option flag here; we just copy everything that got saved.
1533 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1534 * if the encoder library already wrote one.
1538 for (marker
= srcinfo
->marker_list
; marker
!= NULL
; marker
= marker
->next
) {
1539 if (dstinfo
->write_JFIF_header
&&
1540 marker
->marker
== JPEG_APP0
&&
1541 marker
->data_length
>= 5 &&
1542 GETJOCTET(marker
->data
[0]) == 0x4A &&
1543 GETJOCTET(marker
->data
[1]) == 0x46 &&
1544 GETJOCTET(marker
->data
[2]) == 0x49 &&
1545 GETJOCTET(marker
->data
[3]) == 0x46 &&
1546 GETJOCTET(marker
->data
[4]) == 0)
1547 continue; /* reject duplicate JFIF */
1548 if (dstinfo
->write_Adobe_marker
&&
1549 marker
->marker
== JPEG_APP0
+14 &&
1550 marker
->data_length
>= 5 &&
1551 GETJOCTET(marker
->data
[0]) == 0x41 &&
1552 GETJOCTET(marker
->data
[1]) == 0x64 &&
1553 GETJOCTET(marker
->data
[2]) == 0x6F &&
1554 GETJOCTET(marker
->data
[3]) == 0x62 &&
1555 GETJOCTET(marker
->data
[4]) == 0x65)
1556 continue; /* reject duplicate Adobe */
1557 #ifdef NEED_FAR_POINTERS
1558 /* We could use jpeg_write_marker if the data weren't FAR... */
1561 jpeg_write_m_header(dstinfo
, marker
->marker
, marker
->data_length
);
1562 for (i
= 0; i
< marker
->data_length
; i
++)
1563 jpeg_write_m_byte(dstinfo
, marker
->data
[i
]);
1566 jpeg_write_marker(dstinfo
, marker
->marker
,
1567 marker
->data
, marker
->data_length
);