/*
 * transupp.c
 *
 * This file was part of the Independent JPEG Group's software:
 * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding.
 * libjpeg-turbo Modifications:
 * Copyright (C) 2010, 2017, 2021-2022, 2024, D. R. Commander.
 * For conditions of distribution and use, see the accompanying README.ijg
 * file.
 *
 * This file contains image transformation routines and other utility code
 * used by the jpegtran sample application.  These are NOT part of the core
 * JPEG library.  But we keep these routines separate from jpegtran.c to
 * ease the task of maintaining jpegtran-like programs that have other user
 * interfaces.
 */

/* Although this file really shouldn't have access to the library internals,
 * it's helpful to let it call jround_up() and jcopy_block_row().
 */
#define JPEG_INTERNALS

#include "jinclude.h"
#include "jpeglib.h"
#include "transupp.h"           /* My own external interface */
#include "jpegapicomp.h"
#include <ctype.h>              /* to declare isdigit() */


#if JPEG_LIB_VERSION >= 70
#define dstinfo_min_DCT_h_scaled_size  dstinfo->min_DCT_h_scaled_size
#define dstinfo_min_DCT_v_scaled_size  dstinfo->min_DCT_v_scaled_size
#else
#define dstinfo_min_DCT_h_scaled_size  DCTSIZE
#define dstinfo_min_DCT_v_scaled_size  DCTSIZE
#endif


#if TRANSFORMS_SUPPORTED

/*
 * Lossless image transformation routines.  These routines work on DCT
 * coefficient arrays and thus do not require any lossy decompression
 * or recompression of the image.
 * Thanks to Guido Vollbeding for the initial design and code of this feature,
 * and to Ben Jackson for introducing the cropping feature.
 *
 * Horizontal flipping is done in-place, using a single top-to-bottom
 * pass through the virtual source array.  It will thus be much the
 * fastest option for images larger than main memory.
 *
 * The other routines require a set of destination virtual arrays, so they
 * need twice as much memory as jpegtran normally does.  The destination
 * arrays are always written in normal scan order (top to bottom) because
 * the virtual array manager expects this.  The source arrays will be scanned
 * in the corresponding order, which means multiple passes through the source
 * arrays for most of the transforms.  That could result in much thrashing
 * if the image is larger than main memory.
 *
 * If cropping or trimming is involved, the destination arrays may be smaller
 * than the source arrays.  Note it is not possible to do horizontal flip
 * in-place when a nonzero Y crop offset is specified, since we'd have to move
 * data from one block row to another but the virtual array manager doesn't
 * guarantee we can touch more than one row at a time.  So in that case,
 * we have to use a separate destination array.
 *
 * Some notes about the operating environment of the individual transform
 * routines:
 * 1. Both the source and destination virtual arrays are allocated from the
 *    source JPEG object, and therefore should be manipulated by calling the
 *    source's memory manager.
 * 2. The destination's component count should be used.  It may be smaller
 *    than the source's when forcing to grayscale.
 * 3. Likewise the destination's sampling factors should be used.  When
 *    forcing to grayscale the destination's sampling factors will be all 1,
 *    and we may as well take that as the effective iMCU size.
 * 4. When "trim" is in effect, the destination's dimensions will be the
 *    trimmed values but the source's will be untrimmed.
 * 5. When "crop" is in effect, the destination's dimensions will be the
 *    cropped values but the source's will be uncropped.  Each transform
 *    routine is responsible for picking up source data starting at the
 *    correct X and Y offset for the crop region.  (The X and Y offsets
 *    passed to the transform routines are measured in iMCU blocks of the
 *    destination.)
 * 6. All the routines assume that the source and destination buffers are
 *    padded out to a full iMCU boundary.  This is true, although for the
 *    source buffer it is an undocumented property of jdcoefct.c.
 */


LOCAL(void)
dequant_comp(j_decompress_ptr cinfo, jpeg_component_info *compptr,
             jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
{
  JDIMENSION blk_x, blk_y;
  int offset_y, k;
  JQUANT_TBL *qtblptr;
  JBLOCKARRAY buffer;
  JBLOCKROW block;
  JCOEFPTR ptr;

  qtblptr = compptr->quant_table;
  for (blk_y = 0; blk_y < compptr->height_in_blocks;
       blk_y += compptr->v_samp_factor) {
    buffer = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr)cinfo, coef_array, blk_y,
       (JDIMENSION)compptr->v_samp_factor, TRUE);
    for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
      block = buffer[offset_y];
      for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
        ptr = block[blk_x];
        for (k = 0; k < DCTSIZE2; k++)
          if (qtblptr->quantval[k] != qtblptr1->quantval[k])
            ptr[k] *= qtblptr->quantval[k] / qtblptr1->quantval[k];
      }
    }
  }
}


LOCAL(void)
requant_comp(j_decompress_ptr cinfo, jpeg_component_info *compptr,
             jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
{
  JDIMENSION blk_x, blk_y;
  int offset_y, k;
  JQUANT_TBL *qtblptr;
  JBLOCKARRAY buffer;
  JBLOCKROW block;
  JCOEFPTR ptr;
  JCOEF temp, qval;

  qtblptr = compptr->quant_table;
  for (blk_y = 0; blk_y < compptr->height_in_blocks;
       blk_y += compptr->v_samp_factor) {
    buffer = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr)cinfo, coef_array, blk_y,
       (JDIMENSION)compptr->v_samp_factor, TRUE);
    for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
      block = buffer[offset_y];
      for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
        ptr = block[blk_x];
        for (k = 0; k < DCTSIZE2; k++) {
          temp = qtblptr->quantval[k];
          qval = qtblptr1->quantval[k];
          if (temp != qval && qval != 0) {
            temp *= ptr[k];
            /* The following quantization code is copied from jcdctmgr.c */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a, b)  a /= b
#else
#define DIVIDE_BY(a, b)  if (a >= b) a /= b;  else a = 0
#endif
            if (temp < 0) {
              temp = -temp;
              temp += qval >> 1; /* for rounding */
              DIVIDE_BY(temp, qval);
              temp = -temp;
            } else {
              temp += qval >> 1; /* for rounding */
              DIVIDE_BY(temp, qval);
            }
            ptr[k] = temp;
          }
        }
      }
    }
  }
}


/*
 * Calculate largest common denominator using Euclid's algorithm.
 */
LOCAL(JCOEF)
largest_common_denominator(JCOEF a, JCOEF b)
{
  JCOEF c;

  do {
    c = a % b;
    a = b;
    b = c;
  } while (c);

  return a;
}


LOCAL(void)
adjust_quant(j_decompress_ptr srcinfo, jvirt_barray_ptr *src_coef_arrays,
             j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
             boolean trim, j_compress_ptr dstinfo)
{
  jpeg_component_info *compptr1, *compptr2;
  JQUANT_TBL *qtblptr1, *qtblptr2, *qtblptr3;
  int ci, k;

  for (ci = 0; ci < dstinfo->num_components && ci < dropinfo->num_components;
       ci++) {
    compptr1 = srcinfo->comp_info + ci;
    compptr2 = dropinfo->comp_info + ci;
    qtblptr1 = compptr1->quant_table;
    if (qtblptr1 == NULL)
      ERREXIT1(srcinfo, JERR_NO_QUANT_TABLE, compptr1->quant_tbl_no);
    qtblptr2 = compptr2->quant_table;
    if (qtblptr2 == NULL)
      ERREXIT1(dropinfo, JERR_NO_QUANT_TABLE, compptr2->quant_tbl_no);
    for (k = 0; k < DCTSIZE2; k++) {
      if (qtblptr1->quantval[k] != qtblptr2->quantval[k]) {
        if (trim)
          requant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr1);
        else {
          qtblptr3 = dstinfo->quant_tbl_ptrs[compptr1->quant_tbl_no];
          for (k = 0; k < DCTSIZE2; k++)
            if (qtblptr1->quantval[k] != qtblptr2->quantval[k])
              qtblptr3->quantval[k] =
                largest_common_denominator(qtblptr1->quantval[k],
                                           qtblptr2->quantval[k]);
          dequant_comp(srcinfo, compptr1, src_coef_arrays[ci], qtblptr3);
          dequant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr3);
        }
        break;
      }
    }
  }
}


LOCAL(void)
do_drop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
        JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
        jvirt_barray_ptr *src_coef_arrays,
        j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
        JDIMENSION drop_width, JDIMENSION drop_height)
/* Drop (insert) the contents of another image into the source image.  If the
 * number of components in the drop image is smaller than the number of
 * components in the destination image, then we fill in the remaining
 * components with zero.  This allows for dropping the contents of grayscale
 * images into (arbitrarily sampled) color images.
 */
{
  JDIMENSION comp_width, comp_height;
  JDIMENSION blk_y, x_drop_blocks, y_drop_blocks;
  int ci, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  jpeg_component_info *compptr;

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = drop_width * compptr->h_samp_factor;
    comp_height = drop_height * compptr->v_samp_factor;
    x_drop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_drop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (blk_y = 0; blk_y < comp_height; blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], blk_y + y_drop_blocks,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (ci < dropinfo->num_components) {
        src_buffer = (*dropinfo->mem->access_virt_barray)
          ((j_common_ptr)dropinfo, drop_coef_arrays[ci], blk_y,
           (JDIMENSION)compptr->v_samp_factor, FALSE);
        for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
          jcopy_block_row(src_buffer[offset_y],
                          dst_buffer[offset_y] + x_drop_blocks, comp_width);
        }
      } else {
        for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
          memset(dst_buffer[offset_y] + x_drop_blocks, 0,
                 comp_width * sizeof(JBLOCK));
        }
      }
    }
  }
}


