Final 350 project

Dependencies:   uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed

Committer:
shoaib_ahmed
Date:
Mon Jul 31 09:16:35 2017 +0000
Revision:
0:791a779d6220
final project;

Who changed what in which revision?

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