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