LOCAL(void)
do_crop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
        JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
        jvirt_barray_ptr *src_coef_arrays,
        jvirt_barray_ptr *dst_coef_arrays)
/* Crop.  This is only used when no rotate/flip is requested with the crop. */
{
  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
  int ci, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  jpeg_component_info *compptr;

  /* We simply have to copy the right amount of data (the destination's
   * image size) starting at the given X and Y offsets in the source.
   */
  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      src_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], dst_blk_y + y_crop_blocks,
         (JDIMENSION)compptr->v_samp_factor, FALSE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
                        dst_buffer[offset_y], compptr->width_in_blocks);
      }
    }
  }
}


LOCAL(void)
do_crop_ext_zero(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
                 jvirt_barray_ptr *src_coef_arrays,
                 jvirt_barray_ptr *dst_coef_arrays)
/* Crop.  This is only used when no rotate/flip is requested with the crop.
 * Extension: If the destination size is larger than the source, we fill in the
 * expanded region with zero (neutral gray).  Note that we also have to zero
 * partial iMCUs at the right and bottom edge of the source image area in this
 * case.
 */
{
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
  int ci, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  jpeg_component_info *compptr;

  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  MCU_rows = srcinfo->output_height /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (dstinfo->_jpeg_height > srcinfo->output_height) {
        if (dst_blk_y < y_crop_blocks ||
            dst_blk_y >= y_crop_blocks + comp_height) {
          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
            memset(dst_buffer[offset_y], 0,
                   compptr->width_in_blocks * sizeof(JBLOCK));
          }
          continue;
        }
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
           FALSE);
      } else {
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
           FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        if (dstinfo->_jpeg_width > srcinfo->output_width) {
          if (x_crop_blocks > 0) {
            memset(dst_buffer[offset_y], 0, x_crop_blocks * sizeof(JBLOCK));
          }
          jcopy_block_row(src_buffer[offset_y],
                          dst_buffer[offset_y] + x_crop_blocks, comp_width);
          if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
            memset(dst_buffer[offset_y] + x_crop_blocks + comp_width, 0,
                   (compptr->width_in_blocks - x_crop_blocks - comp_width) *
                   sizeof(JBLOCK));
          }
        } else {
          jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
                          dst_buffer[offset_y], compptr->width_in_blocks);
        }
      }
    }
  }
}


LOCAL(void)
do_crop_ext_flat(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
                 jvirt_barray_ptr *src_coef_arrays,
                 jvirt_barray_ptr *dst_coef_arrays)
/* Crop.  This is only used when no rotate/flip is requested with the crop.
 * Extension: The destination width is larger than the source, and we fill in
 * the expanded region with the DC coefficient of the adjacent block.  Note
 * that we also have to fill partial iMCUs at the right and bottom edge of the
 * source image area in this case.
 */
{
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
  int ci, offset_y;
  JCOEF dc;
  JBLOCKARRAY src_buffer, dst_buffer;
  jpeg_component_info *compptr;

  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  MCU_rows = srcinfo->output_height /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (dstinfo->_jpeg_height > srcinfo->output_height) {
        if (dst_blk_y < y_crop_blocks ||
            dst_blk_y >= y_crop_blocks + comp_height) {
          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
            memset(dst_buffer[offset_y], 0,
                   compptr->width_in_blocks * sizeof(JBLOCK));
          }
          continue;
        }
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
           FALSE);
      } else {
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
          FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        if (x_crop_blocks > 0) {
          memset(dst_buffer[offset_y], 0, x_crop_blocks * sizeof(JBLOCK));
          dc = src_buffer[offset_y][0][0];
          for (dst_blk_x = 0; dst_blk_x < x_crop_blocks; dst_blk_x++) {
            dst_buffer[offset_y][dst_blk_x][0] = dc;
          }
        }
        jcopy_block_row(src_buffer[offset_y],
                        dst_buffer[offset_y] + x_crop_blocks, comp_width);
        if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
          memset(dst_buffer[offset_y] + x_crop_blocks + comp_width, 0,
                 (compptr->width_in_blocks - x_crop_blocks - comp_width) *
                 sizeof(JBLOCK));
          dc = src_buffer[offset_y][comp_width - 1][0];
          for (dst_blk_x = x_crop_blocks + comp_width;
               dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
            dst_buffer[offset_y][dst_blk_x][0] = dc;
          }
        }
      }
    }
  }
}


LOCAL(void)
do_crop_ext_reflect(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
                    jvirt_barray_ptr *src_coef_arrays,
                    jvirt_barray_ptr *dst_coef_arrays)
/* Crop.  This is only used when no rotate/flip is requested with the crop.
 * Extension: The destination width is larger than the source, and we fill in
 * the expanded region with repeated reflections of the source image.  Note
 * that we also have to fill partial iMCUs at the right and bottom edge of the
 * source image area in this case.
 */
{
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, src_blk_x;
  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
  int ci, k, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  MCU_rows = srcinfo->output_height /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (dstinfo->_jpeg_height > srcinfo->output_height) {
        if (dst_blk_y < y_crop_blocks ||
            dst_blk_y >= y_crop_blocks + comp_height) {
          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
            memset(dst_buffer[offset_y], 0,
                   compptr->width_in_blocks * sizeof(JBLOCK));
          }
          continue;
        }
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
           FALSE);
      } else {
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
           FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        /* Copy source region */
        jcopy_block_row(src_buffer[offset_y],
                        dst_buffer[offset_y] + x_crop_blocks, comp_width);
        if (x_crop_blocks > 0) {
          /* Reflect to left */
          dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks;
          for (dst_blk_x = x_crop_blocks; dst_blk_x > 0;) {
            src_row_ptr = dst_row_ptr;      /* (re)set axis of reflection */
            for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
                 src_blk_x--, dst_blk_x--) {
              dst_ptr = *(--dst_row_ptr);   /* destination goes left */
              src_ptr = *src_row_ptr++;     /* source goes right */
              /* This unrolled loop doesn't need to know which row it's on. */
              for (k = 0; k < DCTSIZE2; k += 2) {
                *dst_ptr++ = *src_ptr++;    /* copy even column */
                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
                                               change */
              }
            }
          }
        }
        if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
          /* Reflect to right */
          dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks + comp_width;
          for (dst_blk_x = compptr->width_in_blocks - x_crop_blocks - comp_width;
               dst_blk_x > 0;) {
            src_row_ptr = dst_row_ptr;      /* (re)set axis of reflection */
            for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
                 src_blk_x--, dst_blk_x--) {
              dst_ptr = *dst_row_ptr++;     /* destination goes right */
              src_ptr = *(--src_row_ptr);   /* source goes left */
              /* This unrolled loop doesn't need to know which row it's on. */
              for (k = 0; k < DCTSIZE2; k += 2) {
                *dst_ptr++ = *src_ptr++;    /* copy even column */
                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
                                               change */
              }
            }
          }
        }
      }
    }
  }
}


LOCAL(void)
do_wipe(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
        JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
        jvirt_barray_ptr *src_coef_arrays,
        JDIMENSION drop_width, JDIMENSION drop_height)
/* Wipe - discard image contents of specified region and fill with zero
 * (neutral gray)
 */
{
  JDIMENSION x_wipe_blocks, wipe_width;
  JDIMENSION y_wipe_blocks, wipe_bottom;
  int ci, offset_y;
  JBLOCKARRAY buffer;
  jpeg_component_info *compptr;

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
    wipe_width = drop_width * compptr->h_samp_factor;
    y_wipe_blocks = y_crop_offset * compptr->v_samp_factor;
    wipe_bottom = drop_height * compptr->v_samp_factor + y_wipe_blocks;
    for (; y_wipe_blocks < wipe_bottom;
         y_wipe_blocks += compptr->v_samp_factor) {
      buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        memset(buffer[offset_y] + x_wipe_blocks, 0,
               wipe_width * sizeof(JBLOCK));
      }
    }
  }
}


LOCAL(void)
do_flatten(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
           JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
           jvirt_barray_ptr *src_coef_arrays,
           JDIMENSION drop_width, JDIMENSION drop_height)
