3 # DP: Lossless-crop patch from <http://sylvana.net/jpegcrop/croppatch.tar.gz>
4 # DP: by <guido@jpegclub.org>.
7 -patch) patch -f --no-backup-if-mismatch -p1 < $0;;
8 -unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;;
10 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
15 diff -urNad /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/jerror.h libjpeg6b-6b
/jerror.h
16 --- /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/jerror.h
2003-09-22 18:15:48.000000000 +0200
17 +++ libjpeg6b-6b
/jerror.h
2003-09-22 18:16:12.000000000 +0200
19 JMESSAGE
(JERR_BAD_ALLOC_CHUNK
, "MAX_ALLOC_CHUNK is wrong, please fix")
20 JMESSAGE
(JERR_BAD_BUFFER_MODE
, "Bogus buffer control mode")
21 JMESSAGE
(JERR_BAD_COMPONENT_ID
, "Invalid component ID %d in SOS")
22 +JMESSAGE
(JERR_BAD_CROP_SPEC
, "Invalid crop request")
23 JMESSAGE
(JERR_BAD_DCT_COEF
, "DCT coefficient out of range")
24 JMESSAGE
(JERR_BAD_DCTSIZE
, "IDCT output block size %d not supported")
25 JMESSAGE
(JERR_BAD_HUFF_TABLE
, "Bogus Huffman table definition")
26 diff -urNad /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/jpegtran.c libjpeg6b-6b
/jpegtran.c
27 --- /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/jpegtran.c
2003-09-22 18:15:48.000000000 +0200
28 +++ libjpeg6b-6b
/jpegtran.c
2003-09-22 18:16:22.000000000 +0200
33 - * Copyright
(C
) 1995-1997, Thomas G. Lane.
34 + * Copyright
(C
) 1995-2001, Thomas G. Lane.
35 * This
file is part of the Independent JPEG Group
's software.
36 * For conditions of distribution and use, see the accompanying README file.
40 #if TRANSFORMS_SUPPORTED
41 fprintf(stderr, "Switches for modifying the image:\n");
42 + fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n");
43 fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n");
44 fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n");
45 + fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n");
46 fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n");
47 fprintf(stderr, " -transpose Transpose image\n");
48 fprintf(stderr, " -transverse Transverse transpose image\n");
50 copyoption = JCOPYOPT_DEFAULT;
51 transformoption.transform = JXFORM_NONE;
52 transformoption.trim = FALSE;
53 + transformoption.perfect = FALSE;
54 transformoption.force_grayscale = FALSE;
55 + transformoption.crop = FALSE;
56 cinfo->err->trace_level = 0;
58 /* Scan command line options, adjust parameters */
63 - } else if (keymatch(arg, "copy", 1)) {
64 + } else if (keymatch(arg, "copy", 2)) {
65 /* Select which extra markers to copy. */
66 if (++argn >= argc) /* advance to next argument */
72 + } else if (keymatch(arg, "crop", 2)) {
73 + /* Perform lossless cropping. */
74 +#if TRANSFORMS_SUPPORTED
75 + if (++argn >= argc) /* advance to next argument */
77 + if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
78 + fprintf(stderr, "%s: bogus -crop argument '%s
'\n",
79 + progname, argv[argn]);
83 + select_transform(JXFORM_NONE); /* force an error */
86 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
87 /* Enable debug printouts. */
88 /* On first -d, print version identification */
91 outfilename = argv[argn]; /* save it away for later use */
93 - } else if (keymatch(arg, "progressive", 1)) {
94 + } else if (keymatch(arg, "perfect", 2)) {
95 + /* Fail if there is any partial edge MCUs that the transform can't
97 + transformoption.perfect
= TRUE
;
99 + } else if (keymatch
(arg
, "progressive", 2)) {
100 /* Select simple progressive mode.
*/
101 #ifdef C_PROGRESSIVE_SUPPORTED
102 simple_progressive
= TRUE
;
104 jvirt_barray_ptr
* src_coef_arrays
;
105 jvirt_barray_ptr
* dst_coef_arrays
;
108 - FILE
* output_file
;
109 + /* We assume all-in-memory processing and can therefore use only a
110 + * single
file pointer
for sequential input and output operation.
114 /* On Mac
, fetch a
command line.
*/
116 @@
-406,24 +431,13 @@
118 /* Open the input
file.
*/
119 if (file_index
< argc
) {
120 - if ((input_file
= fopen
(argv
[file_index
], READ_BINARY
)) == NULL
) {
121 - fprintf
(stderr
, "%s: can't open %s\n", progname
, argv
[file_index
]);
122 + if ((fp
= fopen
(argv
[file_index
], READ_BINARY
)) == NULL
) {
123 + fprintf
(stderr
, "%s: can't open %s for reading\n", progname
, argv
[file_index
]);
127 /* default input
file is stdin
*/
128 - input_file
= read_stdin
();
131 - /* Open the output
file.
*/
132 - if (outfilename
!= NULL
) {
133 - if ((output_file
= fopen
(outfilename
, WRITE_BINARY
)) == NULL
) {
134 - fprintf
(stderr
, "%s: can't open %s\n", progname
, outfilename
);
135 - exit(EXIT_FAILURE
);
138 - /* default output
file is stdout
*/
139 - output_file
= write_stdout
();
143 #ifdef PROGRESS_REPORT
147 /* Specify data
source for decompression
*/
148 - jpeg_stdio_src
(&srcinfo
, input_file
);
149 + jpeg_stdio_src
(&srcinfo
, fp
);
151 /* Enable saving of extra markers that we want to copy
*/
152 jcopy_markers_setup
(&srcinfo
, copyoption
);
154 * jpeg_read_coefficients so that memory allocation will be
done right.
156 #if TRANSFORMS_SUPPORTED
157 + /* Fails right away
if -perfect is given and transformation is not perfect.
159 + if (transformoption.perfect
&&
160 + !jtransform_perfect_transform
(srcinfo.image_width
, srcinfo.image_height
,
161 + srcinfo.max_h_samp_factor
* DCTSIZE
, srcinfo.max_v_samp_factor
* DCTSIZE
,
162 + transformoption.transform
)) {
163 + fprintf
(stderr
, "%s: transformation is not perfect\n", progname
);
164 + exit(EXIT_FAILURE
);
166 jtransform_request_workspace
(&srcinfo
, &transformoption
);
169 @@
-463,11 +486,32 @@
170 dst_coef_arrays
= src_coef_arrays
;
173 + /* Close input
file, if we opened it.
174 + * Note
: we assume that jpeg_read_coefficients consumed all input
175 + * until JPEG_REACHED_EOI
, and that jpeg_finish_decompress will
176 + * only consume
more while (! cinfo-
>inputctl-
>eoi_reached
).
177 + * We cannot call jpeg_finish_decompress here since we still need the
178 + * virtual arrays allocated from the
source object
for processing.
183 + /* Open the output
file.
*/
184 + if (outfilename
!= NULL
) {
185 + if ((fp
= fopen
(outfilename
, WRITE_BINARY
)) == NULL
) {
186 + fprintf
(stderr
, "%s: can't open %s for writing\n", progname
, outfilename
);
187 + exit(EXIT_FAILURE
);
190 + /* default output
file is stdout
*/
191 + fp
= write_stdout
();
194 /* Adjust default compression parameters by re-parsing the options
*/
195 file_index
= parse_switches
(&dstinfo
, argc
, argv
, 0, TRUE
);
197 /* Specify data destination
for compression
*/
198 - jpeg_stdio_dest
(&dstinfo
, output_file
);
199 + jpeg_stdio_dest
(&dstinfo
, fp
);
201 /* Start compressor
(note no image data is actually written here
) */
202 jpeg_write_coefficients
(&dstinfo
, dst_coef_arrays
);
204 (void
) jpeg_finish_decompress
(&srcinfo
);
205 jpeg_destroy_decompress
(&srcinfo
);
207 - /* Close files
, if we opened them
*/
208 - if (input_file
!= stdin
)
209 - fclose
(input_file
);
210 - if (output_file
!= stdout
)
211 - fclose
(output_file
);
212 + /* Close output
file, if we opened it
*/
216 #ifdef PROGRESS_REPORT
217 end_progress_monitor
((j_common_ptr
) &dstinfo
);
218 diff -urNad /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/transupp.c libjpeg6b-6b
/transupp.c
219 --- /home
/bill
/debian
/libjpeg
/libjpeg6b-6b
/transupp.c
2003-09-22 18:15:49.000000000 +0200
220 +++ libjpeg6b-6b
/transupp.c
2003-09-22 18:16:28.000000000 +0200
225 - * Copyright
(C
) 1997, Thomas G. Lane.
226 + * Copyright
(C
) 1997-2001, Thomas G. Lane.
227 * This
file is part of the Independent JPEG Group
's software.
228 * For conditions of distribution and use, see the accompanying README file.
231 #include "jinclude.h"
233 #include "transupp.h" /* My own external interface */
234 +#include <ctype.h> /* to declare isdigit() */
237 #if TRANSFORMS_SUPPORTED
239 * Lossless image transformation routines. These routines work on DCT
240 * coefficient arrays and thus do not require any lossy decompression
241 * or recompression of the image.
242 - * Thanks to Guido Vollbeding for the initial design and code of this feature.
243 + * Thanks to Guido Vollbeding for the initial design and code of this feature,
244 + * and to Ben Jackson for introducing the cropping feature.
246 * Horizontal flipping is done in-place, using a single top-to-bottom
247 * pass through the virtual source array. It will thus be much the
249 * arrays for most of the transforms. That could result in much thrashing
250 * if the image is larger than main memory.
252 + * If cropping or trimming is involved, the destination arrays may be smaller
253 + * than the source arrays. Note it is not possible to do horizontal flip
254 + * in-place when a nonzero Y crop offset is specified, since we'd have to move
255 + * data from one block row to another but the virtual array manager doesn
't
256 + * guarantee we can touch more than one row at a time. So in that case,
257 + * we have to use a separate destination array.
259 * Some notes about the operating environment of the individual transform
261 * 1. Both the source and destination virtual arrays are allocated from the
263 * and we may as well take that as the effective iMCU size.
264 * 4. When "trim" is in effect, the destination's dimensions will be the
265 * trimmed values but the
source's will be untrimmed.
266 - * 5. All the routines assume that the source and destination buffers are
267 + * 5. When "crop" is in effect, the destination's dimensions will be the
268 + * cropped values but the
source's will be uncropped. Each transform
269 + * routine is responsible for picking up source data starting at the
270 + * correct X and Y offset for the crop region. (The X and Y offsets
271 + * passed to the transform routines are measured in iMCU blocks of the
273 + * 6. All the routines assume that the source and destination buffers are
274 * padded out to a full iMCU boundary. This is true, although for the
275 * source buffer it is an undocumented property of jdcoefct.c.
276 - * Notes 2,3,4 boil down to this: generally we should use the destination's
277 - * dimensions and ignore the
source's.
282 -do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
283 - jvirt_barray_ptr *src_coef_arrays)
284 -/* Horizontal flip; done in-place, so no separate dest array is required */
285 +do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
286 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
287 + jvirt_barray_ptr *src_coef_arrays,
288 + jvirt_barray_ptr *dst_coef_arrays)
289 +/* Crop. This is only used when no rotate/flip is requested with the crop. */
291 - JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
292 + JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
294 + JBLOCKARRAY src_buffer, dst_buffer;
295 + jpeg_component_info *compptr;
297 + /* We simply have to copy the right amount of data (the destination's
298 + * image size
) starting
at the given X and Y offsets
in the
source.
300 + for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
301 + compptr
= dstinfo-
>comp_info
+ ci
;
302 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
303 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
304 + for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
305 + dst_blk_y
+= compptr-
>v_samp_factor
) {
306 + dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
307 + ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
308 + (JDIMENSION
) compptr-
>v_samp_factor
, TRUE
);
309 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
310 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
311 + dst_blk_y
+ y_crop_blocks
,
312 + (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
313 + for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
314 + jcopy_block_row
(src_buffer
[offset_y
] + x_crop_blocks
,
315 + dst_buffer
[offset_y
],
316 + compptr-
>width_in_blocks
);
324 +do_flip_h_no_crop
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
325 + JDIMENSION x_crop_offset
,
326 + jvirt_barray_ptr
*src_coef_arrays
)
327 +/* Horizontal flip
; done in-place
, so no separate dest array is required.
328 + * NB
: this only works when y_crop_offset is zero.
331 + JDIMENSION MCU_cols
, comp_width
, blk_x
, blk_y
, x_crop_blocks
;
336 * mirroring by changing the signs of odd-numbered columns.
337 * Partial iMCUs
at the right edge are left untouched.
339 - MCU_cols
= dstinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
340 + MCU_cols
= srcinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
342 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
343 compptr
= dstinfo-
>comp_info
+ ci
;
344 comp_width
= MCU_cols
* compptr-
>h_samp_factor
;
345 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
346 for (blk_y
= 0; blk_y
< compptr-
>height_in_blocks
;
347 blk_y
+= compptr-
>v_samp_factor
) {
348 buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
349 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], blk_y
,
350 (JDIMENSION
) compptr-
>v_samp_factor
, TRUE
);
351 for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
352 + /* Do the mirroring
*/
353 for (blk_x
= 0; blk_x
* 2 < comp_width
; blk_x
++) {
354 ptr1
= buffer
[offset_y
][blk_x
];
355 ptr2
= buffer
[offset_y
][comp_width
- blk_x
- 1];
360 + if (x_crop_blocks
> 0) {
361 + /* Now left-justify the portion of the data to be kept.
362 + * We can
't use a single jcopy_block_row() call because that routine
363 + * depends on memcpy(), whose behavior is unspecified for overlapping
364 + * source and destination areas. Sigh.
366 + for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
367 + jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
368 + buffer[offset_y] + blk_x,
379 +do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
380 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
381 + jvirt_barray_ptr *src_coef_arrays,
382 + jvirt_barray_ptr *dst_coef_arrays)
383 +/* Horizontal flip in general cropping case */
385 + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
386 + JDIMENSION x_crop_blocks, y_crop_blocks;
387 + int ci, k, offset_y;
388 + JBLOCKARRAY src_buffer, dst_buffer;
389 + JBLOCKROW src_row_ptr, dst_row_ptr;
390 + JCOEFPTR src_ptr, dst_ptr;
391 + jpeg_component_info *compptr;
393 + /* Here we must output into a separate array because we can't
touch
394 + * different rows of a single virtual array simultaneously. Otherwise
,
395 + * this is essentially the same as the routine above.
397 + MCU_cols
= srcinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
399 + for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
400 + compptr
= dstinfo-
>comp_info
+ ci
;
401 + comp_width
= MCU_cols
* compptr-
>h_samp_factor
;
402 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
403 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
404 + for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
405 + dst_blk_y
+= compptr-
>v_samp_factor
) {
406 + dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
407 + ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
408 + (JDIMENSION
) compptr-
>v_samp_factor
, TRUE
);
409 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
410 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
411 + dst_blk_y
+ y_crop_blocks
,
412 + (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
413 + for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
414 + dst_row_ptr
= dst_buffer
[offset_y
];
415 + src_row_ptr
= src_buffer
[offset_y
];
416 + for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
; dst_blk_x
++) {
417 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
418 + /* Do the mirrorable blocks
*/
419 + dst_ptr
= dst_row_ptr
[dst_blk_x
];
420 + src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
421 + /* this unrolled loop doesn
't need to know which row it's on...
*/
422 + for (k
= 0; k
< DCTSIZE2
; k
+= 2) {
423 + *dst_ptr
++ = *src_ptr
++; /* copy even
column */
424 + *dst_ptr
++ = - *src_ptr
++; /* copy odd
column with sign change
*/
427 + /* Copy last partial block
(s
) verbatim
*/
428 + jcopy_block_row
(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
429 + dst_row_ptr
+ dst_blk_x
,
436 @@
-113,11 +242,13 @@
439 do_flip_v
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
440 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
441 jvirt_barray_ptr
*src_coef_arrays
,
442 jvirt_barray_ptr
*dst_coef_arrays
)
445 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
446 + JDIMENSION x_crop_blocks
, y_crop_blocks
;
447 int ci
, i
, j
, offset_y
;
448 JBLOCKARRAY src_buffer
, dst_buffer
;
449 JBLOCKROW src_row_ptr
, dst_row_ptr
;
450 @@
-131,33 +262,38 @@
451 * of odd-numbered rows.
452 * Partial iMCUs
at the bottom edge are copied verbatim.
454 - MCU_rows
= dstinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
455 + MCU_rows
= srcinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
457 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
458 compptr
= dstinfo-
>comp_info
+ ci
;
459 comp_height
= MCU_rows
* compptr-
>v_samp_factor
;
460 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
461 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
462 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
463 dst_blk_y
+= compptr-
>v_samp_factor
) {
464 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
465 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
466 (JDIMENSION
) compptr-
>v_samp_factor
, TRUE
);
467 - if (dst_blk_y
< comp_height
) {
468 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
469 /* Row is within the mirrorable area.
*/
470 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
471 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
472 - comp_height
- dst_blk_y
- (JDIMENSION
) compptr-
>v_samp_factor
,
473 + comp_height
- y_crop_blocks
- dst_blk_y
-
474 + (JDIMENSION
) compptr-
>v_samp_factor
,
475 (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
477 /* Bottom-edge blocks will be copied verbatim.
*/
478 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
479 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_y
,
480 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
481 + dst_blk_y
+ y_crop_blocks
,
482 (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
484 for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
485 - if (dst_blk_y
< comp_height
) {
486 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
487 /* Row is within the mirrorable area.
*/
488 dst_row_ptr
= dst_buffer
[offset_y
];
489 src_row_ptr
= src_buffer
[compptr-
>v_samp_factor
- offset_y
- 1];
490 + src_row_ptr
+= x_crop_blocks
;
491 for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
;
493 dst_ptr
= dst_row_ptr
[dst_blk_x
];
497 /* Just copy row verbatim.
*/
498 - jcopy_block_row
(src_buffer
[offset_y
], dst_buffer
[offset_y
],
499 + jcopy_block_row
(src_buffer
[offset_y
] + x_crop_blocks
,
500 + dst_buffer
[offset_y
],
501 compptr-
>width_in_blocks
);
504 @@
-184,11 +321,12 @@
507 do_transpose
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
508 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
509 jvirt_barray_ptr
*src_coef_arrays
,
510 jvirt_barray_ptr
*dst_coef_arrays
)
511 /* Transpose
source into destination
*/
513 - JDIMENSION dst_blk_x
, dst_blk_y
;
514 + JDIMENSION dst_blk_x
, dst_blk_y
, x_crop_blocks
, y_crop_blocks
;
515 int ci
, i
, j
, offset_x
, offset_y
;
516 JBLOCKARRAY src_buffer
, dst_buffer
;
517 JCOEFPTR src_ptr
, dst_ptr
;
520 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
521 compptr
= dstinfo-
>comp_info
+ ci
;
522 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
523 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
524 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
525 dst_blk_y
+= compptr-
>v_samp_factor
) {
526 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
527 @@
-210,11 +350,12 @@
528 for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
;
529 dst_blk_x
+= compptr-
>h_samp_factor
) {
530 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
531 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_x
,
532 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
533 + dst_blk_x
+ x_crop_blocks
,
534 (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
535 for (offset_x
= 0; offset_x
< compptr-
>h_samp_factor
; offset_x
++) {
536 - src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
];
537 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
538 + src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
+ y_crop_blocks
];
539 for (i
= 0; i
< DCTSIZE
; i
++)
540 for (j
= 0; j
< DCTSIZE
; j
++)
541 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
545 do_rot_90
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
546 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
547 jvirt_barray_ptr
*src_coef_arrays
,
548 jvirt_barray_ptr
*dst_coef_arrays
)
549 /* 90 degree rotation is equivalent to
553 JDIMENSION MCU_cols
, comp_width
, dst_blk_x
, dst_blk_y
;
554 + JDIMENSION x_crop_blocks
, y_crop_blocks
;
555 int ci
, i
, j
, offset_x
, offset_y
;
556 JBLOCKARRAY src_buffer
, dst_buffer
;
557 JCOEFPTR src_ptr
, dst_ptr
;
558 @@
-246,11 +389,13 @@
559 * at the
(output
) right edge properly. They just get transposed and
562 - MCU_cols
= dstinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
563 + MCU_cols
= srcinfo-
>image_height
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
565 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
566 compptr
= dstinfo-
>comp_info
+ ci
;
567 comp_width
= MCU_cols
* compptr-
>h_samp_factor
;
568 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
569 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
570 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
571 dst_blk_y
+= compptr-
>v_samp_factor
) {
572 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
573 @@
-259,15 +404,26 @@
574 for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
575 for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
;
576 dst_blk_x
+= compptr-
>h_samp_factor
) {
577 - src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
578 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_x
,
579 - (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
580 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
581 + /* Block is within the mirrorable area.
*/
582 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
583 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
584 + comp_width
- x_crop_blocks
- dst_blk_x
-
585 + (JDIMENSION
) compptr-
>h_samp_factor
,
586 + (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
588 + /* Edge blocks are transposed but not mirrored.
*/
589 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
590 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
591 + dst_blk_x
+ x_crop_blocks
,
592 + (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
594 for (offset_x
= 0; offset_x
< compptr-
>h_samp_factor
; offset_x
++) {
595 - src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
];
596 - if (dst_blk_x
< comp_width
) {
597 + dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
598 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
599 /* Block is within the mirrorable area.
*/
600 - dst_ptr
= dst_buffer
[offset_y
]
601 - [comp_width
- dst_blk_x
- offset_x
- 1];
602 + src_ptr
= src_buffer
[compptr-
>h_samp_factor
- offset_x
- 1]
603 + [dst_blk_y
+ offset_y
+ y_crop_blocks
];
604 for (i
= 0; i
< DCTSIZE
; i
++) {
605 for (j
= 0; j
< DCTSIZE
; j
++)
606 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
610 /* Edge blocks are transposed but not mirrored.
*/
611 - dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
612 + src_ptr
= src_buffer
[offset_x
]
613 + [dst_blk_y
+ offset_y
+ y_crop_blocks
];
614 for (i
= 0; i
< DCTSIZE
; i
++)
615 for (j
= 0; j
< DCTSIZE
; j
++)
616 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
620 do_rot_270
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
621 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
622 jvirt_barray_ptr
*src_coef_arrays
,
623 jvirt_barray_ptr
*dst_coef_arrays
)
624 /* 270 degree rotation is equivalent to
628 JDIMENSION MCU_rows
, comp_height
, dst_blk_x
, dst_blk_y
;
629 + JDIMENSION x_crop_blocks
, y_crop_blocks
;
630 int ci
, i
, j
, offset_x
, offset_y
;
631 JBLOCKARRAY src_buffer
, dst_buffer
;
632 JCOEFPTR src_ptr
, dst_ptr
;
633 @@
-310,11 +469,13 @@
634 * at the
(output
) bottom edge properly. They just get transposed and
637 - MCU_rows
= dstinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
638 + MCU_rows
= srcinfo-
>image_width
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
640 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
641 compptr
= dstinfo-
>comp_info
+ ci
;
642 comp_height
= MCU_rows
* compptr-
>v_samp_factor
;
643 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
644 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
645 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
646 dst_blk_y
+= compptr-
>v_samp_factor
) {
647 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
648 @@
-324,14 +485,15 @@
649 for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
;
650 dst_blk_x
+= compptr-
>h_samp_factor
) {
651 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
652 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_x
,
653 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
654 + dst_blk_x
+ x_crop_blocks
,
655 (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
656 for (offset_x
= 0; offset_x
< compptr-
>h_samp_factor
; offset_x
++) {
657 dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
658 - if (dst_blk_y
< comp_height
) {
659 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
660 /* Block is within the mirrorable area.
*/
661 src_ptr
= src_buffer
[offset_x
]
662 - [comp_height
- dst_blk_y
- offset_y
- 1];
663 + [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
664 for (i
= 0; i
< DCTSIZE
; i
++) {
665 for (j
= 0; j
< DCTSIZE
; j
++) {
666 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
670 /* Edge blocks are transposed but not mirrored.
*/
671 - src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
];
672 + src_ptr
= src_buffer
[offset_x
]
673 + [dst_blk_y
+ offset_y
+ y_crop_blocks
];
674 for (i
= 0; i
< DCTSIZE
; i
++)
675 for (j
= 0; j
< DCTSIZE
; j
++)
676 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
680 do_rot_180
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
681 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
682 jvirt_barray_ptr
*src_coef_arrays
,
683 jvirt_barray_ptr
*dst_coef_arrays
)
684 /* 180 degree rotation is equivalent to
685 @@
-365,89 +529,93 @@
688 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
689 + JDIMENSION x_crop_blocks
, y_crop_blocks
;
690 int ci
, i
, j
, offset_y
;
691 JBLOCKARRAY src_buffer
, dst_buffer
;
692 JBLOCKROW src_row_ptr
, dst_row_ptr
;
693 JCOEFPTR src_ptr
, dst_ptr
;
694 jpeg_component_info
*compptr
;
696 - MCU_cols
= dstinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
697 - MCU_rows
= dstinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
698 + MCU_cols
= srcinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
699 + MCU_rows
= srcinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
701 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
702 compptr
= dstinfo-
>comp_info
+ ci
;
703 comp_width
= MCU_cols
* compptr-
>h_samp_factor
;
704 comp_height
= MCU_rows
* compptr-
>v_samp_factor
;
705 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
706 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
707 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
708 dst_blk_y
+= compptr-
>v_samp_factor
) {
709 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
710 ((j_common_ptr
) srcinfo
, dst_coef_arrays
[ci
], dst_blk_y
,
711 (JDIMENSION
) compptr-
>v_samp_factor
, TRUE
);
712 - if (dst_blk_y
< comp_height
) {
713 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
714 /* Row is within the vertically mirrorable area.
*/
715 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
716 ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
717 - comp_height
- dst_blk_y
- (JDIMENSION
) compptr-
>v_samp_factor
,
718 + comp_height
- y_crop_blocks
- dst_blk_y
-
719 + (JDIMENSION
) compptr-
>v_samp_factor
,
720 (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
722 /* Bottom-edge rows are only mirrored horizontally.
*/
723 src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
724 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_y
,
725 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
726 + dst_blk_y
+ y_crop_blocks
,
727 (JDIMENSION
) compptr-
>v_samp_factor
, FALSE
);
729 for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
730 - if (dst_blk_y
< comp_height
) {
731 + dst_row_ptr
= dst_buffer
[offset_y
];
732 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
733 /* Row is within the mirrorable area.
*/
734 - dst_row_ptr
= dst_buffer
[offset_y
];
735 src_row_ptr
= src_buffer
[compptr-
>v_samp_factor
- offset_y
- 1];
736 - /* Process the blocks that can be mirrored both ways.
*/
737 - for (dst_blk_x
= 0; dst_blk_x
< comp_width
; dst_blk_x
++) {
738 + for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
; dst_blk_x
++) {
739 dst_ptr
= dst_row_ptr
[dst_blk_x
];
740 - src_ptr
= src_row_ptr
[comp_width
- dst_blk_x
- 1];
741 - for (i
= 0; i
< DCTSIZE
; i
+= 2) {
742 - /* For even row
, negate every odd
column.
*/
743 - for (j
= 0; j
< DCTSIZE
; j
+= 2) {
744 - *dst_ptr
++ = *src_ptr
++;
745 - *dst_ptr
++ = - *src_ptr
++;
746 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
747 + /* Process the blocks that can be mirrored both ways.
*/
748 + src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
749 + for (i
= 0; i
< DCTSIZE
; i
+= 2) {
750 + /* For even row
, negate every odd
column.
*/
751 + for (j
= 0; j
< DCTSIZE
; j
+= 2) {
752 + *dst_ptr
++ = *src_ptr
++;
753 + *dst_ptr
++ = - *src_ptr
++;
755 + /* For odd row
, negate every even
column.
*/
756 + for (j
= 0; j
< DCTSIZE
; j
+= 2) {
757 + *dst_ptr
++ = - *src_ptr
++;
758 + *dst_ptr
++ = *src_ptr
++;
761 - /* For odd row
, negate every even
column.
*/
762 - for (j
= 0; j
< DCTSIZE
; j
+= 2) {
763 - *dst_ptr
++ = - *src_ptr
++;
764 - *dst_ptr
++ = *src_ptr
++;
766 + /* Any remaining right-edge blocks are only mirrored vertically.
*/
767 + src_ptr
= src_row_ptr
[x_crop_blocks
+ dst_blk_x
];
768 + for (i
= 0; i
< DCTSIZE
; i
+= 2) {
769 + for (j
= 0; j
< DCTSIZE
; j
++)
770 + *dst_ptr
++ = *src_ptr
++;
771 + for (j
= 0; j
< DCTSIZE
; j
++)
772 + *dst_ptr
++ = - *src_ptr
++;
776 - /* Any remaining right-edge blocks are only mirrored vertically.
*/
777 - for (; dst_blk_x
< compptr-
>width_in_blocks
; dst_blk_x
++) {
778 - dst_ptr
= dst_row_ptr
[dst_blk_x
];
779 - src_ptr
= src_row_ptr
[dst_blk_x
];
780 - for (i
= 0; i
< DCTSIZE
; i
+= 2) {
781 - for (j
= 0; j
< DCTSIZE
; j
++)
782 - *dst_ptr
++ = *src_ptr
++;
783 - for (j
= 0; j
< DCTSIZE
; j
++)
784 - *dst_ptr
++ = - *src_ptr
++;
788 /* Remaining rows are just mirrored horizontally.
*/
789 - dst_row_ptr
= dst_buffer
[offset_y
];
790 src_row_ptr
= src_buffer
[offset_y
];
791 - /* Process the blocks that can be mirrored.
*/
792 - for (dst_blk_x
= 0; dst_blk_x
< comp_width
; dst_blk_x
++) {
793 - dst_ptr
= dst_row_ptr
[dst_blk_x
];
794 - src_ptr
= src_row_ptr
[comp_width
- dst_blk_x
- 1];
795 - for (i
= 0; i
< DCTSIZE2
; i
+= 2) {
796 - *dst_ptr
++ = *src_ptr
++;
797 - *dst_ptr
++ = - *src_ptr
++;
798 + for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
; dst_blk_x
++) {
799 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
800 + /* Process the blocks that can be mirrored.
*/
801 + dst_ptr
= dst_row_ptr
[dst_blk_x
];
802 + src_ptr
= src_row_ptr
[comp_width
- x_crop_blocks
- dst_blk_x
- 1];
803 + for (i
= 0; i
< DCTSIZE2
; i
+= 2) {
804 + *dst_ptr
++ = *src_ptr
++;
805 + *dst_ptr
++ = - *src_ptr
++;
808 + /* Any remaining right-edge blocks are only copied.
*/
809 + jcopy_block_row
(src_row_ptr
+ dst_blk_x
+ x_crop_blocks
,
810 + dst_row_ptr
+ dst_blk_x
,
814 - /* Any remaining right-edge blocks are only copied.
*/
815 - for (; dst_blk_x
< compptr-
>width_in_blocks
; dst_blk_x
++) {
816 - dst_ptr
= dst_row_ptr
[dst_blk_x
];
817 - src_ptr
= src_row_ptr
[dst_blk_x
];
818 - for (i
= 0; i
< DCTSIZE2
; i
++)
819 - *dst_ptr
++ = *src_ptr
++;
827 do_transverse
(j_decompress_ptr srcinfo
, j_compress_ptr dstinfo
,
828 + JDIMENSION x_crop_offset
, JDIMENSION y_crop_offset
,
829 jvirt_barray_ptr
*src_coef_arrays
,
830 jvirt_barray_ptr
*dst_coef_arrays
)
831 /* Transverse transpose is equivalent to
832 @@
-470,18 +639,21 @@
835 JDIMENSION MCU_cols
, MCU_rows
, comp_width
, comp_height
, dst_blk_x
, dst_blk_y
;
836 + JDIMENSION x_crop_blocks
, y_crop_blocks
;
837 int ci
, i
, j
, offset_x
, offset_y
;
838 JBLOCKARRAY src_buffer
, dst_buffer
;
839 JCOEFPTR src_ptr
, dst_ptr
;
840 jpeg_component_info
*compptr
;
842 - MCU_cols
= dstinfo-
>image_width
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
843 - MCU_rows
= dstinfo-
>image_height
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
844 + MCU_cols
= srcinfo-
>image_height
/ (dstinfo-
>max_h_samp_factor
* DCTSIZE
);
845 + MCU_rows
= srcinfo-
>image_width
/ (dstinfo-
>max_v_samp_factor
* DCTSIZE
);
847 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
848 compptr
= dstinfo-
>comp_info
+ ci
;
849 comp_width
= MCU_cols
* compptr-
>h_samp_factor
;
850 comp_height
= MCU_rows
* compptr-
>v_samp_factor
;
851 + x_crop_blocks
= x_crop_offset
* compptr-
>h_samp_factor
;
852 + y_crop_blocks
= y_crop_offset
* compptr-
>v_samp_factor
;
853 for (dst_blk_y
= 0; dst_blk_y
< compptr-
>height_in_blocks
;
854 dst_blk_y
+= compptr-
>v_samp_factor
) {
855 dst_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
856 @@
-490,17 +662,26 @@
857 for (offset_y
= 0; offset_y
< compptr-
>v_samp_factor
; offset_y
++) {
858 for (dst_blk_x
= 0; dst_blk_x
< compptr-
>width_in_blocks
;
859 dst_blk_x
+= compptr-
>h_samp_factor
) {
860 - src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
861 - ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
], dst_blk_x
,
862 - (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
863 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
864 + /* Block is within the mirrorable area.
*/
865 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
866 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
867 + comp_width
- x_crop_blocks
- dst_blk_x
-
868 + (JDIMENSION
) compptr-
>h_samp_factor
,
869 + (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
871 + src_buffer
= (*srcinfo-
>mem-
>access_virt_barray
)
872 + ((j_common_ptr
) srcinfo
, src_coef_arrays
[ci
],
873 + dst_blk_x
+ x_crop_blocks
,
874 + (JDIMENSION
) compptr-
>h_samp_factor
, FALSE
);
876 for (offset_x
= 0; offset_x
< compptr-
>h_samp_factor
; offset_x
++) {
877 - if (dst_blk_y
< comp_height
) {
878 - src_ptr
= src_buffer
[offset_x
]
879 - [comp_height
- dst_blk_y
- offset_y
- 1];
880 - if (dst_blk_x
< comp_width
) {
881 + dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
882 + if (y_crop_blocks
+ dst_blk_y
< comp_height
) {
883 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
884 /* Block is within the mirrorable area.
*/
885 - dst_ptr
= dst_buffer
[offset_y
]
886 - [comp_width
- dst_blk_x
- offset_x
- 1];
887 + src_ptr
= src_buffer
[compptr-
>h_samp_factor
- offset_x
- 1]
888 + [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
889 for (i
= 0; i
< DCTSIZE
; i
++) {
890 for (j
= 0; j
< DCTSIZE
; j
++) {
891 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
895 /* Right-edge blocks are mirrored
in y only
*/
896 - dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
897 + src_ptr
= src_buffer
[offset_x
]
898 + [comp_height
- y_crop_blocks
- dst_blk_y
- offset_y
- 1];
899 for (i
= 0; i
< DCTSIZE
; i
++) {
900 for (j
= 0; j
< DCTSIZE
; j
++) {
901 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
902 @@
-526,11 +708,10 @@
906 - src_ptr
= src_buffer
[offset_x
][dst_blk_y
+ offset_y
];
907 - if (dst_blk_x
< comp_width
) {
908 + if (x_crop_blocks
+ dst_blk_x
< comp_width
) {
909 /* Bottom-edge blocks are mirrored
in x only
*/
910 - dst_ptr
= dst_buffer
[offset_y
]
911 - [comp_width
- dst_blk_x
- offset_x
- 1];
912 + src_ptr
= src_buffer
[compptr-
>h_samp_factor
- offset_x
- 1]
913 + [dst_blk_y
+ offset_y
+ y_crop_blocks
];
914 for (i
= 0; i
< DCTSIZE
; i
++) {
915 for (j
= 0; j
< DCTSIZE
; j
++)
916 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
920 /* At lower right corner
, just transpose
, no mirroring
*/
921 - dst_ptr
= dst_buffer
[offset_y
][dst_blk_x
+ offset_x
];
922 + src_ptr
= src_buffer
[offset_x
]
923 + [dst_blk_y
+ offset_y
+ y_crop_blocks
];
924 for (i
= 0; i
< DCTSIZE
; i
++)
925 for (j
= 0; j
< DCTSIZE
; j
++)
926 dst_ptr
[j
*DCTSIZE
+i
] = src_ptr
[i
*DCTSIZE
+j
];
927 @@
-554,8 +736,116 @@
931 +/* Parse an unsigned integer
: subroutine
for jtransform_parse_crop_spec.
932 + * Returns TRUE
if valid integer found
, FALSE
if not.
933 + * *strptr is advanced over the digit string
, and
*result is
set to its value.
937 +jt_read_integer
(const char
** strptr
, JDIMENSION
* result
)
939 + const char
* ptr
= *strptr
;
940 + JDIMENSION val
= 0;
942 + for (; isdigit
(*ptr
); ptr
++) {
943 + val
= val
* 10 + (JDIMENSION
) (*ptr
- '0');
946 + if (ptr
== *strptr
)
947 + return FALSE
; /* oops
, no digits
*/
953 +/* Parse a crop specification
(written
in X11 geometry style
).
954 + * The routine returns TRUE
if the spec string is valid
, FALSE
if not.
956 + * The crop spec string should have the format
957 + * <width
>x
<height
>{+-}<xoffset
>{+-}<yoffset
>
958 + * where width
, height
, xoffset
, and yoffset are unsigned integers.
959 + * Each of the elements can be omitted to indicate a default value.
960 + * (A weakness of this style is that it is not possible to omit xoffset
961 + * while specifying yoffset
, since they
look alike.
)
963 + * This code is loosely based on XParseGeometry from the X11 distribution.
967 +jtransform_parse_crop_spec
(jpeg_transform_info
*info
, const char
*spec
)
969 + info-
>crop
= FALSE
;
970 + info-
>crop_width_set
= JCROP_UNSET
;
971 + info-
>crop_height_set
= JCROP_UNSET
;
972 + info-
>crop_xoffset_set
= JCROP_UNSET
;
973 + info-
>crop_yoffset_set
= JCROP_UNSET
;
975 + if (isdigit
(*spec
)) {
977 + if (! jt_read_integer
(&spec
, &info-
>crop_width
))
979 + info-
>crop_width_set
= JCROP_POS
;
981 + if (*spec
== 'x' ||
*spec
== 'X') {
984 + if (! jt_read_integer
(&spec
, &info-
>crop_height
))
986 + info-
>crop_height_set
= JCROP_POS
;
988 + if (*spec
== '+' ||
*spec
== '-') {
989 + /* fetch xoffset
*/
990 + info-
>crop_xoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
992 + if (! jt_read_integer
(&spec
, &info-
>crop_xoffset
))
995 + if (*spec
== '+' ||
*spec
== '-') {
996 + /* fetch yoffset
*/
997 + info-
>crop_yoffset_set
= (*spec
== '-') ? JCROP_NEG
: JCROP_POS
;
999 + if (! jt_read_integer
(&spec
, &info-
>crop_yoffset
))
1002 + /* We had better have gotten to the end of the string.
*/
1003 + if (*spec
!= '\0')
1005 + info-
>crop
= TRUE
;
1010 +/* Trim off any partial iMCUs on the indicated destination edge
*/
1013 +trim_right_edge
(jpeg_transform_info
*info
, JDIMENSION full_width
)
1015 + JDIMENSION MCU_cols
;
1017 + MCU_cols
= info-
>output_width
/ (info-
>max_h_samp_factor
* DCTSIZE
);
1018 + if (MCU_cols
> 0 && info-
>x_crop_offset
+ MCU_cols
==
1019 + full_width
/ (info-
>max_h_samp_factor
* DCTSIZE
))
1020 + info-
>output_width
= MCU_cols
* (info-
>max_h_samp_factor
* DCTSIZE
);
1024 +trim_bottom_edge
(jpeg_transform_info
*info
, JDIMENSION full_height
)
1026 + JDIMENSION MCU_rows
;
1028 + MCU_rows
= info-
>output_height
/ (info-
>max_v_samp_factor
* DCTSIZE
);
1029 + if (MCU_rows
> 0 && info-
>y_crop_offset
+ MCU_rows
==
1030 + full_height
/ (info-
>max_v_samp_factor
* DCTSIZE
))
1031 + info-
>output_height
= MCU_rows
* (info-
>max_v_samp_factor
* DCTSIZE
);
1035 /* Request any required workspace.
1037 + * This routine figures out the size that the output image will be
1038 + * (which implies that all the transform parameters must be
set before
1041 * We allocate the workspace virtual arrays from the
source decompression
1042 * object
, so that all the arrays
(both the original data and the workspace
)
1043 * will be taken into account
while making memory management decisions.
1044 @@
-569,9 +859,13 @@
1045 jpeg_transform_info
*info
)
1047 jvirt_barray_ptr
*coef_arrays
= NULL
;
1048 + boolean need_workspace
, transpose_it
;
1049 jpeg_component_info
*compptr
;
1051 + JDIMENSION xoffset
, yoffset
, width_in_iMCUs
, height_in_iMCUs
;
1052 + JDIMENSION width_in_blocks
, height_in_blocks
;
1053 + int ci
, h_samp_factor
, v_samp_factor
;
1055 + /* Determine number of components
in output image
*/
1056 if (info-
>force_grayscale
&&
1057 srcinfo-
>jpeg_color_space
== JCS_YCbCr
&&
1058 srcinfo-
>num_components
== 3) {
1059 @@
-581,55 +875,181 @@
1060 /* Process all the components
*/
1061 info-
>num_components
= srcinfo-
>num_components
;
1063 + /* If there is only one output component
, force the iMCU size to be
1;
1064 + * else use the
source iMCU size.
(This allows us to
do the right thing
1065 + * when reducing color to grayscale
, and also provides a handy way of
1066 + * cleaning up
"funny" grayscale images whose sampling factors are not
1x1.
)
1069 switch
(info-
>transform
) {
1070 + case JXFORM_TRANSPOSE
:
1071 + case JXFORM_TRANSVERSE
:
1072 + case JXFORM_ROT_90
:
1073 + case JXFORM_ROT_270
:
1074 + info-
>output_width
= srcinfo-
>image_height
;
1075 + info-
>output_height
= srcinfo-
>image_width
;
1076 + if (info-
>num_components
== 1) {
1077 + info-
>max_h_samp_factor
= 1;
1078 + info-
>max_v_samp_factor
= 1;
1080 + info-
>max_h_samp_factor
= srcinfo-
>max_v_samp_factor
;
1081 + info-
>max_v_samp_factor
= srcinfo-
>max_h_samp_factor
;
1085 + info-
>output_width
= srcinfo-
>image_width
;
1086 + info-
>output_height
= srcinfo-
>image_height
;
1087 + if (info-
>num_components
== 1) {
1088 + info-
>max_h_samp_factor
= 1;
1089 + info-
>max_v_samp_factor
= 1;
1091 + info-
>max_h_samp_factor
= srcinfo-
>max_h_samp_factor
;
1092 + info-
>max_v_samp_factor
= srcinfo-
>max_v_samp_factor
;
1097 + /* If cropping has been requested
, compute the crop area
's position and
1098 + * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
1101 + /* Insert default values for unset crop parameters */
1102 + if (info->crop_xoffset_set == JCROP_UNSET)
1103 + info->crop_xoffset = 0; /* default to +0 */
1104 + if (info->crop_yoffset_set == JCROP_UNSET)
1105 + info->crop_yoffset = 0; /* default to +0 */
1106 + if (info->crop_xoffset >= info->output_width ||
1107 + info->crop_yoffset >= info->output_height)
1108 + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
1109 + if (info->crop_width_set == JCROP_UNSET)
1110 + info->crop_width = info->output_width - info->crop_xoffset;
1111 + if (info->crop_height_set == JCROP_UNSET)
1112 + info->crop_height = info->output_height - info->crop_yoffset;
1113 + /* Ensure parameters are valid */
1114 + if (info->crop_width <= 0 || info->crop_width > info->output_width ||
1115 + info->crop_height <= 0 || info->crop_height > info->output_height ||
1116 + info->crop_xoffset > info->output_width - info->crop_width ||
1117 + info->crop_yoffset > info->output_height - info->crop_height)
1118 + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
1119 + /* Convert negative crop offsets into regular offsets */
1120 + if (info->crop_xoffset_set == JCROP_NEG)
1121 + xoffset = info->output_width - info->crop_width - info->crop_xoffset;
1123 + xoffset = info->crop_xoffset;
1124 + if (info->crop_yoffset_set == JCROP_NEG)
1125 + yoffset = info->output_height - info->crop_height - info->crop_yoffset;
1127 + yoffset = info->crop_yoffset;
1128 + /* Now adjust so that upper left corner falls at an iMCU boundary */
1129 + info->output_width =
1130 + info->crop_width + (xoffset % (info->max_h_samp_factor * DCTSIZE));
1131 + info->output_height =
1132 + info->crop_height + (yoffset % (info->max_v_samp_factor * DCTSIZE));
1133 + /* Save x/y offsets measured in iMCUs */
1134 + info->x_crop_offset = xoffset / (info->max_h_samp_factor * DCTSIZE);
1135 + info->y_crop_offset = yoffset / (info->max_v_samp_factor * DCTSIZE);
1137 + info->x_crop_offset = 0;
1138 + info->y_crop_offset = 0;
1141 + /* Figure out whether we need workspace arrays,
1142 + * and if so whether they are transposed relative to the source.
1144 + need_workspace = FALSE;
1145 + transpose_it = FALSE;
1146 + switch (info->transform) {
1148 + if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1149 + need_workspace = TRUE;
1150 + /* No workspace needed if neither cropping nor transforming */
1153 - /* Don't need a workspace array
*/
1155 + trim_right_edge
(info
, srcinfo-
>image_width
);
1156 + if (info-
>y_crop_offset
!= 0)
1157 + need_workspace
= TRUE
;
1158 + /* do_flip_h_no_crop doesn
't need a workspace array */
1161 - case JXFORM_ROT_180:
1162 - /* Need workspace arrays having same dimensions as source image.
1163 - * Note that we allocate arrays padded out to the next iMCU boundary,
1164 - * so that transform routines need not worry about missing edge blocks.
1166 - coef_arrays = (jvirt_barray_ptr *)
1167 - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1168 - SIZEOF(jvirt_barray_ptr) * info->num_components);
1169 - for (ci = 0; ci < info->num_components; ci++) {
1170 - compptr = srcinfo->comp_info + ci;
1171 - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1172 - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
1173 - (JDIMENSION) jround_up((long) compptr->width_in_blocks,
1174 - (long) compptr->h_samp_factor),
1175 - (JDIMENSION) jround_up((long) compptr->height_in_blocks,
1176 - (long) compptr->v_samp_factor),
1177 - (JDIMENSION) compptr->v_samp_factor);
1180 + trim_bottom_edge(info, srcinfo->image_height);
1181 + /* Need workspace arrays having same dimensions as source image. */
1182 + need_workspace = TRUE;
1184 case JXFORM_TRANSPOSE:
1185 + /* transpose does NOT have to trim anything */
1186 + /* Need workspace arrays having transposed dimensions. */
1187 + need_workspace = TRUE;
1188 + transpose_it = TRUE;
1190 case JXFORM_TRANSVERSE:
1192 + trim_right_edge(info, srcinfo->image_height);
1193 + trim_bottom_edge(info, srcinfo->image_width);
1195 + /* Need workspace arrays having transposed dimensions. */
1196 + need_workspace = TRUE;
1197 + transpose_it = TRUE;
1201 + trim_right_edge(info, srcinfo->image_height);
1202 + /* Need workspace arrays having transposed dimensions. */
1203 + need_workspace = TRUE;
1204 + transpose_it = TRUE;
1206 + case JXFORM_ROT_180:
1208 + trim_right_edge(info, srcinfo->image_width);
1209 + trim_bottom_edge(info, srcinfo->image_height);
1211 + /* Need workspace arrays having same dimensions as source image. */
1212 + need_workspace = TRUE;
1214 case JXFORM_ROT_270:
1215 - /* Need workspace arrays having transposed dimensions.
1216 - * Note that we allocate arrays padded out to the next iMCU boundary,
1217 - * so that transform routines need not worry about missing edge blocks.
1220 + trim_bottom_edge(info, srcinfo->image_width);
1221 + /* Need workspace arrays having transposed dimensions. */
1222 + need_workspace = TRUE;
1223 + transpose_it = TRUE;
1227 + /* Allocate workspace if needed.
1228 + * Note that we allocate arrays padded out to the next iMCU boundary,
1229 + * so that transform routines need not worry about missing edge blocks.
1231 + if (need_workspace) {
1232 coef_arrays = (jvirt_barray_ptr *)
1233 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1234 - SIZEOF(jvirt_barray_ptr) * info->num_components);
1235 + SIZEOF(jvirt_barray_ptr) * info->num_components);
1236 + width_in_iMCUs = (JDIMENSION)
1237 + jdiv_round_up((long) info->output_width,
1238 + (long) (info->max_h_samp_factor * DCTSIZE));
1239 + height_in_iMCUs = (JDIMENSION)
1240 + jdiv_round_up((long) info->output_height,
1241 + (long) (info->max_v_samp_factor * DCTSIZE));
1242 for (ci = 0; ci < info->num_components; ci++) {
1243 compptr = srcinfo->comp_info + ci;
1244 + if (info->num_components == 1) {
1245 + /* we're going to force samp factors to
1x1
in this
case */
1246 + h_samp_factor
= v_samp_factor
= 1;
1247 + } else if (transpose_it
) {
1248 + h_samp_factor
= compptr-
>v_samp_factor
;
1249 + v_samp_factor
= compptr-
>h_samp_factor
;
1251 + h_samp_factor
= compptr-
>h_samp_factor
;
1252 + v_samp_factor
= compptr-
>v_samp_factor
;
1254 + width_in_blocks
= width_in_iMCUs
* h_samp_factor
;
1255 + height_in_blocks
= height_in_iMCUs
* v_samp_factor
;
1256 coef_arrays
[ci
] = (*srcinfo-
>mem-
>request_virt_barray
)
1257 ((j_common_ptr
) srcinfo
, JPOOL_IMAGE
, FALSE
,
1258 - (JDIMENSION
) jround_up
((long
) compptr-
>height_in_blocks
,
1259 - (long
) compptr-
>v_samp_factor
),
1260 - (JDIMENSION
) jround_up
((long
) compptr-
>width_in_blocks
,
1261 - (long
) compptr-
>h_samp_factor
),
1262 - (JDIMENSION
) compptr-
>h_samp_factor
);
1263 + width_in_blocks
, height_in_blocks
, (JDIMENSION
) v_samp_factor
);
1268 info-
>workspace_coef_arrays
= coef_arrays
;
1271 @@
-642,14 +1062,8 @@
1272 int tblno
, i
, j
, ci
, itemp
;
1273 jpeg_component_info
*compptr
;
1274 JQUANT_TBL
*qtblptr
;
1278 - /* Transpose basic image dimensions
*/
1279 - dtemp
= dstinfo-
>image_width
;
1280 - dstinfo-
>image_width
= dstinfo-
>image_height
;
1281 - dstinfo-
>image_height
= dtemp
;
1283 /* Transpose sampling factors
*/
1284 for (ci
= 0; ci
< dstinfo-
>num_components
; ci
++) {
1285 compptr
= dstinfo-
>comp_info
+ ci
;
1286 @@
-674,46 +1088,159 @@
1290 -/* Trim off any partial iMCUs on the indicated destination edge
*/
1291 +/* Adjust Exif image parameters.
1293 + * We try to adjust the Tags ExifImageWidth and ExifImageHeight
if possible.
1297 -trim_right_edge (j_compress_ptr dstinfo
)
1298 +adjust_exif_parameters
(JOCTET FAR
* data
, unsigned int length
,
1299 + JDIMENSION new_width
, JDIMENSION new_height
)
1301 - int ci
, max_h_samp_factor
;
1302 - JDIMENSION MCU_cols
;
1303 + boolean is_motorola
; /* Flag
for byte order
*/
1304 + unsigned int number_of_tags
, tagnum
;
1305 + unsigned int firstoffset
, offset
;
1306 + JDIMENSION new_value
;
1308 - /* We have to compute max_h_samp_factor ourselves
,
1309 - * because it hasn
't been set yet in the destination
1310 - * (and we don't want to use the
source's value).
1312 - max_h_samp_factor = 1;
1313 - for (ci = 0; ci < dstinfo->num_components; ci++) {
1314 - int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
1315 - max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
1316 + if (length < 12) return; /* Length of an IFD entry */
1318 + /* Discover byte order */
1319 + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
1320 + is_motorola = FALSE;
1321 + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
1322 + is_motorola = TRUE;
1326 + /* Check Tag Mark */
1327 + if (is_motorola) {
1328 + if (GETJOCTET(data[2]) != 0) return;
1329 + if (GETJOCTET(data[3]) != 0x2A) return;
1331 + if (GETJOCTET(data[3]) != 0) return;
1332 + if (GETJOCTET(data[2]) != 0x2A) return;
1334 - MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
1335 - if (MCU_cols > 0) /* can't trim to
0 pixels
*/
1336 - dstinfo-
>image_width
= MCU_cols
* (max_h_samp_factor
* DCTSIZE
);
1340 -trim_bottom_edge (j_compress_ptr dstinfo
)
1342 - int ci
, max_v_samp_factor
;
1343 - JDIMENSION MCU_rows
;
1344 + /* Get first IFD offset
(offset to IFD0
) */
1345 + if (is_motorola
) {
1346 + if (GETJOCTET
(data
[4]) != 0) return;
1347 + if (GETJOCTET
(data
[5]) != 0) return;
1348 + firstoffset
= GETJOCTET
(data
[6]);
1349 + firstoffset
<<= 8;
1350 + firstoffset
+= GETJOCTET
(data
[7]);
1352 + if (GETJOCTET
(data
[7]) != 0) return;
1353 + if (GETJOCTET
(data
[6]) != 0) return;
1354 + firstoffset
= GETJOCTET
(data
[5]);
1355 + firstoffset
<<= 8;
1356 + firstoffset
+= GETJOCTET
(data
[4]);
1358 + if (firstoffset
> length
- 2) return; /* check end of data segment
*/
1360 - /* We have to compute max_v_samp_factor ourselves
,
1361 - * because it hasn
't been set yet in the destination
1362 - * (and we don't want to use the
source's value).
1364 - max_v_samp_factor = 1;
1365 - for (ci = 0; ci < dstinfo->num_components; ci++) {
1366 - int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
1367 - max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
1368 + /* Get the number of directory entries contained in this IFD */
1369 + if (is_motorola) {
1370 + number_of_tags = GETJOCTET(data[firstoffset]);
1371 + number_of_tags <<= 8;
1372 + number_of_tags += GETJOCTET(data[firstoffset+1]);
1374 + number_of_tags = GETJOCTET(data[firstoffset+1]);
1375 + number_of_tags <<= 8;
1376 + number_of_tags += GETJOCTET(data[firstoffset]);
1378 - MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
1379 - if (MCU_rows > 0) /* can't trim to
0 pixels
*/
1380 - dstinfo-
>image_height
= MCU_rows
* (max_v_samp_factor
* DCTSIZE
);
1381 + if (number_of_tags
== 0) return;
1384 + /* Search
for ExifSubIFD offset Tag
in IFD0
*/
1386 + if (firstoffset
> length
- 12) return; /* check end of data segment
*/
1387 + /* Get Tag number
*/
1388 + if (is_motorola
) {
1389 + tagnum
= GETJOCTET
(data
[firstoffset
]);
1391 + tagnum
+= GETJOCTET
(data
[firstoffset
+1]);
1393 + tagnum
= GETJOCTET
(data
[firstoffset
+1]);
1395 + tagnum
+= GETJOCTET
(data
[firstoffset
]);
1397 + if (tagnum
== 0x8769) break; /* found ExifSubIFD offset Tag
*/
1398 + if (--number_of_tags == 0) return;
1399 + firstoffset
+= 12;
1402 + /* Get the ExifSubIFD offset
*/
1403 + if (is_motorola
) {
1404 + if (GETJOCTET
(data
[firstoffset
+8]) != 0) return;
1405 + if (GETJOCTET
(data
[firstoffset
+9]) != 0) return;
1406 + offset
= GETJOCTET
(data
[firstoffset
+10]);
1408 + offset
+= GETJOCTET
(data
[firstoffset
+11]);
1410 + if (GETJOCTET
(data
[firstoffset
+11]) != 0) return;
1411 + if (GETJOCTET
(data
[firstoffset
+10]) != 0) return;
1412 + offset
= GETJOCTET
(data
[firstoffset
+9]);
1414 + offset
+= GETJOCTET
(data
[firstoffset
+8]);
1416 + if (offset
> length
- 2) return; /* check end of data segment
*/
1418 + /* Get the number of directory entries contained
in this SubIFD
*/
1419 + if (is_motorola
) {
1420 + number_of_tags
= GETJOCTET
(data
[offset
]);
1421 + number_of_tags
<<= 8;
1422 + number_of_tags
+= GETJOCTET
(data
[offset
+1]);
1424 + number_of_tags
= GETJOCTET
(data
[offset
+1]);
1425 + number_of_tags
<<= 8;
1426 + number_of_tags
+= GETJOCTET
(data
[offset
]);
1428 + if (number_of_tags
< 2) return;
1431 + /* Search
for ExifImageWidth and ExifImageHeight Tags
in this SubIFD
*/
1433 + if (offset
> length
- 12) return; /* check end of data segment
*/
1434 + /* Get Tag number
*/
1435 + if (is_motorola
) {
1436 + tagnum
= GETJOCTET
(data
[offset
]);
1438 + tagnum
+= GETJOCTET
(data
[offset
+1]);
1440 + tagnum
= GETJOCTET
(data
[offset
+1]);
1442 + tagnum
+= GETJOCTET
(data
[offset
]);
1444 + if (tagnum
== 0xA002 || tagnum
== 0xA003) {
1445 + if (tagnum
== 0xA002)
1446 + new_value
= new_width
; /* ExifImageWidth Tag
*/
1448 + new_value
= new_height
; /* ExifImageHeight Tag
*/
1449 + if (is_motorola
) {
1450 + data
[offset
+2] = 0; /* Format
= unsigned long
(4 octets
) */
1451 + data
[offset
+3] = 4;
1452 + data
[offset
+4] = 0; /* Number Of Components
= 1 */
1453 + data
[offset
+5] = 0;
1454 + data
[offset
+6] = 0;
1455 + data
[offset
+7] = 1;
1456 + data
[offset
+8] = 0;
1457 + data
[offset
+9] = 0;
1458 + data
[offset
+10] = (JOCTET
)((new_value
>> 8) & 0xFF);
1459 + data
[offset
+11] = (JOCTET
)(new_value
& 0xFF);
1461 + data
[offset
+2] = 4; /* Format
= unsigned long
(4 octets
) */
1462 + data
[offset
+3] = 0;
1463 + data
[offset
+4] = 1; /* Number Of Components
= 1 */
1464 + data
[offset
+5] = 0;
1465 + data
[offset
+6] = 0;
1466 + data
[offset
+7] = 0;
1467 + data
[offset
+8] = (JOCTET
)(new_value
& 0xFF);
1468 + data
[offset
+9] = (JOCTET
)((new_value
>> 8) & 0xFF);
1469 + data
[offset
+10] = 0;
1470 + data
[offset
+11] = 0;
1474 + } while (--number_of_tags);
1478 @@
-736,18 +1263,22 @@
1480 /* If force-to-grayscale is requested
, adjust destination parameters
*/
1481 if (info-
>force_grayscale
) {
1482 - /* We use jpeg_set_colorspace to
make sure subsidiary settings get fixed
1483 - * properly. Among other things
, the target h_samp_factor
& v_samp_factor
1484 - * will get
set to
1, which typically won
't match the source.
1485 - * In fact we do this even if the source is already grayscale; that
1486 - * provides an easy way of coercing a grayscale JPEG with funny sampling
1487 - * factors to the customary 1,1. (Some decoders fail on other factors.)
1488 + /* First, ensure we have YCbCr or grayscale data, and that the source's
1489 + * Y channel is full resolution.
(No reasonable person would
make Y
1490 + * be
less than full resolution
, so actually coping with that
case
1491 + * isn
't worth extra code space. But we check it to avoid crashing.)
1493 - if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
1494 - dstinfo->num_components == 3) ||
1495 - (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
1496 - dstinfo->num_components == 1)) {
1497 - /* We have to preserve the source's quantization table number.
*/
1498 + if (((dstinfo-
>jpeg_color_space
== JCS_YCbCr
&&
1499 + dstinfo-
>num_components
== 3) ||
1500 + (dstinfo-
>jpeg_color_space
== JCS_GRAYSCALE
&&
1501 + dstinfo-
>num_components
== 1)) &&
1502 + srcinfo-
>comp_info
[0].h_samp_factor
== srcinfo-
>max_h_samp_factor
&&
1503 + srcinfo-
>comp_info
[0].v_samp_factor
== srcinfo-
>max_v_samp_factor
) {
1504 + /* We use jpeg_set_colorspace to
make sure subsidiary settings get fixed
1505 + * properly. Among other things
, it sets the target h_samp_factor
&
1506 + * v_samp_factor to
1, which typically won
't match the source.
1507 + * We have to preserve the source's quantization table number
, however.
1509 int sv_quant_tbl_no
= dstinfo-
>comp_info
[0].quant_tbl_no
;
1510 jpeg_set_colorspace
(dstinfo
, JCS_GRAYSCALE
);
1511 dstinfo-
>comp_info
[0].quant_tbl_no
= sv_quant_tbl_no
;
1512 @@
-755,50 +1286,52 @@
1513 /* Sorry
, can
't do it */
1514 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
1516 + } else if (info->num_components == 1) {
1517 + /* For a single-component source, we force the destination sampling factors
1518 + * to 1x1, with or without force_grayscale. This is useful because some
1519 + * decoders choke on grayscale images with other sampling factors.
1521 + dstinfo->comp_info[0].h_samp_factor = 1;
1522 + dstinfo->comp_info[0].v_samp_factor = 1;
1525 - /* Correct the destination's image dimensions etc
if necessary
*/
1526 + /* Correct the destination
's image dimensions as necessary
1527 + * for crop and rotate/flip operations.
1529 + dstinfo->image_width = info->output_width;
1530 + dstinfo->image_height = info->output_height;
1532 + /* Transpose destination image parameters */
1533 switch (info->transform) {
1535 - /* Nothing to do */
1537 - case JXFORM_FLIP_H:
1539 - trim_right_edge(dstinfo);
1541 - case JXFORM_FLIP_V:
1543 - trim_bottom_edge(dstinfo);
1545 case JXFORM_TRANSPOSE:
1546 - transpose_critical_parameters(dstinfo);
1547 - /* transpose does NOT have to trim anything */
1549 case JXFORM_TRANSVERSE:
1550 - transpose_critical_parameters(dstinfo);
1552 - trim_right_edge(dstinfo);
1553 - trim_bottom_edge(dstinfo);
1557 - transpose_critical_parameters(dstinfo);
1559 - trim_right_edge(dstinfo);
1561 - case JXFORM_ROT_180:
1563 - trim_right_edge(dstinfo);
1564 - trim_bottom_edge(dstinfo);
1567 case JXFORM_ROT_270:
1568 transpose_critical_parameters(dstinfo);
1570 - trim_bottom_edge(dstinfo);
1574 + /* Adjust Exif properties */
1575 + if (srcinfo->marker_list != NULL &&
1576 + srcinfo->marker_list->marker == JPEG_APP0+1 &&
1577 + srcinfo->marker_list->data_length >= 6 &&
1578 + GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
1579 + GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
1580 + GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
1581 + GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
1582 + GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
1583 + GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
1584 + /* Suppress output of JFIF marker */
1585 + dstinfo->write_JFIF_header = FALSE;
1586 + /* Adjust Exif image parameters */
1587 + if (dstinfo->image_width != srcinfo->image_width ||
1588 + dstinfo->image_height != srcinfo->image_height)
1589 + /* Align data segment to start of TIFF structure for parsing */
1590 + adjust_exif_parameters(srcinfo->marker_list->data + 6,
1591 + srcinfo->marker_list->data_length - 6,
1592 + dstinfo->image_width, dstinfo->image_height);
1595 /* Return the appropriate output data set */
1596 if (info->workspace_coef_arrays != NULL)
1597 return info->workspace_coef_arrays;
1598 @@ -816,38 +1349,106 @@
1602 -jtransform_execute_transformation (j_decompress_ptr srcinfo,
1603 - j_compress_ptr dstinfo,
1604 - jvirt_barray_ptr *src_coef_arrays,
1605 - jpeg_transform_info *info)
1606 +jtransform_execute_transform (j_decompress_ptr srcinfo,
1607 + j_compress_ptr dstinfo,
1608 + jvirt_barray_ptr *src_coef_arrays,
1609 + jpeg_transform_info *info)
1611 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
1613 + /* Note: conditions tested here should match those in switch statement
1614 + * in jtransform_request_workspace()
1616 switch (info->transform) {
1618 + if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1619 + do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1620 + src_coef_arrays, dst_coef_arrays);
1623 - do_flip_h(srcinfo, dstinfo, src_coef_arrays);
1624 + if (info->y_crop_offset != 0)
1625 + do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1626 + src_coef_arrays, dst_coef_arrays);
1628 + do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
1632 - do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1633 + do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1634 + src_coef_arrays, dst_coef_arrays);
1636 case JXFORM_TRANSPOSE:
1637 - do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1638 + do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1639 + src_coef_arrays, dst_coef_arrays);
1641 case JXFORM_TRANSVERSE:
1642 - do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1643 + do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1644 + src_coef_arrays, dst_coef_arrays);
1647 - do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1648 + do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1649 + src_coef_arrays, dst_coef_arrays);
1651 case JXFORM_ROT_180:
1652 - do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1653 + do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1654 + src_coef_arrays, dst_coef_arrays);
1656 case JXFORM_ROT_270:
1657 - do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1658 + do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1659 + src_coef_arrays, dst_coef_arrays);
1664 +/* jtransform_perfect_transform
1666 + * Determine whether lossless transformation is perfectly
1667 + * possible for a specified image and transformation.
1670 + * image_width, image_height: source image dimensions.
1671 + * MCU_width, MCU_height: pixel dimensions of MCU.
1672 + * transform: transformation identifier.
1673 + * Parameter sources from initialized jpeg_struct
1674 + * (after reading source header):
1675 + * image_width = cinfo.image_width
1676 + * image_height = cinfo.image_height
1677 + * MCU_width = cinfo.max_h_samp_factor * DCTSIZE
1678 + * MCU_height = cinfo.max_v_samp_factor * DCTSIZE
1680 + * TRUE = perfect transformation possible
1681 + * FALSE = perfect transformation not possible
1682 + * (may use custom action then)
1686 +jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
1687 + int MCU_width, int MCU_height,
1688 + JXFORM_CODE transform)
1690 + boolean result = TRUE; /* initialize TRUE */
1692 + switch (transform) {
1693 + case JXFORM_FLIP_H:
1694 + case JXFORM_ROT_270:
1695 + if (image_width % (JDIMENSION) MCU_width)
1698 + case JXFORM_FLIP_V:
1699 + case JXFORM_ROT_90:
1700 + if (image_height % (JDIMENSION) MCU_height)
1703 + case JXFORM_TRANSVERSE:
1704 + case JXFORM_ROT_180:
1705 + if (image_width % (JDIMENSION) MCU_width)
1707 + if (image_height % (JDIMENSION) MCU_height)
1715 #endif /* TRANSFORMS_SUPPORTED */
1716 diff -urNad /home/bill/debian/libjpeg/libjpeg6b-6b/transupp.h libjpeg6b-6b/transupp.h
1717 --- /home/bill/debian/libjpeg/libjpeg6b-6b/transupp.h 2003-09-22 18:15:49.000000000 +0200
1718 +++ libjpeg6b-6b/transupp.h 2003-09-22 18:16:16.000000000 +0200
1723 - * Copyright (C) 1997, Thomas G. Lane.
1724 + * Copyright (C) 1997-2001, Thomas G. Lane.
1725 * This file is part of the Independent JPEG Group's software.
1726 * For conditions of distribution and use
, see the accompanying README
file.
1729 #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */
1732 -/* Short forms of external names
for systems with brain-damaged linkers.
*/
1734 -#ifdef NEED_SHORT_EXTERNAL_NAMES
1735 -#define jtransform_request_workspace jTrRequest
1736 -#define jtransform_adjust_parameters jTrAdjust
1737 -#define jtransform_execute_transformation jTrExec
1738 -#define jcopy_markers_setup jCMrkSetup
1739 -#define jcopy_markers_execute jCMrkExec
1740 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
1744 - * Codes
for supported types of image transformations.
1748 - JXFORM_NONE
, /* no transformation
*/
1749 - JXFORM_FLIP_H
, /* horizontal flip
*/
1750 - JXFORM_FLIP_V
, /* vertical flip
*/
1751 - JXFORM_TRANSPOSE
, /* transpose across UL-to-LR axis
*/
1752 - JXFORM_TRANSVERSE
, /* transpose across UR-to-LL axis
*/
1753 - JXFORM_ROT_90
, /* 90-degree clockwise rotation
*/
1754 - JXFORM_ROT_180
, /* 180-degree rotation
*/
1755 - JXFORM_ROT_270
/* 270-degree clockwise
(or
90 ccw
) */
1759 * Although rotating and flipping data expressed as DCT coefficients is not
1760 * hard
, there is an asymmetry
in the JPEG format specification
for images
1762 * (For example
, -rot 270 -trim trims only the bottom edge
, but
-rot 90 -trim
1763 * followed by
-rot 180 -trim trims both edges.
)
1765 + * We also offer a lossless-crop option
, which discards data outside a given
1766 + * image region but losslessly preserves what is inside. Like the rotate and
1767 + * flip transforms
, lossless crop is restricted by the JPEG format
: the upper
1768 + * left corner of the selected region must fall on an iMCU boundary. If this
1769 + * does not hold
for the given crop parameters
, we silently move the upper left
1770 + * corner up and
/or left to
make it so
, simultaneously increasing the region
1771 + * dimensions to keep the lower right crop corner unchanged.
(Thus
, the
1772 + * output image covers
at least the requested region
, but may cover
more.
)
1774 + * If both crop and a rotate
/flip transform are requested
, the crop is applied
1775 + * last
--- that is
, the crop region is specified
in terms of the destination
1778 * We also offer a
"force to grayscale" option
, which simply discards the
1779 * chrominance channels of a YCbCr image. This is lossless
in the sense that
1780 * the luminance channel is preserved exactly. It
's not the same kind of
1782 * be aware of the option to know how many components to work on.
1786 +/* Short forms of external names for systems with brain-damaged linkers. */
1788 +#ifdef NEED_SHORT_EXTERNAL_NAMES
1789 +#define jtransform_parse_crop_spec jTrParCrop
1790 +#define jtransform_request_workspace jTrRequest
1791 +#define jtransform_adjust_parameters jTrAdjust
1792 +#define jtransform_execute_transform jTrExec
1793 +#define jtransform_perfect_transform jTrPerfect
1794 +#define jcopy_markers_setup jCMrkSetup
1795 +#define jcopy_markers_execute jCMrkExec
1796 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
1800 + * Codes for supported types of image transformations.
1804 + JXFORM_NONE, /* no transformation */
1805 + JXFORM_FLIP_H, /* horizontal flip */
1806 + JXFORM_FLIP_V, /* vertical flip */
1807 + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
1808 + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
1809 + JXFORM_ROT_90, /* 90-degree clockwise rotation */
1810 + JXFORM_ROT_180, /* 180-degree rotation */
1811 + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
1815 + * Codes for crop parameters, which can individually be unspecified,
1816 + * positive, or negative. (Negative width or height makes no sense, though.)
1826 + * Transform parameters struct.
1827 + * NB: application must not change any elements of this struct after
1828 + * calling jtransform_request_workspace.
1832 /* Options: set by caller */
1833 JXFORM_CODE transform; /* image transform operator */
1834 + boolean perfect; /* if TRUE, fail if partial MCUs are requested */
1835 boolean trim; /* if TRUE, trim partial MCUs as needed */
1836 boolean force_grayscale; /* if TRUE, convert color image to grayscale */
1837 + boolean crop; /* if TRUE, crop source image */
1839 + /* Crop parameters: application need not set these unless crop is TRUE.
1840 + * These can be filled in by jtransform_parse_crop_spec().
1842 + JDIMENSION crop_width; /* Width of selected region */
1843 + JCROP_CODE crop_width_set;
1844 + JDIMENSION crop_height; /* Height of selected region */
1845 + JCROP_CODE crop_height_set;
1846 + JDIMENSION crop_xoffset; /* X offset of selected region */
1847 + JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */
1848 + JDIMENSION crop_yoffset; /* Y offset of selected region */
1849 + JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */
1851 /* Internal workspace: caller should not touch these */
1852 int num_components; /* # of components in workspace */
1853 jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
1854 + JDIMENSION output_width; /* cropped destination dimensions */
1855 + JDIMENSION output_height;
1856 + JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */
1857 + JDIMENSION y_crop_offset;
1858 + int max_h_samp_factor; /* destination iMCU size */
1859 + int max_v_samp_factor;
1860 } jpeg_transform_info;
1863 #if TRANSFORMS_SUPPORTED
1865 +/* Parse a crop specification (written in X11 geometry style) */
1866 +EXTERN(boolean) jtransform_parse_crop_spec
1867 + JPP((jpeg_transform_info *info, const char *spec));
1868 /* Request any required workspace */
1869 EXTERN(void) jtransform_request_workspace
1870 JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
1871 @@ -106,10 +162,24 @@
1872 jvirt_barray_ptr *src_coef_arrays,
1873 jpeg_transform_info *info));
1874 /* Execute the actual transformation, if any */
1875 -EXTERN(void) jtransform_execute_transformation
1876 +EXTERN(void) jtransform_execute_transform
1877 JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1878 jvirt_barray_ptr *src_coef_arrays,
1879 jpeg_transform_info *info));
1880 +/* Determine whether lossless transformation is perfectly
1881 + * possible for a specified image and transformation.
1883 +EXTERN(boolean) jtransform_perfect_transform
1884 + JPP((JDIMENSION image_width, JDIMENSION image_height,
1885 + int MCU_width, int MCU_height,
1886 + JXFORM_CODE transform));
1888 +/* jtransform_execute_transform used to be called
1889 + * jtransform_execute_transformation, but some compilers complain about
1890 + * routine names that long. This macro is here to avoid breaking any
1891 + * old source code that uses the original name...
1893 +#define jtransform_execute_transformation jtransform_execute_transform
1895 #endif /* TRANSFORMS_SUPPORTED */