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