/* Flatten - discard image contents of specified region, similarly to wipe,
 * but fill with the average of adjacent blocks instead of zero.
 */
{
  JDIMENSION x_wipe_blocks, wipe_width, wipe_right;
  JDIMENSION y_wipe_blocks, wipe_bottom, blk_x;
  int ci, offset_y, dc_left_value, dc_right_value, average;
  JBLOCKARRAY buffer;
  jpeg_component_info *compptr;

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
    wipe_width = drop_width * compptr->h_samp_factor;
    wipe_right = wipe_width + x_wipe_blocks;
    y_wipe_blocks = y_crop_offset * compptr->v_samp_factor;
    wipe_bottom = drop_height * compptr->v_samp_factor + y_wipe_blocks;
    for (; y_wipe_blocks < wipe_bottom;
         y_wipe_blocks += compptr->v_samp_factor) {
      buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        memset(buffer[offset_y] + x_wipe_blocks, 0,
               wipe_width * sizeof(JBLOCK));
        if (x_wipe_blocks > 0) {
          dc_left_value = buffer[offset_y][x_wipe_blocks - 1][0];
          if (wipe_right < compptr->width_in_blocks) {
            dc_right_value = buffer[offset_y][wipe_right][0];
            average = (dc_left_value + dc_right_value) >> 1;
          } else {
            average = dc_left_value;
          }
        } else if (wipe_right < compptr->width_in_blocks) {
          average = buffer[offset_y][wipe_right][0];
        } else continue;
        for (blk_x = x_wipe_blocks; blk_x < wipe_right; blk_x++) {
          buffer[offset_y][blk_x][0] = (JCOEF)average;
        }
      }
    }
  }
}


LOCAL(void)
do_reflect(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
           JDIMENSION x_crop_offset, jvirt_barray_ptr *src_coef_arrays,
           JDIMENSION drop_width, JDIMENSION drop_height)
/* Reflect - discard image contents of specified region, similarly to wipe,
 * but fill with repeated reflections of the outside region instead of zero.
 * NB: y_crop_offset is assumed to be zero.
 */
{
  JDIMENSION x_wipe_blocks, wipe_width;
  JDIMENSION y_wipe_blocks, wipe_bottom;
  JDIMENSION src_blk_x, dst_blk_x;
  int ci, k, offset_y;
  JBLOCKARRAY buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
    wipe_width = drop_width * compptr->h_samp_factor;
    wipe_bottom = drop_height * compptr->v_samp_factor;
    for (y_wipe_blocks = 0; y_wipe_blocks < wipe_bottom;
         y_wipe_blocks += compptr->v_samp_factor) {
      buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        if (x_wipe_blocks > 0) {
          /* Reflect from left */
          dst_row_ptr = buffer[offset_y] + x_wipe_blocks;
          for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
            src_row_ptr = dst_row_ptr;     /* (re)set axis of reflection */
            for (src_blk_x = x_wipe_blocks;
                 src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
              dst_ptr = *dst_row_ptr++;    /* destination goes right */
              src_ptr = *(--src_row_ptr);  /* source goes left */
              /* this unrolled loop doesn't need to know which row it's on... */
              for (k = 0; k < DCTSIZE2; k += 2) {
                *dst_ptr++ = *src_ptr++;   /* copy even column */
                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign change */
              }
            }
          }
        } else if (compptr->width_in_blocks > x_wipe_blocks + wipe_width) {
          /* Reflect from right */
          dst_row_ptr = buffer[offset_y] + x_wipe_blocks + wipe_width;
          for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
            src_row_ptr = dst_row_ptr;     /* (re)set axis of reflection */
            src_blk_x = compptr->width_in_blocks - x_wipe_blocks - wipe_width;
            for (; src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
              dst_ptr = *(--dst_row_ptr);  /* destination goes left */
              src_ptr = *src_row_ptr++;    /* source goes right */
              /* this unrolled loop doesn't need to know which row it's on... */
              for (k = 0; k < DCTSIZE2; k += 2) {
                *dst_ptr++ = *src_ptr++;   /* copy even column */
                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign change */
              }
            }
          }
        } else {
          memset(buffer[offset_y] + x_wipe_blocks, 0,
                 wipe_width * sizeof(JBLOCK));
        }
      }
    }
  }
}


LOCAL(void)
do_flip_h_no_crop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                  JDIMENSION x_crop_offset, jvirt_barray_ptr *src_coef_arrays)
/* Horizontal flip; done in-place, so no separate dest array is required.
 * NB: this only works when y_crop_offset is zero.
 */
{
  JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
  int ci, k, offset_y;
  JBLOCKARRAY buffer;
  JCOEFPTR ptr1, ptr2;
  JCOEF temp1, temp2;
  jpeg_component_info *compptr;

  /* Horizontal mirroring of DCT blocks is accomplished by swapping
   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
   * mirroring by changing the signs of odd-numbered columns.
   * Partial iMCUs at the right edge are left untouched.
   */
  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    for (blk_y = 0; blk_y < compptr->height_in_blocks;
         blk_y += compptr->v_samp_factor) {
      buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        /* Do the mirroring */
        for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
          ptr1 = buffer[offset_y][blk_x];
          ptr2 = buffer[offset_y][comp_width - blk_x - 1];
          /* this unrolled loop doesn't need to know which row it's on... */
          for (k = 0; k < DCTSIZE2; k += 2) {
            temp1 = *ptr1;      /* swap even column */
            temp2 = *ptr2;
            *ptr1++ = temp2;
            *ptr2++ = temp1;
            temp1 = *ptr1;      /* swap odd column with sign change */
            temp2 = *ptr2;
            *ptr1++ = -temp2;
            *ptr2++ = -temp1;
          }
        }
        if (x_crop_blocks > 0) {
          /* Now left-justify the portion of the data to be kept.
           * We can't use a single jcopy_block_row() call because that routine
           * depends on memcpy(), whose behavior is unspecified for overlapping
           * source and destination areas.  Sigh.
           */
          for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
            jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
                            buffer[offset_y] + blk_x, (JDIMENSION)1);
          }
        }
      }
    }
  }
}


LOCAL(void)
do_flip_h(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
          JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
          jvirt_barray_ptr *src_coef_arrays,
          jvirt_barray_ptr *dst_coef_arrays)
/* Horizontal flip in general cropping case */
{
  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, k, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* Here we must output into a separate array because we can't touch
   * different rows of a single virtual array simultaneously.  Otherwise,
   * this is essentially the same as the routine above.
   */
  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      src_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, src_coef_arrays[ci], dst_blk_y + y_crop_blocks,
         (JDIMENSION)compptr->v_samp_factor, FALSE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        dst_row_ptr = dst_buffer[offset_y];
        src_row_ptr = src_buffer[offset_y];
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
             dst_blk_x++) {
          if (x_crop_blocks + dst_blk_x < comp_width) {
            /* Do the mirrorable blocks */
            dst_ptr = dst_row_ptr[dst_blk_x];
            src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
            /* this unrolled loop doesn't need to know which row it's on... */
            for (k = 0; k < DCTSIZE2; k += 2) {
              *dst_ptr++ = *src_ptr++;    /* copy even column */
              *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
                                             change */
            }
          } else {
            /* Copy last partial block(s) verbatim */
            jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
                            dst_row_ptr + dst_blk_x, (JDIMENSION)1);
          }
        }
      }
    }
  }
}


LOCAL(void)
do_flip_v(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
          JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
          jvirt_barray_ptr *src_coef_arrays,
          jvirt_barray_ptr *dst_coef_arrays)
/* Vertical flip */
{
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* We output into a separate array because we can't touch different
   * rows of the source virtual array simultaneously.  Otherwise, this
   * is a pretty straightforward analog of horizontal flip.
   * Within a DCT block, vertical mirroring is done by changing the signs
   * of odd-numbered rows.
   * Partial iMCUs at the bottom edge are copied verbatim.
   */
  MCU_rows = srcinfo->output_height /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (y_crop_blocks + dst_blk_y < comp_height) {
        /* Row is within the mirrorable area. */
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           comp_height - y_crop_blocks - dst_blk_y -
           (JDIMENSION)compptr->v_samp_factor,
           (JDIMENSION)compptr->v_samp_factor, FALSE);
      } else {
        /* Bottom-edge blocks will be copied verbatim. */
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y + y_crop_blocks,
           (JDIMENSION)compptr->v_samp_factor, FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        if (y_crop_blocks + dst_blk_y < comp_height) {
          /* Row is within the mirrorable area. */
          dst_row_ptr = dst_buffer[offset_y];
          src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
          src_row_ptr += x_crop_blocks;
          for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
               dst_blk_x++) {
            dst_ptr = dst_row_ptr[dst_blk_x];
            src_ptr = src_row_ptr[dst_blk_x];
            for (i = 0; i < DCTSIZE; i += 2) {
              /* copy even row */
              for (j = 0; j < DCTSIZE; j++)
                *dst_ptr++ = *src_ptr++;
              /* copy odd row with sign change */
              for (j = 0; j < DCTSIZE; j++)
                *dst_ptr++ = -(*src_ptr++);
            }
          }
        } else {
          /* Just copy row verbatim. */
          jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
                          dst_buffer[offset_y], compptr->width_in_blocks);
        }
      }
    }
  }
}


LOCAL(void)
do_transpose(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
             JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
             jvirt_barray_ptr *src_coef_arrays,
             jvirt_barray_ptr *dst_coef_arrays)
/* Transpose source into destination */
{
  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_x, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* Transposing pixels within a block just requires transposing the
   * DCT coefficients.
   * Partial iMCUs at the edges require no special treatment; we simply
   * process all the available DCT blocks for every component.
   */
  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
             dst_blk_x += compptr->h_samp_factor) {
          src_buffer = (*srcinfo->mem->access_virt_barray)
            ((j_common_ptr)srcinfo, src_coef_arrays[ci],
             dst_blk_x + x_crop_blocks,
             (JDIMENSION)compptr->h_samp_factor, FALSE);
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
            src_ptr =
              src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
            for (i = 0; i < DCTSIZE; i++)
              for (j = 0; j < DCTSIZE; j++)
                dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
          }
        }
      }
    }
  }
}


