170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * transupp.c 370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1997, Thomas G. Lane. 570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software. 670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file. 770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains image transformation routines and other utility code 970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * used by the jpegtran sample application. These are NOT part of the core 1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * JPEG library. But we keep these routines separate from jpegtran.c to 1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * ease the task of maintaining jpegtran-like programs that have other user 1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * interfaces. 1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Although this file really shouldn't have access to the library internals, 1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * it's helpful to let it call jround_up() and jcopy_block_row(). 1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define JPEG_INTERNALS 1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jinclude.h" 2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jpeglib.h" 2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "transupp.h" /* My own external interface */ 2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if TRANSFORMS_SUPPORTED 2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Lossless image transformation routines. These routines work on DCT 2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * coefficient arrays and thus do not require any lossy decompression 3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * or recompression of the image. 3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Thanks to Guido Vollbeding for the initial design and code of this feature. 3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Horizontal flipping is done in-place, using a single top-to-bottom 3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * pass through the virtual source array. It will thus be much the 3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * fastest option for images larger than main memory. 3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The other routines require a set of destination virtual arrays, so they 3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * need twice as much memory as jpegtran normally does. The destination 3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * arrays are always written in normal scan order (top to bottom) because 4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the virtual array manager expects this. The source arrays will be scanned 4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * in the corresponding order, which means multiple passes through the source 4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * arrays for most of the transforms. That could result in much thrashing 4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * if the image is larger than main memory. 4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Some notes about the operating environment of the individual transform 4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * routines: 4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. Both the source and destination virtual arrays are allocated from the 4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * source JPEG object, and therefore should be manipulated by calling the 4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * source's memory manager. 5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. The destination's component count should be used. It may be smaller 5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * than the source's when forcing to grayscale. 5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 3. Likewise the destination's sampling factors should be used. When 5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * forcing to grayscale the destination's sampling factors will be all 1, 5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * and we may as well take that as the effective iMCU size. 5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 4. When "trim" is in effect, the destination's dimensions will be the 5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * trimmed values but the source's will be untrimmed. 5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 5. All the routines assume that the source and destination buffers are 5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * padded out to a full iMCU boundary. This is true, although for the 5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * source buffer it is an undocumented property of jdcoefct.c. 6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Notes 2,3,4 boil down to this: generally we should use the destination's 6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * dimensions and ignore the source's. 6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays) 6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Horizontal flip; done in-place, so no separate dest array is required */ 6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_cols, comp_width, blk_x, blk_y; 7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, k, offset_y; 7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY buffer; 7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR ptr1, ptr2; 7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEF temp1, temp2; 7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Horizontal mirroring of DCT blocks is accomplished by swapping 7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * pairs of blocks in-place. Within a DCT block, we perform horizontal 7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * mirroring by changing the signs of odd-numbered columns. 8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Partial iMCUs at the right edge are left untouched. 8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_width = MCU_cols * compptr->h_samp_factor; 8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (blk_y = 0; blk_y < compptr->height_in_blocks; 8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine blk_y += compptr->v_samp_factor) { 8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine buffer = (*srcinfo->mem->access_virt_barray) 9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, 9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { 9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ptr1 = buffer[offset_y][blk_x]; 9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ptr2 = buffer[offset_y][comp_width - blk_x - 1]; 9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* this unrolled loop doesn't need to know which row it's on... */ 9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (k = 0; k < DCTSIZE2; k += 2) { 9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine temp1 = *ptr1; /* swap even column */ 9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine temp2 = *ptr2; 10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *ptr1++ = temp2; 10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *ptr2++ = temp1; 10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine temp1 = *ptr1; /* swap odd column with sign change */ 10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine temp2 = *ptr2; 10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *ptr1++ = -temp2; 10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *ptr2++ = -temp1; 10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Vertical flip */ 11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_y; 12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKROW src_row_ptr, dst_row_ptr; 12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We output into a separate array because we can't touch different 12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * rows of the source virtual array simultaneously. Otherwise, this 12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * is a pretty straightforward analog of horizontal flip. 13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Within a DCT block, vertical mirroring is done by changing the signs 13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * of odd-numbered rows. 13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Partial iMCUs at the bottom edge are copied verbatim. 13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height = MCU_rows * compptr->v_samp_factor; 13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Row is within the mirrorable area. */ 14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], 14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, FALSE); 15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Bottom-edge blocks will be copied verbatim. */ 15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, FALSE); 15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Row is within the mirrorable area. */ 15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_row_ptr = dst_buffer[offset_y]; 16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_x++) { 16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_row_ptr[dst_blk_x]; 16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_row_ptr[dst_blk_x]; 16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i += 2) { 16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* copy even row */ 16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* copy odd row with sign change */ 17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = - *src_ptr++; 17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Just copy row verbatim. */ 17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], 17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr->width_in_blocks); 17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Transpose source into destination */ 19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION dst_blk_x, dst_blk_y; 19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_x, offset_y; 19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Transposing pixels within a block just requires transposing the 19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * DCT coefficients. 19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Partial iMCUs at the edges require no special treatment; we simply 20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * process all the available DCT blocks for every component. 20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_x += compptr->h_samp_factor) { 21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->h_samp_factor, FALSE); 21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) 21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 90 degree rotation is equivalent to 23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. Transposing the image; 23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. Horizontal mirroring. 23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These two steps are merged into a single processing routine. 23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_x, offset_y; 24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Because of the horizontal mirror step, we can't process partial iMCUs 24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * at the (output) right edge properly. They just get transposed and 24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * not mirrored. 24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_width = MCU_cols * compptr->h_samp_factor; 25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_x += compptr->h_samp_factor) { 26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->h_samp_factor, FALSE); 26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_x < comp_width) { 26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Block is within the mirrorable area. */ 26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y] 27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine [comp_width - dst_blk_x - offset_x - 1]; 27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine i++; 27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Edge blocks are transposed but not mirrored. */ 28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) 28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270 degree rotation is equivalent to 29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. Horizontal mirroring; 29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. Transposing the image. 30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These two steps are merged into a single processing routine. 30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_x, offset_y; 30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Because of the horizontal mirror step, we can't process partial iMCUs 31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * at the (output) bottom edge properly. They just get transposed and 31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * not mirrored. 31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height = MCU_rows * compptr->v_samp_factor; 31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_x += compptr->h_samp_factor) { 32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->h_samp_factor, FALSE); 32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Block is within the mirrorable area. */ 33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x] 33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine [comp_height - dst_blk_y - offset_y - 1]; 33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) { 33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j++; 33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Edge blocks are transposed but not mirrored. */ 34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) 34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 35570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 35870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 35970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 36070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 36170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 180 degree rotation is equivalent to 36270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. Vertical mirroring; 36370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. Horizontal mirroring. 36470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These two steps are merged into a single processing routine. 36570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 36670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 36770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 36870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_y; 36970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 37070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKROW src_row_ptr, dst_row_ptr; 37170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 37270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 37370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 37470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 37570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 37670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 37770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 37870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 37970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_width = MCU_cols * compptr->h_samp_factor; 38070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height = MCU_rows * compptr->v_samp_factor; 38170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 38270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 38370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 38470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 38570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 38670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 38770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Row is within the vertically mirrorable area. */ 38870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 38970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], 39070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 39170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, FALSE); 39270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 39370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Bottom-edge rows are only mirrored horizontally. */ 39470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 39570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 39670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, FALSE); 39770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 39870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 39970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 40070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Row is within the mirrorable area. */ 40170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_row_ptr = dst_buffer[offset_y]; 40270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 40370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Process the blocks that can be mirrored both ways. */ 40470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 40570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_row_ptr[dst_blk_x]; 40670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 40770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i += 2) { 40870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* For even row, negate every odd column. */ 40970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j += 2) { 41070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 41170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = - *src_ptr++; 41270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 41370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* For odd row, negate every even column. */ 41470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j += 2) { 41570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = - *src_ptr++; 41670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 41770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 41870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 41970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 42070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Any remaining right-edge blocks are only mirrored vertically. */ 42170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 42270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_row_ptr[dst_blk_x]; 42370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_row_ptr[dst_blk_x]; 42470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i += 2) { 42570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 42670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 42770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 42870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = - *src_ptr++; 42970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 43070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 43170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 43270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Remaining rows are just mirrored horizontally. */ 43370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_row_ptr = dst_buffer[offset_y]; 43470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_row_ptr = src_buffer[offset_y]; 43570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Process the blocks that can be mirrored. */ 43670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 43770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_row_ptr[dst_blk_x]; 43870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 43970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE2; i += 2) { 44070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 44170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = - *src_ptr++; 44270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 44370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 44470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Any remaining right-edge blocks are only copied. */ 44570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 44670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_row_ptr[dst_blk_x]; 44770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_row_ptr[dst_blk_x]; 44870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE2; i++) 44970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *dst_ptr++ = *src_ptr++; 45070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 45170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 45270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 45370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 45470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 45570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 45670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 45770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 45870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 45970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedo_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 46070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 46170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays) 46270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Transverse transpose is equivalent to 46370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. 180 degree rotation; 46470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. Transposition; 46570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * or 46670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1. Horizontal mirroring; 46770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2. Transposition; 46870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 3. Horizontal mirroring. 46970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These steps are merged into a single processing routine. 47070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 47170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 47270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 47370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i, j, offset_x, offset_y; 47470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JBLOCKARRAY src_buffer, dst_buffer; 47570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOEFPTR src_ptr, dst_ptr; 47670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 47770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 47870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 47970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 48070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 48170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 48270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 48370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_width = MCU_cols * compptr->h_samp_factor; 48470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine comp_height = MCU_rows * compptr->v_samp_factor; 48570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 48670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_y += compptr->v_samp_factor) { 48770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_buffer = (*srcinfo->mem->access_virt_barray) 48870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 48970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor, TRUE); 49070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 49170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 49270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_blk_x += compptr->h_samp_factor) { 49370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_buffer = (*srcinfo->mem->access_virt_barray) 49470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 49570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->h_samp_factor, FALSE); 49670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 49770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_y < comp_height) { 49870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x] 49970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine [comp_height - dst_blk_y - offset_y - 1]; 50070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_x < comp_width) { 50170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Block is within the mirrorable area. */ 50270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y] 50370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine [comp_width - dst_blk_x - offset_x - 1]; 50470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 50570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) { 50670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 50770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j++; 50870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 50970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 51070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine i++; 51170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) { 51270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 51370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j++; 51470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 51570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 51670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 51770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 51870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Right-edge blocks are mirrored in y only */ 51970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 52070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 52170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) { 52270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 52370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j++; 52470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 52570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 52670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 52770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 52870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 52970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 53070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dst_blk_x < comp_width) { 53170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Bottom-edge blocks are mirrored in x only */ 53270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y] 53370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine [comp_width - dst_blk_x - offset_x - 1]; 53470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 53570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 53670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 53770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine i++; 53870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 53970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 54070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 54170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 54270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* At lower right corner, just transpose, no mirroring */ 54370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 54470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) 54570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < DCTSIZE; j++) 54670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 54770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 54870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 54970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 55070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 55170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 55270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 55370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 55470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 55570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 55670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 55770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Request any required workspace. 55870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 55970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We allocate the workspace virtual arrays from the source decompression 56070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * object, so that all the arrays (both the original data and the workspace) 56170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * will be taken into account while making memory management decisions. 56270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Hence, this routine must be called after jpeg_read_header (which reads 56370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the image dimensions) and before jpeg_read_coefficients (which realizes 56470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the source's virtual arrays). 56570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 56670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 56770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 56870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejtransform_request_workspace (j_decompress_ptr srcinfo, 56970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_transform_info *info) 57070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 57170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *coef_arrays = NULL; 57270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 57370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci; 57470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 57570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->force_grayscale && 57670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine srcinfo->jpeg_color_space == JCS_YCbCr && 57770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine srcinfo->num_components == 3) { 57870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We'll only process the first component */ 57970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine info->num_components = 1; 58070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 58170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Process all the components */ 58270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine info->num_components = srcinfo->num_components; 58370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 58470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 58570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine switch (info->transform) { 58670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_NONE: 58770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_H: 58870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Don't need a workspace array */ 58970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 59070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_V: 59170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_180: 59270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Need workspace arrays having same dimensions as source image. 59370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that we allocate arrays padded out to the next iMCU boundary, 59470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * so that transform routines need not worry about missing edge blocks. 59570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 59670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine coef_arrays = (jvirt_barray_ptr *) 59770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 59870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(jvirt_barray_ptr) * info->num_components); 59970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < info->num_components; ci++) { 60070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = srcinfo->comp_info + ci; 60170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 60270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 60370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) jround_up((long) compptr->width_in_blocks, 60470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (long) compptr->h_samp_factor), 60570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) jround_up((long) compptr->height_in_blocks, 60670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (long) compptr->v_samp_factor), 60770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->v_samp_factor); 60870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 60970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 61070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSPOSE: 61170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSVERSE: 61270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_90: 61370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_270: 61470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Need workspace arrays having transposed dimensions. 61570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that we allocate arrays padded out to the next iMCU boundary, 61670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * so that transform routines need not worry about missing edge blocks. 61770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 61870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine coef_arrays = (jvirt_barray_ptr *) 61970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 62070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(jvirt_barray_ptr) * info->num_components); 62170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < info->num_components; ci++) { 62270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = srcinfo->comp_info + ci; 62370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 62470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 62570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) jround_up((long) compptr->height_in_blocks, 62670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (long) compptr->v_samp_factor), 62770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) jround_up((long) compptr->width_in_blocks, 62870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (long) compptr->h_samp_factor), 62970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) compptr->h_samp_factor); 63070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 63170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 63270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 63370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine info->workspace_coef_arrays = coef_arrays; 63470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 63570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 63670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 63770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Transpose destination image parameters */ 63870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 63970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 64070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetranspose_critical_parameters (j_compress_ptr dstinfo) 64170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 64270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int tblno, i, j, ci, itemp; 64370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info *compptr; 64470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JQUANT_TBL *qtblptr; 64570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION dtemp; 64670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine UINT16 qtemp; 64770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 64870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Transpose basic image dimensions */ 64970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dtemp = dstinfo->image_width; 65070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->image_width = dstinfo->image_height; 65170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->image_height = dtemp; 65270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 65370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Transpose sampling factors */ 65470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 65570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr = dstinfo->comp_info + ci; 65670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine itemp = compptr->h_samp_factor; 65770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr->h_samp_factor = compptr->v_samp_factor; 65870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr->v_samp_factor = itemp; 65970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 66070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 66170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Transpose quantization tables */ 66270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { 66370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine qtblptr = dstinfo->quant_tbl_ptrs[tblno]; 66470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (qtblptr != NULL) { 66570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < DCTSIZE; i++) { 66670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (j = 0; j < i; j++) { 66770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine qtemp = qtblptr->quantval[i*DCTSIZE+j]; 66870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; 66970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine qtblptr->quantval[j*DCTSIZE+i] = qtemp; 67070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 67170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 67270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 67370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 67470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 67570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 67670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 67770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Trim off any partial iMCUs on the indicated destination edge */ 67870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 67970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 68070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetrim_right_edge (j_compress_ptr dstinfo) 68170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 68270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, max_h_samp_factor; 68370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_cols; 68470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 68570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We have to compute max_h_samp_factor ourselves, 68670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * because it hasn't been set yet in the destination 68770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (and we don't want to use the source's value). 68870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 68970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine max_h_samp_factor = 1; 69070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 69170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; 69270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); 69370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 69470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); 69570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (MCU_cols > 0) /* can't trim to 0 pixels */ 69670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); 69770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 69870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 69970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 70070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetrim_bottom_edge (j_compress_ptr dstinfo) 70170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 70270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, max_v_samp_factor; 70370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION MCU_rows; 70470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 70570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We have to compute max_v_samp_factor ourselves, 70670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * because it hasn't been set yet in the destination 70770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (and we don't want to use the source's value). 70870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 70970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine max_v_samp_factor = 1; 71070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < dstinfo->num_components; ci++) { 71170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; 71270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); 71370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 71470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); 71570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (MCU_rows > 0) /* can't trim to 0 pixels */ 71670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); 71770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 71870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 71970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 72070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Adjust output image parameters as needed. 72170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 72270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This must be called after jpeg_copy_critical_parameters() 72370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * and before jpeg_write_coefficients(). 72470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 72570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The return value is the set of virtual coefficient arrays to be written 72670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (either the ones allocated by jtransform_request_workspace, or the 72770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * original source data arrays). The caller will need to pass this value 72870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to jpeg_write_coefficients(). 72970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 73070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 73170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(jvirt_barray_ptr *) 73270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejtransform_adjust_parameters (j_decompress_ptr srcinfo, 73370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j_compress_ptr dstinfo, 73470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 73570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_transform_info *info) 73670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 73770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* If force-to-grayscale is requested, adjust destination parameters */ 73870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->force_grayscale) { 73970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 74070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * properly. Among other things, the target h_samp_factor & v_samp_factor 74170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * will get set to 1, which typically won't match the source. 74270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * In fact we do this even if the source is already grayscale; that 74370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * provides an easy way of coercing a grayscale JPEG with funny sampling 74470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * factors to the customary 1,1. (Some decoders fail on other factors.) 74570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 74670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if ((dstinfo->jpeg_color_space == JCS_YCbCr && 74770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->num_components == 3) || 74870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 74970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->num_components == 1)) { 75070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We have to preserve the source's quantization table number. */ 75170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; 75270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); 75370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; 75470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 75570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Sorry, can't do it */ 75670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); 75770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 75870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 75970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 76070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Correct the destination's image dimensions etc if necessary */ 76170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine switch (info->transform) { 76270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_NONE: 76370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Nothing to do */ 76470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 76570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_H: 76670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) 76770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_right_edge(dstinfo); 76870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 76970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_V: 77070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) 77170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_bottom_edge(dstinfo); 77270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 77370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSPOSE: 77470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine transpose_critical_parameters(dstinfo); 77570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* transpose does NOT have to trim anything */ 77670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 77770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSVERSE: 77870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine transpose_critical_parameters(dstinfo); 77970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) { 78070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_right_edge(dstinfo); 78170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_bottom_edge(dstinfo); 78270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 78370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 78470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_90: 78570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine transpose_critical_parameters(dstinfo); 78670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) 78770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_right_edge(dstinfo); 78870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 78970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_180: 79070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) { 79170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_right_edge(dstinfo); 79270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_bottom_edge(dstinfo); 79370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 79470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 79570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_270: 79670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine transpose_critical_parameters(dstinfo); 79770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->trim) 79870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine trim_bottom_edge(dstinfo); 79970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 80070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 80170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 80270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Return the appropriate output data set */ 80370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (info->workspace_coef_arrays != NULL) 80470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return info->workspace_coef_arrays; 80570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return src_coef_arrays; 80670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 80770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 80870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 80970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Execute the actual transformation, if any. 81070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 81170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This must be called *after* jpeg_write_coefficients, because it depends 81270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * on jpeg_write_coefficients to have computed subsidiary values such as 81370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the per-component width and height fields in the destination object. 81470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 81570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that some transformations will modify the source data arrays! 81670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 81770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 81870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 81970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejtransform_execute_transformation (j_decompress_ptr srcinfo, 82070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine j_compress_ptr dstinfo, 82170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *src_coef_arrays, 82270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_transform_info *info) 82370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 82470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; 82570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 82670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine switch (info->transform) { 82770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_NONE: 82870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 82970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_H: 83070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_flip_h(srcinfo, dstinfo, src_coef_arrays); 83170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 83270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_FLIP_V: 83370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 83470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 83570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSPOSE: 83670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 83770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 83870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_TRANSVERSE: 83970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 84070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 84170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_90: 84270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 84370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 84470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_180: 84570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 84670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 84770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine case JXFORM_ROT_270: 84870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 84970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 85070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 85170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 85270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 85370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* TRANSFORMS_SUPPORTED */ 85470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 85570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 85670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Setup decompression object to save desired markers in memory. 85770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This must be called before jpeg_read_header() to have the desired effect. 85870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 85970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 86070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 86170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) 86270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 86370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef SAVE_MARKERS_SUPPORTED 86470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int m; 86570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 86670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Save comments except under NONE option */ 86770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (option != JCOPYOPT_NONE) { 86870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); 86970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 87070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Save all types of APPn markers iff ALL option */ 87170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (option == JCOPYOPT_ALL) { 87270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (m = 0; m < 16; m++) 87370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); 87470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 87570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* SAVE_MARKERS_SUPPORTED */ 87670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 87770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 87870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Copy markers saved in the given source object to the destination object. 87970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This should be called just after jpeg_start_compress() or 88070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jpeg_write_coefficients(). 88170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that those routines will have written the SOI, and also the 88270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * JFIF APP0 or Adobe APP14 markers if selected. 88370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 88470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 88570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 88670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 88770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JCOPY_OPTION option) 88870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 88970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_saved_marker_ptr marker; 89070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 89170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* In the current implementation, we don't actually need to examine the 89270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * option flag here; we just copy everything that got saved. 89370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * But to avoid confusion, we do not output JFIF and Adobe APP14 markers 89470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * if the encoder library already wrote one. 89570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 89670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { 89770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dstinfo->write_JFIF_header && 89870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine marker->marker == JPEG_APP0 && 89970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine marker->data_length >= 5 && 90070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[0]) == 0x4A && 90170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[1]) == 0x46 && 90270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[2]) == 0x49 && 90370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[3]) == 0x46 && 90470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[4]) == 0) 90570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine continue; /* reject duplicate JFIF */ 90670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (dstinfo->write_Adobe_marker && 90770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine marker->marker == JPEG_APP0+14 && 90870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine marker->data_length >= 5 && 90970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[0]) == 0x41 && 91070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[1]) == 0x64 && 91170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[2]) == 0x6F && 91270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[3]) == 0x62 && 91370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine GETJOCTET(marker->data[4]) == 0x65) 91470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine continue; /* reject duplicate Adobe */ 91570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef NEED_FAR_POINTERS 91670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* We could use jpeg_write_marker if the data weren't FAR... */ 91770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine { 91870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine unsigned int i; 91970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); 92070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < marker->data_length; i++) 92170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_write_m_byte(dstinfo, marker->data[i]); 92270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 92370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else 92470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_write_marker(dstinfo, marker->marker, 92570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine marker->data, marker->data_length); 92670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 92770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 92870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 929