File indexing completed on 2025-01-19 03:55:52
0001 /* 0002 * transupp.c 0003 * 0004 * SPDX-FileCopyrightText: 1997, Thomas G. Lane. 0005 * This file is part of the Independent JPEG Group's software. 0006 * For conditions of distribution and use, see the accompanying README file. 0007 * 0008 * This file contains image transformation routines and other utility code 0009 * used by the jpegtran sample application. These are NOT part of the core 0010 * JPEG library. But we keep these routines separate from jpegtran.c to 0011 * ease the task of maintaining jpegtran-like programs that have other user 0012 * interfaces. 0013 */ 0014 0015 /* Although this file really shouldn't have access to the library internals, 0016 * it's helpful to let it call jround_up() and jcopy_block_row(). 0017 */ 0018 #define JPEG_INTERNALS 0019 0020 #include "jinclude.h" 0021 #include "jpeglib.h" 0022 #include "transupp.h" /* My own external interface */ 0023 0024 0025 #if TRANSFORMS_SUPPORTED 0026 0027 /* 0028 * Lossless image transformation routines. These routines work on DCT 0029 * coefficient arrays and thus do not require any lossy decompression 0030 * or recompression of the image. 0031 * Thanks to Guido Vollbeding for the initial design and code of this feature. 0032 * 0033 * Horizontal flipping is done in-place, using a single top-to-bottom 0034 * pass through the virtual source array. It will thus be much the 0035 * fastest option for images larger than main memory. 0036 * 0037 * The other routines require a set of destination virtual arrays, so they 0038 * need twice as much memory as jpegtran normally does. The destination 0039 * arrays are always written in normal scan order (top to bottom) because 0040 * the virtual array manager expects this. The source arrays will be scanned 0041 * in the corresponding order, which means multiple passes through the source 0042 * arrays for most of the transforms. That could result in much thrashing 0043 * if the image is larger than main memory. 0044 * 0045 * Some notes about the operating environment of the individual transform 0046 * routines: 0047 * 1. Both the source and destination virtual arrays are allocated from the 0048 * source JPEG object, and therefore should be manipulated by calling the 0049 * source's memory manager. 0050 * 2. The destination's component count should be used. It may be smaller 0051 * than the source's when forcing to grayscale. 0052 * 3. Likewise the destination's sampling factors should be used. When 0053 * forcing to grayscale the destination's sampling factors will be all 1, 0054 * and we may as well take that as the effective iMCU size. 0055 * 4. When "trim" is in effect, the destination's dimensions will be the 0056 * trimmed values but the source's will be untrimmed. 0057 * 5. All the routines assume that the source and destination buffers are 0058 * padded out to a full iMCU boundary. This is true, although for the 0059 * source buffer it is an undocumented property of jdcoefct.c. 0060 * Notes 2,3,4 boil down to this: generally we should use the destination's 0061 * dimensions and ignore the source's. 0062 */ 0063 0064 0065 LOCAL(void) 0066 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0067 jvirt_barray_ptr *src_coef_arrays) 0068 /* Horizontal flip; done in-place, so no separate dest array is required */ 0069 { 0070 JDIMENSION MCU_cols, comp_width, blk_x, blk_y; 0071 int ci, k, offset_y; 0072 JBLOCKARRAY buffer; 0073 JCOEFPTR ptr1, ptr2; 0074 JCOEF temp1, temp2; 0075 jpeg_component_info *compptr; 0076 0077 /* Horizontal mirroring of DCT blocks is accomplished by swapping 0078 * pairs of blocks in-place. Within a DCT block, we perform horizontal 0079 * mirroring by changing the signs of odd-numbered columns. 0080 * Partial iMCUs at the right edge are left untouched. 0081 */ 0082 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 0083 0084 for (ci = 0; ci < dstinfo->num_components; ci++) { 0085 compptr = dstinfo->comp_info + ci; 0086 comp_width = MCU_cols * compptr->h_samp_factor; 0087 for (blk_y = 0; blk_y < compptr->height_in_blocks; 0088 blk_y += compptr->v_samp_factor) { 0089 buffer = (*srcinfo->mem->access_virt_barray) 0090 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, 0091 (JDIMENSION) compptr->v_samp_factor, TRUE); 0092 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0093 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { 0094 ptr1 = buffer[offset_y][blk_x]; 0095 ptr2 = buffer[offset_y][comp_width - blk_x - 1]; 0096 /* this unrolled loop doesn't need to know which row it's on... */ 0097 for (k = 0; k < DCTSIZE2; k += 2) { 0098 temp1 = *ptr1; /* swap even column */ 0099 temp2 = *ptr2; 0100 *ptr1++ = temp2; 0101 *ptr2++ = temp1; 0102 temp1 = *ptr1; /* swap odd column with sign change */ 0103 temp2 = *ptr2; 0104 *ptr1++ = -temp2; 0105 *ptr2++ = -temp1; 0106 } 0107 } 0108 } 0109 } 0110 } 0111 } 0112 0113 0114 LOCAL(void) 0115 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0116 jvirt_barray_ptr *src_coef_arrays, 0117 jvirt_barray_ptr *dst_coef_arrays) 0118 /* Vertical flip */ 0119 { 0120 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 0121 int ci, i, j, offset_y; 0122 JBLOCKARRAY src_buffer, dst_buffer; 0123 JBLOCKROW src_row_ptr, dst_row_ptr; 0124 JCOEFPTR src_ptr, dst_ptr; 0125 jpeg_component_info *compptr; 0126 0127 /* We output into a separate array because we can't touch different 0128 * rows of the source virtual array simultaneously. Otherwise, this 0129 * is a pretty straightforward analog of horizontal flip. 0130 * Within a DCT block, vertical mirroring is done by changing the signs 0131 * of odd-numbered rows. 0132 * Partial iMCUs at the bottom edge are copied verbatim. 0133 */ 0134 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 0135 0136 for (ci = 0; ci < dstinfo->num_components; ci++) { 0137 compptr = dstinfo->comp_info + ci; 0138 comp_height = MCU_rows * compptr->v_samp_factor; 0139 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0140 dst_blk_y += compptr->v_samp_factor) { 0141 dst_buffer = (*srcinfo->mem->access_virt_barray) 0142 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0143 (JDIMENSION) compptr->v_samp_factor, TRUE); 0144 if (dst_blk_y < comp_height) { 0145 /* Row is within the mirrorable area. */ 0146 src_buffer = (*srcinfo->mem->access_virt_barray) 0147 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 0148 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 0149 (JDIMENSION) compptr->v_samp_factor, FALSE); 0150 } else { 0151 /* Bottom-edge blocks will be copied verbatim. */ 0152 src_buffer = (*srcinfo->mem->access_virt_barray) 0153 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 0154 (JDIMENSION) compptr->v_samp_factor, FALSE); 0155 } 0156 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0157 if (dst_blk_y < comp_height) { 0158 /* Row is within the mirrorable area. */ 0159 dst_row_ptr = dst_buffer[offset_y]; 0160 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 0161 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 0162 dst_blk_x++) { 0163 dst_ptr = dst_row_ptr[dst_blk_x]; 0164 src_ptr = src_row_ptr[dst_blk_x]; 0165 for (i = 0; i < DCTSIZE; i += 2) { 0166 /* copy even row */ 0167 for (j = 0; j < DCTSIZE; j++) 0168 *dst_ptr++ = *src_ptr++; 0169 /* copy odd row with sign change */ 0170 for (j = 0; j < DCTSIZE; j++) 0171 *dst_ptr++ = - *src_ptr++; 0172 } 0173 } 0174 } else { 0175 /* Just copy row verbatim. */ 0176 jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], 0177 compptr->width_in_blocks); 0178 } 0179 } 0180 } 0181 } 0182 } 0183 0184 0185 LOCAL(void) 0186 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0187 jvirt_barray_ptr *src_coef_arrays, 0188 jvirt_barray_ptr *dst_coef_arrays) 0189 /* Transpose source into destination */ 0190 { 0191 JDIMENSION dst_blk_x, dst_blk_y; 0192 int ci, i, j, offset_x, offset_y; 0193 JBLOCKARRAY src_buffer, dst_buffer; 0194 JCOEFPTR src_ptr, dst_ptr; 0195 jpeg_component_info *compptr; 0196 0197 /* Transposing pixels within a block just requires transposing the 0198 * DCT coefficients. 0199 * Partial iMCUs at the edges require no special treatment; we simply 0200 * process all the available DCT blocks for every component. 0201 */ 0202 for (ci = 0; ci < dstinfo->num_components; ci++) { 0203 compptr = dstinfo->comp_info + ci; 0204 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0205 dst_blk_y += compptr->v_samp_factor) { 0206 dst_buffer = (*srcinfo->mem->access_virt_barray) 0207 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0208 (JDIMENSION) compptr->v_samp_factor, TRUE); 0209 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0210 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 0211 dst_blk_x += compptr->h_samp_factor) { 0212 src_buffer = (*srcinfo->mem->access_virt_barray) 0213 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 0214 (JDIMENSION) compptr->h_samp_factor, FALSE); 0215 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 0216 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 0217 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 0218 for (i = 0; i < DCTSIZE; i++) 0219 for (j = 0; j < DCTSIZE; j++) 0220 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0221 } 0222 } 0223 } 0224 } 0225 } 0226 } 0227 0228 0229 LOCAL(void) 0230 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0231 jvirt_barray_ptr *src_coef_arrays, 0232 jvirt_barray_ptr *dst_coef_arrays) 0233 /* 90 degree rotation is equivalent to 0234 * 1. Transposing the image; 0235 * 2. Horizontal mirroring. 0236 * These two steps are merged into a single processing routine. 0237 */ 0238 { 0239 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 0240 int ci, i, j, offset_x, offset_y; 0241 JBLOCKARRAY src_buffer, dst_buffer; 0242 JCOEFPTR src_ptr, dst_ptr; 0243 jpeg_component_info *compptr; 0244 0245 /* Because of the horizontal mirror step, we can't process partial iMCUs 0246 * at the (output) right edge properly. They just get transposed and 0247 * not mirrored. 0248 */ 0249 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 0250 0251 for (ci = 0; ci < dstinfo->num_components; ci++) { 0252 compptr = dstinfo->comp_info + ci; 0253 comp_width = MCU_cols * compptr->h_samp_factor; 0254 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0255 dst_blk_y += compptr->v_samp_factor) { 0256 dst_buffer = (*srcinfo->mem->access_virt_barray) 0257 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0258 (JDIMENSION) compptr->v_samp_factor, TRUE); 0259 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0260 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 0261 dst_blk_x += compptr->h_samp_factor) { 0262 src_buffer = (*srcinfo->mem->access_virt_barray) 0263 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 0264 (JDIMENSION) compptr->h_samp_factor, FALSE); 0265 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 0266 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 0267 if (dst_blk_x < comp_width) { 0268 /* Block is within the mirrorable area. */ 0269 dst_ptr = dst_buffer[offset_y] 0270 [comp_width - dst_blk_x - offset_x - 1]; 0271 for (i = 0; i < DCTSIZE; i++) { 0272 for (j = 0; j < DCTSIZE; j++) 0273 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0274 i++; 0275 for (j = 0; j < DCTSIZE; j++) 0276 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0277 } 0278 } else { 0279 /* Edge blocks are transposed but not mirrored. */ 0280 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 0281 for (i = 0; i < DCTSIZE; i++) 0282 for (j = 0; j < DCTSIZE; j++) 0283 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0284 } 0285 } 0286 } 0287 } 0288 } 0289 } 0290 } 0291 0292 0293 LOCAL(void) 0294 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0295 jvirt_barray_ptr *src_coef_arrays, 0296 jvirt_barray_ptr *dst_coef_arrays) 0297 /* 270 degree rotation is equivalent to 0298 * 1. Horizontal mirroring; 0299 * 2. Transposing the image. 0300 * These two steps are merged into a single processing routine. 0301 */ 0302 { 0303 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 0304 int ci, i, j, offset_x, offset_y; 0305 JBLOCKARRAY src_buffer, dst_buffer; 0306 JCOEFPTR src_ptr, dst_ptr; 0307 jpeg_component_info *compptr; 0308 0309 /* Because of the horizontal mirror step, we can't process partial iMCUs 0310 * at the (output) bottom edge properly. They just get transposed and 0311 * not mirrored. 0312 */ 0313 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 0314 0315 for (ci = 0; ci < dstinfo->num_components; ci++) { 0316 compptr = dstinfo->comp_info + ci; 0317 comp_height = MCU_rows * compptr->v_samp_factor; 0318 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0319 dst_blk_y += compptr->v_samp_factor) { 0320 dst_buffer = (*srcinfo->mem->access_virt_barray) 0321 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0322 (JDIMENSION) compptr->v_samp_factor, TRUE); 0323 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0324 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 0325 dst_blk_x += compptr->h_samp_factor) { 0326 src_buffer = (*srcinfo->mem->access_virt_barray) 0327 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 0328 (JDIMENSION) compptr->h_samp_factor, FALSE); 0329 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 0330 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 0331 if (dst_blk_y < comp_height) { 0332 /* Block is within the mirrorable area. */ 0333 src_ptr = src_buffer[offset_x] 0334 [comp_height - dst_blk_y - offset_y - 1]; 0335 for (i = 0; i < DCTSIZE; i++) { 0336 for (j = 0; j < DCTSIZE; j++) { 0337 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0338 j++; 0339 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0340 } 0341 } 0342 } else { 0343 /* Edge blocks are transposed but not mirrored. */ 0344 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 0345 for (i = 0; i < DCTSIZE; i++) 0346 for (j = 0; j < DCTSIZE; j++) 0347 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0348 } 0349 } 0350 } 0351 } 0352 } 0353 } 0354 } 0355 0356 0357 LOCAL(void) 0358 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0359 jvirt_barray_ptr *src_coef_arrays, 0360 jvirt_barray_ptr *dst_coef_arrays) 0361 /* 180 degree rotation is equivalent to 0362 * 1. Vertical mirroring; 0363 * 2. Horizontal mirroring. 0364 * These two steps are merged into a single processing routine. 0365 */ 0366 { 0367 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 0368 int ci, i, j, offset_y; 0369 JBLOCKARRAY src_buffer, dst_buffer; 0370 JBLOCKROW src_row_ptr, dst_row_ptr; 0371 JCOEFPTR src_ptr, dst_ptr; 0372 jpeg_component_info *compptr; 0373 0374 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 0375 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 0376 0377 for (ci = 0; ci < dstinfo->num_components; ci++) { 0378 compptr = dstinfo->comp_info + ci; 0379 comp_width = MCU_cols * compptr->h_samp_factor; 0380 comp_height = MCU_rows * compptr->v_samp_factor; 0381 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0382 dst_blk_y += compptr->v_samp_factor) { 0383 dst_buffer = (*srcinfo->mem->access_virt_barray) 0384 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0385 (JDIMENSION) compptr->v_samp_factor, TRUE); 0386 if (dst_blk_y < comp_height) { 0387 /* Row is within the vertically mirrorable area. */ 0388 src_buffer = (*srcinfo->mem->access_virt_barray) 0389 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 0390 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 0391 (JDIMENSION) compptr->v_samp_factor, FALSE); 0392 } else { 0393 /* Bottom-edge rows are only mirrored horizontally. */ 0394 src_buffer = (*srcinfo->mem->access_virt_barray) 0395 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 0396 (JDIMENSION) compptr->v_samp_factor, FALSE); 0397 } 0398 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0399 if (dst_blk_y < comp_height) { 0400 /* Row is within the mirrorable area. */ 0401 dst_row_ptr = dst_buffer[offset_y]; 0402 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 0403 /* Process the blocks that can be mirrored both ways. */ 0404 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 0405 dst_ptr = dst_row_ptr[dst_blk_x]; 0406 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 0407 for (i = 0; i < DCTSIZE; i += 2) { 0408 /* For even row, negate every odd column. */ 0409 for (j = 0; j < DCTSIZE; j += 2) { 0410 *dst_ptr++ = *src_ptr++; 0411 *dst_ptr++ = - *src_ptr++; 0412 } 0413 /* For odd row, negate every even column. */ 0414 for (j = 0; j < DCTSIZE; j += 2) { 0415 *dst_ptr++ = - *src_ptr++; 0416 *dst_ptr++ = *src_ptr++; 0417 } 0418 } 0419 } 0420 /* Any remaining right-edge blocks are only mirrored vertically. */ 0421 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 0422 dst_ptr = dst_row_ptr[dst_blk_x]; 0423 src_ptr = src_row_ptr[dst_blk_x]; 0424 for (i = 0; i < DCTSIZE; i += 2) { 0425 for (j = 0; j < DCTSIZE; j++) 0426 *dst_ptr++ = *src_ptr++; 0427 for (j = 0; j < DCTSIZE; j++) 0428 *dst_ptr++ = - *src_ptr++; 0429 } 0430 } 0431 } else { 0432 /* Remaining rows are just mirrored horizontally. */ 0433 dst_row_ptr = dst_buffer[offset_y]; 0434 src_row_ptr = src_buffer[offset_y]; 0435 /* Process the blocks that can be mirrored. */ 0436 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 0437 dst_ptr = dst_row_ptr[dst_blk_x]; 0438 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 0439 for (i = 0; i < DCTSIZE2; i += 2) { 0440 *dst_ptr++ = *src_ptr++; 0441 *dst_ptr++ = - *src_ptr++; 0442 } 0443 } 0444 /* Any remaining right-edge blocks are only copied. */ 0445 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 0446 dst_ptr = dst_row_ptr[dst_blk_x]; 0447 src_ptr = src_row_ptr[dst_blk_x]; 0448 for (i = 0; i < DCTSIZE2; i++) 0449 *dst_ptr++ = *src_ptr++; 0450 } 0451 } 0452 } 0453 } 0454 } 0455 } 0456 0457 0458 LOCAL(void) 0459 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0460 jvirt_barray_ptr *src_coef_arrays, 0461 jvirt_barray_ptr *dst_coef_arrays) 0462 /* Transverse transpose is equivalent to 0463 * 1. 180 degree rotation; 0464 * 2. Transposition; 0465 * or 0466 * 1. Horizontal mirroring; 0467 * 2. Transposition; 0468 * 3. Horizontal mirroring. 0469 * These steps are merged into a single processing routine. 0470 */ 0471 { 0472 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 0473 int ci, i, j, offset_x, offset_y; 0474 JBLOCKARRAY src_buffer, dst_buffer; 0475 JCOEFPTR src_ptr, dst_ptr; 0476 jpeg_component_info *compptr; 0477 0478 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 0479 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 0480 0481 for (ci = 0; ci < dstinfo->num_components; ci++) { 0482 compptr = dstinfo->comp_info + ci; 0483 comp_width = MCU_cols * compptr->h_samp_factor; 0484 comp_height = MCU_rows * compptr->v_samp_factor; 0485 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 0486 dst_blk_y += compptr->v_samp_factor) { 0487 dst_buffer = (*srcinfo->mem->access_virt_barray) 0488 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 0489 (JDIMENSION) compptr->v_samp_factor, TRUE); 0490 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 0491 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 0492 dst_blk_x += compptr->h_samp_factor) { 0493 src_buffer = (*srcinfo->mem->access_virt_barray) 0494 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 0495 (JDIMENSION) compptr->h_samp_factor, FALSE); 0496 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 0497 if (dst_blk_y < comp_height) { 0498 src_ptr = src_buffer[offset_x] 0499 [comp_height - dst_blk_y - offset_y - 1]; 0500 if (dst_blk_x < comp_width) { 0501 /* Block is within the mirrorable area. */ 0502 dst_ptr = dst_buffer[offset_y] 0503 [comp_width - dst_blk_x - offset_x - 1]; 0504 for (i = 0; i < DCTSIZE; i++) { 0505 for (j = 0; j < DCTSIZE; j++) { 0506 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0507 j++; 0508 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0509 } 0510 i++; 0511 for (j = 0; j < DCTSIZE; j++) { 0512 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0513 j++; 0514 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0515 } 0516 } 0517 } else { 0518 /* Right-edge blocks are mirrored in y only */ 0519 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 0520 for (i = 0; i < DCTSIZE; i++) { 0521 for (j = 0; j < DCTSIZE; j++) { 0522 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0523 j++; 0524 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0525 } 0526 } 0527 } 0528 } else { 0529 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 0530 if (dst_blk_x < comp_width) { 0531 /* Bottom-edge blocks are mirrored in x only */ 0532 dst_ptr = dst_buffer[offset_y] 0533 [comp_width - dst_blk_x - offset_x - 1]; 0534 for (i = 0; i < DCTSIZE; i++) { 0535 for (j = 0; j < DCTSIZE; j++) 0536 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0537 i++; 0538 for (j = 0; j < DCTSIZE; j++) 0539 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 0540 } 0541 } else { 0542 /* At lower right corner, just transpose, no mirroring */ 0543 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 0544 for (i = 0; i < DCTSIZE; i++) 0545 for (j = 0; j < DCTSIZE; j++) 0546 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 0547 } 0548 } 0549 } 0550 } 0551 } 0552 } 0553 } 0554 } 0555 0556 0557 /* Request any required workspace. 0558 * 0559 * We allocate the workspace virtual arrays from the source decompression 0560 * object, so that all the arrays (both the original data and the workspace) 0561 * will be taken into account while making memory management decisions. 0562 * Hence, this routine must be called after jpeg_read_header (which reads 0563 * the image dimensions) and before jpeg_read_coefficients (which realizes 0564 * the source's virtual arrays). 0565 */ 0566 0567 GLOBAL(void) 0568 jtransform_request_workspace (j_decompress_ptr srcinfo, 0569 jpeg_transform_info *info) 0570 { 0571 jvirt_barray_ptr *coef_arrays = NULL; 0572 jpeg_component_info *compptr; 0573 int ci; 0574 0575 if (info->force_grayscale && 0576 srcinfo->jpeg_color_space == JCS_YCbCr && 0577 srcinfo->num_components == 3) { 0578 /* We'll only process the first component */ 0579 info->num_components = 1; 0580 } else { 0581 /* Process all the components */ 0582 info->num_components = srcinfo->num_components; 0583 } 0584 0585 switch (info->transform) { 0586 case JXFORM_NONE: 0587 case JXFORM_FLIP_H: 0588 /* Don't need a workspace array */ 0589 break; 0590 case JXFORM_FLIP_V: 0591 case JXFORM_ROT_180: 0592 /* Need workspace arrays having same dimensions as source image. 0593 * Note that we allocate arrays padded out to the next iMCU boundary, 0594 * so that transform routines need not worry about missing edge blocks. 0595 */ 0596 coef_arrays = (jvirt_barray_ptr *) 0597 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 0598 SIZEOF(jvirt_barray_ptr) * info->num_components); 0599 for (ci = 0; ci < info->num_components; ci++) { 0600 compptr = srcinfo->comp_info + ci; 0601 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 0602 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 0603 (JDIMENSION) jround_up((long) compptr->width_in_blocks, 0604 (long) compptr->h_samp_factor), 0605 (JDIMENSION) jround_up((long) compptr->height_in_blocks, 0606 (long) compptr->v_samp_factor), 0607 (JDIMENSION) compptr->v_samp_factor); 0608 } 0609 break; 0610 case JXFORM_TRANSPOSE: 0611 case JXFORM_TRANSVERSE: 0612 case JXFORM_ROT_90: 0613 case JXFORM_ROT_270: 0614 /* Need workspace arrays having transposed dimensions. 0615 * Note that we allocate arrays padded out to the next iMCU boundary, 0616 * so that transform routines need not worry about missing edge blocks. 0617 */ 0618 coef_arrays = (jvirt_barray_ptr *) 0619 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 0620 SIZEOF(jvirt_barray_ptr) * info->num_components); 0621 for (ci = 0; ci < info->num_components; ci++) { 0622 compptr = srcinfo->comp_info + ci; 0623 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 0624 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 0625 (JDIMENSION) jround_up((long) compptr->height_in_blocks, 0626 (long) compptr->v_samp_factor), 0627 (JDIMENSION) jround_up((long) compptr->width_in_blocks, 0628 (long) compptr->h_samp_factor), 0629 (JDIMENSION) compptr->h_samp_factor); 0630 } 0631 break; 0632 } 0633 info->workspace_coef_arrays = coef_arrays; 0634 } 0635 0636 0637 /* Transpose destination image parameters */ 0638 0639 LOCAL(void) 0640 transpose_critical_parameters (j_compress_ptr dstinfo) 0641 { 0642 int tblno, i, j, ci, itemp; 0643 jpeg_component_info *compptr; 0644 JQUANT_TBL *qtblptr; 0645 JDIMENSION dtemp; 0646 UINT16 qtemp; 0647 0648 /* Transpose basic image dimensions */ 0649 dtemp = dstinfo->image_width; 0650 dstinfo->image_width = dstinfo->image_height; 0651 dstinfo->image_height = dtemp; 0652 0653 /* Transpose sampling factors */ 0654 for (ci = 0; ci < dstinfo->num_components; ci++) { 0655 compptr = dstinfo->comp_info + ci; 0656 itemp = compptr->h_samp_factor; 0657 compptr->h_samp_factor = compptr->v_samp_factor; 0658 compptr->v_samp_factor = itemp; 0659 } 0660 0661 /* Transpose quantization tables */ 0662 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { 0663 qtblptr = dstinfo->quant_tbl_ptrs[tblno]; 0664 if (qtblptr != NULL) { 0665 for (i = 0; i < DCTSIZE; i++) { 0666 for (j = 0; j < i; j++) { 0667 qtemp = qtblptr->quantval[i*DCTSIZE+j]; 0668 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; 0669 qtblptr->quantval[j*DCTSIZE+i] = qtemp; 0670 } 0671 } 0672 } 0673 } 0674 } 0675 0676 0677 /* Trim off any partial iMCUs on the indicated destination edge */ 0678 0679 LOCAL(void) 0680 trim_right_edge (j_compress_ptr dstinfo) 0681 { 0682 int ci, max_h_samp_factor; 0683 JDIMENSION MCU_cols; 0684 0685 /* We have to compute max_h_samp_factor ourselves, 0686 * because it hasn't been set yet in the destination 0687 * (and we don't want to use the source's value). 0688 */ 0689 max_h_samp_factor = 1; 0690 for (ci = 0; ci < dstinfo->num_components; ci++) { 0691 int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; 0692 max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); 0693 } 0694 MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); 0695 if (MCU_cols > 0) /* can't trim to 0 pixels */ 0696 dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); 0697 } 0698 0699 LOCAL(void) 0700 trim_bottom_edge (j_compress_ptr dstinfo) 0701 { 0702 int ci, max_v_samp_factor; 0703 JDIMENSION MCU_rows; 0704 0705 /* We have to compute max_v_samp_factor ourselves, 0706 * because it hasn't been set yet in the destination 0707 * (and we don't want to use the source's value). 0708 */ 0709 max_v_samp_factor = 1; 0710 for (ci = 0; ci < dstinfo->num_components; ci++) { 0711 int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; 0712 max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); 0713 } 0714 MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); 0715 if (MCU_rows > 0) /* can't trim to 0 pixels */ 0716 dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); 0717 } 0718 0719 0720 /* Adjust output image parameters as needed. 0721 * 0722 * This must be called after jpeg_copy_critical_parameters() 0723 * and before jpeg_write_coefficients(). 0724 * 0725 * The return value is the set of virtual coefficient arrays to be written 0726 * (either the ones allocated by jtransform_request_workspace, or the 0727 * original source data arrays). The caller will need to pass this value 0728 * to jpeg_write_coefficients(). 0729 */ 0730 0731 GLOBAL(jvirt_barray_ptr *) 0732 jtransform_adjust_parameters (j_decompress_ptr srcinfo, 0733 j_compress_ptr dstinfo, 0734 jvirt_barray_ptr *src_coef_arrays, 0735 jpeg_transform_info *info) 0736 { 0737 /* If force-to-grayscale is requested, adjust destination parameters */ 0738 if (info->force_grayscale) { 0739 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 0740 * properly. Among other things, the target h_samp_factor & v_samp_factor 0741 * will get set to 1, which typically won't match the source. 0742 * In fact we do this even if the source is already grayscale; that 0743 * provides an easy way of coercing a grayscale JPEG with funny sampling 0744 * factors to the customary 1,1. (Some decoders fail on other factors.) 0745 */ 0746 if ((dstinfo->jpeg_color_space == JCS_YCbCr && 0747 dstinfo->num_components == 3) || 0748 (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 0749 dstinfo->num_components == 1)) { 0750 /* We have to preserve the source's quantization table number. */ 0751 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; 0752 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); 0753 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; 0754 } else { 0755 /* Sorry, can't do it */ 0756 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); 0757 } 0758 } 0759 0760 /* Correct the destination's image dimensions etc if necessary */ 0761 switch (info->transform) { 0762 case JXFORM_NONE: 0763 /* Nothing to do */ 0764 break; 0765 case JXFORM_FLIP_H: 0766 if (info->trim) 0767 trim_right_edge(dstinfo); 0768 break; 0769 case JXFORM_FLIP_V: 0770 if (info->trim) 0771 trim_bottom_edge(dstinfo); 0772 break; 0773 case JXFORM_TRANSPOSE: 0774 transpose_critical_parameters(dstinfo); 0775 /* transpose does NOT have to trim anything */ 0776 break; 0777 case JXFORM_TRANSVERSE: 0778 transpose_critical_parameters(dstinfo); 0779 if (info->trim) { 0780 trim_right_edge(dstinfo); 0781 trim_bottom_edge(dstinfo); 0782 } 0783 break; 0784 case JXFORM_ROT_90: 0785 transpose_critical_parameters(dstinfo); 0786 if (info->trim) 0787 trim_right_edge(dstinfo); 0788 break; 0789 case JXFORM_ROT_180: 0790 if (info->trim) { 0791 trim_right_edge(dstinfo); 0792 trim_bottom_edge(dstinfo); 0793 } 0794 break; 0795 case JXFORM_ROT_270: 0796 transpose_critical_parameters(dstinfo); 0797 if (info->trim) 0798 trim_bottom_edge(dstinfo); 0799 break; 0800 } 0801 0802 /* Return the appropriate output data set */ 0803 if (info->workspace_coef_arrays != NULL) 0804 return info->workspace_coef_arrays; 0805 return src_coef_arrays; 0806 } 0807 0808 0809 /* Execute the actual transformation, if any. 0810 * 0811 * This must be called *after* jpeg_write_coefficients, because it depends 0812 * on jpeg_write_coefficients to have computed subsidiary values such as 0813 * the per-component width and height fields in the destination object. 0814 * 0815 * Note that some transformations will modify the source data arrays! 0816 */ 0817 0818 GLOBAL(void) 0819 jtransform_execute_transformation (j_decompress_ptr srcinfo, 0820 j_compress_ptr dstinfo, 0821 jvirt_barray_ptr *src_coef_arrays, 0822 jpeg_transform_info *info) 0823 { 0824 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; 0825 0826 switch (info->transform) { 0827 case JXFORM_NONE: 0828 break; 0829 case JXFORM_FLIP_H: 0830 do_flip_h(srcinfo, dstinfo, src_coef_arrays); 0831 break; 0832 case JXFORM_FLIP_V: 0833 do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0834 break; 0835 case JXFORM_TRANSPOSE: 0836 do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0837 break; 0838 case JXFORM_TRANSVERSE: 0839 do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0840 break; 0841 case JXFORM_ROT_90: 0842 do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0843 break; 0844 case JXFORM_ROT_180: 0845 do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0846 break; 0847 case JXFORM_ROT_270: 0848 do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 0849 break; 0850 } 0851 } 0852 0853 #endif /* TRANSFORMS_SUPPORTED */ 0854 0855 0856 /* Setup decompression object to save desired markers in memory. 0857 * This must be called before jpeg_read_header() to have the desired effect. 0858 */ 0859 0860 GLOBAL(void) 0861 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) 0862 { 0863 #ifdef SAVE_MARKERS_SUPPORTED 0864 int m; 0865 0866 /* Save comments except under NONE option */ 0867 if (option != JCOPYOPT_NONE) { 0868 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); 0869 } 0870 /* Save all types of APPn markers iff ALL option */ 0871 if (option == JCOPYOPT_ALL) { 0872 for (m = 0; m < 16; m++) 0873 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); 0874 } 0875 #endif /* SAVE_MARKERS_SUPPORTED */ 0876 } 0877 0878 /* Copy markers saved in the given source object to the destination object. 0879 * This should be called just after jpeg_start_compress() or 0880 * jpeg_write_coefficients(). 0881 * Note that those routines will have written the SOI, and also the 0882 * JFIF APP0 or Adobe APP14 markers if selected. 0883 */ 0884 0885 GLOBAL(void) 0886 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 0887 JCOPY_OPTION option) 0888 { 0889 jpeg_saved_marker_ptr marker; 0890 0891 /* In the current implementation, we don't actually need to examine the 0892 * option flag here; we just copy everything that got saved. 0893 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers 0894 * if the encoder library already wrote one. 0895 */ 0896 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { 0897 if (dstinfo->write_JFIF_header && 0898 marker->marker == JPEG_APP0 && 0899 marker->data_length >= 5 && 0900 GETJOCTET(marker->data[0]) == 0x4A && 0901 GETJOCTET(marker->data[1]) == 0x46 && 0902 GETJOCTET(marker->data[2]) == 0x49 && 0903 GETJOCTET(marker->data[3]) == 0x46 && 0904 GETJOCTET(marker->data[4]) == 0) 0905 continue; /* reject duplicate JFIF */ 0906 if (dstinfo->write_Adobe_marker && 0907 marker->marker == JPEG_APP0+14 && 0908 marker->data_length >= 5 && 0909 GETJOCTET(marker->data[0]) == 0x41 && 0910 GETJOCTET(marker->data[1]) == 0x64 && 0911 GETJOCTET(marker->data[2]) == 0x6F && 0912 GETJOCTET(marker->data[3]) == 0x62 && 0913 GETJOCTET(marker->data[4]) == 0x65) 0914 continue; /* reject duplicate Adobe */ 0915 #ifdef NEED_FAR_POINTERS 0916 /* We could use jpeg_write_marker if the data weren't FAR... */ 0917 { 0918 unsigned int i; 0919 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); 0920 for (i = 0; i < marker->data_length; i++) 0921 jpeg_write_m_byte(dstinfo, marker->data[i]); 0922 } 0923 #else 0924 jpeg_write_marker(dstinfo, marker->marker, 0925 marker->data, marker->data_length); 0926 #endif 0927 } 0928 }