LOCAL(void)
do_rot_90(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
          JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
          jvirt_barray_ptr *src_coef_arrays,
          jvirt_barray_ptr *dst_coef_arrays)
/* 90 degree rotation is equivalent to
 *   1. Transposing the image;
 *   2. Horizontal mirroring.
 * These two steps are merged into a single processing routine.
 */
{
  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_x, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* Because of the horizontal mirror step, we can't process partial iMCUs
   * at the (output) right edge properly.  They just get transposed and
   * not mirrored.
   */
  MCU_cols = srcinfo->output_height /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
             dst_blk_x += compptr->h_samp_factor) {
          if (x_crop_blocks + dst_blk_x < comp_width) {
            /* Block is within the mirrorable area. */
            src_buffer = (*srcinfo->mem->access_virt_barray)
              ((j_common_ptr)srcinfo, src_coef_arrays[ci],
               comp_width - x_crop_blocks - dst_blk_x -
               (JDIMENSION)compptr->h_samp_factor,
               (JDIMENSION)compptr->h_samp_factor, FALSE);
          } else {
            /* Edge blocks are transposed but not mirrored. */
            src_buffer = (*srcinfo->mem->access_virt_barray)
              ((j_common_ptr)srcinfo, src_coef_arrays[ci],
               dst_blk_x + x_crop_blocks,
               (JDIMENSION)compptr->h_samp_factor, FALSE);
          }
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
            if (x_crop_blocks + dst_blk_x < comp_width) {
              /* Block is within the mirrorable area. */
              src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
                [dst_blk_y + offset_y + y_crop_blocks];
              for (i = 0; i < DCTSIZE; i++) {
                for (j = 0; j < DCTSIZE; j++)
                  dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                i++;
                for (j = 0; j < DCTSIZE; j++)
                  dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
              }
            } else {
              /* Edge blocks are transposed but not mirrored. */
              src_ptr = src_buffer[offset_x]
                [dst_blk_y + offset_y + y_crop_blocks];
              for (i = 0; i < DCTSIZE; i++)
                for (j = 0; j < DCTSIZE; j++)
                  dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
            }
          }
        }
      }
    }
  }
}


LOCAL(void)
do_rot_270(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
           JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
           jvirt_barray_ptr *src_coef_arrays,
           jvirt_barray_ptr *dst_coef_arrays)
/* 270 degree rotation is equivalent to
 *   1. Horizontal mirroring;
 *   2. Transposing the image.
 * These two steps are merged into a single processing routine.
 */
{
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_x, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  /* Because of the horizontal mirror step, we can't process partial iMCUs
   * at the (output) bottom edge properly.  They just get transposed and
   * not mirrored.
   */
  MCU_rows = srcinfo->output_width /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
             dst_blk_x += compptr->h_samp_factor) {
          src_buffer = (*srcinfo->mem->access_virt_barray)
            ((j_common_ptr)srcinfo, src_coef_arrays[ci],
             dst_blk_x + x_crop_blocks,
             (JDIMENSION)compptr->h_samp_factor, FALSE);
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
            if (y_crop_blocks + dst_blk_y < comp_height) {
              /* Block is within the mirrorable area. */
              src_ptr = src_buffer[offset_x]
                [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
              for (i = 0; i < DCTSIZE; i++) {
                for (j = 0; j < DCTSIZE; j++) {
                  dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                  j++;
                  dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
                }
              }
            } else {
              /* Edge blocks are transposed but not mirrored. */
              src_ptr = src_buffer[offset_x]
                [dst_blk_y + offset_y + y_crop_blocks];
              for (i = 0; i < DCTSIZE; i++)
                for (j = 0; j < DCTSIZE; j++)
                  dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
            }
          }
        }
      }
    }
  }
}


LOCAL(void)
do_rot_180(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
           JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
           jvirt_barray_ptr *src_coef_arrays,
           jvirt_barray_ptr *dst_coef_arrays)
/* 180 degree rotation is equivalent to
 *   1. Vertical mirroring;
 *   2. Horizontal mirroring.
 * These two steps are merged into a single processing routine.
 */
{
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JBLOCKROW src_row_ptr, dst_row_ptr;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  MCU_cols = srcinfo->output_width /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  MCU_rows = srcinfo->output_height /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      if (y_crop_blocks + dst_blk_y < comp_height) {
        /* Row is within the vertically mirrorable area. */
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           comp_height - y_crop_blocks - dst_blk_y -
           (JDIMENSION)compptr->v_samp_factor,
           (JDIMENSION)compptr->v_samp_factor, FALSE);
      } else {
        /* Bottom-edge rows are only mirrored horizontally. */
        src_buffer = (*srcinfo->mem->access_virt_barray)
          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
           dst_blk_y + y_crop_blocks,
           (JDIMENSION)compptr->v_samp_factor, FALSE);
      }
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        dst_row_ptr = dst_buffer[offset_y];
        if (y_crop_blocks + dst_blk_y < comp_height) {
          /* Row is within the mirrorable area. */
          src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
          for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
               dst_blk_x++) {
            dst_ptr = dst_row_ptr[dst_blk_x];
            if (x_crop_blocks + dst_blk_x < comp_width) {
              /* Process the blocks that can be mirrored both ways. */
              src_ptr =
                src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
              for (i = 0; i < DCTSIZE; i += 2) {
                /* For even row, negate every odd column. */
                for (j = 0; j < DCTSIZE; j += 2) {
                  *dst_ptr++ = *src_ptr++;
                  *dst_ptr++ = -(*src_ptr++);
                }
                /* For odd row, negate every even column. */
                for (j = 0; j < DCTSIZE; j += 2) {
                  *dst_ptr++ = -(*src_ptr++);
                  *dst_ptr++ = *src_ptr++;
                }
              }
            } else {
              /* Any remaining right-edge blocks are only mirrored vertically. */
              src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
              for (i = 0; i < DCTSIZE; i += 2) {
                for (j = 0; j < DCTSIZE; j++)
                  *dst_ptr++ = *src_ptr++;
                for (j = 0; j < DCTSIZE; j++)
                  *dst_ptr++ = -(*src_ptr++);
              }
            }
          }
        } else {
          /* Remaining rows are just mirrored horizontally. */
          src_row_ptr = src_buffer[offset_y];
          for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
               dst_blk_x++) {
            if (x_crop_blocks + dst_blk_x < comp_width) {
              /* Process the blocks that can be mirrored. */
              dst_ptr = dst_row_ptr[dst_blk_x];
              src_ptr =
                src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
              for (i = 0; i < DCTSIZE2; i += 2) {
                *dst_ptr++ = *src_ptr++;
                *dst_ptr++ = -(*src_ptr++);
              }
            } else {
              /* Any remaining right-edge blocks are only copied. */
              jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
                              dst_row_ptr + dst_blk_x, (JDIMENSION)1);
            }
          }
        }
      }
    }
  }
}


LOCAL(void)
do_transverse(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
              JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
              jvirt_barray_ptr *src_coef_arrays,
              jvirt_barray_ptr *dst_coef_arrays)
/* Transverse transpose is equivalent to
 *   1. 180 degree rotation;
 *   2. Transposition;
 * or
 *   1. Horizontal mirroring;
 *   2. Transposition;
 *   3. Horizontal mirroring.
 * These steps are merged into a single processing routine.
 */
{
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
  JDIMENSION x_crop_blocks, y_crop_blocks;
  int ci, i, j, offset_x, offset_y;
  JBLOCKARRAY src_buffer, dst_buffer;
  JCOEFPTR src_ptr, dst_ptr;
  jpeg_component_info *compptr;

  MCU_cols = srcinfo->output_height /
             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
  MCU_rows = srcinfo->output_width /
             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);

  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    comp_width = MCU_cols * compptr->h_samp_factor;
    comp_height = MCU_rows * compptr->v_samp_factor;
    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
         dst_blk_y += compptr->v_samp_factor) {
      dst_buffer = (*srcinfo->mem->access_virt_barray)
        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
         (JDIMENSION)compptr->v_samp_factor, TRUE);
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
        for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
             dst_blk_x += compptr->h_samp_factor) {
          if (x_crop_blocks + dst_blk_x < comp_width) {
            /* Block is within the mirrorable area. */
            src_buffer = (*srcinfo->mem->access_virt_barray)
              ((j_common_ptr)srcinfo, src_coef_arrays[ci],
               comp_width - x_crop_blocks - dst_blk_x -
               (JDIMENSION)compptr->h_samp_factor,
               (JDIMENSION)compptr->h_samp_factor, FALSE);
          } else {
            src_buffer = (*srcinfo->mem->access_virt_barray)
              ((j_common_ptr)srcinfo, src_coef_arrays[ci],
               dst_blk_x + x_crop_blocks,
               (JDIMENSION)compptr->h_samp_factor, FALSE);
          }
          for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
            dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
            if (y_crop_blocks + dst_blk_y < comp_height) {
              if (x_crop_blocks + dst_blk_x < comp_width) {
                /* Block is within the mirrorable area. */
                src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
                  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
                for (i = 0; i < DCTSIZE; i++) {
                  for (j = 0; j < DCTSIZE; j++) {
                    dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                    j++;
                    dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
                  }
                  i++;
                  for (j = 0; j < DCTSIZE; j++) {
                    dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
                    j++;
                    dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                  }
                }
              } else {
                /* Right-edge blocks are mirrored in y only */
                src_ptr = src_buffer[offset_x]
                  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
                for (i = 0; i < DCTSIZE; i++) {
                  for (j = 0; j < DCTSIZE; j++) {
                    dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                    j++;
                    dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
                  }
                }
              }
            } else {
              if (x_crop_blocks + dst_blk_x < comp_width) {
                /* Bottom-edge blocks are mirrored in x only */
                src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
                  [dst_blk_y + offset_y + y_crop_blocks];
                for (i = 0; i < DCTSIZE; i++) {
                  for (j = 0; j < DCTSIZE; j++)
                    dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
                  i++;
                  for (j = 0; j < DCTSIZE; j++)
                    dst_ptr[j * DCTSIZE + i] = -src_ptr[i * DCTSIZE + j];
                }
              } else {
                /* At lower right corner, just transpose, no mirroring */
                src_ptr = src_buffer[offset_x]
                  [dst_blk_y + offset_y + y_crop_blocks];
                for (i = 0; i < DCTSIZE; i++)
                  for (j = 0; j < DCTSIZE; j++)
                    dst_ptr[j * DCTSIZE + i] = src_ptr[i * DCTSIZE + j];
              }
            }
          }
        }
      }
    }
  }
}


