1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * GThumb
5 *
6 * Copyright (C) 2001, 2002 The Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 /* based upon file transupp.c from the libjpeg package, original copyright
24 * note follows:
25 .*
26 *
27 * transupp.c
28 *
29 * Copyright (C) 1997, Thomas G. Lane.
30 * This file is part of the Independent JPEG Group's software.
31 * For conditions of distribution and use, see the accompanying README file.
32 *
33 * This file contains image transformation routines and other utility code
34 * used by the jpegtran sample application. These are NOT part of the core
35 * JPEG library. But we keep these routines separate from jpegtran.c to
36 * ease the task of maintaining jpegtran-like programs that have other user
37 * interfaces.
38 */
39
40 #include <config.h>
41
42 #ifdef HAVE_LIBJPEG
43
44 #define SAVE_MARKERS_SUPPORTED 1
45
46 #include <stdio.h>
47 #include <jpeglib.h>
48 #include "transupp-6b.h" /* My own external interface */
49
50 #ifndef MAX
51 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
52 #endif
53
54 enum {
55 JERR_CONVERSION_NOTIMPL
56 };
57
58 #define ERREXIT(cinfo,code) \
59 ((cinfo)->err->msg_code = (code), \
60 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
61
62
63 static long
jround_up(long a,long b)64 jround_up (long a, long b)
65 /* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
66 /* Assumes a >= 0, b > 0 */
67 {
68 a += b - 1L;
69 return a - (a % b);
70 }
71
72
73 static void
jcopy_block_row(JBLOCKROW input_row,JBLOCKROW output_row,JDIMENSION num_blocks)74 jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
75 JDIMENSION num_blocks)
76 /* Copy a row of coefficient blocks from one place to another. */
77 {
78 register JCOEFPTR inptr, outptr;
79 register long count;
80
81 inptr = (JCOEFPTR) input_row;
82 outptr = (JCOEFPTR) output_row;
83 for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
84 *outptr++ = *inptr++;
85 }
86 }
87
88
89 /*
90 * Lossless image transformation routines. These routines work on DCT
91 * coefficient arrays and thus do not require any lossy decompression
92 * or recompression of the image.
93 * Thanks to Guido Vollbeding for the initial design and code of this feature.
94 *
95 * Horizontal flipping is done in-place, using a single top-to-bottom
96 * pass through the virtual source array. It will thus be much the
97 * fastest option for images larger than main memory.
98 *
99 * The other routines require a set of destination virtual arrays, so they
100 * need twice as much memory as jpegtran normally does. The destination
101 * arrays are always written in normal scan order (top to bottom) because
102 * the virtual array manager expects this. The source arrays will be scanned
103 * in the corresponding order, which means multiple passes through the source
104 * arrays for most of the transforms. That could result in much thrashing
105 * if the image is larger than main memory.
106 *
107 * Some notes about the operating environment of the individual transform
108 * routines:
109 * 1. Both the source and destination virtual arrays are allocated from the
110 * source JPEG object, and therefore should be manipulated by calling the
111 * source's memory manager.
112 * 2. The destination's component count should be used. It may be smaller
113 * than the source's when forcing to grayscale.
114 * 3. Likewise the destination's sampling factors should be used. When
115 * forcing to grayscale the destination's sampling factors will be all 1,
116 * and we may as well take that as the effective iMCU size.
117 * 4. When "trim" is in effect, the destination's dimensions will be the
118 * trimmed values but the source's will be untrimmed.
119 * 5. All the routines assume that the source and destination buffers are
120 * padded out to a full iMCU boundary. This is true, although for the
121 * source buffer it is an undocumented property of jdcoefct.c.
122 * Notes 2,3,4 boil down to this: generally we should use the destination's
123 * dimensions and ignore the source's.
124 */
125
126
127 static void
do_flip_h(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays)128 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
129 jvirt_barray_ptr *src_coef_arrays)
130 /* Horizontal flip; done in-place, so no separate dest array is required */
131 {
132 JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
133 int ci, k, offset_y;
134 JBLOCKARRAY buffer;
135 JCOEFPTR ptr1, ptr2;
136 JCOEF temp1, temp2;
137 jpeg_component_info *compptr;
138
139 /* Horizontal mirroring of DCT blocks is accomplished by swapping
140 * pairs of blocks in-place. Within a DCT block, we perform horizontal
141 * mirroring by changing the signs of odd-numbered columns.
142 * Partial iMCUs at the right edge are left untouched.
143 */
144 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
145
146 for (ci = 0; ci < dstinfo->num_components; ci++) {
147 compptr = dstinfo->comp_info + ci;
148 comp_width = MCU_cols * compptr->h_samp_factor;
149 for (blk_y = 0; blk_y < compptr->height_in_blocks;
150 blk_y += compptr->v_samp_factor) {
151 buffer = (*srcinfo->mem->access_virt_barray)
152 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
153 (JDIMENSION) compptr->v_samp_factor, TRUE);
154 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
155 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
156 ptr1 = buffer[offset_y][blk_x];
157 ptr2 = buffer[offset_y][comp_width - blk_x - 1];
158 /* this unrolled loop doesn't need to know which row it's on... */
159 for (k = 0; k < DCTSIZE2; k += 2) {
160 temp1 = *ptr1; /* swap even column */
161 temp2 = *ptr2;
162 *ptr1++ = temp2;
163 *ptr2++ = temp1;
164 temp1 = *ptr1; /* swap odd column with sign change */
165 temp2 = *ptr2;
166 *ptr1++ = -temp2;
167 *ptr2++ = -temp1;
168 }
169 }
170 }
171 }
172 }
173 }
174
175
176 static void
do_flip_v(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)177 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
178 jvirt_barray_ptr *src_coef_arrays,
179 jvirt_barray_ptr *dst_coef_arrays)
180 /* Vertical flip */
181 {
182 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
183 int ci, i, j, offset_y;
184 JBLOCKARRAY src_buffer, dst_buffer;
185 JBLOCKROW src_row_ptr, dst_row_ptr;
186 JCOEFPTR src_ptr, dst_ptr;
187 jpeg_component_info *compptr;
188
189 /* We output into a separate array because we can't touch different
190 * rows of the source virtual array simultaneously. Otherwise, this
191 * is a pretty straightforward analog of horizontal flip.
192 * Within a DCT block, vertical mirroring is done by changing the signs
193 * of odd-numbered rows.
194 * Partial iMCUs at the bottom edge are copied verbatim.
195 */
196 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
197
198 for (ci = 0; ci < dstinfo->num_components; ci++) {
199 compptr = dstinfo->comp_info + ci;
200 comp_height = MCU_rows * compptr->v_samp_factor;
201 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
202 dst_blk_y += compptr->v_samp_factor) {
203 dst_buffer = (*srcinfo->mem->access_virt_barray)
204 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
205 (JDIMENSION) compptr->v_samp_factor, TRUE);
206 if (dst_blk_y < comp_height) {
207 /* Row is within the mirrorable area. */
208 src_buffer = (*srcinfo->mem->access_virt_barray)
209 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
210 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
211 (JDIMENSION) compptr->v_samp_factor, FALSE);
212 } else {
213 /* Bottom-edge blocks will be copied verbatim. */
214 src_buffer = (*srcinfo->mem->access_virt_barray)
215 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
216 (JDIMENSION) compptr->v_samp_factor, FALSE);
217 }
218 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
219 if (dst_blk_y < comp_height) {
220 /* Row is within the mirrorable area. */
221 dst_row_ptr = dst_buffer[offset_y];
222 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
223 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
224 dst_blk_x++) {
225 dst_ptr = dst_row_ptr[dst_blk_x];
226 src_ptr = src_row_ptr[dst_blk_x];
227 for (i = 0; i < DCTSIZE; i += 2) {
228 /* copy even row */
229 for (j = 0; j < DCTSIZE; j++)
230 *dst_ptr++ = *src_ptr++;
231 /* copy odd row with sign change */
232 for (j = 0; j < DCTSIZE; j++)
233 *dst_ptr++ = - *src_ptr++;
234 }
235 }
236 } else {
237 /* Just copy row verbatim. */
238 jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
239 compptr->width_in_blocks);
240 }
241 }
242 }
243 }
244 }
245
246
247 static void
do_transpose(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)248 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
249 jvirt_barray_ptr *src_coef_arrays,
250 jvirt_barray_ptr *dst_coef_arrays)
251 /* Transpose source into destination */
252 {
253 JDIMENSION dst_blk_x, dst_blk_y;
254 int ci, i, j, offset_x, offset_y;
255 JBLOCKARRAY src_buffer, dst_buffer;
256 JCOEFPTR src_ptr, dst_ptr;
257 jpeg_component_info *compptr;
258
259 /* Transposing pixels within a block just requires transposing the
260 * DCT coefficients.
261 * Partial iMCUs at the edges require no special treatment; we simply
262 * process all the available DCT blocks for every component.
263 */
264 for (ci = 0; ci < dstinfo->num_components; ci++) {
265 compptr = dstinfo->comp_info + ci;
266 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
267 dst_blk_y += compptr->v_samp_factor) {
268 dst_buffer = (*srcinfo->mem->access_virt_barray)
269 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
270 (JDIMENSION) compptr->v_samp_factor, TRUE);
271 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
272 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
273 dst_blk_x += compptr->h_samp_factor) {
274 src_buffer = (*srcinfo->mem->access_virt_barray)
275 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
276 (JDIMENSION) compptr->h_samp_factor, FALSE);
277 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
278 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
279 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
280 for (i = 0; i < DCTSIZE; i++)
281 for (j = 0; j < DCTSIZE; j++)
282 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
283 }
284 }
285 }
286 }
287 }
288 }
289
290
291 static void
do_rot_90(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)292 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
293 jvirt_barray_ptr *src_coef_arrays,
294 jvirt_barray_ptr *dst_coef_arrays)
295 /* 90 degree rotation is equivalent to
296 * 1. Transposing the image;
297 * 2. Horizontal mirroring.
298 * These two steps are merged into a single processing routine.
299 */
300 {
301 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
302 int ci, i, j, offset_x, offset_y;
303 JBLOCKARRAY src_buffer, dst_buffer;
304 JCOEFPTR src_ptr, dst_ptr;
305 jpeg_component_info *compptr;
306
307 /* Because of the horizontal mirror step, we can't process partial iMCUs
308 * at the (output) right edge properly. They just get transposed and
309 * not mirrored.
310 */
311 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
312
313 for (ci = 0; ci < dstinfo->num_components; ci++) {
314 compptr = dstinfo->comp_info + ci;
315 comp_width = MCU_cols * compptr->h_samp_factor;
316 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
317 dst_blk_y += compptr->v_samp_factor) {
318 dst_buffer = (*srcinfo->mem->access_virt_barray)
319 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
320 (JDIMENSION) compptr->v_samp_factor, TRUE);
321 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
322 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
323 dst_blk_x += compptr->h_samp_factor) {
324 src_buffer = (*srcinfo->mem->access_virt_barray)
325 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
326 (JDIMENSION) compptr->h_samp_factor, FALSE);
327 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
328 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
329 if (dst_blk_x < comp_width) {
330 /* Block is within the mirrorable area. */
331 dst_ptr = dst_buffer[offset_y]
332 [comp_width - dst_blk_x - offset_x - 1];
333 for (i = 0; i < DCTSIZE; i++) {
334 for (j = 0; j < DCTSIZE; j++)
335 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
336 i++;
337 for (j = 0; j < DCTSIZE; j++)
338 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
339 }
340 } else {
341 /* Edge blocks are transposed but not mirrored. */
342 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
343 for (i = 0; i < DCTSIZE; i++)
344 for (j = 0; j < DCTSIZE; j++)
345 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
346 }
347 }
348 }
349 }
350 }
351 }
352 }
353
354
355 static void
do_rot_270(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)356 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
357 jvirt_barray_ptr *src_coef_arrays,
358 jvirt_barray_ptr *dst_coef_arrays)
359 /* 270 degree rotation is equivalent to
360 * 1. Horizontal mirroring;
361 * 2. Transposing the image.
362 * These two steps are merged into a single processing routine.
363 */
364 {
365 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
366 int ci, i, j, offset_x, offset_y;
367 JBLOCKARRAY src_buffer, dst_buffer;
368 JCOEFPTR src_ptr, dst_ptr;
369 jpeg_component_info *compptr;
370
371 /* Because of the horizontal mirror step, we can't process partial iMCUs
372 * at the (output) bottom edge properly. They just get transposed and
373 * not mirrored.
374 */
375 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
376
377 for (ci = 0; ci < dstinfo->num_components; ci++) {
378 compptr = dstinfo->comp_info + ci;
379 comp_height = MCU_rows * compptr->v_samp_factor;
380 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
381 dst_blk_y += compptr->v_samp_factor) {
382 dst_buffer = (*srcinfo->mem->access_virt_barray)
383 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
384 (JDIMENSION) compptr->v_samp_factor, TRUE);
385 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
386 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
387 dst_blk_x += compptr->h_samp_factor) {
388 src_buffer = (*srcinfo->mem->access_virt_barray)
389 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
390 (JDIMENSION) compptr->h_samp_factor, FALSE);
391 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
392 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
393 if (dst_blk_y < comp_height) {
394 /* Block is within the mirrorable area. */
395 src_ptr = src_buffer[offset_x]
396 [comp_height - dst_blk_y - offset_y - 1];
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];
400 j++;
401 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
402 }
403 }
404 } else {
405 /* Edge blocks are transposed but not mirrored. */
406 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
407 for (i = 0; i < DCTSIZE; i++)
408 for (j = 0; j < DCTSIZE; j++)
409 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
410 }
411 }
412 }
413 }
414 }
415 }
416 }
417
418
419 static void
do_rot_180(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)420 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
421 jvirt_barray_ptr *src_coef_arrays,
422 jvirt_barray_ptr *dst_coef_arrays)
423 /* 180 degree rotation is equivalent to
424 * 1. Vertical mirroring;
425 * 2. Horizontal mirroring.
426 * These two steps are merged into a single processing routine.
427 */
428 {
429 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
430 int ci, i, j, offset_y;
431 JBLOCKARRAY src_buffer, dst_buffer;
432 JBLOCKROW src_row_ptr, dst_row_ptr;
433 JCOEFPTR src_ptr, dst_ptr;
434 jpeg_component_info *compptr;
435
436 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
437 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
438
439 for (ci = 0; ci < dstinfo->num_components; ci++) {
440 compptr = dstinfo->comp_info + ci;
441 comp_width = MCU_cols * compptr->h_samp_factor;
442 comp_height = MCU_rows * compptr->v_samp_factor;
443 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
444 dst_blk_y += compptr->v_samp_factor) {
445 dst_buffer = (*srcinfo->mem->access_virt_barray)
446 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
447 (JDIMENSION) compptr->v_samp_factor, TRUE);
448 if (dst_blk_y < comp_height) {
449 /* Row is within the vertically mirrorable area. */
450 src_buffer = (*srcinfo->mem->access_virt_barray)
451 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
452 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
453 (JDIMENSION) compptr->v_samp_factor, FALSE);
454 } else {
455 /* Bottom-edge rows are only mirrored horizontally. */
456 src_buffer = (*srcinfo->mem->access_virt_barray)
457 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
458 (JDIMENSION) compptr->v_samp_factor, FALSE);
459 }
460 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
461 if (dst_blk_y < comp_height) {
462 /* Row is within the mirrorable area. */
463 dst_row_ptr = dst_buffer[offset_y];
464 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
465 /* Process the blocks that can be mirrored both ways. */
466 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
467 dst_ptr = dst_row_ptr[dst_blk_x];
468 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
469 for (i = 0; i < DCTSIZE; i += 2) {
470 /* For even row, negate every odd column. */
471 for (j = 0; j < DCTSIZE; j += 2) {
472 *dst_ptr++ = *src_ptr++;
473 *dst_ptr++ = - *src_ptr++;
474 }
475 /* For odd row, negate every even column. */
476 for (j = 0; j < DCTSIZE; j += 2) {
477 *dst_ptr++ = - *src_ptr++;
478 *dst_ptr++ = *src_ptr++;
479 }
480 }
481 }
482 /* Any remaining right-edge blocks are only mirrored vertically. */
483 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
484 dst_ptr = dst_row_ptr[dst_blk_x];
485 src_ptr = src_row_ptr[dst_blk_x];
486 for (i = 0; i < DCTSIZE; i += 2) {
487 for (j = 0; j < DCTSIZE; j++)
488 *dst_ptr++ = *src_ptr++;
489 for (j = 0; j < DCTSIZE; j++)
490 *dst_ptr++ = - *src_ptr++;
491 }
492 }
493 } else {
494 /* Remaining rows are just mirrored horizontally. */
495 dst_row_ptr = dst_buffer[offset_y];
496 src_row_ptr = src_buffer[offset_y];
497 /* Process the blocks that can be mirrored. */
498 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
499 dst_ptr = dst_row_ptr[dst_blk_x];
500 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
501 for (i = 0; i < DCTSIZE2; i += 2) {
502 *dst_ptr++ = *src_ptr++;
503 *dst_ptr++ = - *src_ptr++;
504 }
505 }
506 /* Any remaining right-edge blocks are only copied. */
507 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
508 dst_ptr = dst_row_ptr[dst_blk_x];
509 src_ptr = src_row_ptr[dst_blk_x];
510 for (i = 0; i < DCTSIZE2; i++)
511 *dst_ptr++ = *src_ptr++;
512 }
513 }
514 }
515 }
516 }
517 }
518
519
520 static void
do_transverse(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jvirt_barray_ptr * dst_coef_arrays)521 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
522 jvirt_barray_ptr *src_coef_arrays,
523 jvirt_barray_ptr *dst_coef_arrays)
524 /* Transverse transpose is equivalent to
525 * 1. 180 degree rotation;
526 * 2. Transposition;
527 * or
528 * 1. Horizontal mirroring;
529 * 2. Transposition;
530 * 3. Horizontal mirroring.
531 * These steps are merged into a single processing routine.
532 */
533 {
534 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
535 int ci, i, j, offset_x, offset_y;
536 JBLOCKARRAY src_buffer, dst_buffer;
537 JCOEFPTR src_ptr, dst_ptr;
538 jpeg_component_info *compptr;
539
540 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
541 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
542
543 for (ci = 0; ci < dstinfo->num_components; ci++) {
544 compptr = dstinfo->comp_info + ci;
545 comp_width = MCU_cols * compptr->h_samp_factor;
546 comp_height = MCU_rows * compptr->v_samp_factor;
547 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
548 dst_blk_y += compptr->v_samp_factor) {
549 dst_buffer = (*srcinfo->mem->access_virt_barray)
550 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
551 (JDIMENSION) compptr->v_samp_factor, TRUE);
552 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
553 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
554 dst_blk_x += compptr->h_samp_factor) {
555 src_buffer = (*srcinfo->mem->access_virt_barray)
556 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
557 (JDIMENSION) compptr->h_samp_factor, FALSE);
558 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
559 if (dst_blk_y < comp_height) {
560 src_ptr = src_buffer[offset_x]
561 [comp_height - dst_blk_y - offset_y - 1];
562 if (dst_blk_x < comp_width) {
563 /* Block is within the mirrorable area. */
564 dst_ptr = dst_buffer[offset_y]
565 [comp_width - dst_blk_x - offset_x - 1];
566 for (i = 0; i < DCTSIZE; i++) {
567 for (j = 0; j < DCTSIZE; j++) {
568 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
569 j++;
570 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
571 }
572 i++;
573 for (j = 0; j < DCTSIZE; j++) {
574 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
575 j++;
576 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
577 }
578 }
579 } else {
580 /* Right-edge blocks are mirrored in y only */
581 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
582 for (i = 0; i < DCTSIZE; i++) {
583 for (j = 0; j < DCTSIZE; j++) {
584 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
585 j++;
586 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
587 }
588 }
589 }
590 } else {
591 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
592 if (dst_blk_x < comp_width) {
593 /* Bottom-edge blocks are mirrored in x only */
594 dst_ptr = dst_buffer[offset_y]
595 [comp_width - dst_blk_x - offset_x - 1];
596 for (i = 0; i < DCTSIZE; i++) {
597 for (j = 0; j < DCTSIZE; j++)
598 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
599 i++;
600 for (j = 0; j < DCTSIZE; j++)
601 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
602 }
603 } else {
604 /* At lower right corner, just transpose, no mirroring */
605 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
606 for (i = 0; i < DCTSIZE; i++)
607 for (j = 0; j < DCTSIZE; j++)
608 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
609 }
610 }
611 }
612 }
613 }
614 }
615 }
616 }
617
618
619 /* Request any required workspace.
620 *
621 * We allocate the workspace virtual arrays from the source decompression
622 * object, so that all the arrays (both the original data and the workspace)
623 * will be taken into account while making memory management decisions.
624 * Hence, this routine must be called after jpeg_read_header (which reads
625 * the image dimensions) and before jpeg_read_coefficients (which realizes
626 * the source's virtual arrays).
627 */
628
629 void
jtransform_request_workspace(j_decompress_ptr srcinfo,jpeg_transform_info * info)630 jtransform_request_workspace (j_decompress_ptr srcinfo,
631 jpeg_transform_info *info)
632 {
633 jvirt_barray_ptr *coef_arrays = NULL;
634 jpeg_component_info *compptr;
635 int ci;
636
637 if (info->force_grayscale &&
638 srcinfo->jpeg_color_space == JCS_YCbCr &&
639 srcinfo->num_components == 3) {
640 /* We'll only process the first component */
641 info->num_components = 1;
642 } else {
643 /* Process all the components */
644 info->num_components = srcinfo->num_components;
645 }
646
647 switch (info->transform) {
648 case JXFORM_NONE:
649 case JXFORM_FLIP_H:
650 /* Don't need a workspace array */
651 break;
652 case JXFORM_FLIP_V:
653 case JXFORM_ROT_180:
654 /* Need workspace arrays having same dimensions as source image.
655 * Note that we allocate arrays padded out to the next iMCU boundary,
656 * so that transform routines need not worry about missing edge blocks.
657 */
658 coef_arrays = (jvirt_barray_ptr *)
659 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
660 sizeof(jvirt_barray_ptr) * info->num_components);
661 for (ci = 0; ci < info->num_components; ci++) {
662 compptr = srcinfo->comp_info + ci;
663 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
664 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
665 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
666 (long) compptr->h_samp_factor),
667 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
668 (long) compptr->v_samp_factor),
669 (JDIMENSION) compptr->v_samp_factor);
670 }
671 break;
672 case JXFORM_TRANSPOSE:
673 case JXFORM_TRANSVERSE:
674 case JXFORM_ROT_90:
675 case JXFORM_ROT_270:
676 /* Need workspace arrays having transposed dimensions.
677 * Note that we allocate arrays padded out to the next iMCU boundary,
678 * so that transform routines need not worry about missing edge blocks.
679 */
680 coef_arrays = (jvirt_barray_ptr *)
681 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
682 sizeof(jvirt_barray_ptr) * info->num_components);
683 for (ci = 0; ci < info->num_components; ci++) {
684 compptr = srcinfo->comp_info + ci;
685 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
686 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
687 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
688 (long) compptr->v_samp_factor),
689 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
690 (long) compptr->h_samp_factor),
691 (JDIMENSION) compptr->h_samp_factor);
692 }
693 break;
694 }
695 info->workspace_coef_arrays = coef_arrays;
696 }
697
698
699 /* Transpose destination image parameters */
700
701 static void
transpose_critical_parameters(j_compress_ptr dstinfo)702 transpose_critical_parameters (j_compress_ptr dstinfo)
703 {
704 int tblno, i, j, ci, itemp;
705 jpeg_component_info *compptr;
706 JQUANT_TBL *qtblptr;
707 JDIMENSION dtemp;
708 UINT16 qtemp;
709
710 /* Transpose basic image dimensions */
711 dtemp = dstinfo->image_width;
712 dstinfo->image_width = dstinfo->image_height;
713 dstinfo->image_height = dtemp;
714
715 /* Transpose sampling factors */
716 for (ci = 0; ci < dstinfo->num_components; ci++) {
717 compptr = dstinfo->comp_info + ci;
718 itemp = compptr->h_samp_factor;
719 compptr->h_samp_factor = compptr->v_samp_factor;
720 compptr->v_samp_factor = itemp;
721 }
722
723 /* Transpose quantization tables */
724 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
725 qtblptr = dstinfo->quant_tbl_ptrs[tblno];
726 if (qtblptr != NULL) {
727 for (i = 0; i < DCTSIZE; i++) {
728 for (j = 0; j < i; j++) {
729 qtemp = qtblptr->quantval[i*DCTSIZE+j];
730 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
731 qtblptr->quantval[j*DCTSIZE+i] = qtemp;
732 }
733 }
734 }
735 }
736 }
737
738
739 /* Trim off any partial iMCUs on the indicated destination edge */
740
741 static void
trim_right_edge(j_compress_ptr dstinfo)742 trim_right_edge (j_compress_ptr dstinfo)
743 {
744 int ci, max_h_samp_factor;
745 JDIMENSION MCU_cols;
746
747 /* We have to compute max_h_samp_factor ourselves,
748 * because it hasn't been set yet in the destination
749 * (and we don't want to use the source's value).
750 */
751 max_h_samp_factor = 1;
752 for (ci = 0; ci < dstinfo->num_components; ci++) {
753 int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
754 max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
755 }
756 MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
757 if (MCU_cols > 0) /* can't trim to 0 pixels */
758 dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
759 }
760
761 static void
trim_bottom_edge(j_compress_ptr dstinfo)762 trim_bottom_edge (j_compress_ptr dstinfo)
763 {
764 int ci, max_v_samp_factor;
765 JDIMENSION MCU_rows;
766
767 /* We have to compute max_v_samp_factor ourselves,
768 * because it hasn't been set yet in the destination
769 * (and we don't want to use the source's value).
770 */
771 max_v_samp_factor = 1;
772 for (ci = 0; ci < dstinfo->num_components; ci++) {
773 int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
774 max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
775 }
776 MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
777 if (MCU_rows > 0) /* can't trim to 0 pixels */
778 dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
779 }
780
781
782 /* Adjust output image parameters as needed.
783 *
784 * This must be called after jpeg_copy_critical_parameters()
785 * and before jpeg_write_coefficients().
786 *
787 * The return value is the set of virtual coefficient arrays to be written
788 * (either the ones allocated by jtransform_request_workspace, or the
789 * original source data arrays). The caller will need to pass this value
790 * to jpeg_write_coefficients().
791 */
792
793 jvirt_barray_ptr *
jtransform_adjust_parameters(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jpeg_transform_info * info)794 jtransform_adjust_parameters (j_decompress_ptr srcinfo,
795 j_compress_ptr dstinfo,
796 jvirt_barray_ptr *src_coef_arrays,
797 jpeg_transform_info *info)
798 {
799 /* If force-to-grayscale is requested, adjust destination parameters */
800 if (info->force_grayscale) {
801 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
802 * properly. Among other things, the target h_samp_factor & v_samp_factor
803 * will get set to 1, which typically won't match the source.
804 * In fact we do this even if the source is already grayscale; that
805 * provides an easy way of coercing a grayscale JPEG with funny sampling
806 * factors to the customary 1,1. (Some decoders fail on other factors.)
807 */
808 if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
809 dstinfo->num_components == 3) ||
810 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
811 dstinfo->num_components == 1)) {
812 /* We have to preserve the source's quantization table number. */
813 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
814 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
815 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
816 } else {
817 /* Sorry, can't do it */
818 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
819 }
820 }
821
822 /* Correct the destination's image dimensions etc if necessary */
823 switch (info->transform) {
824 case JXFORM_NONE:
825 /* Nothing to do */
826 break;
827 case JXFORM_FLIP_H:
828 if (info->trim)
829 trim_right_edge(dstinfo);
830 break;
831 case JXFORM_FLIP_V:
832 if (info->trim)
833 trim_bottom_edge(dstinfo);
834 break;
835 case JXFORM_TRANSPOSE:
836 transpose_critical_parameters(dstinfo);
837 /* transpose does NOT have to trim anything */
838 break;
839 case JXFORM_TRANSVERSE:
840 transpose_critical_parameters(dstinfo);
841 if (info->trim) {
842 trim_right_edge(dstinfo);
843 trim_bottom_edge(dstinfo);
844 }
845 break;
846 case JXFORM_ROT_90:
847 transpose_critical_parameters(dstinfo);
848 if (info->trim)
849 trim_right_edge(dstinfo);
850 break;
851 case JXFORM_ROT_180:
852 if (info->trim) {
853 trim_right_edge(dstinfo);
854 trim_bottom_edge(dstinfo);
855 }
856 break;
857 case JXFORM_ROT_270:
858 transpose_critical_parameters(dstinfo);
859 if (info->trim)
860 trim_bottom_edge(dstinfo);
861 break;
862 }
863
864 /* Return the appropriate output data set */
865 if (info->workspace_coef_arrays != NULL)
866 return info->workspace_coef_arrays;
867 return src_coef_arrays;
868 }
869
870
871 /* Execute the actual transformation, if any.
872 *
873 * This must be called *after* jpeg_write_coefficients, because it depends
874 * on jpeg_write_coefficients to have computed subsidiary values such as
875 * the per-component width and height fields in the destination object.
876 *
877 * Note that some transformations will modify the source data arrays!
878 */
879
880 void
jtransform_execute_transformation(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,jvirt_barray_ptr * src_coef_arrays,jpeg_transform_info * info)881 jtransform_execute_transformation (j_decompress_ptr srcinfo,
882 j_compress_ptr dstinfo,
883 jvirt_barray_ptr *src_coef_arrays,
884 jpeg_transform_info *info)
885 {
886 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
887
888 switch (info->transform) {
889 case JXFORM_NONE:
890 break;
891 case JXFORM_FLIP_H:
892 do_flip_h(srcinfo, dstinfo, src_coef_arrays);
893 break;
894 case JXFORM_FLIP_V:
895 do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
896 break;
897 case JXFORM_TRANSPOSE:
898 do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
899 break;
900 case JXFORM_TRANSVERSE:
901 do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
902 break;
903 case JXFORM_ROT_90:
904 do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
905 break;
906 case JXFORM_ROT_180:
907 do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
908 break;
909 case JXFORM_ROT_270:
910 do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
911 break;
912 }
913 }
914
915
916 /* Setup decompression object to save desired markers in memory.
917 * This must be called before jpeg_read_header() to have the desired effect.
918 */
919
920 void
jcopy_markers_setup(j_decompress_ptr srcinfo,JCOPY_OPTION option)921 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
922 {
923 #ifdef SAVE_MARKERS_SUPPORTED
924 int m;
925
926 /* Save comments except under NONE option */
927 if (option != JCOPYOPT_NONE) {
928 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
929 }
930 /* Save all types of APPn markers iff ALL option */
931 if (option == JCOPYOPT_ALL) {
932 for (m = 0; m < 16; m++)
933 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
934 }
935 #endif /* SAVE_MARKERS_SUPPORTED */
936 }
937
938 /* Copy markers saved in the given source object to the destination object.
939 * This should be called just after jpeg_start_compress() or
940 * jpeg_write_coefficients().
941 * Note that those routines will have written the SOI, and also the
942 * JFIF APP0 or Adobe APP14 markers if selected.
943 */
944
945 void
jcopy_markers_execute(j_decompress_ptr srcinfo,j_compress_ptr dstinfo,JCOPY_OPTION option)946 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
947 JCOPY_OPTION option)
948 {
949 jpeg_saved_marker_ptr marker;
950
951 /* In the current implementation, we don't actually need to examine the
952 * option flag here; we just copy everything that got saved.
953 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
954 * if the encoder library already wrote one.
955 */
956 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
957 if (dstinfo->write_JFIF_header &&
958 marker->marker == JPEG_APP0 &&
959 marker->data_length >= 5 &&
960 GETJOCTET(marker->data[0]) == 0x4A &&
961 GETJOCTET(marker->data[1]) == 0x46 &&
962 GETJOCTET(marker->data[2]) == 0x49 &&
963 GETJOCTET(marker->data[3]) == 0x46 &&
964 GETJOCTET(marker->data[4]) == 0)
965 continue; /* reject duplicate JFIF */
966 if (dstinfo->write_Adobe_marker &&
967 marker->marker == JPEG_APP0+14 &&
968 marker->data_length >= 5 &&
969 GETJOCTET(marker->data[0]) == 0x41 &&
970 GETJOCTET(marker->data[1]) == 0x64 &&
971 GETJOCTET(marker->data[2]) == 0x6F &&
972 GETJOCTET(marker->data[3]) == 0x62 &&
973 GETJOCTET(marker->data[4]) == 0x65)
974 continue; /* reject duplicate Adobe */
975
976 #ifdef NEED_FAR_POINTERS
977 /* We could use jpeg_write_marker if the data weren't FAR... */
978 {
979 unsigned int i;
980 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
981 for (i = 0; i < marker->data_length; i++)
982 jpeg_write_m_byte(dstinfo, marker->data[i]);
983 }
984 #else
985 jpeg_write_marker(dstinfo, marker->marker,
986 marker->data, marker->data_length);
987 #endif
988 }
989 }
990
991
992 #endif /* HAVE_LIBJPEG */
993