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