/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
 * Returns TRUE if valid integer found, FALSE if not.
 * *strptr is advanced over the digit string, and *result is set to its value.
 */

LOCAL(boolean)
jt_read_integer(const char **strptr, JDIMENSION *result)
{
  const char *ptr = *strptr;
  JDIMENSION val = 0;

  for (; isdigit(*ptr); ptr++) {
    val = val * 10 + (JDIMENSION)(*ptr - '0');
  }
  *result = val;
  if (ptr == *strptr)
    return FALSE;               /* oops, no digits */
  *strptr = ptr;
  return TRUE;
}


/* Parse a crop specification (written in X11 geometry style).
 * The routine returns TRUE if the spec string is valid, FALSE if not.
 *
 * The crop spec string should have the format
 *      <width>[{fr}]x<height>[{fr}]{+-}<xoffset>{+-}<yoffset>
 * where width, height, xoffset, and yoffset are unsigned integers.
 * Each of the elements can be omitted to indicate a default value.
 * (A weakness of this style is that it is not possible to omit xoffset
 * while specifying yoffset, since they look alike.)
 *
 * This code is loosely based on XParseGeometry from the X11 distribution.
 */

GLOBAL(boolean)
jtransform_parse_crop_spec(jpeg_transform_info *info, const char *spec)
{
  info->crop = FALSE;
  info->crop_width_set = JCROP_UNSET;
  info->crop_height_set = JCROP_UNSET;
  info->crop_xoffset_set = JCROP_UNSET;
  info->crop_yoffset_set = JCROP_UNSET;

  if (isdigit(*spec)) {
    /* fetch width */
    if (!jt_read_integer(&spec, &info->crop_width))
      return FALSE;
    if (*spec == 'f' || *spec == 'F') {
      spec++;
      info->crop_width_set = JCROP_FORCE;
    } else if (*spec == 'r' || *spec == 'R') {
      spec++;
      info->crop_width_set = JCROP_REFLECT;
    } else
      info->crop_width_set = JCROP_POS;
  }
  if (*spec == 'x' || *spec == 'X') {
    /* fetch height */
    spec++;
    if (!jt_read_integer(&spec, &info->crop_height))
      return FALSE;
    if (*spec == 'f' || *spec == 'F') {
      spec++;
      info->crop_height_set = JCROP_FORCE;
    } else if (*spec == 'r' || *spec == 'R') {
      spec++;
      info->crop_height_set = JCROP_REFLECT;
    } else
      info->crop_height_set = JCROP_POS;
  }
  if (*spec == '+' || *spec == '-') {
    /* fetch xoffset */
    info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
    spec++;
    if (!jt_read_integer(&spec, &info->crop_xoffset))
      return FALSE;
  }
  if (*spec == '+' || *spec == '-') {
    /* fetch yoffset */
    info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
    spec++;
    if (!jt_read_integer(&spec, &info->crop_yoffset))
      return FALSE;
  }
  /* We had better have gotten to the end of the string. */
  if (*spec != '\0')
    return FALSE;
  info->crop = TRUE;
  return TRUE;
}


/* Trim off any partial iMCUs on the indicated destination edge */

LOCAL(void)
trim_right_edge(jpeg_transform_info *info, JDIMENSION full_width)
{
  JDIMENSION MCU_cols;

  MCU_cols = info->output_width / info->iMCU_sample_width;
  if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
      full_width / info->iMCU_sample_width)
    info->output_width = MCU_cols * info->iMCU_sample_width;
}

LOCAL(void)
trim_bottom_edge(jpeg_transform_info *info, JDIMENSION full_height)
{
  JDIMENSION MCU_rows;

  MCU_rows = info->output_height / info->iMCU_sample_height;
  if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
      full_height / info->iMCU_sample_height)
    info->output_height = MCU_rows * info->iMCU_sample_height;
}


/* Request any required workspace.
 *
 * This routine figures out the size that the output image will be
 * (which implies that all the transform parameters must be set before
 * it is called).
 *
 * We allocate the workspace virtual arrays from the source decompression
 * object, so that all the arrays (both the original data and the workspace)
 * will be taken into account while making memory management decisions.
 * Hence, this routine must be called after jpeg_read_header (which reads
 * the image dimensions) and before jpeg_read_coefficients (which realizes
 * the source's virtual arrays).
 *
 * This function returns FALSE right away if -perfect is given
 * and transformation is not perfect.  Otherwise returns TRUE.
 */

