1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/*
2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * transupp.c
3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
43395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org * This file was part of the Independent JPEG Group's software:
53395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
63395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org * libjpeg-turbo Modifications:
79862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Copyright (C) 2010, D. R. Commander.
8f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For conditions of distribution and use, see the accompanying README file.
9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file contains image transformation routines and other utility code
11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * used by the jpegtran sample application.  These are NOT part of the core
12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * JPEG library.  But we keep these routines separate from jpegtran.c to
13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * ease the task of maintaining jpegtran-like programs that have other user
14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * interfaces.
15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Although this file really shouldn't have access to the library internals,
18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * it's helpful to let it call jround_up() and jcopy_block_row().
19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define JPEG_INTERNALS
21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "jinclude.h"
23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "jpeglib.h"
24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "transupp.h"		/* My own external interface */
259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#include "jpegcomp.h"
269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#include <ctype.h>		/* to declare isdigit() */
279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION >= 70
309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#else
339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#define dstinfo_min_DCT_h_scaled_size DCTSIZE
349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#define dstinfo_min_DCT_v_scaled_size DCTSIZE
359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#if TRANSFORMS_SUPPORTED
39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/*
41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Lossless image transformation routines.  These routines work on DCT
42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * coefficient arrays and thus do not require any lossy decompression
43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * or recompression of the image.
449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Thanks to Guido Vollbeding for the initial design and code of this feature,
459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * and to Ben Jackson for introducing the cropping feature.
46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Horizontal flipping is done in-place, using a single top-to-bottom
48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * pass through the virtual source array.  It will thus be much the
49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * fastest option for images larger than main memory.
50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The other routines require a set of destination virtual arrays, so they
52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * need twice as much memory as jpegtran normally does.  The destination
53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * arrays are always written in normal scan order (top to bottom) because
54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the virtual array manager expects this.  The source arrays will be scanned
55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * in the corresponding order, which means multiple passes through the source
56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * arrays for most of the transforms.  That could result in much thrashing
57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * if the image is larger than main memory.
58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * If cropping or trimming is involved, the destination arrays may be smaller
609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * than the source arrays.  Note it is not possible to do horizontal flip
619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * in-place when a nonzero Y crop offset is specified, since we'd have to move
629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * data from one block row to another but the virtual array manager doesn't
639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * guarantee we can touch more than one row at a time.  So in that case,
649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * we have to use a separate destination array.
659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Some notes about the operating environment of the individual transform
67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * routines:
68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 1. Both the source and destination virtual arrays are allocated from the
69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    source JPEG object, and therefore should be manipulated by calling the
70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    source's memory manager.
71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 2. The destination's component count should be used.  It may be smaller
72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    than the source's when forcing to grayscale.
73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 3. Likewise the destination's sampling factors should be used.  When
74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    forcing to grayscale the destination's sampling factors will be all 1,
75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    and we may as well take that as the effective iMCU size.
76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 4. When "trim" is in effect, the destination's dimensions will be the
77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    trimmed values but the source's will be untrimmed.
789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * 5. When "crop" is in effect, the destination's dimensions will be the
799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *    cropped values but the source's will be uncropped.  Each transform
809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *    routine is responsible for picking up source data starting at the
819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *    correct X and Y offset for the crop region.  (The X and Y offsets
829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *    passed to the transform routines are measured in iMCU blocks of the
839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *    destination.)
849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * 6. All the routines assume that the source and destination buffers are
85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    padded out to a full iMCU boundary.  This is true, although for the
86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *    source buffer it is an undocumented property of jdcoefct.c.
87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgdo_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 jvirt_barray_ptr *src_coef_arrays,
949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 jvirt_barray_ptr *dst_coef_arrays)
959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Crop.  This is only used when no rotate/flip is requested with the crop. */
969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  int ci, offset_y;
999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
1009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  jpeg_component_info *compptr;
1019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* We simply have to copy the right amount of data (the destination's
1039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * image size) starting at the given X and Y offsets in the source.
1049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
1059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
1069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    compptr = dstinfo->comp_info + ci;
1079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
1089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
1099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
1109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
1119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
1129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
1139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
1149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      src_buffer = (*srcinfo->mem->access_virt_barray)
1159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	((j_common_ptr) srcinfo, src_coef_arrays[ci],
1169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 dst_blk_y + y_crop_blocks,
1179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, FALSE);
1189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
1199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
1209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			dst_buffer[offset_y],
1219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			compptr->width_in_blocks);
1229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      }
1239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
1249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
1259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
1269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgLOCAL(void)
1299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgdo_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		   JDIMENSION x_crop_offset,
1319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		   jvirt_barray_ptr *src_coef_arrays)
1329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Horizontal flip; done in-place, so no separate dest array is required.
1339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * NB: this only works when y_crop_offset is zero.
1349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */
135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, k, offset_y;
138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY buffer;
139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR ptr1, ptr2;
140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEF temp1, temp2;
141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Horizontal mirroring of DCT blocks is accomplished by swapping
144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * mirroring by changing the signs of odd-numbered columns.
146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * Partial iMCUs at the right edge are left untouched.
147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
1489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = srcinfo->output_width /
1499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_width = MCU_cols * compptr->h_samp_factor;
1549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (blk_y = 0; blk_y < compptr->height_in_blocks;
156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 blk_y += compptr->v_samp_factor) {
157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      buffer = (*srcinfo->mem->access_virt_barray)
158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
1619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	/* Do the mirroring */
162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  ptr1 = buffer[offset_y][blk_x];
164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  /* this unrolled loop doesn't need to know which row it's on... */
166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (k = 0; k < DCTSIZE2; k += 2) {
167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    temp1 = *ptr1;	/* swap even column */
168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    temp2 = *ptr2;
169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    *ptr1++ = temp2;
170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    *ptr2++ = temp1;
171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    temp1 = *ptr1;	/* swap odd column with sign change */
172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    temp2 = *ptr2;
173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    *ptr1++ = -temp2;
174f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    *ptr2++ = -temp1;
175f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
176f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
1779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	if (x_crop_blocks > 0) {
1789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  /* Now left-justify the portion of the data to be kept.
1799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   * We can't use a single jcopy_block_row() call because that routine
1809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   * depends on memcpy(), whose behavior is unspecified for overlapping
1819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   * source and destination areas.  Sigh.
1829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   */
1839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
1849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
1859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			    buffer[offset_y] + blk_x,
1869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			    (JDIMENSION) 1);
1879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  }
1889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	}
1899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      }
1909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
1919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
1929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
1939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgLOCAL(void)
1969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgdo_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
1989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   jvirt_barray_ptr *src_coef_arrays,
1999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   jvirt_barray_ptr *dst_coef_arrays)
2009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Horizontal flip in general cropping case */
2019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
2029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
2039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
2049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  int ci, k, offset_y;
2059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
2069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JBLOCKROW src_row_ptr, dst_row_ptr;
2079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
2089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  jpeg_component_info *compptr;
2099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
2109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Here we must output into a separate array because we can't touch
2119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * different rows of a single virtual array simultaneously.  Otherwise,
2129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * this is essentially the same as the routine above.
2139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
2149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = srcinfo->output_width /
2159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
2169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
2179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
2189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    compptr = dstinfo->comp_info + ci;
2199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    comp_width = MCU_cols * compptr->h_samp_factor;
2209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
2219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
2229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
2239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
2249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
2259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
2269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
2279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      src_buffer = (*srcinfo->mem->access_virt_barray)
2289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	((j_common_ptr) srcinfo, src_coef_arrays[ci],
2299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 dst_blk_y + y_crop_blocks,
2309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, FALSE);
2319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
2329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	dst_row_ptr = dst_buffer[offset_y];
2339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	src_row_ptr = src_buffer[offset_y];
2349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
2359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  if (x_crop_blocks + dst_blk_x < comp_width) {
2369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* Do the mirrorable blocks */
2379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    dst_ptr = dst_row_ptr[dst_blk_x];
2389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
2399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* this unrolled loop doesn't need to know which row it's on... */
2409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    for (k = 0; k < DCTSIZE2; k += 2) {
2419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      *dst_ptr++ = *src_ptr++;	 /* copy even column */
2429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
2439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    }
2449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  } else {
2459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* Copy last partial block(s) verbatim */
2469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
2479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			    dst_row_ptr + dst_blk_x,
2489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			    (JDIMENSION) 1);
2499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  }
2509862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	}
251f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
252f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
253f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
254f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
255f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
256f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
257f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
258f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
2599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
260f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   jvirt_barray_ptr *src_coef_arrays,
261f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   jvirt_barray_ptr *dst_coef_arrays)
262f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Vertical flip */
263f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
264f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
2659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
266f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_y;
267f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
268f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKROW src_row_ptr, dst_row_ptr;
269f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
270f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
271f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
272f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* We output into a separate array because we can't touch different
273f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * rows of the source virtual array simultaneously.  Otherwise, this
274f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * is a pretty straightforward analog of horizontal flip.
275f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * Within a DCT block, vertical mirroring is done by changing the signs
276f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * of odd-numbered rows.
277f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * Partial iMCUs at the bottom edge are copied verbatim.
278f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
2799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_rows = srcinfo->output_height /
2809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
281f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
282f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
283f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
284f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_height = MCU_rows * compptr->v_samp_factor;
2859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
2869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
287f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
288f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
289f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
290f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
291f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
2929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (y_crop_blocks + dst_blk_y < comp_height) {
293f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	/* Row is within the mirrorable area. */
294f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	src_buffer = (*srcinfo->mem->access_virt_barray)
295f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
2969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   comp_height - y_crop_blocks - dst_blk_y -
2979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor,
298f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor, FALSE);
299f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      } else {
300f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	/* Bottom-edge blocks will be copied verbatim. */
301f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	src_buffer = (*srcinfo->mem->access_virt_barray)
3029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
3039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   dst_blk_y + y_crop_blocks,
304f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor, FALSE);
305f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
306f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
3079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	if (y_crop_blocks + dst_blk_y < comp_height) {
308f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  /* Row is within the mirrorable area. */
309f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  dst_row_ptr = dst_buffer[offset_y];
310f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
3119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  src_row_ptr += x_crop_blocks;
312f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
313f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	       dst_blk_x++) {
314f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    dst_ptr = dst_row_ptr[dst_blk_x];
315f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    src_ptr = src_row_ptr[dst_blk_x];
316f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    for (i = 0; i < DCTSIZE; i += 2) {
317f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* copy even row */
318f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (j = 0; j < DCTSIZE; j++)
319f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		*dst_ptr++ = *src_ptr++;
320f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* copy odd row with sign change */
321f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (j = 0; j < DCTSIZE; j++)
322f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		*dst_ptr++ = - *src_ptr++;
323f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
324f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
325f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	} else {
326f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  /* Just copy row verbatim. */
3279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
3289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			  dst_buffer[offset_y],
329f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org			  compptr->width_in_blocks);
330f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
331f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
332f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
333f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
334f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
335f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
336f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
337f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
338f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
3399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
340f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      jvirt_barray_ptr *src_coef_arrays,
341f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      jvirt_barray_ptr *dst_coef_arrays)
342f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Transpose source into destination */
343f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
3449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
345f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_x, offset_y;
346f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
347f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
348f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
349f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
350f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Transposing pixels within a block just requires transposing the
351f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * DCT coefficients.
352f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * Partial iMCUs at the edges require no special treatment; we simply
353f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * process all the available DCT blocks for every component.
354f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
355f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
356f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
3579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
3589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
359f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
360f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
361f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
362f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
363f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
364f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
365f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
366f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     dst_blk_x += compptr->h_samp_factor) {
367f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  src_buffer = (*srcinfo->mem->access_virt_barray)
3689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    ((j_common_ptr) srcinfo, src_coef_arrays[ci],
3699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	     dst_blk_x + x_crop_blocks,
370f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     (JDIMENSION) compptr->h_samp_factor, FALSE);
371f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
372f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
3739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
374f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    for (i = 0; i < DCTSIZE; i++)
375f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (j = 0; j < DCTSIZE; j++)
376f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
377f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
378f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
379f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
380f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
381f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
382f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
383f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
384f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
385f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
386f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
3879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
388f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   jvirt_barray_ptr *src_coef_arrays,
389f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   jvirt_barray_ptr *dst_coef_arrays)
390f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 90 degree rotation is equivalent to
391f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   1. Transposing the image;
392f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   2. Horizontal mirroring.
393f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These two steps are merged into a single processing routine.
394f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
395f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
396f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
3979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
398f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_x, offset_y;
399f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
400f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
401f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
402f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
403f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Because of the horizontal mirror step, we can't process partial iMCUs
404f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * at the (output) right edge properly.  They just get transposed and
405f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * not mirrored.
406f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
4079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = srcinfo->output_height /
4089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
409f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
410f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
411f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
412f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_width = MCU_cols * compptr->h_samp_factor;
4139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
4149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
415f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
416f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
417f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
418f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
419f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
420f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
421f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
422f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     dst_blk_x += compptr->h_samp_factor) {
4239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  if (x_crop_blocks + dst_blk_x < comp_width) {
4249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* Block is within the mirrorable area. */
4259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_buffer = (*srcinfo->mem->access_virt_barray)
4269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
4279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       comp_width - x_crop_blocks - dst_blk_x -
4289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor,
4299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor, FALSE);
4309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  } else {
4319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* Edge blocks are transposed but not mirrored. */
4329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_buffer = (*srcinfo->mem->access_virt_barray)
4339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
4349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       dst_blk_x + x_crop_blocks,
4359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor, FALSE);
4369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  }
437f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
4389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
4399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    if (x_crop_blocks + dst_blk_x < comp_width) {
440f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* Block is within the mirrorable area. */
4419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
4429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		[dst_blk_y + offset_y + y_crop_blocks];
443f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (i = 0; i < DCTSIZE; i++) {
444f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
445f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
446f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		i++;
447f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
448f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
449f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
450f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    } else {
451f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* Edge blocks are transposed but not mirrored. */
4529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_buffer[offset_x]
4539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		[dst_blk_y + offset_y + y_crop_blocks];
454f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (i = 0; i < DCTSIZE; i++)
455f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
456f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
457f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
458f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
459f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
460f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
461f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
462f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
463f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
464f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
465f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
466f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
467f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
4689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
469f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    jvirt_barray_ptr *src_coef_arrays,
470f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    jvirt_barray_ptr *dst_coef_arrays)
471f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 270 degree rotation is equivalent to
472f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   1. Horizontal mirroring;
473f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   2. Transposing the image.
474f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These two steps are merged into a single processing routine.
475f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
476f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
477f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
4789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
479f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_x, offset_y;
480f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
481f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
482f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
483f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
484f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Because of the horizontal mirror step, we can't process partial iMCUs
485f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * at the (output) bottom edge properly.  They just get transposed and
486f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * not mirrored.
487f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
4889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_rows = srcinfo->output_width /
4899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
490f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
491f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
492f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
493f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_height = MCU_rows * compptr->v_samp_factor;
4949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
4959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
496f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
497f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
498f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
499f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
500f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
501f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
502f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
503f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     dst_blk_x += compptr->h_samp_factor) {
504f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  src_buffer = (*srcinfo->mem->access_virt_barray)
5059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    ((j_common_ptr) srcinfo, src_coef_arrays[ci],
5069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	     dst_blk_x + x_crop_blocks,
507f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     (JDIMENSION) compptr->h_samp_factor, FALSE);
508f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
509f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
5109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    if (y_crop_blocks + dst_blk_y < comp_height) {
511f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* Block is within the mirrorable area. */
512f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      src_ptr = src_buffer[offset_x]
5139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		[comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
514f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (i = 0; i < DCTSIZE; i++) {
515f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (j = 0; j < DCTSIZE; j++) {
516f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
517f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  j++;
518f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
519f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		}
520f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
521f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    } else {
522f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      /* Edge blocks are transposed but not mirrored. */
5239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_buffer[offset_x]
5249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		[dst_blk_y + offset_y + y_crop_blocks];
525f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      for (i = 0; i < DCTSIZE; i++)
526f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
527f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
528f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
529f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
530f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
531f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
532f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
533f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
534f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
535f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
536f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
537f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
538f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
5399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
540f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    jvirt_barray_ptr *src_coef_arrays,
541f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    jvirt_barray_ptr *dst_coef_arrays)
542f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 180 degree rotation is equivalent to
543f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   1. Vertical mirroring;
544f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   2. Horizontal mirroring.
545f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These two steps are merged into a single processing routine.
546f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
547f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
548f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
5499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
550f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_y;
551f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
552f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKROW src_row_ptr, dst_row_ptr;
553f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
554f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
555f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
5569862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = srcinfo->output_width /
5579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
5589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_rows = srcinfo->output_height /
5599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
560f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
561f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
562f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
563f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_width = MCU_cols * compptr->h_samp_factor;
564f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_height = MCU_rows * compptr->v_samp_factor;
5659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
5669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
567f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
568f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
569f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
570f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
571f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
5729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (y_crop_blocks + dst_blk_y < comp_height) {
573f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	/* Row is within the vertically mirrorable area. */
574f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	src_buffer = (*srcinfo->mem->access_virt_barray)
575f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
5769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   comp_height - y_crop_blocks - dst_blk_y -
5779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor,
578f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor, FALSE);
579f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      } else {
580f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	/* Bottom-edge rows are only mirrored horizontally. */
581f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	src_buffer = (*srcinfo->mem->access_virt_barray)
5829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
5839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	   dst_blk_y + y_crop_blocks,
584f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	   (JDIMENSION) compptr->v_samp_factor, FALSE);
585f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
586f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
5879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	dst_row_ptr = dst_buffer[offset_y];
5889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	if (y_crop_blocks + dst_blk_y < comp_height) {
589f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  /* Row is within the mirrorable area. */
590f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
5919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
592f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    dst_ptr = dst_row_ptr[dst_blk_x];
5939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    if (x_crop_blocks + dst_blk_x < comp_width) {
5949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      /* Process the blocks that can be mirrored both ways. */
5959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
5969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      for (i = 0; i < DCTSIZE; i += 2) {
5979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		/* For even row, negate every odd column. */
5989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		for (j = 0; j < DCTSIZE; j += 2) {
5999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = *src_ptr++;
6009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = - *src_ptr++;
6019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		}
6029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		/* For odd row, negate every even column. */
6039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		for (j = 0; j < DCTSIZE; j += 2) {
6049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = - *src_ptr++;
6059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = *src_ptr++;
6069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		}
607f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
6089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    } else {
6099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      /* Any remaining right-edge blocks are only mirrored vertically. */
6109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
6119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      for (i = 0; i < DCTSIZE; i += 2) {
6129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
6139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = *src_ptr++;
6149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		for (j = 0; j < DCTSIZE; j++)
6159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  *dst_ptr++ = - *src_ptr++;
616f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
617f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
618f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
619f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	} else {
620f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  /* Remaining rows are just mirrored horizontally. */
621f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  src_row_ptr = src_buffer[offset_y];
6229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
6239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    if (x_crop_blocks + dst_blk_x < comp_width) {
6249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      /* Process the blocks that can be mirrored. */
6259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      dst_ptr = dst_row_ptr[dst_blk_x];
6269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
6279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      for (i = 0; i < DCTSIZE2; i += 2) {
6289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		*dst_ptr++ = *src_ptr++;
6299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		*dst_ptr++ = - *src_ptr++;
6309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      }
6319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    } else {
6329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      /* Any remaining right-edge blocks are only copied. */
6339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
6349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			      dst_row_ptr + dst_blk_x,
6359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			      (JDIMENSION) 1);
636f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
637f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
638f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
639f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
640f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
641f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
642f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
643f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
644f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
645f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
646f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgdo_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
6479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
648f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	       jvirt_barray_ptr *src_coef_arrays,
649f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	       jvirt_barray_ptr *dst_coef_arrays)
650f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Transverse transpose is equivalent to
651f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   1. 180 degree rotation;
652f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   2. Transposition;
653f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * or
654f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   1. Horizontal mirroring;
655f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   2. Transposition;
656f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *   3. Horizontal mirroring.
657f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These steps are merged into a single processing routine.
658f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
659f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
660f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
6619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION x_crop_blocks, y_crop_blocks;
662f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int ci, i, j, offset_x, offset_y;
663f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JBLOCKARRAY src_buffer, dst_buffer;
664f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JCOEFPTR src_ptr, dst_ptr;
665f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
666f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
6679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = srcinfo->output_height /
6689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
6699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_rows = srcinfo->output_width /
6709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
671f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
672f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
673f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
674f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_width = MCU_cols * compptr->h_samp_factor;
675f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    comp_height = MCU_rows * compptr->v_samp_factor;
6769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
6779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
678f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
679f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 dst_blk_y += compptr->v_samp_factor) {
680f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dst_buffer = (*srcinfo->mem->access_virt_barray)
681f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
682f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	 (JDIMENSION) compptr->v_samp_factor, TRUE);
683f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
684f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
685f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	     dst_blk_x += compptr->h_samp_factor) {
6869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  if (x_crop_blocks + dst_blk_x < comp_width) {
6879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    /* Block is within the mirrorable area. */
6889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_buffer = (*srcinfo->mem->access_virt_barray)
6899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
6909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       comp_width - x_crop_blocks - dst_blk_x -
6919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor,
6929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor, FALSE);
6939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  } else {
6949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    src_buffer = (*srcinfo->mem->access_virt_barray)
6959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      ((j_common_ptr) srcinfo, src_coef_arrays[ci],
6969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       dst_blk_x + x_crop_blocks,
6979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       (JDIMENSION) compptr->h_samp_factor, FALSE);
6989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  }
699f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
7009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
7019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	    if (y_crop_blocks + dst_blk_y < comp_height) {
7029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      if (x_crop_blocks + dst_blk_x < comp_width) {
703f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		/* Block is within the mirrorable area. */
7049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
7059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
706f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (i = 0; i < DCTSIZE; i++) {
707f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++) {
708f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
709f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    j++;
710f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
711f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  }
712f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  i++;
713f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++) {
714f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
715f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    j++;
716f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
717f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  }
718f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		}
719f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      } else {
720f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		/* Right-edge blocks are mirrored in y only */
7219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		src_ptr = src_buffer[offset_x]
7229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
723f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (i = 0; i < DCTSIZE; i++) {
724f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++) {
725f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
726f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    j++;
727f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
728f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  }
729f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		}
730f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
731f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    } else {
7329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      if (x_crop_blocks + dst_blk_x < comp_width) {
733f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		/* Bottom-edge blocks are mirrored in x only */
7349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
7359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  [dst_blk_y + offset_y + y_crop_blocks];
736f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (i = 0; i < DCTSIZE; i++) {
737f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++)
738f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
739f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  i++;
740f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++)
741f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
742f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		}
743f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      } else {
744f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		/* At lower right corner, just transpose, no mirroring */
7459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		src_ptr = src_buffer[offset_x]
7469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  [dst_blk_y + offset_y + y_crop_blocks];
747f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		for (i = 0; i < DCTSIZE; i++)
748f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		  for (j = 0; j < DCTSIZE; j++)
749f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
750f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	      }
751f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	    }
752f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  }
753f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
754f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
755f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
756f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
757f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
758f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
759f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
7609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
7619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Returns TRUE if valid integer found, FALSE if not.
7629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * *strptr is advanced over the digit string, and *result is set to its value.
7639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */
7649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
7659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgLOCAL(boolean)
7669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgjt_read_integer (const char ** strptr, JDIMENSION * result)
7679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
7689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  const char * ptr = *strptr;
7699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION val = 0;
7709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
7719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  for (; isdigit(*ptr); ptr++) {
7729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    val = val * 10 + (JDIMENSION) (*ptr - '0');
7739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
7749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  *result = val;
7759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (ptr == *strptr)
7769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    return FALSE;		/* oops, no digits */
7779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  *strptr = ptr;
7789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  return TRUE;
7799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
7809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
7819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
7829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Parse a crop specification (written in X11 geometry style).
7839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * The routine returns TRUE if the spec string is valid, FALSE if not.
7849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
7859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * The crop spec string should have the format
7863395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org *	<width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
7879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * where width, height, xoffset, and yoffset are unsigned integers.
7889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Each of the elements can be omitted to indicate a default value.
7899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * (A weakness of this style is that it is not possible to omit xoffset
7909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * while specifying yoffset, since they look alike.)
7919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
7929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * This code is loosely based on XParseGeometry from the X11 distribution.
7939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */
7949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
7959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgGLOBAL(boolean)
7969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgjtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
7979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
7989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop = FALSE;
7999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop_width_set = JCROP_UNSET;
8009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop_height_set = JCROP_UNSET;
8019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop_xoffset_set = JCROP_UNSET;
8029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop_yoffset_set = JCROP_UNSET;
8039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (isdigit(*spec)) {
8059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* fetch width */
8069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (! jt_read_integer(&spec, &info->crop_width))
8079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      return FALSE;
8083395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    if (*spec == 'f' || *spec == 'F') {
8093395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      spec++;
8103395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->crop_width_set = JCROP_FORCE;
8113395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    } else
8123395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->crop_width_set = JCROP_POS;
8139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
8143395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org  if (*spec == 'x' || *spec == 'X') {
8159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* fetch height */
8169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    spec++;
8179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (! jt_read_integer(&spec, &info->crop_height))
8189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      return FALSE;
8193395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    if (*spec == 'f' || *spec == 'F') {
8203395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      spec++;
8213395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->crop_height_set = JCROP_FORCE;
8223395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    } else
8233395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->crop_height_set = JCROP_POS;
8249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
8259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (*spec == '+' || *spec == '-') {
8269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* fetch xoffset */
8279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
8289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    spec++;
8299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (! jt_read_integer(&spec, &info->crop_xoffset))
8309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      return FALSE;
8319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
8329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (*spec == '+' || *spec == '-') {
8339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* fetch yoffset */
8349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
8359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    spec++;
8369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (! jt_read_integer(&spec, &info->crop_yoffset))
8379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      return FALSE;
8389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
8399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* We had better have gotten to the end of the string. */
8409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (*spec != '\0')
8419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    return FALSE;
8429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  info->crop = TRUE;
8439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  return TRUE;
8449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
8459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Trim off any partial iMCUs on the indicated destination edge */
8489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgLOCAL(void)
8509862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgtrim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
8519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
8529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION MCU_cols;
8539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_cols = info->output_width / info->iMCU_sample_width;
8559862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
8569862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      full_width / info->iMCU_sample_width)
8579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_width = MCU_cols * info->iMCU_sample_width;
8589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
8599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgLOCAL(void)
8619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgtrim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
8629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
8639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION MCU_rows;
8649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  MCU_rows = info->output_height / info->iMCU_sample_height;
8669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
8679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      full_height / info->iMCU_sample_height)
8689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_height = MCU_rows * info->iMCU_sample_height;
8699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
8709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
8719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
872f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Request any required workspace.
873f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
8749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * This routine figures out the size that the output image will be
8759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * (which implies that all the transform parameters must be set before
8769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * it is called).
8779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
878f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * We allocate the workspace virtual arrays from the source decompression
879f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * object, so that all the arrays (both the original data and the workspace)
880f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * will be taken into account while making memory management decisions.
881f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Hence, this routine must be called after jpeg_read_header (which reads
882f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the image dimensions) and before jpeg_read_coefficients (which realizes
883f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the source's virtual arrays).
8849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
8859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * This function returns FALSE right away if -perfect is given
8869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * and transformation is not perfect.  Otherwise returns TRUE.
887f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
888f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
8899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgGLOBAL(boolean)
890f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjtransform_request_workspace (j_decompress_ptr srcinfo,
891f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org			      jpeg_transform_info *info)
892f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
8939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  jvirt_barray_ptr *coef_arrays;
8949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  boolean need_workspace, transpose_it;
895f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
8969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION xoffset, yoffset;
8979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION width_in_iMCUs, height_in_iMCUs;
8989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION width_in_blocks, height_in_blocks;
8999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  int ci, h_samp_factor, v_samp_factor;
900f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
9019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Determine number of components in output image */
902f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  if (info->force_grayscale &&
903f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      srcinfo->jpeg_color_space == JCS_YCbCr &&
9049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      srcinfo->num_components == 3)
905f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /* We'll only process the first component */
906f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    info->num_components = 1;
9079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  else
908f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /* Process all the components */
909f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    info->num_components = srcinfo->num_components;
9109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
9119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Compute output image dimensions and related values. */
9129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION >= 80
9139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  jpeg_core_output_dimensions(srcinfo);
9149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#else
9159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  srcinfo->output_width = srcinfo->image_width;
9169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  srcinfo->output_height = srcinfo->image_height;
9179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
9189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
9199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Return right away if -perfect is given and transformation is not perfect.
9209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
9219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (info->perfect) {
9229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->num_components == 1) {
9239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (!jtransform_perfect_transform(srcinfo->output_width,
9249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->output_height,
9259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->_min_DCT_h_scaled_size,
9269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->_min_DCT_v_scaled_size,
9279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  info->transform))
9289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	return FALSE;
9299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    } else {
9309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (!jtransform_perfect_transform(srcinfo->output_width,
9319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->output_height,
9329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size,
9339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size,
9349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  info->transform))
9359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	return FALSE;
9369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
9379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
9389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
9399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* If there is only one output component, force the iMCU size to be 1;
9409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * else use the source iMCU size.  (This allows us to do the right thing
9419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * when reducing color to grayscale, and also provides a handy way of
9429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
9439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
9449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  switch (info->transform) {
9459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_TRANSPOSE:
9469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_TRANSVERSE:
9479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_90:
9489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_270:
9499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_width = srcinfo->output_height;
9509862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_height = srcinfo->output_width;
9519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->num_components == 1) {
9529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size;
9539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size;
9549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    } else {
9559862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_width =
9569862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
9579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_height =
9589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
9599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
9609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
9619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  default:
9629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_width = srcinfo->output_width;
9639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->output_height = srcinfo->output_height;
9649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->num_components == 1) {
9659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size;
9669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size;
9679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    } else {
9689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_width =
9699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
9709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->iMCU_sample_height =
9719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
9729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
9739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
9749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
9759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
9769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* If cropping has been requested, compute the crop area's position and
9779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
9789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
9799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (info->crop) {
9809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Insert default values for unset crop parameters */
9819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_xoffset_set == JCROP_UNSET)
9829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->crop_xoffset = 0;	/* default to +0 */
9839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_yoffset_set == JCROP_UNSET)
9849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->crop_yoffset = 0;	/* default to +0 */
9859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_xoffset >= info->output_width ||
9869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	info->crop_yoffset >= info->output_height)
9879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
9889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_width_set == JCROP_UNSET)
9899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->crop_width = info->output_width - info->crop_xoffset;
9909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_height_set == JCROP_UNSET)
9919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      info->crop_height = info->output_height - info->crop_yoffset;
9929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Ensure parameters are valid */
9939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_width <= 0 || info->crop_width > info->output_width ||
9949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	info->crop_height <= 0 || info->crop_height > info->output_height ||
9959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	info->crop_xoffset > info->output_width - info->crop_width ||
9969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	info->crop_yoffset > info->output_height - info->crop_height)
9979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
9989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Convert negative crop offsets into regular offsets */
9999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_xoffset_set == JCROP_NEG)
10009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
10019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    else
10029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      xoffset = info->crop_xoffset;
10039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->crop_yoffset_set == JCROP_NEG)
10049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
10059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    else
10069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      yoffset = info->crop_yoffset;
10079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Now adjust so that upper left corner falls at an iMCU boundary */
10083395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    if (info->crop_width_set == JCROP_FORCE)
10093395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->output_width = info->crop_width;
10103395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    else
10113395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->output_width =
10123395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org        info->crop_width + (xoffset % info->iMCU_sample_width);
10133395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    if (info->crop_height_set == JCROP_FORCE)
10143395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->output_height = info->crop_height;
10153395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org    else
10163395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org      info->output_height =
10173395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org        info->crop_height + (yoffset % info->iMCU_sample_height);
10189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Save x/y offsets measured in iMCUs */
10199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->x_crop_offset = xoffset / info->iMCU_sample_width;
10209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->y_crop_offset = yoffset / info->iMCU_sample_height;
10219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
10229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->x_crop_offset = 0;
10239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->y_crop_offset = 0;
1024f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1025f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
10269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Figure out whether we need workspace arrays,
10279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * and if so whether they are transposed relative to the source.
10289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
10299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  need_workspace = FALSE;
10309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  transpose_it = FALSE;
1031f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  switch (info->transform) {
1032f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_NONE:
10339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
10349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      need_workspace = TRUE;
10359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* No workspace needed if neither cropping nor transforming */
10369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
1037f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_FLIP_H:
10389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim)
10399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_right_edge(info, srcinfo->output_width);
10409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->y_crop_offset != 0 || info->slow_hflip)
10419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      need_workspace = TRUE;
10429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* do_flip_h_no_crop doesn't need a workspace array */
1043f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1044f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_FLIP_V:
10459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim)
10469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_bottom_edge(info, srcinfo->output_height);
10479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having same dimensions as source image. */
10489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
1049f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1050f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSPOSE:
10519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* transpose does NOT have to trim anything */
10529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having transposed dimensions. */
10539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
10549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    transpose_it = TRUE;
10559862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
1056f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSVERSE:
10579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim) {
10589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_right_edge(info, srcinfo->output_height);
10599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_bottom_edge(info, srcinfo->output_width);
10609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
10619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having transposed dimensions. */
10629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
10639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    transpose_it = TRUE;
10649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
1065f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_90:
10669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim)
10679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_right_edge(info, srcinfo->output_height);
10689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having transposed dimensions. */
10699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
10709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    transpose_it = TRUE;
10719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
10729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_180:
10739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim) {
10749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_right_edge(info, srcinfo->output_width);
10759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_bottom_edge(info, srcinfo->output_height);
10769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
10779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having same dimensions as source image. */
10789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
10799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
1080f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_270:
10819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->trim)
10829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      trim_bottom_edge(info, srcinfo->output_width);
10839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Need workspace arrays having transposed dimensions. */
10849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    need_workspace = TRUE;
10859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    transpose_it = TRUE;
10869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
10879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
10889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
10899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Allocate workspace if needed.
10909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * Note that we allocate arrays padded out to the next iMCU boundary,
10919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * so that transform routines need not worry about missing edge blocks.
10929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
10939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (need_workspace) {
1094f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    coef_arrays = (jvirt_barray_ptr *)
1095f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
10969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		SIZEOF(jvirt_barray_ptr) * info->num_components);
10979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    width_in_iMCUs = (JDIMENSION)
10989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      jdiv_round_up((long) info->output_width,
10999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		    (long) info->iMCU_sample_width);
11009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    height_in_iMCUs = (JDIMENSION)
11019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      jdiv_round_up((long) info->output_height,
11029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		    (long) info->iMCU_sample_height);
1103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (ci = 0; ci < info->num_components; ci++) {
1104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      compptr = srcinfo->comp_info + ci;
11059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (info->num_components == 1) {
11069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	/* we're going to force samp factors to 1x1 in this case */
11079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	h_samp_factor = v_samp_factor = 1;
11089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      } else if (transpose_it) {
11099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	h_samp_factor = compptr->v_samp_factor;
11109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	v_samp_factor = compptr->h_samp_factor;
11119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      } else {
11129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	h_samp_factor = compptr->h_samp_factor;
11139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	v_samp_factor = compptr->v_samp_factor;
11149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      }
11159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      width_in_blocks = width_in_iMCUs * h_samp_factor;
11169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      height_in_blocks = height_in_iMCUs * v_samp_factor;
1117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
11199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
1120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
11219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->workspace_coef_arrays = coef_arrays;
11229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else
11239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    info->workspace_coef_arrays = NULL;
11249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
11259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  return TRUE;
1126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Transpose destination image parameters */
1130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
1132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtranspose_critical_parameters (j_compress_ptr dstinfo)
1133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int tblno, i, j, ci, itemp;
1135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_component_info *compptr;
1136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  JQUANT_TBL *qtblptr;
11379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION jtemp;
1138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  UINT16 qtemp;
1139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
11409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Transpose image dimensions */
11419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  jtemp = dstinfo->image_width;
1142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  dstinfo->image_width = dstinfo->image_height;
11439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  dstinfo->image_height = jtemp;
11449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION >= 70
11459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  itemp = dstinfo->min_DCT_h_scaled_size;
11469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
11479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  dstinfo->min_DCT_v_scaled_size = itemp;
11489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
1149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Transpose sampling factors */
1151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (ci = 0; ci < dstinfo->num_components; ci++) {
1152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr = dstinfo->comp_info + ci;
1153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    itemp = compptr->h_samp_factor;
1154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr->h_samp_factor = compptr->v_samp_factor;
1155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    compptr->v_samp_factor = itemp;
1156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Transpose quantization tables */
1159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
1160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
1161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (qtblptr != NULL) {
1162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (i = 0; i < DCTSIZE; i++) {
1163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	for (j = 0; j < i; j++) {
1164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  qtemp = qtblptr->quantval[i*DCTSIZE+j];
1165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
1166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
1167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	}
1168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      }
1169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
1170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
11749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* Adjust Exif image parameters.
11759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
11769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
11779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */
1178f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
11793395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org#if JPEG_LIB_VERSION >= 70
1180f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void)
11819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgadjust_exif_parameters (JOCTET FAR * data, unsigned int length,
11829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			JDIMENSION new_width, JDIMENSION new_height)
1183f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
11849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  boolean is_motorola; /* Flag for byte order */
11859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  unsigned int number_of_tags, tagnum;
11869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  unsigned int firstoffset, offset;
11879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  JDIMENSION new_value;
1188f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
11899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (length < 12) return; /* Length of an IFD entry */
11909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
11919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Discover byte order */
11929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
11939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    is_motorola = FALSE;
11949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
11959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    is_motorola = TRUE;
11969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  else
11979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    return;
11989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
11999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Check Tag Mark */
12009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (is_motorola) {
12019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[2]) != 0) return;
12029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[3]) != 0x2A) return;
12039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
12049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[3]) != 0) return;
12059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[2]) != 0x2A) return;
1206f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1207f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
12089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Get first IFD offset (offset to IFD0) */
12099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (is_motorola) {
12109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[4]) != 0) return;
12119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[5]) != 0) return;
12129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset = GETJOCTET(data[6]);
12139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset <<= 8;
12149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset += GETJOCTET(data[7]);
12159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
12169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[7]) != 0) return;
12179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[6]) != 0) return;
12189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset = GETJOCTET(data[5]);
12199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset <<= 8;
12209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset += GETJOCTET(data[4]);
12219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
12229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (firstoffset > length - 2) return; /* check end of data segment */
1223f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
12249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Get the number of directory entries contained in this IFD */
12259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (is_motorola) {
12269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags = GETJOCTET(data[firstoffset]);
12279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags <<= 8;
12289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags += GETJOCTET(data[firstoffset+1]);
12299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
12309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags = GETJOCTET(data[firstoffset+1]);
12319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags <<= 8;
12329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags += GETJOCTET(data[firstoffset]);
12339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
12349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (number_of_tags == 0) return;
12359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  firstoffset += 2;
12369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
12379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Search for ExifSubIFD offset Tag in IFD0 */
12389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  for (;;) {
12399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (firstoffset > length - 12) return; /* check end of data segment */
12409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Get Tag number */
12419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (is_motorola) {
12429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum = GETJOCTET(data[firstoffset]);
12439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum <<= 8;
12449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum += GETJOCTET(data[firstoffset+1]);
12459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    } else {
12469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum = GETJOCTET(data[firstoffset+1]);
12479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum <<= 8;
12489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum += GETJOCTET(data[firstoffset]);
12499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
12509862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
12519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (--number_of_tags == 0) return;
12529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    firstoffset += 12;
12539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
12549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
12559862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Get the ExifSubIFD offset */
12569862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (is_motorola) {
12579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[firstoffset+8]) != 0) return;
12589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[firstoffset+9]) != 0) return;
12599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset = GETJOCTET(data[firstoffset+10]);
12609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset <<= 8;
12619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset += GETJOCTET(data[firstoffset+11]);
12629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
12639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[firstoffset+11]) != 0) return;
12649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (GETJOCTET(data[firstoffset+10]) != 0) return;
12659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset = GETJOCTET(data[firstoffset+9]);
12669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset <<= 8;
12679862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset += GETJOCTET(data[firstoffset+8]);
1268f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
12699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (offset > length - 2) return; /* check end of data segment */
12709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
12719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Get the number of directory entries contained in this SubIFD */
12729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (is_motorola) {
12739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags = GETJOCTET(data[offset]);
12749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags <<= 8;
12759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags += GETJOCTET(data[offset+1]);
12769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else {
12779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags = GETJOCTET(data[offset+1]);
12789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags <<= 8;
12799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    number_of_tags += GETJOCTET(data[offset]);
12809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
12819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (number_of_tags < 2) return;
12829862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  offset += 2;
12839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
12849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
12859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  do {
12869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (offset > length - 12) return; /* check end of data segment */
12879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Get Tag number */
12889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (is_motorola) {
12899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum = GETJOCTET(data[offset]);
12909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum <<= 8;
12919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum += GETJOCTET(data[offset+1]);
12929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    } else {
12939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum = GETJOCTET(data[offset+1]);
12949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum <<= 8;
12959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      tagnum += GETJOCTET(data[offset]);
12969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
12979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (tagnum == 0xA002 || tagnum == 0xA003) {
12989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (tagnum == 0xA002)
12999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	new_value = new_width; /* ExifImageWidth Tag */
13009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      else
13019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	new_value = new_height; /* ExifImageHeight Tag */
13029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      if (is_motorola) {
13039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+2] = 0; /* Format = unsigned long (4 octets) */
13049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+3] = 4;
13059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+4] = 0; /* Number Of Components = 1 */
13069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+5] = 0;
13079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+6] = 0;
13089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+7] = 1;
13099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+8] = 0;
13109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+9] = 0;
13119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
13129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+11] = (JOCTET)(new_value & 0xFF);
13139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      } else {
13149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+2] = 4; /* Format = unsigned long (4 octets) */
13159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+3] = 0;
13169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+4] = 1; /* Number Of Components = 1 */
13179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+5] = 0;
13189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+6] = 0;
13199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+7] = 0;
13209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+8] = (JOCTET)(new_value & 0xFF);
13219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
13229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+10] = 0;
13239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	data[offset+11] = 0;
13249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      }
13259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    }
13269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    offset += 12;
13279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } while (--number_of_tags);
1328f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
13293395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org#endif
1330f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1331f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1332f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Adjust output image parameters as needed.
1333f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
1334f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This must be called after jpeg_copy_critical_parameters()
1335f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * and before jpeg_write_coefficients().
1336f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
1337f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The return value is the set of virtual coefficient arrays to be written
1338f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * (either the ones allocated by jtransform_request_workspace, or the
1339f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * original source data arrays).  The caller will need to pass this value
1340f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * to jpeg_write_coefficients().
1341f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
1342f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1343f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(jvirt_barray_ptr *)
1344f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjtransform_adjust_parameters (j_decompress_ptr srcinfo,
1345f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org			      j_compress_ptr dstinfo,
1346f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org			      jvirt_barray_ptr *src_coef_arrays,
1347f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org			      jpeg_transform_info *info)
1348f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1349f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* If force-to-grayscale is requested, adjust destination parameters */
1350f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  if (info->force_grayscale) {
13519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* First, ensure we have YCbCr or grayscale data, and that the source's
13529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     * Y channel is full resolution.  (No reasonable person would make Y
13539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     * be less than full resolution, so actually coping with that case
13549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     * isn't worth extra code space.  But we check it to avoid crashing.)
1355f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org     */
13569862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
13579862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  dstinfo->num_components == 3) ||
13589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
13599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	  dstinfo->num_components == 1)) &&
13609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
13619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
13629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
13639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org       * properly.  Among other things, it sets the target h_samp_factor &
13649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org       * v_samp_factor to 1, which typically won't match the source.
13659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org       * We have to preserve the source's quantization table number, however.
13669862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org       */
1367f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
1368f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
1369f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
1370f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    } else {
1371f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      /* Sorry, can't do it */
1372f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
1373f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
13749862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  } else if (info->num_components == 1) {
13759862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* For a single-component source, we force the destination sampling factors
13769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     * to 1x1, with or without force_grayscale.  This is useful because some
13779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     * decoders choke on grayscale images with other sampling factors.
13789862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org     */
13799862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->comp_info[0].h_samp_factor = 1;
13809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->comp_info[0].v_samp_factor = 1;
1381f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1382f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
13839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Correct the destination's image dimensions as necessary
13849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * for rotate/flip, resize, and crop operations.
13859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
13869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION >= 70
13879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  dstinfo->jpeg_width = info->output_width;
13889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  dstinfo->jpeg_height = info->output_height;
13899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
13909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
13919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Transpose destination image parameters */
1392f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  switch (info->transform) {
1393f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSPOSE:
1394f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSVERSE:
1395f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_90:
1396f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_270:
13979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION < 70
13989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->image_width = info->output_height;
13999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->image_height = info->output_width;
14009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
1401f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    transpose_critical_parameters(dstinfo);
14029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
14039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  default:
14049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION < 70
14059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->image_width = info->output_width;
14069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->image_height = info->output_height;
14079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
1408f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1409f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1410f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
14119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Adjust Exif properties */
14129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  if (srcinfo->marker_list != NULL &&
14139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      srcinfo->marker_list->marker == JPEG_APP0+1 &&
14149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      srcinfo->marker_list->data_length >= 6 &&
14159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
14169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
14179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
14189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
14199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
14209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
14219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Suppress output of JFIF marker */
14229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    dstinfo->write_JFIF_header = FALSE;
14239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#if JPEG_LIB_VERSION >= 70
14249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    /* Adjust Exif image parameters */
14259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (dstinfo->jpeg_width != srcinfo->image_width ||
14269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	dstinfo->jpeg_height != srcinfo->image_height)
14279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      /* Align data segment to start of TIFF structure for parsing */
14289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      adjust_exif_parameters(srcinfo->marker_list->data + 6,
14299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	srcinfo->marker_list->data_length - 6,
14309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	dstinfo->jpeg_width, dstinfo->jpeg_height);
14319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org#endif
14329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
14339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1434f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Return the appropriate output data set */
1435f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  if (info->workspace_coef_arrays != NULL)
1436f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    return info->workspace_coef_arrays;
1437f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  return src_coef_arrays;
1438f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1439f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1440f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1441f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Execute the actual transformation, if any.
1442f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
1443f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This must be called *after* jpeg_write_coefficients, because it depends
1444f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * on jpeg_write_coefficients to have computed subsidiary values such as
1445f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the per-component width and height fields in the destination object.
1446f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *
1447f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Note that some transformations will modify the source data arrays!
1448f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
1449f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1450f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void)
14519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgjtransform_execute_transform (j_decompress_ptr srcinfo,
14529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			      j_compress_ptr dstinfo,
14539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			      jvirt_barray_ptr *src_coef_arrays,
14549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			      jpeg_transform_info *info)
1455f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1456f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
1457f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
14589862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  /* Note: conditions tested here should match those in switch statement
14599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   * in jtransform_request_workspace()
14609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org   */
1461f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  switch (info->transform) {
1462f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_NONE:
14639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
14649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14659862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_coef_arrays, dst_coef_arrays);
1466f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1467f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_FLIP_H:
14689862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (info->y_crop_offset != 0 || info->slow_hflip)
14699862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14709862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		src_coef_arrays, dst_coef_arrays);
14719862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    else
14729862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
14739862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			src_coef_arrays);
1474f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1475f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_FLIP_V:
14769862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14779862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_coef_arrays, dst_coef_arrays);
1478f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1479f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSPOSE:
14809862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		 src_coef_arrays, dst_coef_arrays);
1482f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1483f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_TRANSVERSE:
14849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org		  src_coef_arrays, dst_coef_arrays);
1486f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1487f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_90:
14889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	      src_coef_arrays, dst_coef_arrays);
1490f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1491f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_180:
14929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       src_coef_arrays, dst_coef_arrays);
1494f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1495f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  case JXFORM_ROT_270:
14969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
14979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org	       src_coef_arrays, dst_coef_arrays);
1498f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    break;
1499f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1500f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1501f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
15029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* jtransform_perfect_transform
15039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
15049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Determine whether lossless transformation is perfectly
15059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * possible for a specified image and transformation.
15069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *
15079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Inputs:
15089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   image_width, image_height: source image dimensions.
15099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   MCU_width, MCU_height: pixel dimensions of MCU.
15109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   transform: transformation identifier.
15119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Parameter sources from initialized jpeg_struct
15129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * (after reading source header):
15139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   image_width = cinfo.image_width
15149862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   image_height = cinfo.image_height
15159862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
15169862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
15179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Result:
15189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   TRUE = perfect transformation possible
15199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *   FALSE = perfect transformation not possible
15209862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org *           (may use custom action then)
15219862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */
15229862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
15239862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgGLOBAL(boolean)
15249862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgjtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
15259862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			     int MCU_width, int MCU_height,
15269862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org			     JXFORM_CODE transform)
15279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{
15289862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  boolean result = TRUE; /* initialize TRUE */
15299862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
15309862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  switch (transform) {
15319862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_FLIP_H:
15329862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_270:
15339862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (image_width % (JDIMENSION) MCU_width)
15349862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      result = FALSE;
15359862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
15369862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_FLIP_V:
15379862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_90:
15389862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (image_height % (JDIMENSION) MCU_height)
15399862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      result = FALSE;
15409862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
15419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_TRANSVERSE:
15429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  case JXFORM_ROT_180:
15439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (image_width % (JDIMENSION) MCU_width)
15449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      result = FALSE;
15459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    if (image_height % (JDIMENSION) MCU_height)
15469862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org      result = FALSE;
15479862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
15489862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  default:
15499862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org    break;
15509862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  }
15519862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
15529862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org  return result;
15539862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org}
15549862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org
1555f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif /* TRANSFORMS_SUPPORTED */
1556f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1557f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1558f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Setup decompression object to save desired markers in memory.
1559f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This must be called before jpeg_read_header() to have the desired effect.
1560f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
1561f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1562f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void)
1563f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
1564f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1565f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef SAVE_MARKERS_SUPPORTED
1566f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  int m;
1567f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1568f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Save comments except under NONE option */
1569f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  if (option != JCOPYOPT_NONE) {
1570f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
1571f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1572f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* Save all types of APPn markers iff ALL option */
1573f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  if (option == JCOPYOPT_ALL) {
1574f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    for (m = 0; m < 16; m++)
1575f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
1576f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1577f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif /* SAVE_MARKERS_SUPPORTED */
1578f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1579f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1580f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Copy markers saved in the given source object to the destination object.
1581f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This should be called just after jpeg_start_compress() or
1582f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * jpeg_write_coefficients().
1583f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Note that those routines will have written the SOI, and also the
1584f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * JFIF APP0 or Adobe APP14 markers if selected.
1585f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */
1586f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1587f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void)
1588f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1589f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		       JCOPY_OPTION option)
1590f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{
1591f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  jpeg_saved_marker_ptr marker;
1592f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org
1593f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  /* In the current implementation, we don't actually need to examine the
1594f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * option flag here; we just copy everything that got saved.
1595f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1596f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   * if the encoder library already wrote one.
1597f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org   */
1598f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
1599f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (dstinfo->write_JFIF_header &&
1600f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	marker->marker == JPEG_APP0 &&
1601f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	marker->data_length >= 5 &&
1602f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[0]) == 0x4A &&
1603f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[1]) == 0x46 &&
1604f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[2]) == 0x49 &&
1605f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[3]) == 0x46 &&
1606f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[4]) == 0)
1607f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      continue;			/* reject duplicate JFIF */
1608f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    if (dstinfo->write_Adobe_marker &&
1609f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	marker->marker == JPEG_APP0+14 &&
1610f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	marker->data_length >= 5 &&
1611f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[0]) == 0x41 &&
1612f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[1]) == 0x64 &&
1613f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[2]) == 0x6F &&
1614f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[3]) == 0x62 &&
1615f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	GETJOCTET(marker->data[4]) == 0x65)
1616f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      continue;			/* reject duplicate Adobe */
1617f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef NEED_FAR_POINTERS
1618f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    /* We could use jpeg_write_marker if the data weren't FAR... */
1619f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    {
1620f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      unsigned int i;
1621f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
1622f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org      for (i = 0; i < marker->data_length; i++)
1623f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org	jpeg_write_m_byte(dstinfo, marker->data[i]);
1624f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    }
1625f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#else
1626f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org    jpeg_write_marker(dstinfo, marker->marker,
1627f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org		      marker->data, marker->data_length);
1628f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif
1629f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org  }
1630f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org}
1631