Final 350 project
Dependencies: uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed
includes/transupp.c@0:791a779d6220, 2017-07-31 (annotated)
- Committer:
- shoaib_ahmed
- Date:
- Mon Jul 31 09:16:35 2017 +0000
- Revision:
- 0:791a779d6220
final project;
Who changed what in which revision?
User | Revision | Line number | New 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 | } |