GLOBAL(boolean)
jtransform_request_workspace(j_decompress_ptr srcinfo,
                             jpeg_transform_info *info)
{
  jvirt_barray_ptr *coef_arrays;
  boolean need_workspace, transpose_it;
  jpeg_component_info *compptr;
  JDIMENSION xoffset, yoffset, dtemp;
  JDIMENSION width_in_iMCUs, height_in_iMCUs;
  JDIMENSION width_in_blocks, height_in_blocks;
  int itemp, ci, h_samp_factor, v_samp_factor;

  /* Determine number of components in output image */
  if (info->force_grayscale &&
      srcinfo->jpeg_color_space == JCS_YCbCr &&
      srcinfo->num_components == 3)
    /* We'll only process the first component */
    info->num_components = 1;
  else
    /* Process all the components */
    info->num_components = srcinfo->num_components;

  /* Compute output image dimensions and related values. */
#if JPEG_LIB_VERSION >= 80
  jpeg_core_output_dimensions(srcinfo);
#else
  srcinfo->output_width = srcinfo->image_width;
  srcinfo->output_height = srcinfo->image_height;
#endif

  /* Return right away if -perfect is given and transformation is not perfect.
   */
  if (info->perfect) {
    if (info->num_components == 1) {
      if (!jtransform_perfect_transform(srcinfo->output_width,
          srcinfo->output_height,
          srcinfo->_min_DCT_h_scaled_size,
          srcinfo->_min_DCT_v_scaled_size,
          info->transform))
        return FALSE;
    } else {
      if (!jtransform_perfect_transform(srcinfo->output_width,
          srcinfo->output_height,
          srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size,
          srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size,
          info->transform))
        return FALSE;
    }
  }

  /* If there is only one output component, force the iMCU size to be 1;
   * else use the source iMCU size.  (This allows us to do the right thing
   * when reducing color to grayscale, and also provides a handy way of
   * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
   */
  switch (info->transform) {
  case JXFORM_TRANSPOSE:
  case JXFORM_TRANSVERSE:
  case JXFORM_ROT_90:
  case JXFORM_ROT_270:
    info->output_width = srcinfo->output_height;
    info->output_height = srcinfo->output_width;
    if (info->num_components == 1) {
      info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size;
      info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size;
    } else {
      info->iMCU_sample_width =
        srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
      info->iMCU_sample_height =
        srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
    }
    break;
  default:
    info->output_width = srcinfo->output_width;
    info->output_height = srcinfo->output_height;
    if (info->num_components == 1) {
      info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size;
      info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size;
    } else {
      info->iMCU_sample_width =
        srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
      info->iMCU_sample_height =
        srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
    }
    break;
  }

  /* If cropping has been requested, compute the crop area's position and
   * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
   */
  if (info->crop) {
    /* Insert default values for unset crop parameters */
    if (info->crop_xoffset_set == JCROP_UNSET)
      info->crop_xoffset = 0;   /* default to +0 */
    if (info->crop_yoffset_set == JCROP_UNSET)
      info->crop_yoffset = 0;   /* default to +0 */
    if (info->crop_width_set == JCROP_UNSET) {
      if (info->crop_xoffset >= info->output_width)
        ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      info->crop_width = info->output_width - info->crop_xoffset;
    } else {
      /* Check for crop extension */
      if (info->crop_width > info->output_width) {
        /* Crop extension does not work when transforming! */
        if (info->transform != JXFORM_NONE ||
            info->crop_xoffset >= info->crop_width ||
            info->crop_xoffset > info->crop_width - info->output_width)
          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      } else {
        if (info->crop_xoffset >= info->output_width ||
            info->crop_width <= 0 ||
            info->crop_xoffset > info->output_width - info->crop_width)
          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      }
    }
    if (info->crop_height_set == JCROP_UNSET) {
      if (info->crop_yoffset >= info->output_height)
        ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      info->crop_height = info->output_height - info->crop_yoffset;
    } else {
      /* Check for crop extension */
      if (info->crop_height > info->output_height) {
        /* Crop extension does not work when transforming! */
        if (info->transform != JXFORM_NONE ||
            info->crop_yoffset >= info->crop_height ||
            info->crop_yoffset > info->crop_height - info->output_height)
          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      } else {
        if (info->crop_yoffset >= info->output_height ||
            info->crop_height <= 0 ||
            info->crop_yoffset > info->output_height - info->crop_height)
          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
      }
    }
    /* Convert negative crop offsets into regular offsets */
    if (info->crop_xoffset_set != JCROP_NEG)
      xoffset = info->crop_xoffset;
    else if (info->crop_width > info->output_width) /* crop extension */
      xoffset = info->crop_width - info->output_width - info->crop_xoffset;
    else
      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
    if (info->crop_yoffset_set != JCROP_NEG)
      yoffset = info->crop_yoffset;
    else if (info->crop_height > info->output_height) /* crop extension */
      yoffset = info->crop_height - info->output_height - info->crop_yoffset;
    else
      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
    /* Now adjust so that upper left corner falls at an iMCU boundary */
    switch (info->transform) {
    case JXFORM_DROP:
      /* Ensure the effective drop region will not exceed the requested */
      itemp = info->iMCU_sample_width;
      dtemp = itemp - 1 - ((xoffset + itemp - 1) % itemp);
      xoffset += dtemp;
      if (info->crop_width <= dtemp)
        info->drop_width = 0;
      else if (xoffset + info->crop_width - dtemp == info->output_width)
        /* Matching right edge: include partial iMCU */
        info->drop_width = (info->crop_width - dtemp + itemp - 1) / itemp;
      else
        info->drop_width = (info->crop_width - dtemp) / itemp;
      itemp = info->iMCU_sample_height;
      dtemp = itemp - 1 - ((yoffset + itemp - 1) % itemp);
      yoffset += dtemp;
      if (info->crop_height <= dtemp)
        info->drop_height = 0;
      else if (yoffset + info->crop_height - dtemp == info->output_height)
        /* Matching bottom edge: include partial iMCU */
        info->drop_height = (info->crop_height - dtemp + itemp - 1) / itemp;
      else
        info->drop_height = (info->crop_height - dtemp) / itemp;
      /* Check if sampling factors match for dropping */
      if (info->drop_width != 0 && info->drop_height != 0)
        for (ci = 0; ci < info->num_components &&
                     ci < info->drop_ptr->num_components; ci++) {
          if (info->drop_ptr->comp_info[ci].h_samp_factor *
              srcinfo->max_h_samp_factor !=
              srcinfo->comp_info[ci].h_samp_factor *
              info->drop_ptr->max_h_samp_factor)
            ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
              info->drop_ptr->comp_info[ci].h_samp_factor,
              info->drop_ptr->max_h_samp_factor,
              srcinfo->comp_info[ci].h_samp_factor,
              srcinfo->max_h_samp_factor, 'h');
          if (info->drop_ptr->comp_info[ci].v_samp_factor *
              srcinfo->max_v_samp_factor !=
              srcinfo->comp_info[ci].v_samp_factor *
              info->drop_ptr->max_v_samp_factor)
            ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
              info->drop_ptr->comp_info[ci].v_samp_factor,
              info->drop_ptr->max_v_samp_factor,
              srcinfo->comp_info[ci].v_samp_factor,
              srcinfo->max_v_samp_factor, 'v');
        }
      break;
    case JXFORM_WIPE:
      /* Ensure the effective wipe region will cover the requested */
      info->drop_width = (JDIMENSION)jdiv_round_up
        ((long)(info->crop_width + (xoffset % info->iMCU_sample_width)),
         (long)info->iMCU_sample_width);
      info->drop_height = (JDIMENSION)jdiv_round_up
        ((long)(info->crop_height + (yoffset % info->iMCU_sample_height)),
         (long)info->iMCU_sample_height);
      break;
    default:
      /* Ensure the effective crop region will cover the requested */
      if (info->crop_width_set == JCROP_FORCE ||
          info->crop_width > info->output_width)
        info->output_width = info->crop_width;
      else
        info->output_width =
          info->crop_width + (xoffset % info->iMCU_sample_width);
      if (info->crop_height_set == JCROP_FORCE ||
          info->crop_height > info->output_height)
        info->output_height = info->crop_height;
      else
        info->output_height =
          info->crop_height + (yoffset % info->iMCU_sample_height);
    }
    /* Save x/y offsets measured in iMCUs */
    info->x_crop_offset = xoffset / info->iMCU_sample_width;
    info->y_crop_offset = yoffset / info->iMCU_sample_height;
  } else {
    info->x_crop_offset = 0;
    info->y_crop_offset = 0;
  }

  /* Figure out whether we need workspace arrays,
   * and if so whether they are transposed relative to the source.
   */
  need_workspace = FALSE;
  transpose_it = FALSE;
  switch (info->transform) {
  case JXFORM_NONE:
    if (info->x_crop_offset != 0 || info->y_crop_offset != 0 ||
        info->output_width > srcinfo->output_width ||
        info->output_height > srcinfo->output_height)
      need_workspace = TRUE;
    /* No workspace needed if neither cropping nor transforming */
    break;
  case JXFORM_FLIP_H:
    if (info->trim)
      trim_right_edge(info, srcinfo->output_width);
    if (info->y_crop_offset != 0 || info->slow_hflip)
      need_workspace = TRUE;
    /* do_flip_h_no_crop doesn't need a workspace array */
    break;
  case JXFORM_FLIP_V:
    if (info->trim)
      trim_bottom_edge(info, srcinfo->output_height);
    /* Need workspace arrays having same dimensions as source image. */
    need_workspace = TRUE;
    break;
  case JXFORM_TRANSPOSE:
    /* transpose does NOT have to trim anything */
    /* Need workspace arrays having transposed dimensions. */
    need_workspace = TRUE;
    transpose_it = TRUE;
    break;
  case JXFORM_TRANSVERSE:
    if (info->trim) {
      trim_right_edge(info, srcinfo->output_height);
      trim_bottom_edge(info, srcinfo->output_width);
    }
    /* Need workspace arrays having transposed dimensions. */
    need_workspace = TRUE;
    transpose_it = TRUE;
    break;
  case JXFORM_ROT_90:
    if (info->trim)
      trim_right_edge(info, srcinfo->output_height);
    /* Need workspace arrays having transposed dimensions. */
    need_workspace = TRUE;
    transpose_it = TRUE;
    break;
  case JXFORM_ROT_180:
    if (info->trim) {
      trim_right_edge(info, srcinfo->output_width);
      trim_bottom_edge(info, srcinfo->output_height);
    }
    /* Need workspace arrays having same dimensions as source image. */
    need_workspace = TRUE;
    break;
  case JXFORM_ROT_270:
    if (info->trim)
      trim_bottom_edge(info, srcinfo->output_width);
    /* Need workspace arrays having transposed dimensions. */
    need_workspace = TRUE;
    transpose_it = TRUE;
    break;
  case JXFORM_WIPE:
    break;
  case JXFORM_DROP:
    break;
  }

  /* Allocate workspace if needed.
   * Note that we allocate arrays padded out to the next iMCU boundary,
   * so that transform routines need not worry about missing edge blocks.
   */
  if (need_workspace) {
    coef_arrays = (jvirt_barray_ptr *)
      (*srcinfo->mem->alloc_small) ((j_common_ptr)srcinfo, JPOOL_IMAGE,
                sizeof(jvirt_barray_ptr) * info->num_components);
    width_in_iMCUs = (JDIMENSION)
      jdiv_round_up((long)info->output_width, (long)info->iMCU_sample_width);
    height_in_iMCUs = (JDIMENSION)
      jdiv_round_up((long)info->output_height, (long)info->iMCU_sample_height);
    for (ci = 0; ci < info->num_components; ci++) {
      compptr = srcinfo->comp_info + ci;
      if (info->num_components == 1) {
        /* we're going to force samp factors to 1x1 in this case */
        h_samp_factor = v_samp_factor = 1;
      } else if (transpose_it) {
        h_samp_factor = compptr->v_samp_factor;
        v_samp_factor = compptr->h_samp_factor;
      } else {
        h_samp_factor = compptr->h_samp_factor;
        v_samp_factor = compptr->v_samp_factor;
      }
      width_in_blocks = width_in_iMCUs * h_samp_factor;
      height_in_blocks = height_in_iMCUs * v_samp_factor;
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
        ((j_common_ptr)srcinfo, JPOOL_IMAGE, FALSE,
         width_in_blocks, height_in_blocks, (JDIMENSION)v_samp_factor);
    }
    info->workspace_coef_arrays = coef_arrays;
  } else
    info->workspace_coef_arrays = NULL;

  return TRUE;
}


