1*4882a593SmuzhiyunAdd patch by Ondrej Sury to migrate to libjpeg-turbo (Closes: #763263) 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunIndex: fbida-2.10/jpeg/62/jpegcomp.h 4*4882a593Smuzhiyun=================================================================== 5*4882a593Smuzhiyun--- /dev/null 6*4882a593Smuzhiyun+++ fbida-2.10/jpeg/62/jpegcomp.h 7*4882a593Smuzhiyun@@ -0,0 +1,30 @@ 8*4882a593Smuzhiyun+/* 9*4882a593Smuzhiyun+ * jpegcomp.h 10*4882a593Smuzhiyun+ * 11*4882a593Smuzhiyun+ * Copyright (C) 2010, D. R. Commander 12*4882a593Smuzhiyun+ * For conditions of distribution and use, see the accompanying README file. 13*4882a593Smuzhiyun+ * 14*4882a593Smuzhiyun+ * JPEG compatibility macros 15*4882a593Smuzhiyun+ * These declarations are considered internal to the JPEG library; most 16*4882a593Smuzhiyun+ * applications using the library shouldn't need to include this file. 17*4882a593Smuzhiyun+ */ 18*4882a593Smuzhiyun+ 19*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 20*4882a593Smuzhiyun+#define _DCT_scaled_size DCT_h_scaled_size 21*4882a593Smuzhiyun+#define _DCT_h_scaled_size DCT_h_scaled_size 22*4882a593Smuzhiyun+#define _DCT_v_scaled_size DCT_v_scaled_size 23*4882a593Smuzhiyun+#define _min_DCT_scaled_size min_DCT_h_scaled_size 24*4882a593Smuzhiyun+#define _min_DCT_h_scaled_size min_DCT_h_scaled_size 25*4882a593Smuzhiyun+#define _min_DCT_v_scaled_size min_DCT_v_scaled_size 26*4882a593Smuzhiyun+#define _jpeg_width jpeg_width 27*4882a593Smuzhiyun+#define _jpeg_height jpeg_height 28*4882a593Smuzhiyun+#else 29*4882a593Smuzhiyun+#define _DCT_scaled_size DCT_scaled_size 30*4882a593Smuzhiyun+#define _DCT_h_scaled_size DCT_scaled_size 31*4882a593Smuzhiyun+#define _DCT_v_scaled_size DCT_scaled_size 32*4882a593Smuzhiyun+#define _min_DCT_scaled_size min_DCT_scaled_size 33*4882a593Smuzhiyun+#define _min_DCT_h_scaled_size min_DCT_scaled_size 34*4882a593Smuzhiyun+#define _min_DCT_v_scaled_size min_DCT_scaled_size 35*4882a593Smuzhiyun+#define _jpeg_width image_width 36*4882a593Smuzhiyun+#define _jpeg_height image_height 37*4882a593Smuzhiyun+#endif 38*4882a593SmuzhiyunIndex: fbida-2.10/jpeg/62/transupp.c 39*4882a593Smuzhiyun=================================================================== 40*4882a593Smuzhiyun--- fbida-2.10.orig/jpeg/62/transupp.c 41*4882a593Smuzhiyun+++ fbida-2.10/jpeg/62/transupp.c 42*4882a593Smuzhiyun@@ -1,8 +1,10 @@ 43*4882a593Smuzhiyun /* 44*4882a593Smuzhiyun * transupp.c 45*4882a593Smuzhiyun * 46*4882a593Smuzhiyun- * Copyright (C) 1997, Thomas G. Lane. 47*4882a593Smuzhiyun- * This file is part of the Independent JPEG Group's software. 48*4882a593Smuzhiyun+ * This file was part of the Independent JPEG Group's software: 49*4882a593Smuzhiyun+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding. 50*4882a593Smuzhiyun+ * libjpeg-turbo Modifications: 51*4882a593Smuzhiyun+ * Copyright (C) 2010, D. R. Commander. 52*4882a593Smuzhiyun * For conditions of distribution and use, see the accompanying README file. 53*4882a593Smuzhiyun * 54*4882a593Smuzhiyun * This file contains image transformation routines and other utility code 55*4882a593Smuzhiyun@@ -20,6 +22,17 @@ 56*4882a593Smuzhiyun #include "jinclude.h" 57*4882a593Smuzhiyun #include "jpeglib.h" 58*4882a593Smuzhiyun #include "transupp.h" /* My own external interface */ 59*4882a593Smuzhiyun+#include "jpegcomp.h" 60*4882a593Smuzhiyun+#include <ctype.h> /* to declare isdigit() */ 61*4882a593Smuzhiyun+ 62*4882a593Smuzhiyun+ 63*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 64*4882a593Smuzhiyun+#define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size 65*4882a593Smuzhiyun+#define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size 66*4882a593Smuzhiyun+#else 67*4882a593Smuzhiyun+#define dstinfo_min_DCT_h_scaled_size DCTSIZE 68*4882a593Smuzhiyun+#define dstinfo_min_DCT_v_scaled_size DCTSIZE 69*4882a593Smuzhiyun+#endif 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #if TRANSFORMS_SUPPORTED 73*4882a593Smuzhiyun@@ -28,7 +41,8 @@ 74*4882a593Smuzhiyun * Lossless image transformation routines. These routines work on DCT 75*4882a593Smuzhiyun * coefficient arrays and thus do not require any lossy decompression 76*4882a593Smuzhiyun * or recompression of the image. 77*4882a593Smuzhiyun- * Thanks to Guido Vollbeding for the initial design and code of this feature. 78*4882a593Smuzhiyun+ * Thanks to Guido Vollbeding for the initial design and code of this feature, 79*4882a593Smuzhiyun+ * and to Ben Jackson for introducing the cropping feature. 80*4882a593Smuzhiyun * 81*4882a593Smuzhiyun * Horizontal flipping is done in-place, using a single top-to-bottom 82*4882a593Smuzhiyun * pass through the virtual source array. It will thus be much the 83*4882a593Smuzhiyun@@ -42,6 +56,13 @@ 84*4882a593Smuzhiyun * arrays for most of the transforms. That could result in much thrashing 85*4882a593Smuzhiyun * if the image is larger than main memory. 86*4882a593Smuzhiyun * 87*4882a593Smuzhiyun+ * If cropping or trimming is involved, the destination arrays may be smaller 88*4882a593Smuzhiyun+ * than the source arrays. Note it is not possible to do horizontal flip 89*4882a593Smuzhiyun+ * in-place when a nonzero Y crop offset is specified, since we'd have to move 90*4882a593Smuzhiyun+ * data from one block row to another but the virtual array manager doesn't 91*4882a593Smuzhiyun+ * guarantee we can touch more than one row at a time. So in that case, 92*4882a593Smuzhiyun+ * we have to use a separate destination array. 93*4882a593Smuzhiyun+ * 94*4882a593Smuzhiyun * Some notes about the operating environment of the individual transform 95*4882a593Smuzhiyun * routines: 96*4882a593Smuzhiyun * 1. Both the source and destination virtual arrays are allocated from the 97*4882a593Smuzhiyun@@ -54,20 +75,65 @@ 98*4882a593Smuzhiyun * and we may as well take that as the effective iMCU size. 99*4882a593Smuzhiyun * 4. When "trim" is in effect, the destination's dimensions will be the 100*4882a593Smuzhiyun * trimmed values but the source's will be untrimmed. 101*4882a593Smuzhiyun- * 5. All the routines assume that the source and destination buffers are 102*4882a593Smuzhiyun+ * 5. When "crop" is in effect, the destination's dimensions will be the 103*4882a593Smuzhiyun+ * cropped values but the source's will be uncropped. Each transform 104*4882a593Smuzhiyun+ * routine is responsible for picking up source data starting at the 105*4882a593Smuzhiyun+ * correct X and Y offset for the crop region. (The X and Y offsets 106*4882a593Smuzhiyun+ * passed to the transform routines are measured in iMCU blocks of the 107*4882a593Smuzhiyun+ * destination.) 108*4882a593Smuzhiyun+ * 6. All the routines assume that the source and destination buffers are 109*4882a593Smuzhiyun * padded out to a full iMCU boundary. This is true, although for the 110*4882a593Smuzhiyun * source buffer it is an undocumented property of jdcoefct.c. 111*4882a593Smuzhiyun- * Notes 2,3,4 boil down to this: generally we should use the destination's 112*4882a593Smuzhiyun- * dimensions and ignore the source's. 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun LOCAL(void) 117*4882a593Smuzhiyun-do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 118*4882a593Smuzhiyun- jvirt_barray_ptr *src_coef_arrays) 119*4882a593Smuzhiyun-/* Horizontal flip; done in-place, so no separate dest array is required */ 120*4882a593Smuzhiyun+do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 121*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 122*4882a593Smuzhiyun+ jvirt_barray_ptr *src_coef_arrays, 123*4882a593Smuzhiyun+ jvirt_barray_ptr *dst_coef_arrays) 124*4882a593Smuzhiyun+/* Crop. This is only used when no rotate/flip is requested with the crop. */ 125*4882a593Smuzhiyun+{ 126*4882a593Smuzhiyun+ JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks; 127*4882a593Smuzhiyun+ int ci, offset_y; 128*4882a593Smuzhiyun+ JBLOCKARRAY src_buffer, dst_buffer; 129*4882a593Smuzhiyun+ jpeg_component_info *compptr; 130*4882a593Smuzhiyun+ 131*4882a593Smuzhiyun+ /* We simply have to copy the right amount of data (the destination's 132*4882a593Smuzhiyun+ * image size) starting at the given X and Y offsets in the source. 133*4882a593Smuzhiyun+ */ 134*4882a593Smuzhiyun+ for (ci = 0; ci < dstinfo->num_components; ci++) { 135*4882a593Smuzhiyun+ compptr = dstinfo->comp_info + ci; 136*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 137*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 138*4882a593Smuzhiyun+ for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 139*4882a593Smuzhiyun+ dst_blk_y += compptr->v_samp_factor) { 140*4882a593Smuzhiyun+ dst_buffer = (*srcinfo->mem->access_virt_barray) 141*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 142*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, TRUE); 143*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 144*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 145*4882a593Smuzhiyun+ dst_blk_y + y_crop_blocks, 146*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, FALSE); 147*4882a593Smuzhiyun+ for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 148*4882a593Smuzhiyun+ jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, 149*4882a593Smuzhiyun+ dst_buffer[offset_y], 150*4882a593Smuzhiyun+ compptr->width_in_blocks); 151*4882a593Smuzhiyun+ } 152*4882a593Smuzhiyun+ } 153*4882a593Smuzhiyun+ } 154*4882a593Smuzhiyun+} 155*4882a593Smuzhiyun+ 156*4882a593Smuzhiyun+ 157*4882a593Smuzhiyun+LOCAL(void) 158*4882a593Smuzhiyun+do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 159*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, 160*4882a593Smuzhiyun+ jvirt_barray_ptr *src_coef_arrays) 161*4882a593Smuzhiyun+/* Horizontal flip; done in-place, so no separate dest array is required. 162*4882a593Smuzhiyun+ * NB: this only works when y_crop_offset is zero. 163*4882a593Smuzhiyun+ */ 164*4882a593Smuzhiyun { 165*4882a593Smuzhiyun- JDIMENSION MCU_cols, comp_width, blk_x, blk_y; 166*4882a593Smuzhiyun+ JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks; 167*4882a593Smuzhiyun int ci, k, offset_y; 168*4882a593Smuzhiyun JBLOCKARRAY buffer; 169*4882a593Smuzhiyun JCOEFPTR ptr1, ptr2; 170*4882a593Smuzhiyun@@ -79,17 +145,20 @@ do_flip_h (j_decompress_ptr srcinfo, j_c 171*4882a593Smuzhiyun * mirroring by changing the signs of odd-numbered columns. 172*4882a593Smuzhiyun * Partial iMCUs at the right edge are left untouched. 173*4882a593Smuzhiyun */ 174*4882a593Smuzhiyun- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 175*4882a593Smuzhiyun+ MCU_cols = srcinfo->output_width / 176*4882a593Smuzhiyun+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size); 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 179*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 180*4882a593Smuzhiyun comp_width = MCU_cols * compptr->h_samp_factor; 181*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 182*4882a593Smuzhiyun for (blk_y = 0; blk_y < compptr->height_in_blocks; 183*4882a593Smuzhiyun blk_y += compptr->v_samp_factor) { 184*4882a593Smuzhiyun buffer = (*srcinfo->mem->access_virt_barray) 185*4882a593Smuzhiyun ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, 186*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, TRUE); 187*4882a593Smuzhiyun for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 188*4882a593Smuzhiyun+ /* Do the mirroring */ 189*4882a593Smuzhiyun for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { 190*4882a593Smuzhiyun ptr1 = buffer[offset_y][blk_x]; 191*4882a593Smuzhiyun ptr2 = buffer[offset_y][comp_width - blk_x - 1]; 192*4882a593Smuzhiyun@@ -105,6 +174,80 @@ do_flip_h (j_decompress_ptr srcinfo, j_c 193*4882a593Smuzhiyun *ptr2++ = -temp1; 194*4882a593Smuzhiyun } 195*4882a593Smuzhiyun } 196*4882a593Smuzhiyun+ if (x_crop_blocks > 0) { 197*4882a593Smuzhiyun+ /* Now left-justify the portion of the data to be kept. 198*4882a593Smuzhiyun+ * We can't use a single jcopy_block_row() call because that routine 199*4882a593Smuzhiyun+ * depends on memcpy(), whose behavior is unspecified for overlapping 200*4882a593Smuzhiyun+ * source and destination areas. Sigh. 201*4882a593Smuzhiyun+ */ 202*4882a593Smuzhiyun+ for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { 203*4882a593Smuzhiyun+ jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks, 204*4882a593Smuzhiyun+ buffer[offset_y] + blk_x, 205*4882a593Smuzhiyun+ (JDIMENSION) 1); 206*4882a593Smuzhiyun+ } 207*4882a593Smuzhiyun+ } 208*4882a593Smuzhiyun+ } 209*4882a593Smuzhiyun+ } 210*4882a593Smuzhiyun+ } 211*4882a593Smuzhiyun+} 212*4882a593Smuzhiyun+ 213*4882a593Smuzhiyun+ 214*4882a593Smuzhiyun+LOCAL(void) 215*4882a593Smuzhiyun+do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 216*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 217*4882a593Smuzhiyun+ jvirt_barray_ptr *src_coef_arrays, 218*4882a593Smuzhiyun+ jvirt_barray_ptr *dst_coef_arrays) 219*4882a593Smuzhiyun+/* Horizontal flip in general cropping case */ 220*4882a593Smuzhiyun+{ 221*4882a593Smuzhiyun+ JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 222*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 223*4882a593Smuzhiyun+ int ci, k, offset_y; 224*4882a593Smuzhiyun+ JBLOCKARRAY src_buffer, dst_buffer; 225*4882a593Smuzhiyun+ JBLOCKROW src_row_ptr, dst_row_ptr; 226*4882a593Smuzhiyun+ JCOEFPTR src_ptr, dst_ptr; 227*4882a593Smuzhiyun+ jpeg_component_info *compptr; 228*4882a593Smuzhiyun+ 229*4882a593Smuzhiyun+ /* Here we must output into a separate array because we can't touch 230*4882a593Smuzhiyun+ * different rows of a single virtual array simultaneously. Otherwise, 231*4882a593Smuzhiyun+ * this is essentially the same as the routine above. 232*4882a593Smuzhiyun+ */ 233*4882a593Smuzhiyun+ MCU_cols = srcinfo->output_width / 234*4882a593Smuzhiyun+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size); 235*4882a593Smuzhiyun+ 236*4882a593Smuzhiyun+ for (ci = 0; ci < dstinfo->num_components; ci++) { 237*4882a593Smuzhiyun+ compptr = dstinfo->comp_info + ci; 238*4882a593Smuzhiyun+ comp_width = MCU_cols * compptr->h_samp_factor; 239*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 240*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 241*4882a593Smuzhiyun+ for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 242*4882a593Smuzhiyun+ dst_blk_y += compptr->v_samp_factor) { 243*4882a593Smuzhiyun+ dst_buffer = (*srcinfo->mem->access_virt_barray) 244*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 245*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, TRUE); 246*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 247*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 248*4882a593Smuzhiyun+ dst_blk_y + y_crop_blocks, 249*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, FALSE); 250*4882a593Smuzhiyun+ for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 251*4882a593Smuzhiyun+ dst_row_ptr = dst_buffer[offset_y]; 252*4882a593Smuzhiyun+ src_row_ptr = src_buffer[offset_y]; 253*4882a593Smuzhiyun+ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 254*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 255*4882a593Smuzhiyun+ /* Do the mirrorable blocks */ 256*4882a593Smuzhiyun+ dst_ptr = dst_row_ptr[dst_blk_x]; 257*4882a593Smuzhiyun+ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 258*4882a593Smuzhiyun+ /* this unrolled loop doesn't need to know which row it's on... */ 259*4882a593Smuzhiyun+ for (k = 0; k < DCTSIZE2; k += 2) { 260*4882a593Smuzhiyun+ *dst_ptr++ = *src_ptr++; /* copy even column */ 261*4882a593Smuzhiyun+ *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */ 262*4882a593Smuzhiyun+ } 263*4882a593Smuzhiyun+ } else { 264*4882a593Smuzhiyun+ /* Copy last partial block(s) verbatim */ 265*4882a593Smuzhiyun+ jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, 266*4882a593Smuzhiyun+ dst_row_ptr + dst_blk_x, 267*4882a593Smuzhiyun+ (JDIMENSION) 1); 268*4882a593Smuzhiyun+ } 269*4882a593Smuzhiyun+ } 270*4882a593Smuzhiyun } 271*4882a593Smuzhiyun } 272*4882a593Smuzhiyun } 273*4882a593Smuzhiyun@@ -113,11 +256,13 @@ do_flip_h (j_decompress_ptr srcinfo, j_c 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun LOCAL(void) 276*4882a593Smuzhiyun do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 277*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 278*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 279*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 280*4882a593Smuzhiyun /* Vertical flip */ 281*4882a593Smuzhiyun { 282*4882a593Smuzhiyun JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 283*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 284*4882a593Smuzhiyun int ci, i, j, offset_y; 285*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 286*4882a593Smuzhiyun JBLOCKROW src_row_ptr, dst_row_ptr; 287*4882a593Smuzhiyun@@ -131,33 +276,39 @@ do_flip_v (j_decompress_ptr srcinfo, j_c 288*4882a593Smuzhiyun * of odd-numbered rows. 289*4882a593Smuzhiyun * Partial iMCUs at the bottom edge are copied verbatim. 290*4882a593Smuzhiyun */ 291*4882a593Smuzhiyun- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 292*4882a593Smuzhiyun+ MCU_rows = srcinfo->output_height / 293*4882a593Smuzhiyun+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size); 294*4882a593Smuzhiyun 295*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 296*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 297*4882a593Smuzhiyun comp_height = MCU_rows * compptr->v_samp_factor; 298*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 299*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 300*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 301*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 302*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 303*4882a593Smuzhiyun ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 304*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, TRUE); 305*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 306*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 307*4882a593Smuzhiyun /* Row is within the mirrorable area. */ 308*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 309*4882a593Smuzhiyun ((j_common_ptr) srcinfo, src_coef_arrays[ci], 310*4882a593Smuzhiyun- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 311*4882a593Smuzhiyun+ comp_height - y_crop_blocks - dst_blk_y - 312*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, 313*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, FALSE); 314*4882a593Smuzhiyun } else { 315*4882a593Smuzhiyun /* Bottom-edge blocks will be copied verbatim. */ 316*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 317*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 318*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 319*4882a593Smuzhiyun+ dst_blk_y + y_crop_blocks, 320*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, FALSE); 321*4882a593Smuzhiyun } 322*4882a593Smuzhiyun for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 323*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 324*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 325*4882a593Smuzhiyun /* Row is within the mirrorable area. */ 326*4882a593Smuzhiyun dst_row_ptr = dst_buffer[offset_y]; 327*4882a593Smuzhiyun src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 328*4882a593Smuzhiyun+ src_row_ptr += x_crop_blocks; 329*4882a593Smuzhiyun for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 330*4882a593Smuzhiyun dst_blk_x++) { 331*4882a593Smuzhiyun dst_ptr = dst_row_ptr[dst_blk_x]; 332*4882a593Smuzhiyun@@ -173,7 +324,8 @@ do_flip_v (j_decompress_ptr srcinfo, j_c 333*4882a593Smuzhiyun } 334*4882a593Smuzhiyun } else { 335*4882a593Smuzhiyun /* Just copy row verbatim. */ 336*4882a593Smuzhiyun- jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], 337*4882a593Smuzhiyun+ jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, 338*4882a593Smuzhiyun+ dst_buffer[offset_y], 339*4882a593Smuzhiyun compptr->width_in_blocks); 340*4882a593Smuzhiyun } 341*4882a593Smuzhiyun } 342*4882a593Smuzhiyun@@ -184,11 +336,12 @@ do_flip_v (j_decompress_ptr srcinfo, j_c 343*4882a593Smuzhiyun 344*4882a593Smuzhiyun LOCAL(void) 345*4882a593Smuzhiyun do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 346*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 347*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 348*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 349*4882a593Smuzhiyun /* Transpose source into destination */ 350*4882a593Smuzhiyun { 351*4882a593Smuzhiyun- JDIMENSION dst_blk_x, dst_blk_y; 352*4882a593Smuzhiyun+ JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks; 353*4882a593Smuzhiyun int ci, i, j, offset_x, offset_y; 354*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 355*4882a593Smuzhiyun JCOEFPTR src_ptr, dst_ptr; 356*4882a593Smuzhiyun@@ -201,6 +354,8 @@ do_transpose (j_decompress_ptr srcinfo, 357*4882a593Smuzhiyun */ 358*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 359*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 360*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 361*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 362*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 363*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 364*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 365*4882a593Smuzhiyun@@ -210,11 +365,12 @@ do_transpose (j_decompress_ptr srcinfo, 366*4882a593Smuzhiyun for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 367*4882a593Smuzhiyun dst_blk_x += compptr->h_samp_factor) { 368*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 369*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 370*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 371*4882a593Smuzhiyun+ dst_blk_x + x_crop_blocks, 372*4882a593Smuzhiyun (JDIMENSION) compptr->h_samp_factor, FALSE); 373*4882a593Smuzhiyun for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 374*4882a593Smuzhiyun- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 375*4882a593Smuzhiyun dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 376*4882a593Smuzhiyun+ src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks]; 377*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) 378*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 379*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 380*4882a593Smuzhiyun@@ -228,6 +384,7 @@ do_transpose (j_decompress_ptr srcinfo, 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun LOCAL(void) 383*4882a593Smuzhiyun do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 384*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 385*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 386*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 387*4882a593Smuzhiyun /* 90 degree rotation is equivalent to 388*4882a593Smuzhiyun@@ -237,6 +394,7 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c 389*4882a593Smuzhiyun */ 390*4882a593Smuzhiyun { 391*4882a593Smuzhiyun JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 392*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 393*4882a593Smuzhiyun int ci, i, j, offset_x, offset_y; 394*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 395*4882a593Smuzhiyun JCOEFPTR src_ptr, dst_ptr; 396*4882a593Smuzhiyun@@ -246,11 +404,14 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c 397*4882a593Smuzhiyun * at the (output) right edge properly. They just get transposed and 398*4882a593Smuzhiyun * not mirrored. 399*4882a593Smuzhiyun */ 400*4882a593Smuzhiyun- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 401*4882a593Smuzhiyun+ MCU_cols = srcinfo->output_height / 402*4882a593Smuzhiyun+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size); 403*4882a593Smuzhiyun 404*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 405*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 406*4882a593Smuzhiyun comp_width = MCU_cols * compptr->h_samp_factor; 407*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 408*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 409*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 410*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 411*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 412*4882a593Smuzhiyun@@ -259,15 +420,26 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c 413*4882a593Smuzhiyun for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 414*4882a593Smuzhiyun for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 415*4882a593Smuzhiyun dst_blk_x += compptr->h_samp_factor) { 416*4882a593Smuzhiyun- src_buffer = (*srcinfo->mem->access_virt_barray) 417*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 418*4882a593Smuzhiyun- (JDIMENSION) compptr->h_samp_factor, FALSE); 419*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 420*4882a593Smuzhiyun+ /* Block is within the mirrorable area. */ 421*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 422*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 423*4882a593Smuzhiyun+ comp_width - x_crop_blocks - dst_blk_x - 424*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, 425*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, FALSE); 426*4882a593Smuzhiyun+ } else { 427*4882a593Smuzhiyun+ /* Edge blocks are transposed but not mirrored. */ 428*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 429*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 430*4882a593Smuzhiyun+ dst_blk_x + x_crop_blocks, 431*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, FALSE); 432*4882a593Smuzhiyun+ } 433*4882a593Smuzhiyun for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 434*4882a593Smuzhiyun- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 435*4882a593Smuzhiyun- if (dst_blk_x < comp_width) { 436*4882a593Smuzhiyun+ dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 437*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 438*4882a593Smuzhiyun /* Block is within the mirrorable area. */ 439*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y] 440*4882a593Smuzhiyun- [comp_width - dst_blk_x - offset_x - 1]; 441*4882a593Smuzhiyun+ src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 442*4882a593Smuzhiyun+ [dst_blk_y + offset_y + y_crop_blocks]; 443*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) { 444*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 445*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 446*4882a593Smuzhiyun@@ -277,7 +449,8 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c 447*4882a593Smuzhiyun } 448*4882a593Smuzhiyun } else { 449*4882a593Smuzhiyun /* Edge blocks are transposed but not mirrored. */ 450*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 451*4882a593Smuzhiyun+ src_ptr = src_buffer[offset_x] 452*4882a593Smuzhiyun+ [dst_blk_y + offset_y + y_crop_blocks]; 453*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) 454*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 455*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 456*4882a593Smuzhiyun@@ -292,6 +465,7 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c 457*4882a593Smuzhiyun 458*4882a593Smuzhiyun LOCAL(void) 459*4882a593Smuzhiyun do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 460*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 461*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 462*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 463*4882a593Smuzhiyun /* 270 degree rotation is equivalent to 464*4882a593Smuzhiyun@@ -301,6 +475,7 @@ do_rot_270 (j_decompress_ptr srcinfo, j_ 465*4882a593Smuzhiyun */ 466*4882a593Smuzhiyun { 467*4882a593Smuzhiyun JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 468*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 469*4882a593Smuzhiyun int ci, i, j, offset_x, offset_y; 470*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 471*4882a593Smuzhiyun JCOEFPTR src_ptr, dst_ptr; 472*4882a593Smuzhiyun@@ -310,11 +485,14 @@ do_rot_270 (j_decompress_ptr srcinfo, j_ 473*4882a593Smuzhiyun * at the (output) bottom edge properly. They just get transposed and 474*4882a593Smuzhiyun * not mirrored. 475*4882a593Smuzhiyun */ 476*4882a593Smuzhiyun- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 477*4882a593Smuzhiyun+ MCU_rows = srcinfo->output_width / 478*4882a593Smuzhiyun+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size); 479*4882a593Smuzhiyun 480*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 481*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 482*4882a593Smuzhiyun comp_height = MCU_rows * compptr->v_samp_factor; 483*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 484*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 485*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 486*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 487*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 488*4882a593Smuzhiyun@@ -324,14 +502,15 @@ do_rot_270 (j_decompress_ptr srcinfo, j_ 489*4882a593Smuzhiyun for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 490*4882a593Smuzhiyun dst_blk_x += compptr->h_samp_factor) { 491*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 492*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 493*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 494*4882a593Smuzhiyun+ dst_blk_x + x_crop_blocks, 495*4882a593Smuzhiyun (JDIMENSION) compptr->h_samp_factor, FALSE); 496*4882a593Smuzhiyun for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 497*4882a593Smuzhiyun dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 498*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 499*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 500*4882a593Smuzhiyun /* Block is within the mirrorable area. */ 501*4882a593Smuzhiyun src_ptr = src_buffer[offset_x] 502*4882a593Smuzhiyun- [comp_height - dst_blk_y - offset_y - 1]; 503*4882a593Smuzhiyun+ [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 504*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) { 505*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) { 506*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 507*4882a593Smuzhiyun@@ -341,7 +520,8 @@ do_rot_270 (j_decompress_ptr srcinfo, j_ 508*4882a593Smuzhiyun } 509*4882a593Smuzhiyun } else { 510*4882a593Smuzhiyun /* Edge blocks are transposed but not mirrored. */ 511*4882a593Smuzhiyun- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 512*4882a593Smuzhiyun+ src_ptr = src_buffer[offset_x] 513*4882a593Smuzhiyun+ [dst_blk_y + offset_y + y_crop_blocks]; 514*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) 515*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 516*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 517*4882a593Smuzhiyun@@ -356,6 +536,7 @@ do_rot_270 (j_decompress_ptr srcinfo, j_ 518*4882a593Smuzhiyun 519*4882a593Smuzhiyun LOCAL(void) 520*4882a593Smuzhiyun do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 521*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 522*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 523*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 524*4882a593Smuzhiyun /* 180 degree rotation is equivalent to 525*4882a593Smuzhiyun@@ -365,89 +546,95 @@ do_rot_180 (j_decompress_ptr srcinfo, j_ 526*4882a593Smuzhiyun */ 527*4882a593Smuzhiyun { 528*4882a593Smuzhiyun JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 529*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 530*4882a593Smuzhiyun int ci, i, j, offset_y; 531*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 532*4882a593Smuzhiyun JBLOCKROW src_row_ptr, dst_row_ptr; 533*4882a593Smuzhiyun JCOEFPTR src_ptr, dst_ptr; 534*4882a593Smuzhiyun jpeg_component_info *compptr; 535*4882a593Smuzhiyun 536*4882a593Smuzhiyun- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 537*4882a593Smuzhiyun- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 538*4882a593Smuzhiyun+ MCU_cols = srcinfo->output_width / 539*4882a593Smuzhiyun+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size); 540*4882a593Smuzhiyun+ MCU_rows = srcinfo->output_height / 541*4882a593Smuzhiyun+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size); 542*4882a593Smuzhiyun 543*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 544*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 545*4882a593Smuzhiyun comp_width = MCU_cols * compptr->h_samp_factor; 546*4882a593Smuzhiyun comp_height = MCU_rows * compptr->v_samp_factor; 547*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 548*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 549*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 550*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 551*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 552*4882a593Smuzhiyun ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 553*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, TRUE); 554*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 555*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 556*4882a593Smuzhiyun /* Row is within the vertically mirrorable area. */ 557*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 558*4882a593Smuzhiyun ((j_common_ptr) srcinfo, src_coef_arrays[ci], 559*4882a593Smuzhiyun- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 560*4882a593Smuzhiyun+ comp_height - y_crop_blocks - dst_blk_y - 561*4882a593Smuzhiyun+ (JDIMENSION) compptr->v_samp_factor, 562*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, FALSE); 563*4882a593Smuzhiyun } else { 564*4882a593Smuzhiyun /* Bottom-edge rows are only mirrored horizontally. */ 565*4882a593Smuzhiyun src_buffer = (*srcinfo->mem->access_virt_barray) 566*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 567*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 568*4882a593Smuzhiyun+ dst_blk_y + y_crop_blocks, 569*4882a593Smuzhiyun (JDIMENSION) compptr->v_samp_factor, FALSE); 570*4882a593Smuzhiyun } 571*4882a593Smuzhiyun for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 572*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 573*4882a593Smuzhiyun+ dst_row_ptr = dst_buffer[offset_y]; 574*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 575*4882a593Smuzhiyun /* Row is within the mirrorable area. */ 576*4882a593Smuzhiyun- dst_row_ptr = dst_buffer[offset_y]; 577*4882a593Smuzhiyun src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 578*4882a593Smuzhiyun- /* Process the blocks that can be mirrored both ways. */ 579*4882a593Smuzhiyun- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 580*4882a593Smuzhiyun+ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 581*4882a593Smuzhiyun dst_ptr = dst_row_ptr[dst_blk_x]; 582*4882a593Smuzhiyun- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 583*4882a593Smuzhiyun- for (i = 0; i < DCTSIZE; i += 2) { 584*4882a593Smuzhiyun- /* For even row, negate every odd column. */ 585*4882a593Smuzhiyun- for (j = 0; j < DCTSIZE; j += 2) { 586*4882a593Smuzhiyun- *dst_ptr++ = *src_ptr++; 587*4882a593Smuzhiyun- *dst_ptr++ = - *src_ptr++; 588*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 589*4882a593Smuzhiyun+ /* Process the blocks that can be mirrored both ways. */ 590*4882a593Smuzhiyun+ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 591*4882a593Smuzhiyun+ for (i = 0; i < DCTSIZE; i += 2) { 592*4882a593Smuzhiyun+ /* For even row, negate every odd column. */ 593*4882a593Smuzhiyun+ for (j = 0; j < DCTSIZE; j += 2) { 594*4882a593Smuzhiyun+ *dst_ptr++ = *src_ptr++; 595*4882a593Smuzhiyun+ *dst_ptr++ = - *src_ptr++; 596*4882a593Smuzhiyun+ } 597*4882a593Smuzhiyun+ /* For odd row, negate every even column. */ 598*4882a593Smuzhiyun+ for (j = 0; j < DCTSIZE; j += 2) { 599*4882a593Smuzhiyun+ *dst_ptr++ = - *src_ptr++; 600*4882a593Smuzhiyun+ *dst_ptr++ = *src_ptr++; 601*4882a593Smuzhiyun+ } 602*4882a593Smuzhiyun } 603*4882a593Smuzhiyun- /* For odd row, negate every even column. */ 604*4882a593Smuzhiyun- for (j = 0; j < DCTSIZE; j += 2) { 605*4882a593Smuzhiyun- *dst_ptr++ = - *src_ptr++; 606*4882a593Smuzhiyun- *dst_ptr++ = *src_ptr++; 607*4882a593Smuzhiyun+ } else { 608*4882a593Smuzhiyun+ /* Any remaining right-edge blocks are only mirrored vertically. */ 609*4882a593Smuzhiyun+ src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x]; 610*4882a593Smuzhiyun+ for (i = 0; i < DCTSIZE; i += 2) { 611*4882a593Smuzhiyun+ for (j = 0; j < DCTSIZE; j++) 612*4882a593Smuzhiyun+ *dst_ptr++ = *src_ptr++; 613*4882a593Smuzhiyun+ for (j = 0; j < DCTSIZE; j++) 614*4882a593Smuzhiyun+ *dst_ptr++ = - *src_ptr++; 615*4882a593Smuzhiyun } 616*4882a593Smuzhiyun } 617*4882a593Smuzhiyun } 618*4882a593Smuzhiyun- /* Any remaining right-edge blocks are only mirrored vertically. */ 619*4882a593Smuzhiyun- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 620*4882a593Smuzhiyun- dst_ptr = dst_row_ptr[dst_blk_x]; 621*4882a593Smuzhiyun- src_ptr = src_row_ptr[dst_blk_x]; 622*4882a593Smuzhiyun- for (i = 0; i < DCTSIZE; i += 2) { 623*4882a593Smuzhiyun- for (j = 0; j < DCTSIZE; j++) 624*4882a593Smuzhiyun- *dst_ptr++ = *src_ptr++; 625*4882a593Smuzhiyun- for (j = 0; j < DCTSIZE; j++) 626*4882a593Smuzhiyun- *dst_ptr++ = - *src_ptr++; 627*4882a593Smuzhiyun- } 628*4882a593Smuzhiyun- } 629*4882a593Smuzhiyun } else { 630*4882a593Smuzhiyun /* Remaining rows are just mirrored horizontally. */ 631*4882a593Smuzhiyun- dst_row_ptr = dst_buffer[offset_y]; 632*4882a593Smuzhiyun src_row_ptr = src_buffer[offset_y]; 633*4882a593Smuzhiyun- /* Process the blocks that can be mirrored. */ 634*4882a593Smuzhiyun- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 635*4882a593Smuzhiyun- dst_ptr = dst_row_ptr[dst_blk_x]; 636*4882a593Smuzhiyun- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 637*4882a593Smuzhiyun- for (i = 0; i < DCTSIZE2; i += 2) { 638*4882a593Smuzhiyun- *dst_ptr++ = *src_ptr++; 639*4882a593Smuzhiyun- *dst_ptr++ = - *src_ptr++; 640*4882a593Smuzhiyun+ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 641*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 642*4882a593Smuzhiyun+ /* Process the blocks that can be mirrored. */ 643*4882a593Smuzhiyun+ dst_ptr = dst_row_ptr[dst_blk_x]; 644*4882a593Smuzhiyun+ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; 645*4882a593Smuzhiyun+ for (i = 0; i < DCTSIZE2; i += 2) { 646*4882a593Smuzhiyun+ *dst_ptr++ = *src_ptr++; 647*4882a593Smuzhiyun+ *dst_ptr++ = - *src_ptr++; 648*4882a593Smuzhiyun+ } 649*4882a593Smuzhiyun+ } else { 650*4882a593Smuzhiyun+ /* Any remaining right-edge blocks are only copied. */ 651*4882a593Smuzhiyun+ jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, 652*4882a593Smuzhiyun+ dst_row_ptr + dst_blk_x, 653*4882a593Smuzhiyun+ (JDIMENSION) 1); 654*4882a593Smuzhiyun } 655*4882a593Smuzhiyun } 656*4882a593Smuzhiyun- /* Any remaining right-edge blocks are only copied. */ 657*4882a593Smuzhiyun- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 658*4882a593Smuzhiyun- dst_ptr = dst_row_ptr[dst_blk_x]; 659*4882a593Smuzhiyun- src_ptr = src_row_ptr[dst_blk_x]; 660*4882a593Smuzhiyun- for (i = 0; i < DCTSIZE2; i++) 661*4882a593Smuzhiyun- *dst_ptr++ = *src_ptr++; 662*4882a593Smuzhiyun- } 663*4882a593Smuzhiyun } 664*4882a593Smuzhiyun } 665*4882a593Smuzhiyun } 666*4882a593Smuzhiyun@@ -457,6 +644,7 @@ do_rot_180 (j_decompress_ptr srcinfo, j_ 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun LOCAL(void) 669*4882a593Smuzhiyun do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 670*4882a593Smuzhiyun+ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, 671*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 672*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays) 673*4882a593Smuzhiyun /* Transverse transpose is equivalent to 674*4882a593Smuzhiyun@@ -470,18 +658,23 @@ do_transverse (j_decompress_ptr srcinfo, 675*4882a593Smuzhiyun */ 676*4882a593Smuzhiyun { 677*4882a593Smuzhiyun JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 678*4882a593Smuzhiyun+ JDIMENSION x_crop_blocks, y_crop_blocks; 679*4882a593Smuzhiyun int ci, i, j, offset_x, offset_y; 680*4882a593Smuzhiyun JBLOCKARRAY src_buffer, dst_buffer; 681*4882a593Smuzhiyun JCOEFPTR src_ptr, dst_ptr; 682*4882a593Smuzhiyun jpeg_component_info *compptr; 683*4882a593Smuzhiyun 684*4882a593Smuzhiyun- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 685*4882a593Smuzhiyun- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 686*4882a593Smuzhiyun+ MCU_cols = srcinfo->output_height / 687*4882a593Smuzhiyun+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size); 688*4882a593Smuzhiyun+ MCU_rows = srcinfo->output_width / 689*4882a593Smuzhiyun+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size); 690*4882a593Smuzhiyun 691*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 692*4882a593Smuzhiyun compptr = dstinfo->comp_info + ci; 693*4882a593Smuzhiyun comp_width = MCU_cols * compptr->h_samp_factor; 694*4882a593Smuzhiyun comp_height = MCU_rows * compptr->v_samp_factor; 695*4882a593Smuzhiyun+ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; 696*4882a593Smuzhiyun+ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; 697*4882a593Smuzhiyun for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 698*4882a593Smuzhiyun dst_blk_y += compptr->v_samp_factor) { 699*4882a593Smuzhiyun dst_buffer = (*srcinfo->mem->access_virt_barray) 700*4882a593Smuzhiyun@@ -490,17 +683,26 @@ do_transverse (j_decompress_ptr srcinfo, 701*4882a593Smuzhiyun for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 702*4882a593Smuzhiyun for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 703*4882a593Smuzhiyun dst_blk_x += compptr->h_samp_factor) { 704*4882a593Smuzhiyun- src_buffer = (*srcinfo->mem->access_virt_barray) 705*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 706*4882a593Smuzhiyun- (JDIMENSION) compptr->h_samp_factor, FALSE); 707*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 708*4882a593Smuzhiyun+ /* Block is within the mirrorable area. */ 709*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 710*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 711*4882a593Smuzhiyun+ comp_width - x_crop_blocks - dst_blk_x - 712*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, 713*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, FALSE); 714*4882a593Smuzhiyun+ } else { 715*4882a593Smuzhiyun+ src_buffer = (*srcinfo->mem->access_virt_barray) 716*4882a593Smuzhiyun+ ((j_common_ptr) srcinfo, src_coef_arrays[ci], 717*4882a593Smuzhiyun+ dst_blk_x + x_crop_blocks, 718*4882a593Smuzhiyun+ (JDIMENSION) compptr->h_samp_factor, FALSE); 719*4882a593Smuzhiyun+ } 720*4882a593Smuzhiyun for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 721*4882a593Smuzhiyun- if (dst_blk_y < comp_height) { 722*4882a593Smuzhiyun- src_ptr = src_buffer[offset_x] 723*4882a593Smuzhiyun- [comp_height - dst_blk_y - offset_y - 1]; 724*4882a593Smuzhiyun- if (dst_blk_x < comp_width) { 725*4882a593Smuzhiyun+ dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 726*4882a593Smuzhiyun+ if (y_crop_blocks + dst_blk_y < comp_height) { 727*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 728*4882a593Smuzhiyun /* Block is within the mirrorable area. */ 729*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y] 730*4882a593Smuzhiyun- [comp_width - dst_blk_x - offset_x - 1]; 731*4882a593Smuzhiyun+ src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 732*4882a593Smuzhiyun+ [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 733*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) { 734*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) { 735*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 736*4882a593Smuzhiyun@@ -516,7 +718,8 @@ do_transverse (j_decompress_ptr srcinfo, 737*4882a593Smuzhiyun } 738*4882a593Smuzhiyun } else { 739*4882a593Smuzhiyun /* Right-edge blocks are mirrored in y only */ 740*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 741*4882a593Smuzhiyun+ src_ptr = src_buffer[offset_x] 742*4882a593Smuzhiyun+ [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; 743*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) { 744*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) { 745*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 746*4882a593Smuzhiyun@@ -526,11 +729,10 @@ do_transverse (j_decompress_ptr srcinfo, 747*4882a593Smuzhiyun } 748*4882a593Smuzhiyun } 749*4882a593Smuzhiyun } else { 750*4882a593Smuzhiyun- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 751*4882a593Smuzhiyun- if (dst_blk_x < comp_width) { 752*4882a593Smuzhiyun+ if (x_crop_blocks + dst_blk_x < comp_width) { 753*4882a593Smuzhiyun /* Bottom-edge blocks are mirrored in x only */ 754*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y] 755*4882a593Smuzhiyun- [comp_width - dst_blk_x - offset_x - 1]; 756*4882a593Smuzhiyun+ src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] 757*4882a593Smuzhiyun+ [dst_blk_y + offset_y + y_crop_blocks]; 758*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) { 759*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 760*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 761*4882a593Smuzhiyun@@ -540,7 +742,8 @@ do_transverse (j_decompress_ptr srcinfo, 762*4882a593Smuzhiyun } 763*4882a593Smuzhiyun } else { 764*4882a593Smuzhiyun /* At lower right corner, just transpose, no mirroring */ 765*4882a593Smuzhiyun- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 766*4882a593Smuzhiyun+ src_ptr = src_buffer[offset_x] 767*4882a593Smuzhiyun+ [dst_blk_y + offset_y + y_crop_blocks]; 768*4882a593Smuzhiyun for (i = 0; i < DCTSIZE; i++) 769*4882a593Smuzhiyun for (j = 0; j < DCTSIZE; j++) 770*4882a593Smuzhiyun dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 771*4882a593Smuzhiyun@@ -554,83 +757,372 @@ do_transverse (j_decompress_ptr srcinfo, 772*4882a593Smuzhiyun } 773*4882a593Smuzhiyun 774*4882a593Smuzhiyun 775*4882a593Smuzhiyun+/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec. 776*4882a593Smuzhiyun+ * Returns TRUE if valid integer found, FALSE if not. 777*4882a593Smuzhiyun+ * *strptr is advanced over the digit string, and *result is set to its value. 778*4882a593Smuzhiyun+ */ 779*4882a593Smuzhiyun+ 780*4882a593Smuzhiyun+LOCAL(boolean) 781*4882a593Smuzhiyun+jt_read_integer (const char ** strptr, JDIMENSION * result) 782*4882a593Smuzhiyun+{ 783*4882a593Smuzhiyun+ const char * ptr = *strptr; 784*4882a593Smuzhiyun+ JDIMENSION val = 0; 785*4882a593Smuzhiyun+ 786*4882a593Smuzhiyun+ for (; isdigit(*ptr); ptr++) { 787*4882a593Smuzhiyun+ val = val * 10 + (JDIMENSION) (*ptr - '0'); 788*4882a593Smuzhiyun+ } 789*4882a593Smuzhiyun+ *result = val; 790*4882a593Smuzhiyun+ if (ptr == *strptr) 791*4882a593Smuzhiyun+ return FALSE; /* oops, no digits */ 792*4882a593Smuzhiyun+ *strptr = ptr; 793*4882a593Smuzhiyun+ return TRUE; 794*4882a593Smuzhiyun+} 795*4882a593Smuzhiyun+ 796*4882a593Smuzhiyun+ 797*4882a593Smuzhiyun+/* Parse a crop specification (written in X11 geometry style). 798*4882a593Smuzhiyun+ * The routine returns TRUE if the spec string is valid, FALSE if not. 799*4882a593Smuzhiyun+ * 800*4882a593Smuzhiyun+ * The crop spec string should have the format 801*4882a593Smuzhiyun+ * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset> 802*4882a593Smuzhiyun+ * where width, height, xoffset, and yoffset are unsigned integers. 803*4882a593Smuzhiyun+ * Each of the elements can be omitted to indicate a default value. 804*4882a593Smuzhiyun+ * (A weakness of this style is that it is not possible to omit xoffset 805*4882a593Smuzhiyun+ * while specifying yoffset, since they look alike.) 806*4882a593Smuzhiyun+ * 807*4882a593Smuzhiyun+ * This code is loosely based on XParseGeometry from the X11 distribution. 808*4882a593Smuzhiyun+ */ 809*4882a593Smuzhiyun+ 810*4882a593Smuzhiyun+GLOBAL(boolean) 811*4882a593Smuzhiyun+jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec) 812*4882a593Smuzhiyun+{ 813*4882a593Smuzhiyun+ info->crop = FALSE; 814*4882a593Smuzhiyun+ info->crop_width_set = JCROP_UNSET; 815*4882a593Smuzhiyun+ info->crop_height_set = JCROP_UNSET; 816*4882a593Smuzhiyun+ info->crop_xoffset_set = JCROP_UNSET; 817*4882a593Smuzhiyun+ info->crop_yoffset_set = JCROP_UNSET; 818*4882a593Smuzhiyun+ 819*4882a593Smuzhiyun+ if (isdigit(*spec)) { 820*4882a593Smuzhiyun+ /* fetch width */ 821*4882a593Smuzhiyun+ if (! jt_read_integer(&spec, &info->crop_width)) 822*4882a593Smuzhiyun+ return FALSE; 823*4882a593Smuzhiyun+ if (*spec == 'f' || *spec == 'F') { 824*4882a593Smuzhiyun+ spec++; 825*4882a593Smuzhiyun+ info->crop_width_set = JCROP_FORCE; 826*4882a593Smuzhiyun+ } else 827*4882a593Smuzhiyun+ info->crop_width_set = JCROP_POS; 828*4882a593Smuzhiyun+ } 829*4882a593Smuzhiyun+ if (*spec == 'x' || *spec == 'X') { 830*4882a593Smuzhiyun+ /* fetch height */ 831*4882a593Smuzhiyun+ spec++; 832*4882a593Smuzhiyun+ if (! jt_read_integer(&spec, &info->crop_height)) 833*4882a593Smuzhiyun+ return FALSE; 834*4882a593Smuzhiyun+ if (*spec == 'f' || *spec == 'F') { 835*4882a593Smuzhiyun+ spec++; 836*4882a593Smuzhiyun+ info->crop_height_set = JCROP_FORCE; 837*4882a593Smuzhiyun+ } else 838*4882a593Smuzhiyun+ info->crop_height_set = JCROP_POS; 839*4882a593Smuzhiyun+ } 840*4882a593Smuzhiyun+ if (*spec == '+' || *spec == '-') { 841*4882a593Smuzhiyun+ /* fetch xoffset */ 842*4882a593Smuzhiyun+ info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; 843*4882a593Smuzhiyun+ spec++; 844*4882a593Smuzhiyun+ if (! jt_read_integer(&spec, &info->crop_xoffset)) 845*4882a593Smuzhiyun+ return FALSE; 846*4882a593Smuzhiyun+ } 847*4882a593Smuzhiyun+ if (*spec == '+' || *spec == '-') { 848*4882a593Smuzhiyun+ /* fetch yoffset */ 849*4882a593Smuzhiyun+ info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS; 850*4882a593Smuzhiyun+ spec++; 851*4882a593Smuzhiyun+ if (! jt_read_integer(&spec, &info->crop_yoffset)) 852*4882a593Smuzhiyun+ return FALSE; 853*4882a593Smuzhiyun+ } 854*4882a593Smuzhiyun+ /* We had better have gotten to the end of the string. */ 855*4882a593Smuzhiyun+ if (*spec != '\0') 856*4882a593Smuzhiyun+ return FALSE; 857*4882a593Smuzhiyun+ info->crop = TRUE; 858*4882a593Smuzhiyun+ return TRUE; 859*4882a593Smuzhiyun+} 860*4882a593Smuzhiyun+ 861*4882a593Smuzhiyun+ 862*4882a593Smuzhiyun+/* Trim off any partial iMCUs on the indicated destination edge */ 863*4882a593Smuzhiyun+ 864*4882a593Smuzhiyun+LOCAL(void) 865*4882a593Smuzhiyun+trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width) 866*4882a593Smuzhiyun+{ 867*4882a593Smuzhiyun+ JDIMENSION MCU_cols; 868*4882a593Smuzhiyun+ 869*4882a593Smuzhiyun+ MCU_cols = info->output_width / info->iMCU_sample_width; 870*4882a593Smuzhiyun+ if (MCU_cols > 0 && info->x_crop_offset + MCU_cols == 871*4882a593Smuzhiyun+ full_width / info->iMCU_sample_width) 872*4882a593Smuzhiyun+ info->output_width = MCU_cols * info->iMCU_sample_width; 873*4882a593Smuzhiyun+} 874*4882a593Smuzhiyun+ 875*4882a593Smuzhiyun+LOCAL(void) 876*4882a593Smuzhiyun+trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height) 877*4882a593Smuzhiyun+{ 878*4882a593Smuzhiyun+ JDIMENSION MCU_rows; 879*4882a593Smuzhiyun+ 880*4882a593Smuzhiyun+ MCU_rows = info->output_height / info->iMCU_sample_height; 881*4882a593Smuzhiyun+ if (MCU_rows > 0 && info->y_crop_offset + MCU_rows == 882*4882a593Smuzhiyun+ full_height / info->iMCU_sample_height) 883*4882a593Smuzhiyun+ info->output_height = MCU_rows * info->iMCU_sample_height; 884*4882a593Smuzhiyun+} 885*4882a593Smuzhiyun+ 886*4882a593Smuzhiyun+ 887*4882a593Smuzhiyun /* Request any required workspace. 888*4882a593Smuzhiyun * 889*4882a593Smuzhiyun+ * This routine figures out the size that the output image will be 890*4882a593Smuzhiyun+ * (which implies that all the transform parameters must be set before 891*4882a593Smuzhiyun+ * it is called). 892*4882a593Smuzhiyun+ * 893*4882a593Smuzhiyun * We allocate the workspace virtual arrays from the source decompression 894*4882a593Smuzhiyun * object, so that all the arrays (both the original data and the workspace) 895*4882a593Smuzhiyun * will be taken into account while making memory management decisions. 896*4882a593Smuzhiyun * Hence, this routine must be called after jpeg_read_header (which reads 897*4882a593Smuzhiyun * the image dimensions) and before jpeg_read_coefficients (which realizes 898*4882a593Smuzhiyun * the source's virtual arrays). 899*4882a593Smuzhiyun+ * 900*4882a593Smuzhiyun+ * This function returns FALSE right away if -perfect is given 901*4882a593Smuzhiyun+ * and transformation is not perfect. Otherwise returns TRUE. 902*4882a593Smuzhiyun */ 903*4882a593Smuzhiyun 904*4882a593Smuzhiyun-GLOBAL(void) 905*4882a593Smuzhiyun+GLOBAL(boolean) 906*4882a593Smuzhiyun jtransform_request_workspace (j_decompress_ptr srcinfo, 907*4882a593Smuzhiyun jpeg_transform_info *info) 908*4882a593Smuzhiyun { 909*4882a593Smuzhiyun- jvirt_barray_ptr *coef_arrays = NULL; 910*4882a593Smuzhiyun+ jvirt_barray_ptr *coef_arrays; 911*4882a593Smuzhiyun+ boolean need_workspace, transpose_it; 912*4882a593Smuzhiyun jpeg_component_info *compptr; 913*4882a593Smuzhiyun- int ci; 914*4882a593Smuzhiyun+ JDIMENSION xoffset, yoffset; 915*4882a593Smuzhiyun+ JDIMENSION width_in_iMCUs, height_in_iMCUs; 916*4882a593Smuzhiyun+ JDIMENSION width_in_blocks, height_in_blocks; 917*4882a593Smuzhiyun+ int ci, h_samp_factor, v_samp_factor; 918*4882a593Smuzhiyun 919*4882a593Smuzhiyun+ /* Determine number of components in output image */ 920*4882a593Smuzhiyun if (info->force_grayscale && 921*4882a593Smuzhiyun srcinfo->jpeg_color_space == JCS_YCbCr && 922*4882a593Smuzhiyun- srcinfo->num_components == 3) { 923*4882a593Smuzhiyun+ srcinfo->num_components == 3) 924*4882a593Smuzhiyun /* We'll only process the first component */ 925*4882a593Smuzhiyun info->num_components = 1; 926*4882a593Smuzhiyun- } else { 927*4882a593Smuzhiyun+ else 928*4882a593Smuzhiyun /* Process all the components */ 929*4882a593Smuzhiyun info->num_components = srcinfo->num_components; 930*4882a593Smuzhiyun+ 931*4882a593Smuzhiyun+ /* Compute output image dimensions and related values. */ 932*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 80 933*4882a593Smuzhiyun+ jpeg_core_output_dimensions(srcinfo); 934*4882a593Smuzhiyun+#else 935*4882a593Smuzhiyun+ srcinfo->output_width = srcinfo->image_width; 936*4882a593Smuzhiyun+ srcinfo->output_height = srcinfo->image_height; 937*4882a593Smuzhiyun+#endif 938*4882a593Smuzhiyun+ 939*4882a593Smuzhiyun+ /* Return right away if -perfect is given and transformation is not perfect. 940*4882a593Smuzhiyun+ */ 941*4882a593Smuzhiyun+ if (info->perfect) { 942*4882a593Smuzhiyun+ if (info->num_components == 1) { 943*4882a593Smuzhiyun+ if (!jtransform_perfect_transform(srcinfo->output_width, 944*4882a593Smuzhiyun+ srcinfo->output_height, 945*4882a593Smuzhiyun+ srcinfo->_min_DCT_h_scaled_size, 946*4882a593Smuzhiyun+ srcinfo->_min_DCT_v_scaled_size, 947*4882a593Smuzhiyun+ info->transform)) 948*4882a593Smuzhiyun+ return FALSE; 949*4882a593Smuzhiyun+ } else { 950*4882a593Smuzhiyun+ if (!jtransform_perfect_transform(srcinfo->output_width, 951*4882a593Smuzhiyun+ srcinfo->output_height, 952*4882a593Smuzhiyun+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size, 953*4882a593Smuzhiyun+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size, 954*4882a593Smuzhiyun+ info->transform)) 955*4882a593Smuzhiyun+ return FALSE; 956*4882a593Smuzhiyun+ } 957*4882a593Smuzhiyun+ } 958*4882a593Smuzhiyun+ 959*4882a593Smuzhiyun+ /* If there is only one output component, force the iMCU size to be 1; 960*4882a593Smuzhiyun+ * else use the source iMCU size. (This allows us to do the right thing 961*4882a593Smuzhiyun+ * when reducing color to grayscale, and also provides a handy way of 962*4882a593Smuzhiyun+ * cleaning up "funny" grayscale images whose sampling factors are not 1x1.) 963*4882a593Smuzhiyun+ */ 964*4882a593Smuzhiyun+ switch (info->transform) { 965*4882a593Smuzhiyun+ case JXFORM_TRANSPOSE: 966*4882a593Smuzhiyun+ case JXFORM_TRANSVERSE: 967*4882a593Smuzhiyun+ case JXFORM_ROT_90: 968*4882a593Smuzhiyun+ case JXFORM_ROT_270: 969*4882a593Smuzhiyun+ info->output_width = srcinfo->output_height; 970*4882a593Smuzhiyun+ info->output_height = srcinfo->output_width; 971*4882a593Smuzhiyun+ if (info->num_components == 1) { 972*4882a593Smuzhiyun+ info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size; 973*4882a593Smuzhiyun+ info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size; 974*4882a593Smuzhiyun+ } else { 975*4882a593Smuzhiyun+ info->iMCU_sample_width = 976*4882a593Smuzhiyun+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size; 977*4882a593Smuzhiyun+ info->iMCU_sample_height = 978*4882a593Smuzhiyun+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size; 979*4882a593Smuzhiyun+ } 980*4882a593Smuzhiyun+ break; 981*4882a593Smuzhiyun+ default: 982*4882a593Smuzhiyun+ info->output_width = srcinfo->output_width; 983*4882a593Smuzhiyun+ info->output_height = srcinfo->output_height; 984*4882a593Smuzhiyun+ if (info->num_components == 1) { 985*4882a593Smuzhiyun+ info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size; 986*4882a593Smuzhiyun+ info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size; 987*4882a593Smuzhiyun+ } else { 988*4882a593Smuzhiyun+ info->iMCU_sample_width = 989*4882a593Smuzhiyun+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size; 990*4882a593Smuzhiyun+ info->iMCU_sample_height = 991*4882a593Smuzhiyun+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size; 992*4882a593Smuzhiyun+ } 993*4882a593Smuzhiyun+ break; 994*4882a593Smuzhiyun } 995*4882a593Smuzhiyun 996*4882a593Smuzhiyun+ /* If cropping has been requested, compute the crop area's position and 997*4882a593Smuzhiyun+ * dimensions, ensuring that its upper left corner falls at an iMCU boundary. 998*4882a593Smuzhiyun+ */ 999*4882a593Smuzhiyun+ if (info->crop) { 1000*4882a593Smuzhiyun+ /* Insert default values for unset crop parameters */ 1001*4882a593Smuzhiyun+ if (info->crop_xoffset_set == JCROP_UNSET) 1002*4882a593Smuzhiyun+ info->crop_xoffset = 0; /* default to +0 */ 1003*4882a593Smuzhiyun+ if (info->crop_yoffset_set == JCROP_UNSET) 1004*4882a593Smuzhiyun+ info->crop_yoffset = 0; /* default to +0 */ 1005*4882a593Smuzhiyun+ if (info->crop_xoffset >= info->output_width || 1006*4882a593Smuzhiyun+ info->crop_yoffset >= info->output_height) 1007*4882a593Smuzhiyun+ ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); 1008*4882a593Smuzhiyun+ if (info->crop_width_set == JCROP_UNSET) 1009*4882a593Smuzhiyun+ info->crop_width = info->output_width - info->crop_xoffset; 1010*4882a593Smuzhiyun+ if (info->crop_height_set == JCROP_UNSET) 1011*4882a593Smuzhiyun+ info->crop_height = info->output_height - info->crop_yoffset; 1012*4882a593Smuzhiyun+ /* Ensure parameters are valid */ 1013*4882a593Smuzhiyun+ if (info->crop_width <= 0 || info->crop_width > info->output_width || 1014*4882a593Smuzhiyun+ info->crop_height <= 0 || info->crop_height > info->output_height || 1015*4882a593Smuzhiyun+ info->crop_xoffset > info->output_width - info->crop_width || 1016*4882a593Smuzhiyun+ info->crop_yoffset > info->output_height - info->crop_height) 1017*4882a593Smuzhiyun+ ERREXIT(srcinfo, JERR_BAD_CROP_SPEC); 1018*4882a593Smuzhiyun+ /* Convert negative crop offsets into regular offsets */ 1019*4882a593Smuzhiyun+ if (info->crop_xoffset_set == JCROP_NEG) 1020*4882a593Smuzhiyun+ xoffset = info->output_width - info->crop_width - info->crop_xoffset; 1021*4882a593Smuzhiyun+ else 1022*4882a593Smuzhiyun+ xoffset = info->crop_xoffset; 1023*4882a593Smuzhiyun+ if (info->crop_yoffset_set == JCROP_NEG) 1024*4882a593Smuzhiyun+ yoffset = info->output_height - info->crop_height - info->crop_yoffset; 1025*4882a593Smuzhiyun+ else 1026*4882a593Smuzhiyun+ yoffset = info->crop_yoffset; 1027*4882a593Smuzhiyun+ /* Now adjust so that upper left corner falls at an iMCU boundary */ 1028*4882a593Smuzhiyun+ if (info->crop_width_set == JCROP_FORCE) 1029*4882a593Smuzhiyun+ info->output_width = info->crop_width; 1030*4882a593Smuzhiyun+ else 1031*4882a593Smuzhiyun+ info->output_width = 1032*4882a593Smuzhiyun+ info->crop_width + (xoffset % info->iMCU_sample_width); 1033*4882a593Smuzhiyun+ if (info->crop_height_set == JCROP_FORCE) 1034*4882a593Smuzhiyun+ info->output_height = info->crop_height; 1035*4882a593Smuzhiyun+ else 1036*4882a593Smuzhiyun+ info->output_height = 1037*4882a593Smuzhiyun+ info->crop_height + (yoffset % info->iMCU_sample_height); 1038*4882a593Smuzhiyun+ /* Save x/y offsets measured in iMCUs */ 1039*4882a593Smuzhiyun+ info->x_crop_offset = xoffset / info->iMCU_sample_width; 1040*4882a593Smuzhiyun+ info->y_crop_offset = yoffset / info->iMCU_sample_height; 1041*4882a593Smuzhiyun+ } else { 1042*4882a593Smuzhiyun+ info->x_crop_offset = 0; 1043*4882a593Smuzhiyun+ info->y_crop_offset = 0; 1044*4882a593Smuzhiyun+ } 1045*4882a593Smuzhiyun+ 1046*4882a593Smuzhiyun+ /* Figure out whether we need workspace arrays, 1047*4882a593Smuzhiyun+ * and if so whether they are transposed relative to the source. 1048*4882a593Smuzhiyun+ */ 1049*4882a593Smuzhiyun+ need_workspace = FALSE; 1050*4882a593Smuzhiyun+ transpose_it = FALSE; 1051*4882a593Smuzhiyun switch (info->transform) { 1052*4882a593Smuzhiyun case JXFORM_NONE: 1053*4882a593Smuzhiyun+ if (info->x_crop_offset != 0 || info->y_crop_offset != 0) 1054*4882a593Smuzhiyun+ need_workspace = TRUE; 1055*4882a593Smuzhiyun+ /* No workspace needed if neither cropping nor transforming */ 1056*4882a593Smuzhiyun+ break; 1057*4882a593Smuzhiyun case JXFORM_FLIP_H: 1058*4882a593Smuzhiyun- /* Don't need a workspace array */ 1059*4882a593Smuzhiyun+ if (info->trim) 1060*4882a593Smuzhiyun+ trim_right_edge(info, srcinfo->output_width); 1061*4882a593Smuzhiyun+ if (info->y_crop_offset != 0 || info->slow_hflip) 1062*4882a593Smuzhiyun+ need_workspace = TRUE; 1063*4882a593Smuzhiyun+ /* do_flip_h_no_crop doesn't need a workspace array */ 1064*4882a593Smuzhiyun break; 1065*4882a593Smuzhiyun case JXFORM_FLIP_V: 1066*4882a593Smuzhiyun- case JXFORM_ROT_180: 1067*4882a593Smuzhiyun- /* Need workspace arrays having same dimensions as source image. 1068*4882a593Smuzhiyun- * Note that we allocate arrays padded out to the next iMCU boundary, 1069*4882a593Smuzhiyun- * so that transform routines need not worry about missing edge blocks. 1070*4882a593Smuzhiyun- */ 1071*4882a593Smuzhiyun- coef_arrays = (jvirt_barray_ptr *) 1072*4882a593Smuzhiyun- (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 1073*4882a593Smuzhiyun- SIZEOF(jvirt_barray_ptr) * info->num_components); 1074*4882a593Smuzhiyun- for (ci = 0; ci < info->num_components; ci++) { 1075*4882a593Smuzhiyun- compptr = srcinfo->comp_info + ci; 1076*4882a593Smuzhiyun- coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 1077*4882a593Smuzhiyun- ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 1078*4882a593Smuzhiyun- (JDIMENSION) jround_up((long) compptr->width_in_blocks, 1079*4882a593Smuzhiyun- (long) compptr->h_samp_factor), 1080*4882a593Smuzhiyun- (JDIMENSION) jround_up((long) compptr->height_in_blocks, 1081*4882a593Smuzhiyun- (long) compptr->v_samp_factor), 1082*4882a593Smuzhiyun- (JDIMENSION) compptr->v_samp_factor); 1083*4882a593Smuzhiyun- } 1084*4882a593Smuzhiyun+ if (info->trim) 1085*4882a593Smuzhiyun+ trim_bottom_edge(info, srcinfo->output_height); 1086*4882a593Smuzhiyun+ /* Need workspace arrays having same dimensions as source image. */ 1087*4882a593Smuzhiyun+ need_workspace = TRUE; 1088*4882a593Smuzhiyun break; 1089*4882a593Smuzhiyun case JXFORM_TRANSPOSE: 1090*4882a593Smuzhiyun+ /* transpose does NOT have to trim anything */ 1091*4882a593Smuzhiyun+ /* Need workspace arrays having transposed dimensions. */ 1092*4882a593Smuzhiyun+ need_workspace = TRUE; 1093*4882a593Smuzhiyun+ transpose_it = TRUE; 1094*4882a593Smuzhiyun+ break; 1095*4882a593Smuzhiyun case JXFORM_TRANSVERSE: 1096*4882a593Smuzhiyun+ if (info->trim) { 1097*4882a593Smuzhiyun+ trim_right_edge(info, srcinfo->output_height); 1098*4882a593Smuzhiyun+ trim_bottom_edge(info, srcinfo->output_width); 1099*4882a593Smuzhiyun+ } 1100*4882a593Smuzhiyun+ /* Need workspace arrays having transposed dimensions. */ 1101*4882a593Smuzhiyun+ need_workspace = TRUE; 1102*4882a593Smuzhiyun+ transpose_it = TRUE; 1103*4882a593Smuzhiyun+ break; 1104*4882a593Smuzhiyun case JXFORM_ROT_90: 1105*4882a593Smuzhiyun+ if (info->trim) 1106*4882a593Smuzhiyun+ trim_right_edge(info, srcinfo->output_height); 1107*4882a593Smuzhiyun+ /* Need workspace arrays having transposed dimensions. */ 1108*4882a593Smuzhiyun+ need_workspace = TRUE; 1109*4882a593Smuzhiyun+ transpose_it = TRUE; 1110*4882a593Smuzhiyun+ break; 1111*4882a593Smuzhiyun+ case JXFORM_ROT_180: 1112*4882a593Smuzhiyun+ if (info->trim) { 1113*4882a593Smuzhiyun+ trim_right_edge(info, srcinfo->output_width); 1114*4882a593Smuzhiyun+ trim_bottom_edge(info, srcinfo->output_height); 1115*4882a593Smuzhiyun+ } 1116*4882a593Smuzhiyun+ /* Need workspace arrays having same dimensions as source image. */ 1117*4882a593Smuzhiyun+ need_workspace = TRUE; 1118*4882a593Smuzhiyun+ break; 1119*4882a593Smuzhiyun case JXFORM_ROT_270: 1120*4882a593Smuzhiyun- /* Need workspace arrays having transposed dimensions. 1121*4882a593Smuzhiyun- * Note that we allocate arrays padded out to the next iMCU boundary, 1122*4882a593Smuzhiyun- * so that transform routines need not worry about missing edge blocks. 1123*4882a593Smuzhiyun- */ 1124*4882a593Smuzhiyun+ if (info->trim) 1125*4882a593Smuzhiyun+ trim_bottom_edge(info, srcinfo->output_width); 1126*4882a593Smuzhiyun+ /* Need workspace arrays having transposed dimensions. */ 1127*4882a593Smuzhiyun+ need_workspace = TRUE; 1128*4882a593Smuzhiyun+ transpose_it = TRUE; 1129*4882a593Smuzhiyun+ break; 1130*4882a593Smuzhiyun+ } 1131*4882a593Smuzhiyun+ 1132*4882a593Smuzhiyun+ /* Allocate workspace if needed. 1133*4882a593Smuzhiyun+ * Note that we allocate arrays padded out to the next iMCU boundary, 1134*4882a593Smuzhiyun+ * so that transform routines need not worry about missing edge blocks. 1135*4882a593Smuzhiyun+ */ 1136*4882a593Smuzhiyun+ if (need_workspace) { 1137*4882a593Smuzhiyun coef_arrays = (jvirt_barray_ptr *) 1138*4882a593Smuzhiyun (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 1139*4882a593Smuzhiyun- SIZEOF(jvirt_barray_ptr) * info->num_components); 1140*4882a593Smuzhiyun+ SIZEOF(jvirt_barray_ptr) * info->num_components); 1141*4882a593Smuzhiyun+ width_in_iMCUs = (JDIMENSION) 1142*4882a593Smuzhiyun+ jdiv_round_up((long) info->output_width, 1143*4882a593Smuzhiyun+ (long) info->iMCU_sample_width); 1144*4882a593Smuzhiyun+ height_in_iMCUs = (JDIMENSION) 1145*4882a593Smuzhiyun+ jdiv_round_up((long) info->output_height, 1146*4882a593Smuzhiyun+ (long) info->iMCU_sample_height); 1147*4882a593Smuzhiyun for (ci = 0; ci < info->num_components; ci++) { 1148*4882a593Smuzhiyun compptr = srcinfo->comp_info + ci; 1149*4882a593Smuzhiyun+ if (info->num_components == 1) { 1150*4882a593Smuzhiyun+ /* we're going to force samp factors to 1x1 in this case */ 1151*4882a593Smuzhiyun+ h_samp_factor = v_samp_factor = 1; 1152*4882a593Smuzhiyun+ } else if (transpose_it) { 1153*4882a593Smuzhiyun+ h_samp_factor = compptr->v_samp_factor; 1154*4882a593Smuzhiyun+ v_samp_factor = compptr->h_samp_factor; 1155*4882a593Smuzhiyun+ } else { 1156*4882a593Smuzhiyun+ h_samp_factor = compptr->h_samp_factor; 1157*4882a593Smuzhiyun+ v_samp_factor = compptr->v_samp_factor; 1158*4882a593Smuzhiyun+ } 1159*4882a593Smuzhiyun+ width_in_blocks = width_in_iMCUs * h_samp_factor; 1160*4882a593Smuzhiyun+ height_in_blocks = height_in_iMCUs * v_samp_factor; 1161*4882a593Smuzhiyun coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 1162*4882a593Smuzhiyun ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 1163*4882a593Smuzhiyun- (JDIMENSION) jround_up((long) compptr->height_in_blocks, 1164*4882a593Smuzhiyun- (long) compptr->v_samp_factor), 1165*4882a593Smuzhiyun- (JDIMENSION) jround_up((long) compptr->width_in_blocks, 1166*4882a593Smuzhiyun- (long) compptr->h_samp_factor), 1167*4882a593Smuzhiyun- (JDIMENSION) compptr->h_samp_factor); 1168*4882a593Smuzhiyun+ width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor); 1169*4882a593Smuzhiyun } 1170*4882a593Smuzhiyun- break; 1171*4882a593Smuzhiyun- } 1172*4882a593Smuzhiyun- info->workspace_coef_arrays = coef_arrays; 1173*4882a593Smuzhiyun+ info->workspace_coef_arrays = coef_arrays; 1174*4882a593Smuzhiyun+ } else 1175*4882a593Smuzhiyun+ info->workspace_coef_arrays = NULL; 1176*4882a593Smuzhiyun+ 1177*4882a593Smuzhiyun+ return TRUE; 1178*4882a593Smuzhiyun } 1179*4882a593Smuzhiyun 1180*4882a593Smuzhiyun 1181*4882a593Smuzhiyun@@ -642,13 +1134,18 @@ transpose_critical_parameters (j_compres 1182*4882a593Smuzhiyun int tblno, i, j, ci, itemp; 1183*4882a593Smuzhiyun jpeg_component_info *compptr; 1184*4882a593Smuzhiyun JQUANT_TBL *qtblptr; 1185*4882a593Smuzhiyun- JDIMENSION dtemp; 1186*4882a593Smuzhiyun+ JDIMENSION jtemp; 1187*4882a593Smuzhiyun UINT16 qtemp; 1188*4882a593Smuzhiyun 1189*4882a593Smuzhiyun- /* Transpose basic image dimensions */ 1190*4882a593Smuzhiyun- dtemp = dstinfo->image_width; 1191*4882a593Smuzhiyun+ /* Transpose image dimensions */ 1192*4882a593Smuzhiyun+ jtemp = dstinfo->image_width; 1193*4882a593Smuzhiyun dstinfo->image_width = dstinfo->image_height; 1194*4882a593Smuzhiyun- dstinfo->image_height = dtemp; 1195*4882a593Smuzhiyun+ dstinfo->image_height = jtemp; 1196*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 1197*4882a593Smuzhiyun+ itemp = dstinfo->min_DCT_h_scaled_size; 1198*4882a593Smuzhiyun+ dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size; 1199*4882a593Smuzhiyun+ dstinfo->min_DCT_v_scaled_size = itemp; 1200*4882a593Smuzhiyun+#endif 1201*4882a593Smuzhiyun 1202*4882a593Smuzhiyun /* Transpose sampling factors */ 1203*4882a593Smuzhiyun for (ci = 0; ci < dstinfo->num_components; ci++) { 1204*4882a593Smuzhiyun@@ -674,47 +1171,162 @@ transpose_critical_parameters (j_compres 1205*4882a593Smuzhiyun } 1206*4882a593Smuzhiyun 1207*4882a593Smuzhiyun 1208*4882a593Smuzhiyun-/* Trim off any partial iMCUs on the indicated destination edge */ 1209*4882a593Smuzhiyun+/* Adjust Exif image parameters. 1210*4882a593Smuzhiyun+ * 1211*4882a593Smuzhiyun+ * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. 1212*4882a593Smuzhiyun+ */ 1213*4882a593Smuzhiyun 1214*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 1215*4882a593Smuzhiyun LOCAL(void) 1216*4882a593Smuzhiyun-trim_right_edge (j_compress_ptr dstinfo) 1217*4882a593Smuzhiyun+adjust_exif_parameters (JOCTET FAR * data, unsigned int length, 1218*4882a593Smuzhiyun+ JDIMENSION new_width, JDIMENSION new_height) 1219*4882a593Smuzhiyun { 1220*4882a593Smuzhiyun- int ci, max_h_samp_factor; 1221*4882a593Smuzhiyun- JDIMENSION MCU_cols; 1222*4882a593Smuzhiyun+ boolean is_motorola; /* Flag for byte order */ 1223*4882a593Smuzhiyun+ unsigned int number_of_tags, tagnum; 1224*4882a593Smuzhiyun+ unsigned int firstoffset, offset; 1225*4882a593Smuzhiyun+ JDIMENSION new_value; 1226*4882a593Smuzhiyun+ 1227*4882a593Smuzhiyun+ if (length < 12) return; /* Length of an IFD entry */ 1228*4882a593Smuzhiyun+ 1229*4882a593Smuzhiyun+ /* Discover byte order */ 1230*4882a593Smuzhiyun+ if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) 1231*4882a593Smuzhiyun+ is_motorola = FALSE; 1232*4882a593Smuzhiyun+ else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) 1233*4882a593Smuzhiyun+ is_motorola = TRUE; 1234*4882a593Smuzhiyun+ else 1235*4882a593Smuzhiyun+ return; 1236*4882a593Smuzhiyun+ 1237*4882a593Smuzhiyun+ /* Check Tag Mark */ 1238*4882a593Smuzhiyun+ if (is_motorola) { 1239*4882a593Smuzhiyun+ if (GETJOCTET(data[2]) != 0) return; 1240*4882a593Smuzhiyun+ if (GETJOCTET(data[3]) != 0x2A) return; 1241*4882a593Smuzhiyun+ } else { 1242*4882a593Smuzhiyun+ if (GETJOCTET(data[3]) != 0) return; 1243*4882a593Smuzhiyun+ if (GETJOCTET(data[2]) != 0x2A) return; 1244*4882a593Smuzhiyun+ } 1245*4882a593Smuzhiyun 1246*4882a593Smuzhiyun- /* We have to compute max_h_samp_factor ourselves, 1247*4882a593Smuzhiyun- * because it hasn't been set yet in the destination 1248*4882a593Smuzhiyun- * (and we don't want to use the source's value). 1249*4882a593Smuzhiyun- */ 1250*4882a593Smuzhiyun- max_h_samp_factor = 1; 1251*4882a593Smuzhiyun- for (ci = 0; ci < dstinfo->num_components; ci++) { 1252*4882a593Smuzhiyun- int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; 1253*4882a593Smuzhiyun- max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); 1254*4882a593Smuzhiyun+ /* Get first IFD offset (offset to IFD0) */ 1255*4882a593Smuzhiyun+ if (is_motorola) { 1256*4882a593Smuzhiyun+ if (GETJOCTET(data[4]) != 0) return; 1257*4882a593Smuzhiyun+ if (GETJOCTET(data[5]) != 0) return; 1258*4882a593Smuzhiyun+ firstoffset = GETJOCTET(data[6]); 1259*4882a593Smuzhiyun+ firstoffset <<= 8; 1260*4882a593Smuzhiyun+ firstoffset += GETJOCTET(data[7]); 1261*4882a593Smuzhiyun+ } else { 1262*4882a593Smuzhiyun+ if (GETJOCTET(data[7]) != 0) return; 1263*4882a593Smuzhiyun+ if (GETJOCTET(data[6]) != 0) return; 1264*4882a593Smuzhiyun+ firstoffset = GETJOCTET(data[5]); 1265*4882a593Smuzhiyun+ firstoffset <<= 8; 1266*4882a593Smuzhiyun+ firstoffset += GETJOCTET(data[4]); 1267*4882a593Smuzhiyun } 1268*4882a593Smuzhiyun- MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); 1269*4882a593Smuzhiyun- if (MCU_cols > 0) /* can't trim to 0 pixels */ 1270*4882a593Smuzhiyun- dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); 1271*4882a593Smuzhiyun-} 1272*4882a593Smuzhiyun+ if (firstoffset > length - 2) return; /* check end of data segment */ 1273*4882a593Smuzhiyun 1274*4882a593Smuzhiyun-LOCAL(void) 1275*4882a593Smuzhiyun-trim_bottom_edge (j_compress_ptr dstinfo) 1276*4882a593Smuzhiyun-{ 1277*4882a593Smuzhiyun- int ci, max_v_samp_factor; 1278*4882a593Smuzhiyun- JDIMENSION MCU_rows; 1279*4882a593Smuzhiyun+ /* Get the number of directory entries contained in this IFD */ 1280*4882a593Smuzhiyun+ if (is_motorola) { 1281*4882a593Smuzhiyun+ number_of_tags = GETJOCTET(data[firstoffset]); 1282*4882a593Smuzhiyun+ number_of_tags <<= 8; 1283*4882a593Smuzhiyun+ number_of_tags += GETJOCTET(data[firstoffset+1]); 1284*4882a593Smuzhiyun+ } else { 1285*4882a593Smuzhiyun+ number_of_tags = GETJOCTET(data[firstoffset+1]); 1286*4882a593Smuzhiyun+ number_of_tags <<= 8; 1287*4882a593Smuzhiyun+ number_of_tags += GETJOCTET(data[firstoffset]); 1288*4882a593Smuzhiyun+ } 1289*4882a593Smuzhiyun+ if (number_of_tags == 0) return; 1290*4882a593Smuzhiyun+ firstoffset += 2; 1291*4882a593Smuzhiyun 1292*4882a593Smuzhiyun- /* We have to compute max_v_samp_factor ourselves, 1293*4882a593Smuzhiyun- * because it hasn't been set yet in the destination 1294*4882a593Smuzhiyun- * (and we don't want to use the source's value). 1295*4882a593Smuzhiyun- */ 1296*4882a593Smuzhiyun- max_v_samp_factor = 1; 1297*4882a593Smuzhiyun- for (ci = 0; ci < dstinfo->num_components; ci++) { 1298*4882a593Smuzhiyun- int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; 1299*4882a593Smuzhiyun- max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); 1300*4882a593Smuzhiyun+ /* Search for ExifSubIFD offset Tag in IFD0 */ 1301*4882a593Smuzhiyun+ for (;;) { 1302*4882a593Smuzhiyun+ if (firstoffset > length - 12) return; /* check end of data segment */ 1303*4882a593Smuzhiyun+ /* Get Tag number */ 1304*4882a593Smuzhiyun+ if (is_motorola) { 1305*4882a593Smuzhiyun+ tagnum = GETJOCTET(data[firstoffset]); 1306*4882a593Smuzhiyun+ tagnum <<= 8; 1307*4882a593Smuzhiyun+ tagnum += GETJOCTET(data[firstoffset+1]); 1308*4882a593Smuzhiyun+ } else { 1309*4882a593Smuzhiyun+ tagnum = GETJOCTET(data[firstoffset+1]); 1310*4882a593Smuzhiyun+ tagnum <<= 8; 1311*4882a593Smuzhiyun+ tagnum += GETJOCTET(data[firstoffset]); 1312*4882a593Smuzhiyun+ } 1313*4882a593Smuzhiyun+ if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */ 1314*4882a593Smuzhiyun+ if (--number_of_tags == 0) return; 1315*4882a593Smuzhiyun+ firstoffset += 12; 1316*4882a593Smuzhiyun+ } 1317*4882a593Smuzhiyun+ 1318*4882a593Smuzhiyun+ /* Get the ExifSubIFD offset */ 1319*4882a593Smuzhiyun+ if (is_motorola) { 1320*4882a593Smuzhiyun+ if (GETJOCTET(data[firstoffset+8]) != 0) return; 1321*4882a593Smuzhiyun+ if (GETJOCTET(data[firstoffset+9]) != 0) return; 1322*4882a593Smuzhiyun+ offset = GETJOCTET(data[firstoffset+10]); 1323*4882a593Smuzhiyun+ offset <<= 8; 1324*4882a593Smuzhiyun+ offset += GETJOCTET(data[firstoffset+11]); 1325*4882a593Smuzhiyun+ } else { 1326*4882a593Smuzhiyun+ if (GETJOCTET(data[firstoffset+11]) != 0) return; 1327*4882a593Smuzhiyun+ if (GETJOCTET(data[firstoffset+10]) != 0) return; 1328*4882a593Smuzhiyun+ offset = GETJOCTET(data[firstoffset+9]); 1329*4882a593Smuzhiyun+ offset <<= 8; 1330*4882a593Smuzhiyun+ offset += GETJOCTET(data[firstoffset+8]); 1331*4882a593Smuzhiyun+ } 1332*4882a593Smuzhiyun+ if (offset > length - 2) return; /* check end of data segment */ 1333*4882a593Smuzhiyun+ 1334*4882a593Smuzhiyun+ /* Get the number of directory entries contained in this SubIFD */ 1335*4882a593Smuzhiyun+ if (is_motorola) { 1336*4882a593Smuzhiyun+ number_of_tags = GETJOCTET(data[offset]); 1337*4882a593Smuzhiyun+ number_of_tags <<= 8; 1338*4882a593Smuzhiyun+ number_of_tags += GETJOCTET(data[offset+1]); 1339*4882a593Smuzhiyun+ } else { 1340*4882a593Smuzhiyun+ number_of_tags = GETJOCTET(data[offset+1]); 1341*4882a593Smuzhiyun+ number_of_tags <<= 8; 1342*4882a593Smuzhiyun+ number_of_tags += GETJOCTET(data[offset]); 1343*4882a593Smuzhiyun } 1344*4882a593Smuzhiyun- MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); 1345*4882a593Smuzhiyun- if (MCU_rows > 0) /* can't trim to 0 pixels */ 1346*4882a593Smuzhiyun- dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); 1347*4882a593Smuzhiyun+ if (number_of_tags < 2) return; 1348*4882a593Smuzhiyun+ offset += 2; 1349*4882a593Smuzhiyun+ 1350*4882a593Smuzhiyun+ /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ 1351*4882a593Smuzhiyun+ do { 1352*4882a593Smuzhiyun+ if (offset > length - 12) return; /* check end of data segment */ 1353*4882a593Smuzhiyun+ /* Get Tag number */ 1354*4882a593Smuzhiyun+ if (is_motorola) { 1355*4882a593Smuzhiyun+ tagnum = GETJOCTET(data[offset]); 1356*4882a593Smuzhiyun+ tagnum <<= 8; 1357*4882a593Smuzhiyun+ tagnum += GETJOCTET(data[offset+1]); 1358*4882a593Smuzhiyun+ } else { 1359*4882a593Smuzhiyun+ tagnum = GETJOCTET(data[offset+1]); 1360*4882a593Smuzhiyun+ tagnum <<= 8; 1361*4882a593Smuzhiyun+ tagnum += GETJOCTET(data[offset]); 1362*4882a593Smuzhiyun+ } 1363*4882a593Smuzhiyun+ if (tagnum == 0xA002 || tagnum == 0xA003) { 1364*4882a593Smuzhiyun+ if (tagnum == 0xA002) 1365*4882a593Smuzhiyun+ new_value = new_width; /* ExifImageWidth Tag */ 1366*4882a593Smuzhiyun+ else 1367*4882a593Smuzhiyun+ new_value = new_height; /* ExifImageHeight Tag */ 1368*4882a593Smuzhiyun+ if (is_motorola) { 1369*4882a593Smuzhiyun+ data[offset+2] = 0; /* Format = unsigned long (4 octets) */ 1370*4882a593Smuzhiyun+ data[offset+3] = 4; 1371*4882a593Smuzhiyun+ data[offset+4] = 0; /* Number Of Components = 1 */ 1372*4882a593Smuzhiyun+ data[offset+5] = 0; 1373*4882a593Smuzhiyun+ data[offset+6] = 0; 1374*4882a593Smuzhiyun+ data[offset+7] = 1; 1375*4882a593Smuzhiyun+ data[offset+8] = 0; 1376*4882a593Smuzhiyun+ data[offset+9] = 0; 1377*4882a593Smuzhiyun+ data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); 1378*4882a593Smuzhiyun+ data[offset+11] = (JOCTET)(new_value & 0xFF); 1379*4882a593Smuzhiyun+ } else { 1380*4882a593Smuzhiyun+ data[offset+2] = 4; /* Format = unsigned long (4 octets) */ 1381*4882a593Smuzhiyun+ data[offset+3] = 0; 1382*4882a593Smuzhiyun+ data[offset+4] = 1; /* Number Of Components = 1 */ 1383*4882a593Smuzhiyun+ data[offset+5] = 0; 1384*4882a593Smuzhiyun+ data[offset+6] = 0; 1385*4882a593Smuzhiyun+ data[offset+7] = 0; 1386*4882a593Smuzhiyun+ data[offset+8] = (JOCTET)(new_value & 0xFF); 1387*4882a593Smuzhiyun+ data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); 1388*4882a593Smuzhiyun+ data[offset+10] = 0; 1389*4882a593Smuzhiyun+ data[offset+11] = 0; 1390*4882a593Smuzhiyun+ } 1391*4882a593Smuzhiyun+ } 1392*4882a593Smuzhiyun+ offset += 12; 1393*4882a593Smuzhiyun+ } while (--number_of_tags); 1394*4882a593Smuzhiyun } 1395*4882a593Smuzhiyun+#endif 1396*4882a593Smuzhiyun 1397*4882a593Smuzhiyun 1398*4882a593Smuzhiyun /* Adjust output image parameters as needed. 1399*4882a593Smuzhiyun@@ -736,18 +1348,22 @@ jtransform_adjust_parameters (j_decompre 1400*4882a593Smuzhiyun { 1401*4882a593Smuzhiyun /* If force-to-grayscale is requested, adjust destination parameters */ 1402*4882a593Smuzhiyun if (info->force_grayscale) { 1403*4882a593Smuzhiyun- /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 1404*4882a593Smuzhiyun- * properly. Among other things, the target h_samp_factor & v_samp_factor 1405*4882a593Smuzhiyun- * will get set to 1, which typically won't match the source. 1406*4882a593Smuzhiyun- * In fact we do this even if the source is already grayscale; that 1407*4882a593Smuzhiyun- * provides an easy way of coercing a grayscale JPEG with funny sampling 1408*4882a593Smuzhiyun- * factors to the customary 1,1. (Some decoders fail on other factors.) 1409*4882a593Smuzhiyun+ /* First, ensure we have YCbCr or grayscale data, and that the source's 1410*4882a593Smuzhiyun+ * Y channel is full resolution. (No reasonable person would make Y 1411*4882a593Smuzhiyun+ * be less than full resolution, so actually coping with that case 1412*4882a593Smuzhiyun+ * isn't worth extra code space. But we check it to avoid crashing.) 1413*4882a593Smuzhiyun */ 1414*4882a593Smuzhiyun- if ((dstinfo->jpeg_color_space == JCS_YCbCr && 1415*4882a593Smuzhiyun- dstinfo->num_components == 3) || 1416*4882a593Smuzhiyun- (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 1417*4882a593Smuzhiyun- dstinfo->num_components == 1)) { 1418*4882a593Smuzhiyun- /* We have to preserve the source's quantization table number. */ 1419*4882a593Smuzhiyun+ if (((dstinfo->jpeg_color_space == JCS_YCbCr && 1420*4882a593Smuzhiyun+ dstinfo->num_components == 3) || 1421*4882a593Smuzhiyun+ (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 1422*4882a593Smuzhiyun+ dstinfo->num_components == 1)) && 1423*4882a593Smuzhiyun+ srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor && 1424*4882a593Smuzhiyun+ srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) { 1425*4882a593Smuzhiyun+ /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 1426*4882a593Smuzhiyun+ * properly. Among other things, it sets the target h_samp_factor & 1427*4882a593Smuzhiyun+ * v_samp_factor to 1, which typically won't match the source. 1428*4882a593Smuzhiyun+ * We have to preserve the source's quantization table number, however. 1429*4882a593Smuzhiyun+ */ 1430*4882a593Smuzhiyun int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; 1431*4882a593Smuzhiyun jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); 1432*4882a593Smuzhiyun dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; 1433*4882a593Smuzhiyun@@ -755,50 +1371,66 @@ jtransform_adjust_parameters (j_decompre 1434*4882a593Smuzhiyun /* Sorry, can't do it */ 1435*4882a593Smuzhiyun ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); 1436*4882a593Smuzhiyun } 1437*4882a593Smuzhiyun+ } else if (info->num_components == 1) { 1438*4882a593Smuzhiyun+ /* For a single-component source, we force the destination sampling factors 1439*4882a593Smuzhiyun+ * to 1x1, with or without force_grayscale. This is useful because some 1440*4882a593Smuzhiyun+ * decoders choke on grayscale images with other sampling factors. 1441*4882a593Smuzhiyun+ */ 1442*4882a593Smuzhiyun+ dstinfo->comp_info[0].h_samp_factor = 1; 1443*4882a593Smuzhiyun+ dstinfo->comp_info[0].v_samp_factor = 1; 1444*4882a593Smuzhiyun } 1445*4882a593Smuzhiyun 1446*4882a593Smuzhiyun- /* Correct the destination's image dimensions etc if necessary */ 1447*4882a593Smuzhiyun+ /* Correct the destination's image dimensions as necessary 1448*4882a593Smuzhiyun+ * for rotate/flip, resize, and crop operations. 1449*4882a593Smuzhiyun+ */ 1450*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 1451*4882a593Smuzhiyun+ dstinfo->jpeg_width = info->output_width; 1452*4882a593Smuzhiyun+ dstinfo->jpeg_height = info->output_height; 1453*4882a593Smuzhiyun+#endif 1454*4882a593Smuzhiyun+ 1455*4882a593Smuzhiyun+ /* Transpose destination image parameters */ 1456*4882a593Smuzhiyun switch (info->transform) { 1457*4882a593Smuzhiyun- case JXFORM_NONE: 1458*4882a593Smuzhiyun- /* Nothing to do */ 1459*4882a593Smuzhiyun- break; 1460*4882a593Smuzhiyun- case JXFORM_FLIP_H: 1461*4882a593Smuzhiyun- if (info->trim) 1462*4882a593Smuzhiyun- trim_right_edge(dstinfo); 1463*4882a593Smuzhiyun- break; 1464*4882a593Smuzhiyun- case JXFORM_FLIP_V: 1465*4882a593Smuzhiyun- if (info->trim) 1466*4882a593Smuzhiyun- trim_bottom_edge(dstinfo); 1467*4882a593Smuzhiyun- break; 1468*4882a593Smuzhiyun case JXFORM_TRANSPOSE: 1469*4882a593Smuzhiyun- transpose_critical_parameters(dstinfo); 1470*4882a593Smuzhiyun- /* transpose does NOT have to trim anything */ 1471*4882a593Smuzhiyun- break; 1472*4882a593Smuzhiyun case JXFORM_TRANSVERSE: 1473*4882a593Smuzhiyun- transpose_critical_parameters(dstinfo); 1474*4882a593Smuzhiyun- if (info->trim) { 1475*4882a593Smuzhiyun- trim_right_edge(dstinfo); 1476*4882a593Smuzhiyun- trim_bottom_edge(dstinfo); 1477*4882a593Smuzhiyun- } 1478*4882a593Smuzhiyun- break; 1479*4882a593Smuzhiyun case JXFORM_ROT_90: 1480*4882a593Smuzhiyun- transpose_critical_parameters(dstinfo); 1481*4882a593Smuzhiyun- if (info->trim) 1482*4882a593Smuzhiyun- trim_right_edge(dstinfo); 1483*4882a593Smuzhiyun- break; 1484*4882a593Smuzhiyun- case JXFORM_ROT_180: 1485*4882a593Smuzhiyun- if (info->trim) { 1486*4882a593Smuzhiyun- trim_right_edge(dstinfo); 1487*4882a593Smuzhiyun- trim_bottom_edge(dstinfo); 1488*4882a593Smuzhiyun- } 1489*4882a593Smuzhiyun- break; 1490*4882a593Smuzhiyun case JXFORM_ROT_270: 1491*4882a593Smuzhiyun+#if JPEG_LIB_VERSION < 70 1492*4882a593Smuzhiyun+ dstinfo->image_width = info->output_height; 1493*4882a593Smuzhiyun+ dstinfo->image_height = info->output_width; 1494*4882a593Smuzhiyun+#endif 1495*4882a593Smuzhiyun transpose_critical_parameters(dstinfo); 1496*4882a593Smuzhiyun- if (info->trim) 1497*4882a593Smuzhiyun- trim_bottom_edge(dstinfo); 1498*4882a593Smuzhiyun+ break; 1499*4882a593Smuzhiyun+ default: 1500*4882a593Smuzhiyun+#if JPEG_LIB_VERSION < 70 1501*4882a593Smuzhiyun+ dstinfo->image_width = info->output_width; 1502*4882a593Smuzhiyun+ dstinfo->image_height = info->output_height; 1503*4882a593Smuzhiyun+#endif 1504*4882a593Smuzhiyun break; 1505*4882a593Smuzhiyun } 1506*4882a593Smuzhiyun 1507*4882a593Smuzhiyun+ /* Adjust Exif properties */ 1508*4882a593Smuzhiyun+ if (srcinfo->marker_list != NULL && 1509*4882a593Smuzhiyun+ srcinfo->marker_list->marker == JPEG_APP0+1 && 1510*4882a593Smuzhiyun+ srcinfo->marker_list->data_length >= 6 && 1511*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 && 1512*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 && 1513*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 && 1514*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 && 1515*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[4]) == 0 && 1516*4882a593Smuzhiyun+ GETJOCTET(srcinfo->marker_list->data[5]) == 0) { 1517*4882a593Smuzhiyun+ /* Suppress output of JFIF marker */ 1518*4882a593Smuzhiyun+ dstinfo->write_JFIF_header = FALSE; 1519*4882a593Smuzhiyun+#if JPEG_LIB_VERSION >= 70 1520*4882a593Smuzhiyun+ /* Adjust Exif image parameters */ 1521*4882a593Smuzhiyun+ if (dstinfo->jpeg_width != srcinfo->image_width || 1522*4882a593Smuzhiyun+ dstinfo->jpeg_height != srcinfo->image_height) 1523*4882a593Smuzhiyun+ /* Align data segment to start of TIFF structure for parsing */ 1524*4882a593Smuzhiyun+ adjust_exif_parameters(srcinfo->marker_list->data + 6, 1525*4882a593Smuzhiyun+ srcinfo->marker_list->data_length - 6, 1526*4882a593Smuzhiyun+ dstinfo->jpeg_width, dstinfo->jpeg_height); 1527*4882a593Smuzhiyun+#endif 1528*4882a593Smuzhiyun+ } 1529*4882a593Smuzhiyun+ 1530*4882a593Smuzhiyun /* Return the appropriate output data set */ 1531*4882a593Smuzhiyun if (info->workspace_coef_arrays != NULL) 1532*4882a593Smuzhiyun return info->workspace_coef_arrays; 1533*4882a593Smuzhiyun@@ -816,40 +1448,110 @@ jtransform_adjust_parameters (j_decompre 1534*4882a593Smuzhiyun */ 1535*4882a593Smuzhiyun 1536*4882a593Smuzhiyun GLOBAL(void) 1537*4882a593Smuzhiyun-jtransform_execute_transformation (j_decompress_ptr srcinfo, 1538*4882a593Smuzhiyun- j_compress_ptr dstinfo, 1539*4882a593Smuzhiyun- jvirt_barray_ptr *src_coef_arrays, 1540*4882a593Smuzhiyun- jpeg_transform_info *info) 1541*4882a593Smuzhiyun+jtransform_execute_transform (j_decompress_ptr srcinfo, 1542*4882a593Smuzhiyun+ j_compress_ptr dstinfo, 1543*4882a593Smuzhiyun+ jvirt_barray_ptr *src_coef_arrays, 1544*4882a593Smuzhiyun+ jpeg_transform_info *info) 1545*4882a593Smuzhiyun { 1546*4882a593Smuzhiyun jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; 1547*4882a593Smuzhiyun 1548*4882a593Smuzhiyun+ /* Note: conditions tested here should match those in switch statement 1549*4882a593Smuzhiyun+ * in jtransform_request_workspace() 1550*4882a593Smuzhiyun+ */ 1551*4882a593Smuzhiyun switch (info->transform) { 1552*4882a593Smuzhiyun case JXFORM_NONE: 1553*4882a593Smuzhiyun+ if (info->x_crop_offset != 0 || info->y_crop_offset != 0) 1554*4882a593Smuzhiyun+ do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1555*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1556*4882a593Smuzhiyun break; 1557*4882a593Smuzhiyun case JXFORM_FLIP_H: 1558*4882a593Smuzhiyun- do_flip_h(srcinfo, dstinfo, src_coef_arrays); 1559*4882a593Smuzhiyun+ if (info->y_crop_offset != 0 || info->slow_hflip) 1560*4882a593Smuzhiyun+ do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1561*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1562*4882a593Smuzhiyun+ else 1563*4882a593Smuzhiyun+ do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset, 1564*4882a593Smuzhiyun+ src_coef_arrays); 1565*4882a593Smuzhiyun break; 1566*4882a593Smuzhiyun case JXFORM_FLIP_V: 1567*4882a593Smuzhiyun- do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1568*4882a593Smuzhiyun+ do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1569*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1570*4882a593Smuzhiyun break; 1571*4882a593Smuzhiyun case JXFORM_TRANSPOSE: 1572*4882a593Smuzhiyun- do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1573*4882a593Smuzhiyun+ do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1574*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1575*4882a593Smuzhiyun break; 1576*4882a593Smuzhiyun case JXFORM_TRANSVERSE: 1577*4882a593Smuzhiyun- do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1578*4882a593Smuzhiyun+ do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1579*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1580*4882a593Smuzhiyun break; 1581*4882a593Smuzhiyun case JXFORM_ROT_90: 1582*4882a593Smuzhiyun- do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1583*4882a593Smuzhiyun+ do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1584*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1585*4882a593Smuzhiyun break; 1586*4882a593Smuzhiyun case JXFORM_ROT_180: 1587*4882a593Smuzhiyun- do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1588*4882a593Smuzhiyun+ do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1589*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1590*4882a593Smuzhiyun break; 1591*4882a593Smuzhiyun case JXFORM_ROT_270: 1592*4882a593Smuzhiyun- do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 1593*4882a593Smuzhiyun+ do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset, 1594*4882a593Smuzhiyun+ src_coef_arrays, dst_coef_arrays); 1595*4882a593Smuzhiyun break; 1596*4882a593Smuzhiyun } 1597*4882a593Smuzhiyun } 1598*4882a593Smuzhiyun 1599*4882a593Smuzhiyun+/* jtransform_perfect_transform 1600*4882a593Smuzhiyun+ * 1601*4882a593Smuzhiyun+ * Determine whether lossless transformation is perfectly 1602*4882a593Smuzhiyun+ * possible for a specified image and transformation. 1603*4882a593Smuzhiyun+ * 1604*4882a593Smuzhiyun+ * Inputs: 1605*4882a593Smuzhiyun+ * image_width, image_height: source image dimensions. 1606*4882a593Smuzhiyun+ * MCU_width, MCU_height: pixel dimensions of MCU. 1607*4882a593Smuzhiyun+ * transform: transformation identifier. 1608*4882a593Smuzhiyun+ * Parameter sources from initialized jpeg_struct 1609*4882a593Smuzhiyun+ * (after reading source header): 1610*4882a593Smuzhiyun+ * image_width = cinfo.image_width 1611*4882a593Smuzhiyun+ * image_height = cinfo.image_height 1612*4882a593Smuzhiyun+ * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size 1613*4882a593Smuzhiyun+ * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size 1614*4882a593Smuzhiyun+ * Result: 1615*4882a593Smuzhiyun+ * TRUE = perfect transformation possible 1616*4882a593Smuzhiyun+ * FALSE = perfect transformation not possible 1617*4882a593Smuzhiyun+ * (may use custom action then) 1618*4882a593Smuzhiyun+ */ 1619*4882a593Smuzhiyun+ 1620*4882a593Smuzhiyun+GLOBAL(boolean) 1621*4882a593Smuzhiyun+jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height, 1622*4882a593Smuzhiyun+ int MCU_width, int MCU_height, 1623*4882a593Smuzhiyun+ JXFORM_CODE transform) 1624*4882a593Smuzhiyun+{ 1625*4882a593Smuzhiyun+ boolean result = TRUE; /* initialize TRUE */ 1626*4882a593Smuzhiyun+ 1627*4882a593Smuzhiyun+ switch (transform) { 1628*4882a593Smuzhiyun+ case JXFORM_FLIP_H: 1629*4882a593Smuzhiyun+ case JXFORM_ROT_270: 1630*4882a593Smuzhiyun+ if (image_width % (JDIMENSION) MCU_width) 1631*4882a593Smuzhiyun+ result = FALSE; 1632*4882a593Smuzhiyun+ break; 1633*4882a593Smuzhiyun+ case JXFORM_FLIP_V: 1634*4882a593Smuzhiyun+ case JXFORM_ROT_90: 1635*4882a593Smuzhiyun+ if (image_height % (JDIMENSION) MCU_height) 1636*4882a593Smuzhiyun+ result = FALSE; 1637*4882a593Smuzhiyun+ break; 1638*4882a593Smuzhiyun+ case JXFORM_TRANSVERSE: 1639*4882a593Smuzhiyun+ case JXFORM_ROT_180: 1640*4882a593Smuzhiyun+ if (image_width % (JDIMENSION) MCU_width) 1641*4882a593Smuzhiyun+ result = FALSE; 1642*4882a593Smuzhiyun+ if (image_height % (JDIMENSION) MCU_height) 1643*4882a593Smuzhiyun+ result = FALSE; 1644*4882a593Smuzhiyun+ break; 1645*4882a593Smuzhiyun+ default: 1646*4882a593Smuzhiyun+ break; 1647*4882a593Smuzhiyun+ } 1648*4882a593Smuzhiyun+ 1649*4882a593Smuzhiyun+ return result; 1650*4882a593Smuzhiyun+} 1651*4882a593Smuzhiyun+ 1652*4882a593Smuzhiyun #endif /* TRANSFORMS_SUPPORTED */ 1653*4882a593Smuzhiyun 1654*4882a593Smuzhiyun 1655*4882a593SmuzhiyunIndex: fbida-2.10/jpeg/62/transupp.h 1656*4882a593Smuzhiyun=================================================================== 1657*4882a593Smuzhiyun--- fbida-2.10.orig/jpeg/62/transupp.h 1658*4882a593Smuzhiyun+++ fbida-2.10/jpeg/62/transupp.h 1659*4882a593Smuzhiyun@@ -1,7 +1,7 @@ 1660*4882a593Smuzhiyun /* 1661*4882a593Smuzhiyun * transupp.h 1662*4882a593Smuzhiyun * 1663*4882a593Smuzhiyun- * Copyright (C) 1997, Thomas G. Lane. 1664*4882a593Smuzhiyun+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding. 1665*4882a593Smuzhiyun * This file is part of the Independent JPEG Group's software. 1666*4882a593Smuzhiyun * For conditions of distribution and use, see the accompanying README file. 1667*4882a593Smuzhiyun * 1668*4882a593Smuzhiyun@@ -22,32 +22,6 @@ 1669*4882a593Smuzhiyun #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ 1670*4882a593Smuzhiyun #endif 1671*4882a593Smuzhiyun 1672*4882a593Smuzhiyun-/* Short forms of external names for systems with brain-damaged linkers. */ 1673*4882a593Smuzhiyun- 1674*4882a593Smuzhiyun-#ifdef NEED_SHORT_EXTERNAL_NAMES 1675*4882a593Smuzhiyun-#define jtransform_request_workspace jTrRequest 1676*4882a593Smuzhiyun-#define jtransform_adjust_parameters jTrAdjust 1677*4882a593Smuzhiyun-#define jtransform_execute_transformation jTrExec 1678*4882a593Smuzhiyun-#define jcopy_markers_setup jCMrkSetup 1679*4882a593Smuzhiyun-#define jcopy_markers_execute jCMrkExec 1680*4882a593Smuzhiyun-#endif /* NEED_SHORT_EXTERNAL_NAMES */ 1681*4882a593Smuzhiyun- 1682*4882a593Smuzhiyun- 1683*4882a593Smuzhiyun-/* 1684*4882a593Smuzhiyun- * Codes for supported types of image transformations. 1685*4882a593Smuzhiyun- */ 1686*4882a593Smuzhiyun- 1687*4882a593Smuzhiyun-typedef enum { 1688*4882a593Smuzhiyun- JXFORM_NONE, /* no transformation */ 1689*4882a593Smuzhiyun- JXFORM_FLIP_H, /* horizontal flip */ 1690*4882a593Smuzhiyun- JXFORM_FLIP_V, /* vertical flip */ 1691*4882a593Smuzhiyun- JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ 1692*4882a593Smuzhiyun- JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ 1693*4882a593Smuzhiyun- JXFORM_ROT_90, /* 90-degree clockwise rotation */ 1694*4882a593Smuzhiyun- JXFORM_ROT_180, /* 180-degree rotation */ 1695*4882a593Smuzhiyun- JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ 1696*4882a593Smuzhiyun-} JXFORM_CODE; 1697*4882a593Smuzhiyun- 1698*4882a593Smuzhiyun /* 1699*4882a593Smuzhiyun * Although rotating and flipping data expressed as DCT coefficients is not 1700*4882a593Smuzhiyun * hard, there is an asymmetry in the JPEG format specification for images 1701*4882a593Smuzhiyun@@ -75,6 +49,25 @@ typedef enum { 1702*4882a593Smuzhiyun * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim 1703*4882a593Smuzhiyun * followed by -rot 180 -trim trims both edges.) 1704*4882a593Smuzhiyun * 1705*4882a593Smuzhiyun+ * We also offer a lossless-crop option, which discards data outside a given 1706*4882a593Smuzhiyun+ * image region but losslessly preserves what is inside. Like the rotate and 1707*4882a593Smuzhiyun+ * flip transforms, lossless crop is restricted by the JPEG format: the upper 1708*4882a593Smuzhiyun+ * left corner of the selected region must fall on an iMCU boundary. If this 1709*4882a593Smuzhiyun+ * does not hold for the given crop parameters, we silently move the upper left 1710*4882a593Smuzhiyun+ * corner up and/or left to make it so, simultaneously increasing the region 1711*4882a593Smuzhiyun+ * dimensions to keep the lower right crop corner unchanged. (Thus, the 1712*4882a593Smuzhiyun+ * output image covers at least the requested region, but may cover more.) 1713*4882a593Smuzhiyun+ * The adjustment of the region dimensions may be optionally disabled. 1714*4882a593Smuzhiyun+ * 1715*4882a593Smuzhiyun+ * We also provide a lossless-resize option, which is kind of a lossless-crop 1716*4882a593Smuzhiyun+ * operation in the DCT coefficient block domain - it discards higher-order 1717*4882a593Smuzhiyun+ * coefficients and losslessly preserves lower-order coefficients of a 1718*4882a593Smuzhiyun+ * sub-block. 1719*4882a593Smuzhiyun+ * 1720*4882a593Smuzhiyun+ * Rotate/flip transform, resize, and crop can be requested together in a 1721*4882a593Smuzhiyun+ * single invocation. The crop is applied last --- that is, the crop region 1722*4882a593Smuzhiyun+ * is specified in terms of the destination image after transform/resize. 1723*4882a593Smuzhiyun+ * 1724*4882a593Smuzhiyun * We also offer a "force to grayscale" option, which simply discards the 1725*4882a593Smuzhiyun * chrominance channels of a YCbCr image. This is lossless in the sense that 1726*4882a593Smuzhiyun * the luminance channel is preserved exactly. It's not the same kind of 1727*4882a593Smuzhiyun@@ -83,22 +76,100 @@ typedef enum { 1728*4882a593Smuzhiyun * be aware of the option to know how many components to work on. 1729*4882a593Smuzhiyun */ 1730*4882a593Smuzhiyun 1731*4882a593Smuzhiyun+ 1732*4882a593Smuzhiyun+/* Short forms of external names for systems with brain-damaged linkers. */ 1733*4882a593Smuzhiyun+ 1734*4882a593Smuzhiyun+#ifdef NEED_SHORT_EXTERNAL_NAMES 1735*4882a593Smuzhiyun+#define jtransform_parse_crop_spec jTrParCrop 1736*4882a593Smuzhiyun+#define jtransform_request_workspace jTrRequest 1737*4882a593Smuzhiyun+#define jtransform_adjust_parameters jTrAdjust 1738*4882a593Smuzhiyun+#define jtransform_execute_transform jTrExec 1739*4882a593Smuzhiyun+#define jtransform_perfect_transform jTrPerfect 1740*4882a593Smuzhiyun+#define jcopy_markers_setup jCMrkSetup 1741*4882a593Smuzhiyun+#define jcopy_markers_execute jCMrkExec 1742*4882a593Smuzhiyun+#endif /* NEED_SHORT_EXTERNAL_NAMES */ 1743*4882a593Smuzhiyun+ 1744*4882a593Smuzhiyun+ 1745*4882a593Smuzhiyun+/* 1746*4882a593Smuzhiyun+ * Codes for supported types of image transformations. 1747*4882a593Smuzhiyun+ */ 1748*4882a593Smuzhiyun+ 1749*4882a593Smuzhiyun+typedef enum { 1750*4882a593Smuzhiyun+ JXFORM_NONE, /* no transformation */ 1751*4882a593Smuzhiyun+ JXFORM_FLIP_H, /* horizontal flip */ 1752*4882a593Smuzhiyun+ JXFORM_FLIP_V, /* vertical flip */ 1753*4882a593Smuzhiyun+ JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ 1754*4882a593Smuzhiyun+ JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ 1755*4882a593Smuzhiyun+ JXFORM_ROT_90, /* 90-degree clockwise rotation */ 1756*4882a593Smuzhiyun+ JXFORM_ROT_180, /* 180-degree rotation */ 1757*4882a593Smuzhiyun+ JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ 1758*4882a593Smuzhiyun+} JXFORM_CODE; 1759*4882a593Smuzhiyun+ 1760*4882a593Smuzhiyun+/* 1761*4882a593Smuzhiyun+ * Codes for crop parameters, which can individually be unspecified, 1762*4882a593Smuzhiyun+ * positive or negative for xoffset or yoffset, 1763*4882a593Smuzhiyun+ * positive or forced for width or height. 1764*4882a593Smuzhiyun+ */ 1765*4882a593Smuzhiyun+ 1766*4882a593Smuzhiyun+typedef enum { 1767*4882a593Smuzhiyun+ JCROP_UNSET, 1768*4882a593Smuzhiyun+ JCROP_POS, 1769*4882a593Smuzhiyun+ JCROP_NEG, 1770*4882a593Smuzhiyun+ JCROP_FORCE 1771*4882a593Smuzhiyun+} JCROP_CODE; 1772*4882a593Smuzhiyun+ 1773*4882a593Smuzhiyun+/* 1774*4882a593Smuzhiyun+ * Transform parameters struct. 1775*4882a593Smuzhiyun+ * NB: application must not change any elements of this struct after 1776*4882a593Smuzhiyun+ * calling jtransform_request_workspace. 1777*4882a593Smuzhiyun+ */ 1778*4882a593Smuzhiyun+ 1779*4882a593Smuzhiyun typedef struct { 1780*4882a593Smuzhiyun /* Options: set by caller */ 1781*4882a593Smuzhiyun JXFORM_CODE transform; /* image transform operator */ 1782*4882a593Smuzhiyun+ boolean perfect; /* if TRUE, fail if partial MCUs are requested */ 1783*4882a593Smuzhiyun boolean trim; /* if TRUE, trim partial MCUs as needed */ 1784*4882a593Smuzhiyun boolean force_grayscale; /* if TRUE, convert color image to grayscale */ 1785*4882a593Smuzhiyun+ boolean crop; /* if TRUE, crop source image */ 1786*4882a593Smuzhiyun+ boolean slow_hflip; /* For best performance, the JXFORM_FLIP_H transform 1787*4882a593Smuzhiyun+ normally modifies the source coefficients in place. 1788*4882a593Smuzhiyun+ Setting this to TRUE will instead use a slower, 1789*4882a593Smuzhiyun+ double-buffered algorithm, which leaves the source 1790*4882a593Smuzhiyun+ coefficients in tact (necessary if other transformed 1791*4882a593Smuzhiyun+ images must be generated from the same set of 1792*4882a593Smuzhiyun+ coefficients. */ 1793*4882a593Smuzhiyun+ 1794*4882a593Smuzhiyun+ /* Crop parameters: application need not set these unless crop is TRUE. 1795*4882a593Smuzhiyun+ * These can be filled in by jtransform_parse_crop_spec(). 1796*4882a593Smuzhiyun+ */ 1797*4882a593Smuzhiyun+ JDIMENSION crop_width; /* Width of selected region */ 1798*4882a593Smuzhiyun+ JCROP_CODE crop_width_set; /* (forced disables adjustment) */ 1799*4882a593Smuzhiyun+ JDIMENSION crop_height; /* Height of selected region */ 1800*4882a593Smuzhiyun+ JCROP_CODE crop_height_set; /* (forced disables adjustment) */ 1801*4882a593Smuzhiyun+ JDIMENSION crop_xoffset; /* X offset of selected region */ 1802*4882a593Smuzhiyun+ JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */ 1803*4882a593Smuzhiyun+ JDIMENSION crop_yoffset; /* Y offset of selected region */ 1804*4882a593Smuzhiyun+ JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */ 1805*4882a593Smuzhiyun 1806*4882a593Smuzhiyun /* Internal workspace: caller should not touch these */ 1807*4882a593Smuzhiyun int num_components; /* # of components in workspace */ 1808*4882a593Smuzhiyun jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ 1809*4882a593Smuzhiyun+ JDIMENSION output_width; /* cropped destination dimensions */ 1810*4882a593Smuzhiyun+ JDIMENSION output_height; 1811*4882a593Smuzhiyun+ JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */ 1812*4882a593Smuzhiyun+ JDIMENSION y_crop_offset; 1813*4882a593Smuzhiyun+ int iMCU_sample_width; /* destination iMCU size */ 1814*4882a593Smuzhiyun+ int iMCU_sample_height; 1815*4882a593Smuzhiyun } jpeg_transform_info; 1816*4882a593Smuzhiyun 1817*4882a593Smuzhiyun 1818*4882a593Smuzhiyun #if TRANSFORMS_SUPPORTED 1819*4882a593Smuzhiyun 1820*4882a593Smuzhiyun+/* Parse a crop specification (written in X11 geometry style) */ 1821*4882a593Smuzhiyun+EXTERN(boolean) jtransform_parse_crop_spec 1822*4882a593Smuzhiyun+ JPP((jpeg_transform_info *info, const char *spec)); 1823*4882a593Smuzhiyun /* Request any required workspace */ 1824*4882a593Smuzhiyun-EXTERN(void) jtransform_request_workspace 1825*4882a593Smuzhiyun+EXTERN(boolean) jtransform_request_workspace 1826*4882a593Smuzhiyun JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); 1827*4882a593Smuzhiyun /* Adjust output image parameters */ 1828*4882a593Smuzhiyun EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters 1829*4882a593Smuzhiyun@@ -106,10 +177,24 @@ EXTERN(jvirt_barray_ptr *) jtransform_ad 1830*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 1831*4882a593Smuzhiyun jpeg_transform_info *info)); 1832*4882a593Smuzhiyun /* Execute the actual transformation, if any */ 1833*4882a593Smuzhiyun-EXTERN(void) jtransform_execute_transformation 1834*4882a593Smuzhiyun+EXTERN(void) jtransform_execute_transform 1835*4882a593Smuzhiyun JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 1836*4882a593Smuzhiyun jvirt_barray_ptr *src_coef_arrays, 1837*4882a593Smuzhiyun jpeg_transform_info *info)); 1838*4882a593Smuzhiyun+/* Determine whether lossless transformation is perfectly 1839*4882a593Smuzhiyun+ * possible for a specified image and transformation. 1840*4882a593Smuzhiyun+ */ 1841*4882a593Smuzhiyun+EXTERN(boolean) jtransform_perfect_transform 1842*4882a593Smuzhiyun+ JPP((JDIMENSION image_width, JDIMENSION image_height, 1843*4882a593Smuzhiyun+ int MCU_width, int MCU_height, 1844*4882a593Smuzhiyun+ JXFORM_CODE transform)); 1845*4882a593Smuzhiyun+ 1846*4882a593Smuzhiyun+/* jtransform_execute_transform used to be called 1847*4882a593Smuzhiyun+ * jtransform_execute_transformation, but some compilers complain about 1848*4882a593Smuzhiyun+ * routine names that long. This macro is here to avoid breaking any 1849*4882a593Smuzhiyun+ * old source code that uses the original name... 1850*4882a593Smuzhiyun+ */ 1851*4882a593Smuzhiyun+#define jtransform_execute_transformation jtransform_execute_transform 1852*4882a593Smuzhiyun 1853*4882a593Smuzhiyun #endif /* TRANSFORMS_SUPPORTED */ 1854*4882a593Smuzhiyun 1855