1 /* 2 * transupp.c 3 * 4 * Copyright (C) 1997, Thomas G. Lane. 5 * This file is part of the Independent JPEG Group's software. 6 * For conditions of distribution and use, see the accompanying README file. 7 * 8 * This file contains image transformation routines and other utility code 9 * used by the jpegtran sample application. These are NOT part of the core 10 * JPEG library. But we keep these routines separate from jpegtran.c to 11 * ease the task of maintaining jpegtran-like programs that have other user 12 * interfaces. 13 */ 14 15 /* Although this file really shouldn't have access to the library internals, 16 * it's helpful to let it call jround_up() and jcopy_block_row(). 17 */ 18 #define JPEG_INTERNALS 19 20 #include "jinclude.h" 21 #include "jpeglib.h" 22 #include "transupp.h" /* My own external interface */ 23 24 25 #if TRANSFORMS_SUPPORTED 26 27 /* 28 * Lossless image transformation routines. These routines work on DCT 29 * coefficient arrays and thus do not require any lossy decompression 30 * or recompression of the image. 31 * Thanks to Guido Vollbeding for the initial design and code of this feature. 32 * 33 * Horizontal flipping is done in-place, using a single top-to-bottom 34 * pass through the virtual source array. It will thus be much the 35 * fastest option for images larger than main memory. 36 * 37 * The other routines require a set of destination virtual arrays, so they 38 * need twice as much memory as jpegtran normally does. The destination 39 * arrays are always written in normal scan order (top to bottom) because 40 * the virtual array manager expects this. The source arrays will be scanned 41 * in the corresponding order, which means multiple passes through the source 42 * arrays for most of the transforms. That could result in much thrashing 43 * if the image is larger than main memory. 44 * 45 * Some notes about the operating environment of the individual transform 46 * routines: 47 * 1. Both the source and destination virtual arrays are allocated from the 48 * source JPEG object, and therefore should be manipulated by calling the 49 * source's memory manager. 50 * 2. The destination's component count should be used. It may be smaller 51 * than the source's when forcing to grayscale. 52 * 3. Likewise the destination's sampling factors should be used. When 53 * forcing to grayscale the destination's sampling factors will be all 1, 54 * and we may as well take that as the effective iMCU size. 55 * 4. When "trim" is in effect, the destination's dimensions will be the 56 * trimmed values but the source's will be untrimmed. 57 * 5. All the routines assume that the source and destination buffers are 58 * padded out to a full iMCU boundary. This is true, although for the 59 * source buffer it is an undocumented property of jdcoefct.c. 60 * Notes 2,3,4 boil down to this: generally we should use the destination's 61 * dimensions and ignore the source's. 62 */ 63 64 65 LOCAL(void) 66 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 67 jvirt_barray_ptr *src_coef_arrays) 68 /* Horizontal flip; done in-place, so no separate dest array is required */ 69 { 70 JDIMENSION MCU_cols, comp_width, blk_x, blk_y; 71 int ci, k, offset_y; 72 JBLOCKARRAY buffer; 73 JCOEFPTR ptr1, ptr2; 74 JCOEF temp1, temp2; 75 jpeg_component_info *compptr; 76 77 /* Horizontal mirroring of DCT blocks is accomplished by swapping 78 * pairs of blocks in-place. Within a DCT block, we perform horizontal 79 * mirroring by changing the signs of odd-numbered columns. 80 * Partial iMCUs at the right edge are left untouched. 81 */ 82 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 83 84 for (ci = 0; ci < dstinfo->num_components; ci++) { 85 compptr = dstinfo->comp_info + ci; 86 comp_width = MCU_cols * compptr->h_samp_factor; 87 for (blk_y = 0; blk_y < compptr->height_in_blocks; 88 blk_y += compptr->v_samp_factor) { 89 buffer = (*srcinfo->mem->access_virt_barray) 90 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, 91 (JDIMENSION) compptr->v_samp_factor, TRUE); 92 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 93 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { 94 ptr1 = buffer[offset_y][blk_x]; 95 ptr2 = buffer[offset_y][comp_width - blk_x - 1]; 96 /* this unrolled loop doesn't need to know which row it's on... */ 97 for (k = 0; k < DCTSIZE2; k += 2) { 98 temp1 = *ptr1; /* swap even column */ 99 temp2 = *ptr2; 100 *ptr1++ = temp2; 101 *ptr2++ = temp1; 102 temp1 = *ptr1; /* swap odd column with sign change */ 103 temp2 = *ptr2; 104 *ptr1++ = -temp2; 105 *ptr2++ = -temp1; 106 } 107 } 108 } 109 } 110 } 111 } 112 113 114 LOCAL(void) 115 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 116 jvirt_barray_ptr *src_coef_arrays, 117 jvirt_barray_ptr *dst_coef_arrays) 118 /* Vertical flip */ 119 { 120 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 121 int ci, i, j, offset_y; 122 JBLOCKARRAY src_buffer, dst_buffer; 123 JBLOCKROW src_row_ptr, dst_row_ptr; 124 JCOEFPTR src_ptr, dst_ptr; 125 jpeg_component_info *compptr; 126 127 /* We output into a separate array because we can't touch different 128 * rows of the source virtual array simultaneously. Otherwise, this 129 * is a pretty straightforward analog of horizontal flip. 130 * Within a DCT block, vertical mirroring is done by changing the signs 131 * of odd-numbered rows. 132 * Partial iMCUs at the bottom edge are copied verbatim. 133 */ 134 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 135 136 for (ci = 0; ci < dstinfo->num_components; ci++) { 137 compptr = dstinfo->comp_info + ci; 138 comp_height = MCU_rows * compptr->v_samp_factor; 139 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 140 dst_blk_y += compptr->v_samp_factor) { 141 dst_buffer = (*srcinfo->mem->access_virt_barray) 142 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 143 (JDIMENSION) compptr->v_samp_factor, TRUE); 144 if (dst_blk_y < comp_height) { 145 /* Row is within the mirrorable area. */ 146 src_buffer = (*srcinfo->mem->access_virt_barray) 147 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 148 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 149 (JDIMENSION) compptr->v_samp_factor, FALSE); 150 } else { 151 /* Bottom-edge blocks will be copied verbatim. */ 152 src_buffer = (*srcinfo->mem->access_virt_barray) 153 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 154 (JDIMENSION) compptr->v_samp_factor, FALSE); 155 } 156 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 157 if (dst_blk_y < comp_height) { 158 /* Row is within the mirrorable area. */ 159 dst_row_ptr = dst_buffer[offset_y]; 160 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 161 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 162 dst_blk_x++) { 163 dst_ptr = dst_row_ptr[dst_blk_x]; 164 src_ptr = src_row_ptr[dst_blk_x]; 165 for (i = 0; i < DCTSIZE; i += 2) { 166 /* copy even row */ 167 for (j = 0; j < DCTSIZE; j++) 168 *dst_ptr++ = *src_ptr++; 169 /* copy odd row with sign change */ 170 for (j = 0; j < DCTSIZE; j++) 171 *dst_ptr++ = - *src_ptr++; 172 } 173 } 174 } else { 175 /* Just copy row verbatim. */ 176 jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], 177 compptr->width_in_blocks); 178 } 179 } 180 } 181 } 182 } 183 184 185 LOCAL(void) 186 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 187 jvirt_barray_ptr *src_coef_arrays, 188 jvirt_barray_ptr *dst_coef_arrays) 189 /* Transpose source into destination */ 190 { 191 JDIMENSION dst_blk_x, dst_blk_y; 192 int ci, i, j, offset_x, offset_y; 193 JBLOCKARRAY src_buffer, dst_buffer; 194 JCOEFPTR src_ptr, dst_ptr; 195 jpeg_component_info *compptr; 196 197 /* Transposing pixels within a block just requires transposing the 198 * DCT coefficients. 199 * Partial iMCUs at the edges require no special treatment; we simply 200 * process all the available DCT blocks for every component. 201 */ 202 for (ci = 0; ci < dstinfo->num_components; ci++) { 203 compptr = dstinfo->comp_info + ci; 204 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 205 dst_blk_y += compptr->v_samp_factor) { 206 dst_buffer = (*srcinfo->mem->access_virt_barray) 207 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 208 (JDIMENSION) compptr->v_samp_factor, TRUE); 209 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 210 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 211 dst_blk_x += compptr->h_samp_factor) { 212 src_buffer = (*srcinfo->mem->access_virt_barray) 213 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 214 (JDIMENSION) compptr->h_samp_factor, FALSE); 215 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 216 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 217 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 218 for (i = 0; i < DCTSIZE; i++) 219 for (j = 0; j < DCTSIZE; j++) 220 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 221 } 222 } 223 } 224 } 225 } 226 } 227 228 229 LOCAL(void) 230 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 231 jvirt_barray_ptr *src_coef_arrays, 232 jvirt_barray_ptr *dst_coef_arrays) 233 /* 90 degree rotation is equivalent to 234 * 1. Transposing the image; 235 * 2. Horizontal mirroring. 236 * These two steps are merged into a single processing routine. 237 */ 238 { 239 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; 240 int ci, i, j, offset_x, offset_y; 241 JBLOCKARRAY src_buffer, dst_buffer; 242 JCOEFPTR src_ptr, dst_ptr; 243 jpeg_component_info *compptr; 244 245 /* Because of the horizontal mirror step, we can't process partial iMCUs 246 * at the (output) right edge properly. They just get transposed and 247 * not mirrored. 248 */ 249 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 250 251 for (ci = 0; ci < dstinfo->num_components; ci++) { 252 compptr = dstinfo->comp_info + ci; 253 comp_width = MCU_cols * compptr->h_samp_factor; 254 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 255 dst_blk_y += compptr->v_samp_factor) { 256 dst_buffer = (*srcinfo->mem->access_virt_barray) 257 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 258 (JDIMENSION) compptr->v_samp_factor, TRUE); 259 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 260 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 261 dst_blk_x += compptr->h_samp_factor) { 262 src_buffer = (*srcinfo->mem->access_virt_barray) 263 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 264 (JDIMENSION) compptr->h_samp_factor, FALSE); 265 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 266 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 267 if (dst_blk_x < comp_width) { 268 /* Block is within the mirrorable area. */ 269 dst_ptr = dst_buffer[offset_y] 270 [comp_width - dst_blk_x - offset_x - 1]; 271 for (i = 0; i < DCTSIZE; i++) { 272 for (j = 0; j < DCTSIZE; j++) 273 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 274 i++; 275 for (j = 0; j < DCTSIZE; j++) 276 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 277 } 278 } else { 279 /* Edge blocks are transposed but not mirrored. */ 280 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 281 for (i = 0; i < DCTSIZE; i++) 282 for (j = 0; j < DCTSIZE; j++) 283 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 284 } 285 } 286 } 287 } 288 } 289 } 290 } 291 292 293 LOCAL(void) 294 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 295 jvirt_barray_ptr *src_coef_arrays, 296 jvirt_barray_ptr *dst_coef_arrays) 297 /* 270 degree rotation is equivalent to 298 * 1. Horizontal mirroring; 299 * 2. Transposing the image. 300 * These two steps are merged into a single processing routine. 301 */ 302 { 303 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; 304 int ci, i, j, offset_x, offset_y; 305 JBLOCKARRAY src_buffer, dst_buffer; 306 JCOEFPTR src_ptr, dst_ptr; 307 jpeg_component_info *compptr; 308 309 /* Because of the horizontal mirror step, we can't process partial iMCUs 310 * at the (output) bottom edge properly. They just get transposed and 311 * not mirrored. 312 */ 313 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 314 315 for (ci = 0; ci < dstinfo->num_components; ci++) { 316 compptr = dstinfo->comp_info + ci; 317 comp_height = MCU_rows * compptr->v_samp_factor; 318 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 319 dst_blk_y += compptr->v_samp_factor) { 320 dst_buffer = (*srcinfo->mem->access_virt_barray) 321 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 322 (JDIMENSION) compptr->v_samp_factor, TRUE); 323 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 324 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 325 dst_blk_x += compptr->h_samp_factor) { 326 src_buffer = (*srcinfo->mem->access_virt_barray) 327 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 328 (JDIMENSION) compptr->h_samp_factor, FALSE); 329 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 330 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 331 if (dst_blk_y < comp_height) { 332 /* Block is within the mirrorable area. */ 333 src_ptr = src_buffer[offset_x] 334 [comp_height - dst_blk_y - offset_y - 1]; 335 for (i = 0; i < DCTSIZE; i++) { 336 for (j = 0; j < DCTSIZE; j++) { 337 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 338 j++; 339 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 340 } 341 } 342 } else { 343 /* Edge blocks are transposed but not mirrored. */ 344 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 345 for (i = 0; i < DCTSIZE; i++) 346 for (j = 0; j < DCTSIZE; j++) 347 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 348 } 349 } 350 } 351 } 352 } 353 } 354 } 355 356 357 LOCAL(void) 358 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 359 jvirt_barray_ptr *src_coef_arrays, 360 jvirt_barray_ptr *dst_coef_arrays) 361 /* 180 degree rotation is equivalent to 362 * 1. Vertical mirroring; 363 * 2. Horizontal mirroring. 364 * These two steps are merged into a single processing routine. 365 */ 366 { 367 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 368 int ci, i, j, offset_y; 369 JBLOCKARRAY src_buffer, dst_buffer; 370 JBLOCKROW src_row_ptr, dst_row_ptr; 371 JCOEFPTR src_ptr, dst_ptr; 372 jpeg_component_info *compptr; 373 374 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 375 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 376 377 for (ci = 0; ci < dstinfo->num_components; ci++) { 378 compptr = dstinfo->comp_info + ci; 379 comp_width = MCU_cols * compptr->h_samp_factor; 380 comp_height = MCU_rows * compptr->v_samp_factor; 381 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 382 dst_blk_y += compptr->v_samp_factor) { 383 dst_buffer = (*srcinfo->mem->access_virt_barray) 384 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 385 (JDIMENSION) compptr->v_samp_factor, TRUE); 386 if (dst_blk_y < comp_height) { 387 /* Row is within the vertically mirrorable area. */ 388 src_buffer = (*srcinfo->mem->access_virt_barray) 389 ((j_common_ptr) srcinfo, src_coef_arrays[ci], 390 comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, 391 (JDIMENSION) compptr->v_samp_factor, FALSE); 392 } else { 393 /* Bottom-edge rows are only mirrored horizontally. */ 394 src_buffer = (*srcinfo->mem->access_virt_barray) 395 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, 396 (JDIMENSION) compptr->v_samp_factor, FALSE); 397 } 398 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 399 if (dst_blk_y < comp_height) { 400 /* Row is within the mirrorable area. */ 401 dst_row_ptr = dst_buffer[offset_y]; 402 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; 403 /* Process the blocks that can be mirrored both ways. */ 404 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 405 dst_ptr = dst_row_ptr[dst_blk_x]; 406 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 407 for (i = 0; i < DCTSIZE; i += 2) { 408 /* For even row, negate every odd column. */ 409 for (j = 0; j < DCTSIZE; j += 2) { 410 *dst_ptr++ = *src_ptr++; 411 *dst_ptr++ = - *src_ptr++; 412 } 413 /* For odd row, negate every even column. */ 414 for (j = 0; j < DCTSIZE; j += 2) { 415 *dst_ptr++ = - *src_ptr++; 416 *dst_ptr++ = *src_ptr++; 417 } 418 } 419 } 420 /* Any remaining right-edge blocks are only mirrored vertically. */ 421 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 422 dst_ptr = dst_row_ptr[dst_blk_x]; 423 src_ptr = src_row_ptr[dst_blk_x]; 424 for (i = 0; i < DCTSIZE; i += 2) { 425 for (j = 0; j < DCTSIZE; j++) 426 *dst_ptr++ = *src_ptr++; 427 for (j = 0; j < DCTSIZE; j++) 428 *dst_ptr++ = - *src_ptr++; 429 } 430 } 431 } else { 432 /* Remaining rows are just mirrored horizontally. */ 433 dst_row_ptr = dst_buffer[offset_y]; 434 src_row_ptr = src_buffer[offset_y]; 435 /* Process the blocks that can be mirrored. */ 436 for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { 437 dst_ptr = dst_row_ptr[dst_blk_x]; 438 src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; 439 for (i = 0; i < DCTSIZE2; i += 2) { 440 *dst_ptr++ = *src_ptr++; 441 *dst_ptr++ = - *src_ptr++; 442 } 443 } 444 /* Any remaining right-edge blocks are only copied. */ 445 for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { 446 dst_ptr = dst_row_ptr[dst_blk_x]; 447 src_ptr = src_row_ptr[dst_blk_x]; 448 for (i = 0; i < DCTSIZE2; i++) 449 *dst_ptr++ = *src_ptr++; 450 } 451 } 452 } 453 } 454 } 455 } 456 457 458 LOCAL(void) 459 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 460 jvirt_barray_ptr *src_coef_arrays, 461 jvirt_barray_ptr *dst_coef_arrays) 462 /* Transverse transpose is equivalent to 463 * 1. 180 degree rotation; 464 * 2. Transposition; 465 * or 466 * 1. Horizontal mirroring; 467 * 2. Transposition; 468 * 3. Horizontal mirroring. 469 * These steps are merged into a single processing routine. 470 */ 471 { 472 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; 473 int ci, i, j, offset_x, offset_y; 474 JBLOCKARRAY src_buffer, dst_buffer; 475 JCOEFPTR src_ptr, dst_ptr; 476 jpeg_component_info *compptr; 477 478 MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); 479 MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); 480 481 for (ci = 0; ci < dstinfo->num_components; ci++) { 482 compptr = dstinfo->comp_info + ci; 483 comp_width = MCU_cols * compptr->h_samp_factor; 484 comp_height = MCU_rows * compptr->v_samp_factor; 485 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; 486 dst_blk_y += compptr->v_samp_factor) { 487 dst_buffer = (*srcinfo->mem->access_virt_barray) 488 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, 489 (JDIMENSION) compptr->v_samp_factor, TRUE); 490 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { 491 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; 492 dst_blk_x += compptr->h_samp_factor) { 493 src_buffer = (*srcinfo->mem->access_virt_barray) 494 ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, 495 (JDIMENSION) compptr->h_samp_factor, FALSE); 496 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { 497 if (dst_blk_y < comp_height) { 498 src_ptr = src_buffer[offset_x] 499 [comp_height - dst_blk_y - offset_y - 1]; 500 if (dst_blk_x < comp_width) { 501 /* Block is within the mirrorable area. */ 502 dst_ptr = dst_buffer[offset_y] 503 [comp_width - dst_blk_x - offset_x - 1]; 504 for (i = 0; i < DCTSIZE; i++) { 505 for (j = 0; j < DCTSIZE; j++) { 506 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 507 j++; 508 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 509 } 510 i++; 511 for (j = 0; j < DCTSIZE; j++) { 512 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 513 j++; 514 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 515 } 516 } 517 } else { 518 /* Right-edge blocks are mirrored in y only */ 519 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 520 for (i = 0; i < DCTSIZE; i++) { 521 for (j = 0; j < DCTSIZE; j++) { 522 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 523 j++; 524 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 525 } 526 } 527 } 528 } else { 529 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; 530 if (dst_blk_x < comp_width) { 531 /* Bottom-edge blocks are mirrored in x only */ 532 dst_ptr = dst_buffer[offset_y] 533 [comp_width - dst_blk_x - offset_x - 1]; 534 for (i = 0; i < DCTSIZE; i++) { 535 for (j = 0; j < DCTSIZE; j++) 536 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 537 i++; 538 for (j = 0; j < DCTSIZE; j++) 539 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; 540 } 541 } else { 542 /* At lower right corner, just transpose, no mirroring */ 543 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; 544 for (i = 0; i < DCTSIZE; i++) 545 for (j = 0; j < DCTSIZE; j++) 546 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; 547 } 548 } 549 } 550 } 551 } 552 } 553 } 554 } 555 556 557 /* Request any required workspace. 558 * 559 * We allocate the workspace virtual arrays from the source decompression 560 * object, so that all the arrays (both the original data and the workspace) 561 * will be taken into account while making memory management decisions. 562 * Hence, this routine must be called after jpeg_read_header (which reads 563 * the image dimensions) and before jpeg_read_coefficients (which realizes 564 * the source's virtual arrays). 565 */ 566 567 GLOBAL(void) 568 jtransform_request_workspace (j_decompress_ptr srcinfo, 569 jpeg_transform_info *info) 570 { 571 jvirt_barray_ptr *coef_arrays = NULL; 572 jpeg_component_info *compptr; 573 int ci; 574 575 if (info->force_grayscale && 576 srcinfo->jpeg_color_space == JCS_YCbCr && 577 srcinfo->num_components == 3) { 578 /* We'll only process the first component */ 579 info->num_components = 1; 580 } else { 581 /* Process all the components */ 582 info->num_components = srcinfo->num_components; 583 } 584 585 switch (info->transform) { 586 case JXFORM_NONE: 587 case JXFORM_FLIP_H: 588 /* Don't need a workspace array */ 589 break; 590 case JXFORM_FLIP_V: 591 case JXFORM_ROT_180: 592 /* Need workspace arrays having same dimensions as source image. 593 * Note that we allocate arrays padded out to the next iMCU boundary, 594 * so that transform routines need not worry about missing edge blocks. 595 */ 596 coef_arrays = (jvirt_barray_ptr *) 597 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 598 SIZEOF(jvirt_barray_ptr) * info->num_components); 599 for (ci = 0; ci < info->num_components; ci++) { 600 compptr = srcinfo->comp_info + ci; 601 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 602 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 603 (JDIMENSION) jround_up((long) compptr->width_in_blocks, 604 (long) compptr->h_samp_factor), 605 (JDIMENSION) jround_up((long) compptr->height_in_blocks, 606 (long) compptr->v_samp_factor), 607 (JDIMENSION) compptr->v_samp_factor); 608 } 609 break; 610 case JXFORM_TRANSPOSE: 611 case JXFORM_TRANSVERSE: 612 case JXFORM_ROT_90: 613 case JXFORM_ROT_270: 614 /* Need workspace arrays having transposed dimensions. 615 * Note that we allocate arrays padded out to the next iMCU boundary, 616 * so that transform routines need not worry about missing edge blocks. 617 */ 618 coef_arrays = (jvirt_barray_ptr *) 619 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, 620 SIZEOF(jvirt_barray_ptr) * info->num_components); 621 for (ci = 0; ci < info->num_components; ci++) { 622 compptr = srcinfo->comp_info + ci; 623 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) 624 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, 625 (JDIMENSION) jround_up((long) compptr->height_in_blocks, 626 (long) compptr->v_samp_factor), 627 (JDIMENSION) jround_up((long) compptr->width_in_blocks, 628 (long) compptr->h_samp_factor), 629 (JDIMENSION) compptr->h_samp_factor); 630 } 631 break; 632 } 633 info->workspace_coef_arrays = coef_arrays; 634 } 635 636 637 /* Transpose destination image parameters */ 638 639 LOCAL(void) 640 transpose_critical_parameters (j_compress_ptr dstinfo) 641 { 642 int tblno, i, j, ci, itemp; 643 jpeg_component_info *compptr; 644 JQUANT_TBL *qtblptr; 645 JDIMENSION dtemp; 646 UINT16 qtemp; 647 648 /* Transpose basic image dimensions */ 649 dtemp = dstinfo->image_width; 650 dstinfo->image_width = dstinfo->image_height; 651 dstinfo->image_height = dtemp; 652 653 /* Transpose sampling factors */ 654 for (ci = 0; ci < dstinfo->num_components; ci++) { 655 compptr = dstinfo->comp_info + ci; 656 itemp = compptr->h_samp_factor; 657 compptr->h_samp_factor = compptr->v_samp_factor; 658 compptr->v_samp_factor = itemp; 659 } 660 661 /* Transpose quantization tables */ 662 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { 663 qtblptr = dstinfo->quant_tbl_ptrs[tblno]; 664 if (qtblptr != NULL) { 665 for (i = 0; i < DCTSIZE; i++) { 666 for (j = 0; j < i; j++) { 667 qtemp = qtblptr->quantval[i*DCTSIZE+j]; 668 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; 669 qtblptr->quantval[j*DCTSIZE+i] = qtemp; 670 } 671 } 672 } 673 } 674 } 675 676 677 /* Trim off any partial iMCUs on the indicated destination edge */ 678 679 LOCAL(void) 680 trim_right_edge (j_compress_ptr dstinfo) 681 { 682 int ci, max_h_samp_factor; 683 JDIMENSION MCU_cols; 684 685 /* We have to compute max_h_samp_factor ourselves, 686 * because it hasn't been set yet in the destination 687 * (and we don't want to use the source's value). 688 */ 689 max_h_samp_factor = 1; 690 for (ci = 0; ci < dstinfo->num_components; ci++) { 691 int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; 692 max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); 693 } 694 MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); 695 if (MCU_cols > 0) /* can't trim to 0 pixels */ 696 dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); 697 } 698 699 LOCAL(void) 700 trim_bottom_edge (j_compress_ptr dstinfo) 701 { 702 int ci, max_v_samp_factor; 703 JDIMENSION MCU_rows; 704 705 /* We have to compute max_v_samp_factor ourselves, 706 * because it hasn't been set yet in the destination 707 * (and we don't want to use the source's value). 708 */ 709 max_v_samp_factor = 1; 710 for (ci = 0; ci < dstinfo->num_components; ci++) { 711 int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; 712 max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); 713 } 714 MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); 715 if (MCU_rows > 0) /* can't trim to 0 pixels */ 716 dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); 717 } 718 719 720 /* Adjust output image parameters as needed. 721 * 722 * This must be called after jpeg_copy_critical_parameters() 723 * and before jpeg_write_coefficients(). 724 * 725 * The return value is the set of virtual coefficient arrays to be written 726 * (either the ones allocated by jtransform_request_workspace, or the 727 * original source data arrays). The caller will need to pass this value 728 * to jpeg_write_coefficients(). 729 */ 730 731 GLOBAL(jvirt_barray_ptr *) 732 jtransform_adjust_parameters (j_decompress_ptr srcinfo, 733 j_compress_ptr dstinfo, 734 jvirt_barray_ptr *src_coef_arrays, 735 jpeg_transform_info *info) 736 { 737 /* If force-to-grayscale is requested, adjust destination parameters */ 738 if (info->force_grayscale) { 739 /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed 740 * properly. Among other things, the target h_samp_factor & v_samp_factor 741 * will get set to 1, which typically won't match the source. 742 * In fact we do this even if the source is already grayscale; that 743 * provides an easy way of coercing a grayscale JPEG with funny sampling 744 * factors to the customary 1,1. (Some decoders fail on other factors.) 745 */ 746 if ((dstinfo->jpeg_color_space == JCS_YCbCr && 747 dstinfo->num_components == 3) || 748 (dstinfo->jpeg_color_space == JCS_GRAYSCALE && 749 dstinfo->num_components == 1)) { 750 /* We have to preserve the source's quantization table number. */ 751 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; 752 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); 753 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; 754 } else { 755 /* Sorry, can't do it */ 756 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); 757 } 758 } 759 760 /* Correct the destination's image dimensions etc if necessary */ 761 switch (info->transform) { 762 case JXFORM_NONE: 763 /* Nothing to do */ 764 break; 765 case JXFORM_FLIP_H: 766 if (info->trim) 767 trim_right_edge(dstinfo); 768 break; 769 case JXFORM_FLIP_V: 770 if (info->trim) 771 trim_bottom_edge(dstinfo); 772 break; 773 case JXFORM_TRANSPOSE: 774 transpose_critical_parameters(dstinfo); 775 /* transpose does NOT have to trim anything */ 776 break; 777 case JXFORM_TRANSVERSE: 778 transpose_critical_parameters(dstinfo); 779 if (info->trim) { 780 trim_right_edge(dstinfo); 781 trim_bottom_edge(dstinfo); 782 } 783 break; 784 case JXFORM_ROT_90: 785 transpose_critical_parameters(dstinfo); 786 if (info->trim) 787 trim_right_edge(dstinfo); 788 break; 789 case JXFORM_ROT_180: 790 if (info->trim) { 791 trim_right_edge(dstinfo); 792 trim_bottom_edge(dstinfo); 793 } 794 break; 795 case JXFORM_ROT_270: 796 transpose_critical_parameters(dstinfo); 797 if (info->trim) 798 trim_bottom_edge(dstinfo); 799 break; 800 } 801 802 /* Return the appropriate output data set */ 803 if (info->workspace_coef_arrays != NULL) 804 return info->workspace_coef_arrays; 805 return src_coef_arrays; 806 } 807 808 809 /* Execute the actual transformation, if any. 810 * 811 * This must be called *after* jpeg_write_coefficients, because it depends 812 * on jpeg_write_coefficients to have computed subsidiary values such as 813 * the per-component width and height fields in the destination object. 814 * 815 * Note that some transformations will modify the source data arrays! 816 */ 817 818 GLOBAL(void) 819 jtransform_execute_transformation (j_decompress_ptr srcinfo, 820 j_compress_ptr dstinfo, 821 jvirt_barray_ptr *src_coef_arrays, 822 jpeg_transform_info *info) 823 { 824 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; 825 826 switch (info->transform) { 827 case JXFORM_NONE: 828 break; 829 case JXFORM_FLIP_H: 830 do_flip_h(srcinfo, dstinfo, src_coef_arrays); 831 break; 832 case JXFORM_FLIP_V: 833 do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 834 break; 835 case JXFORM_TRANSPOSE: 836 do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 837 break; 838 case JXFORM_TRANSVERSE: 839 do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 840 break; 841 case JXFORM_ROT_90: 842 do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 843 break; 844 case JXFORM_ROT_180: 845 do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 846 break; 847 case JXFORM_ROT_270: 848 do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); 849 break; 850 } 851 } 852 853 #endif /* TRANSFORMS_SUPPORTED */ 854 855 856 /* Setup decompression object to save desired markers in memory. 857 * This must be called before jpeg_read_header() to have the desired effect. 858 */ 859 860 GLOBAL(void) 861 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) 862 { 863 #ifdef SAVE_MARKERS_SUPPORTED 864 int m; 865 866 /* Save comments except under NONE option */ 867 if (option != JCOPYOPT_NONE) { 868 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); 869 } 870 /* Save all types of APPn markers iff ALL option */ 871 if (option == JCOPYOPT_ALL) { 872 for (m = 0; m < 16; m++) 873 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); 874 } 875 #endif /* SAVE_MARKERS_SUPPORTED */ 876 } 877 878 /* Copy markers saved in the given source object to the destination object. 879 * This should be called just after jpeg_start_compress() or 880 * jpeg_write_coefficients(). 881 * Note that those routines will have written the SOI, and also the 882 * JFIF APP0 or Adobe APP14 markers if selected. 883 */ 884 885 GLOBAL(void) 886 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, 887 JCOPY_OPTION option) 888 { 889 jpeg_saved_marker_ptr marker; 890 891 /* In the current implementation, we don't actually need to examine the 892 * option flag here; we just copy everything that got saved. 893 * But to avoid confusion, we do not output JFIF and Adobe APP14 markers 894 * if the encoder library already wrote one. 895 */ 896 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { 897 if (dstinfo->write_JFIF_header && 898 marker->marker == JPEG_APP0 && 899 marker->data_length >= 5 && 900 GETJOCTET(marker->data[0]) == 0x4A && 901 GETJOCTET(marker->data[1]) == 0x46 && 902 GETJOCTET(marker->data[2]) == 0x49 && 903 GETJOCTET(marker->data[3]) == 0x46 && 904 GETJOCTET(marker->data[4]) == 0) 905 continue; /* reject duplicate JFIF */ 906 if (dstinfo->write_Adobe_marker && 907 marker->marker == JPEG_APP0+14 && 908 marker->data_length >= 5 && 909 GETJOCTET(marker->data[0]) == 0x41 && 910 GETJOCTET(marker->data[1]) == 0x64 && 911 GETJOCTET(marker->data[2]) == 0x6F && 912 GETJOCTET(marker->data[3]) == 0x62 && 913 GETJOCTET(marker->data[4]) == 0x65) 914 continue; /* reject duplicate Adobe */ 915 #ifdef NEED_FAR_POINTERS 916 /* We could use jpeg_write_marker if the data weren't FAR... */ 917 { 918 unsigned int i; 919 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); 920 for (i = 0; i < marker->data_length; i++) 921 jpeg_write_m_byte(dstinfo, marker->data[i]); 922 } 923 #else 924 jpeg_write_marker(dstinfo, marker->marker, 925 marker->data, marker->data_length); 926 #endif 927 } 928 } 929