/* Transpose destination image parameters */

LOCAL(void)
transpose_critical_parameters(j_compress_ptr dstinfo)
{
  int tblno, i, j, ci, itemp;
  jpeg_component_info *compptr;
  JQUANT_TBL *qtblptr;
  JDIMENSION jtemp;
  UINT16 qtemp;

  /* Transpose image dimensions */
  jtemp = dstinfo->image_width;
  dstinfo->image_width = dstinfo->image_height;
  dstinfo->image_height = jtemp;
#if JPEG_LIB_VERSION >= 70
  itemp = dstinfo->min_DCT_h_scaled_size;
  dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
  dstinfo->min_DCT_v_scaled_size = itemp;
#endif

  /* Transpose sampling factors */
  for (ci = 0; ci < dstinfo->num_components; ci++) {
    compptr = dstinfo->comp_info + ci;
    itemp = compptr->h_samp_factor;
    compptr->h_samp_factor = compptr->v_samp_factor;
    compptr->v_samp_factor = itemp;
  }

  /* Transpose quantization tables */
  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
    if (qtblptr != NULL) {
      for (i = 0; i < DCTSIZE; i++) {
        for (j = 0; j < i; j++) {
          qtemp = qtblptr->quantval[i * DCTSIZE + j];
          qtblptr->quantval[i * DCTSIZE + j] =
            qtblptr->quantval[j * DCTSIZE + i];
          qtblptr->quantval[j * DCTSIZE + i] = qtemp;
        }
      }
    }
  }
}


/* Adjust Exif image parameters.
 *
 * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
 */

LOCAL(void)
adjust_exif_parameters(JOCTET *data, unsigned int length, JDIMENSION new_width,
                       JDIMENSION new_height)
{
  boolean is_motorola; /* Flag for byte order */
  unsigned int number_of_tags, tagnum;
  unsigned int firstoffset, offset;
  JDIMENSION new_value;

  if (length < 12) return; /* Length of an IFD entry */

  /* Discover byte order */
  if (data[0] == 0x49 && data[1] == 0x49)
    is_motorola = FALSE;
  else if (data[0] == 0x4D && data[1] == 0x4D)
    is_motorola = TRUE;
  else
    return;

  /* Check Tag Mark */
  if (is_motorola) {
    if (data[2] != 0) return;
    if (data[3] != 0x2A) return;
  } else {
    if (data[3] != 0) return;
    if (data[2] != 0x2A) return;
  }

  /* Get first IFD offset (offset to IFD0) */
  if (is_motorola) {
    if (data[4] != 0) return;
    if (data[5] != 0) return;
    firstoffset = data[6];
    firstoffset <<= 8;
    firstoffset += data[7];
  } else {
    if (data[7] != 0) return;
    if (data[6] != 0) return;
    firstoffset = data[5];
    firstoffset <<= 8;
    firstoffset += data[4];
  }
  if (firstoffset > length - 2) return; /* check end of data segment */

  /* Get the number of directory entries contained in this IFD */
  if (is_motorola) {
    number_of_tags = data[firstoffset];
    number_of_tags <<= 8;
    number_of_tags += data[firstoffset + 1];
  } else {
    number_of_tags = data[firstoffset + 1];
    number_of_tags <<= 8;
    number_of_tags += data[firstoffset];
  }
  if (number_of_tags == 0) return;
  firstoffset += 2;

  /* Search for ExifSubIFD offset Tag in IFD0 */
  for (;;) {
    if (firstoffset > length - 12) return; /* check end of data segment */
    /* Get Tag number */
    if (is_motorola) {
      tagnum = data[firstoffset];
      tagnum <<= 8;
      tagnum += data[firstoffset + 1];
    } else {
      tagnum = data[firstoffset + 1];
      tagnum <<= 8;
      tagnum += data[firstoffset];
    }
    if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
    if (--number_of_tags == 0) return;
    firstoffset += 12;
  }

  /* Get the ExifSubIFD offset */
  if (is_motorola) {
    if (data[firstoffset + 8] != 0) return;
    if (data[firstoffset + 9] != 0) return;
    offset = data[firstoffset + 10];
    offset <<= 8;
    offset += data[firstoffset + 11];
  } else {
    if (data[firstoffset + 11] != 0) return;
    if (data[firstoffset + 10] != 0) return;
    offset = data[firstoffset + 9];
    offset <<= 8;
    offset += data[firstoffset + 8];
  }
  if (offset > length - 2) return; /* check end of data segment */

  /* Get the number of directory entries contained in this SubIFD */
  if (is_motorola) {
    number_of_tags = data[offset];
    number_of_tags <<= 8;
    number_of_tags += data[offset + 1];
  } else {
    number_of_tags = data[offset + 1];
    number_of_tags <<= 8;
    number_of_tags += data[offset];
  }
  if (number_of_tags < 2) return;
  offset += 2;

  /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
  do {
    if (offset > length - 12) return; /* check end of data segment */
    /* Get Tag number */
    if (is_motorola) {
      tagnum = data[offset];
      tagnum <<= 8;
      tagnum += data[offset + 1];
    } else {
      tagnum = data[offset + 1];
      tagnum <<= 8;
      tagnum += data[offset];
    }
    if (tagnum == 0xA002 || tagnum == 0xA003) {
      if (tagnum == 0xA002)
        new_value = new_width; /* ExifImageWidth Tag */
      else
        new_value = new_height; /* ExifImageHeight Tag */
      if (is_motorola) {
        data[offset + 2] = 0; /* Format = unsigned long (4 octets) */
        data[offset + 3] = 4;
        data[offset + 4] = 0; /* Number Of Components = 1 */
        data[offset + 5] = 0;
        data[offset + 6] = 0;
        data[offset + 7] = 1;
        data[offset + 8] = 0;
        data[offset + 9] = 0;
        data[offset + 10] = (JOCTET)((new_value >> 8) & 0xFF);
        data[offset + 11] = (JOCTET)(new_value & 0xFF);
      } else {
        data[offset + 2] = 4; /* Format = unsigned long (4 octets) */
        data[offset + 3] = 0;
        data[offset + 4] = 1; /* Number Of Components = 1 */
        data[offset + 5] = 0;
        data[offset + 6] = 0;
        data[offset + 7] = 0;
        data[offset + 8] = (JOCTET)(new_value & 0xFF);
        data[offset + 9] = (JOCTET)((new_value >> 8) & 0xFF);
        data[offset + 10] = 0;
        data[offset + 11] = 0;
      }
    }
    offset += 12;
  } while (--number_of_tags);
}


/* Adjust output image parameters as needed.
 *
 * This must be called after jpeg_copy_critical_parameters()
 * and before jpeg_write_coefficients().
 *
 * The return value is the set of virtual coefficient arrays to be written
 * (either the ones allocated by jtransform_request_workspace, or the
 * original source data arrays).  The caller will need to pass this value
 * to jpeg_write_coefficients().
 */

GLOBAL(jvirt_barray_ptr *)
jtransform_adjust_parameters(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                             jvirt_barray_ptr *src_coef_arrays,
                             jpeg_transform_info *info)
{
  /* If force-to-grayscale is requested, adjust destination parameters */
  if (info->force_grayscale) {
    /* First, ensure we have YCbCr or grayscale data, and that the source's
     * Y channel is full resolution.  (No reasonable person would make Y
     * be less than full resolution, so actually coping with that case
     * isn't worth extra code space.  But we check it to avoid crashing.)
     */
    if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
          dstinfo->num_components == 3) ||
         (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
          dstinfo->num_components == 1)) &&
        srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
        srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
      /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
       * properly.  Among other things, it sets the target h_samp_factor &
       * v_samp_factor to 1, which typically won't match the source.
       * We have to preserve the source's quantization table number, however.
       */
      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
    } else {
      /* Sorry, can't do it */
      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
    }
  } else if (info->num_components == 1) {
    /* For a single-component source, we force the destination sampling factors
     * to 1x1, with or without force_grayscale.  This is useful because some
     * decoders choke on grayscale images with other sampling factors.
     */
    dstinfo->comp_info[0].h_samp_factor = 1;
    dstinfo->comp_info[0].v_samp_factor = 1;
  }

  /* Correct the destination's image dimensions as necessary
   * for rotate/flip, resize, and crop operations.
   */
#if JPEG_LIB_VERSION >= 80
  dstinfo->jpeg_width = info->output_width;
  dstinfo->jpeg_height = info->output_height;
#endif

  /* Transpose destination image parameters, adjust quantization */
  switch (info->transform) {
  case JXFORM_TRANSPOSE:
  case JXFORM_TRANSVERSE:
  case JXFORM_ROT_90:
  case JXFORM_ROT_270:
#if JPEG_LIB_VERSION < 80
    dstinfo->image_width = info->output_height;
    dstinfo->image_height = info->output_width;
#endif
    transpose_critical_parameters(dstinfo);
    break;
  case JXFORM_DROP:
    if (info->drop_width != 0 && info->drop_height != 0)
      adjust_quant(srcinfo, src_coef_arrays,
                   info->drop_ptr, info->drop_coef_arrays,
                   info->trim, dstinfo);
    break;
  default:
#if JPEG_LIB_VERSION < 80
    dstinfo->image_width = info->output_width;
    dstinfo->image_height = info->output_height;
#endif
    break;
  }

  /* Adjust Exif properties */
  if (srcinfo->marker_list != NULL &&
      srcinfo->marker_list->marker == JPEG_APP0 + 1 &&
      srcinfo->marker_list->data_length >= 6 &&
      srcinfo->marker_list->data[0] == 0x45 &&
      srcinfo->marker_list->data[1] == 0x78 &&
      srcinfo->marker_list->data[2] == 0x69 &&
      srcinfo->marker_list->data[3] == 0x66 &&
      srcinfo->marker_list->data[4] == 0 &&
      srcinfo->marker_list->data[5] == 0) {
    /* Suppress output of JFIF marker */
    dstinfo->write_JFIF_header = FALSE;
    /* Adjust Exif image parameters */
#if JPEG_LIB_VERSION >= 80
    if (dstinfo->jpeg_width != srcinfo->image_width ||
        dstinfo->jpeg_height != srcinfo->image_height)
      /* Align data segment to start of TIFF structure for parsing */
      adjust_exif_parameters(srcinfo->marker_list->data + 6,
                             srcinfo->marker_list->data_length - 6,
                             dstinfo->jpeg_width, dstinfo->jpeg_height);
#else
    if (dstinfo->image_width != srcinfo->image_width ||
        dstinfo->image_height != srcinfo->image_height)
      /* Align data segment to start of TIFF structure for parsing */
      adjust_exif_parameters(srcinfo->marker_list->data + 6,
                             srcinfo->marker_list->data_length - 6,
                             dstinfo->image_width, dstinfo->image_height);
#endif
  }

  /* Return the appropriate output data set */
  if (info->workspace_coef_arrays != NULL)
    return info->workspace_coef_arrays;
  return src_coef_arrays;
}


/* Execute the actual transformation, if any.
 *
 * This must be called *after* jpeg_write_coefficients, because it depends
 * on jpeg_write_coefficients to have computed subsidiary values such as
 * the per-component width and height fields in the destination object.
 *
 * Note that some transformations will modify the source data arrays!
 */

GLOBAL(void)
jtransform_execute_transform(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                             jvirt_barray_ptr *src_coef_arrays,
                             jpeg_transform_info *info)
{
  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;

  /* Note: conditions tested here should match those in switch statement
   * in jtransform_request_workspace()
   */
  switch (info->transform) {
  case JXFORM_NONE:
    if (info->output_width > srcinfo->output_width ||
        info->output_height > srcinfo->output_height) {
      if (info->output_width > srcinfo->output_width &&
          info->crop_width_set == JCROP_REFLECT)
        do_crop_ext_reflect(srcinfo, dstinfo,
                            info->x_crop_offset, info->y_crop_offset,
                            src_coef_arrays, dst_coef_arrays);
      else if (info->output_width > srcinfo->output_width &&
               info->crop_width_set == JCROP_FORCE)
        do_crop_ext_flat(srcinfo, dstinfo,
                         info->x_crop_offset, info->y_crop_offset,
                         src_coef_arrays, dst_coef_arrays);
      else
        do_crop_ext_zero(srcinfo, dstinfo,
                         info->x_crop_offset, info->y_crop_offset,
                         src_coef_arrays, dst_coef_arrays);
    } else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
      do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
              src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_FLIP_H:
    if (info->y_crop_offset != 0 || info->slow_hflip)
      do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
                src_coef_arrays, dst_coef_arrays);
    else
      do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
                        src_coef_arrays);
    break;
  case JXFORM_FLIP_V:
    do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
              src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_TRANSPOSE:
    do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
                 src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_TRANSVERSE:
    do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
                  src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_ROT_90:
    do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
              src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_ROT_180:
    do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
               src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_ROT_270:
    do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
               src_coef_arrays, dst_coef_arrays);
    break;
  case JXFORM_WIPE:
    if (info->crop_width_set == JCROP_REFLECT &&
        info->y_crop_offset == 0 && info->drop_height ==
        (JDIMENSION)jdiv_round_up
          ((long)info->output_height, (long)info->iMCU_sample_height) &&
        (info->x_crop_offset == 0 ||
         info->x_crop_offset + info->drop_width ==
         (JDIMENSION)jdiv_round_up
           ((long)info->output_width, (long)info->iMCU_sample_width)))
      do_reflect(srcinfo, dstinfo, info->x_crop_offset,
                 src_coef_arrays, info->drop_width, info->drop_height);
    else if (info->crop_width_set == JCROP_FORCE)
      do_flatten(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
                 src_coef_arrays, info->drop_width, info->drop_height);
    else
      do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
              src_coef_arrays, info->drop_width, info->drop_height);
    break;
  case JXFORM_DROP:
    if (info->drop_width != 0 && info->drop_height != 0)
      do_drop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
              src_coef_arrays, info->drop_ptr, info->drop_coef_arrays,
              info->drop_width, info->drop_height);
    break;
  }
}

/* jtransform_perfect_transform
 *
 * Determine whether lossless transformation is perfectly
 * possible for a specified image and transformation.
 *
 * Inputs:
 *   image_width, image_height: source image dimensions.
 *   MCU_width, MCU_height: pixel dimensions of MCU.
 *   transform: transformation identifier.
 * Parameter sources from initialized jpeg_struct
 * (after reading source header):
 *   image_width = cinfo.image_width
 *   image_height = cinfo.image_height
 *   MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
 *   MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
 * Result:
 *   TRUE = perfect transformation possible
 *   FALSE = perfect transformation not possible
 *           (may use custom action then)
 */

GLOBAL(boolean)
jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
                             int MCU_width, int MCU_height,
                             JXFORM_CODE transform)
{
  boolean result = TRUE; /* initialize TRUE */

  switch (transform) {
  case JXFORM_FLIP_H:
  case JXFORM_ROT_270:
    if (image_width % (JDIMENSION)MCU_width)
      result = FALSE;
    break;
  case JXFORM_FLIP_V:
  case JXFORM_ROT_90:
    if (image_height % (JDIMENSION)MCU_height)
      result = FALSE;
    break;
  case JXFORM_TRANSVERSE:
  case JXFORM_ROT_180:
    if (image_width % (JDIMENSION)MCU_width)
      result = FALSE;
    if (image_height % (JDIMENSION)MCU_height)
      result = FALSE;
    break;
  default:
    break;
  }

  return result;
}

#endif /* TRANSFORMS_SUPPORTED */


/* Setup decompression object to save desired markers in memory.
 * This must be called before jpeg_read_header() to have the desired effect.
 */

GLOBAL(void)
jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option)
{
#ifdef SAVE_MARKERS_SUPPORTED
  int m;

  /* Save comments except under NONE option */
  if (option != JCOPYOPT_NONE && option != JCOPYOPT_ICC) {
    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
  }
  /* Save all types of APPn markers iff ALL option */
  if (option == JCOPYOPT_ALL || option == JCOPYOPT_ALL_EXCEPT_ICC) {
    for (m = 0; m < 16; m++) {
      if (option == JCOPYOPT_ALL_EXCEPT_ICC && m == 2)
        continue;
      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
    }
  }
  /* Save only APP2 markers if ICC option selected */
  if (option == JCOPYOPT_ICC) {
    jpeg_save_markers(srcinfo, JPEG_APP0 + 2, 0xFFFF);
  }
#endif /* SAVE_MARKERS_SUPPORTED */
}

/* Copy markers saved in the given source object to the destination object.
 * This should be called just after jpeg_start_compress() or
 * jpeg_write_coefficients().
 * Note that those routines will have written the SOI, and also the
 * JFIF APP0 or Adobe APP14 markers if selected.
 */

GLOBAL(void)
jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
                      JCOPY_OPTION option)
{
  jpeg_saved_marker_ptr marker;

  /* In the current implementation, we don't actually need to examine the
   * option flag here; we just copy everything that got saved.
   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
   * if the encoder library already wrote one.
   */
  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
    if (dstinfo->write_JFIF_header &&
        marker->marker == JPEG_APP0 &&
        marker->data_length >= 5 &&
        marker->data[0] == 0x4A &&
        marker->data[1] == 0x46 &&
        marker->data[2] == 0x49 &&
        marker->data[3] == 0x46 &&
        marker->data[4] == 0)
      continue;                 /* reject duplicate JFIF */
    if (dstinfo->write_Adobe_marker &&
        marker->marker == JPEG_APP0 + 14 &&
        marker->data_length >= 5 &&
        marker->data[0] == 0x41 &&
        marker->data[1] == 0x64 &&
        marker->data[2] == 0x6F &&
        marker->data[3] == 0x62 &&
        marker->data[4] == 0x65)
      continue;                 /* reject duplicate Adobe */
    jpeg_write_marker(dstinfo, marker->marker,
                      marker->data, marker->data_length);
  }
}
