00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define JPEG_INTERNALS
00019
00020 #include "jinclude.h"
00021 #include "jpeglib.h"
00022 #include "transupp.h"
00023 #include <ctype.h>
00024
00025
00026 #if TRANSFORMS_SUPPORTED
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 LOCAL(void)
00079 do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00080 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00081 jvirt_barray_ptr *src_coef_arrays,
00082 jvirt_barray_ptr *dst_coef_arrays)
00083
00084 {
00085 JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
00086 int ci, offset_y;
00087 JBLOCKARRAY src_buffer, dst_buffer;
00088 jpeg_component_info *compptr;
00089
00090
00091
00092
00093 for (ci = 0; ci < dstinfo->num_components; ci++) {
00094 compptr = dstinfo->comp_info + ci;
00095 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00096 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00097 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00098 dst_blk_y += compptr->v_samp_factor) {
00099 dst_buffer = (*srcinfo->mem->access_virt_barray)
00100 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00101 (JDIMENSION) compptr->v_samp_factor, TRUE);
00102 src_buffer = (*srcinfo->mem->access_virt_barray)
00103 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00104 dst_blk_y + y_crop_blocks,
00105 (JDIMENSION) compptr->v_samp_factor, FALSE);
00106 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00107 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
00108 dst_buffer[offset_y],
00109 compptr->width_in_blocks);
00110 }
00111 }
00112 }
00113 }
00114
00115
00116 LOCAL(void)
00117 do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00118 JDIMENSION x_crop_offset,
00119 jvirt_barray_ptr *src_coef_arrays)
00120
00121
00122
00123 {
00124 JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
00125 int ci, k, offset_y;
00126 JBLOCKARRAY buffer;
00127 JCOEFPTR ptr1, ptr2;
00128 JCOEF temp1, temp2;
00129 jpeg_component_info *compptr;
00130
00131
00132
00133
00134
00135
00136 MCU_cols = srcinfo->output_width /
00137 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
00138
00139 for (ci = 0; ci < dstinfo->num_components; ci++) {
00140 compptr = dstinfo->comp_info + ci;
00141 comp_width = MCU_cols * compptr->h_samp_factor;
00142 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00143 for (blk_y = 0; blk_y < compptr->height_in_blocks;
00144 blk_y += compptr->v_samp_factor) {
00145 buffer = (*srcinfo->mem->access_virt_barray)
00146 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
00147 (JDIMENSION) compptr->v_samp_factor, TRUE);
00148 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00149
00150 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
00151 ptr1 = buffer[offset_y][blk_x];
00152 ptr2 = buffer[offset_y][comp_width - blk_x - 1];
00153
00154 for (k = 0; k < DCTSIZE2; k += 2) {
00155 temp1 = *ptr1;
00156 temp2 = *ptr2;
00157 *ptr1++ = temp2;
00158 *ptr2++ = temp1;
00159 temp1 = *ptr1;
00160 temp2 = *ptr2;
00161 *ptr1++ = -temp2;
00162 *ptr2++ = -temp1;
00163 }
00164 }
00165 if (x_crop_blocks > 0) {
00166
00167
00168
00169
00170
00171 for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
00172 jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
00173 buffer[offset_y] + blk_x,
00174 (JDIMENSION) 1);
00175 }
00176 }
00177 }
00178 }
00179 }
00180 }
00181
00182
00183 LOCAL(void)
00184 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00185 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00186 jvirt_barray_ptr *src_coef_arrays,
00187 jvirt_barray_ptr *dst_coef_arrays)
00188
00189 {
00190 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
00191 JDIMENSION x_crop_blocks, y_crop_blocks;
00192 int ci, k, offset_y;
00193 JBLOCKARRAY src_buffer, dst_buffer;
00194 JBLOCKROW src_row_ptr, dst_row_ptr;
00195 JCOEFPTR src_ptr, dst_ptr;
00196 jpeg_component_info *compptr;
00197
00198
00199
00200
00201
00202 MCU_cols = srcinfo->output_width /
00203 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
00204
00205 for (ci = 0; ci < dstinfo->num_components; ci++) {
00206 compptr = dstinfo->comp_info + ci;
00207 comp_width = MCU_cols * compptr->h_samp_factor;
00208 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00209 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00210 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00211 dst_blk_y += compptr->v_samp_factor) {
00212 dst_buffer = (*srcinfo->mem->access_virt_barray)
00213 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00214 (JDIMENSION) compptr->v_samp_factor, TRUE);
00215 src_buffer = (*srcinfo->mem->access_virt_barray)
00216 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00217 dst_blk_y + y_crop_blocks,
00218 (JDIMENSION) compptr->v_samp_factor, FALSE);
00219 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00220 dst_row_ptr = dst_buffer[offset_y];
00221 src_row_ptr = src_buffer[offset_y];
00222 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
00223 if (x_crop_blocks + dst_blk_x < comp_width) {
00224
00225 dst_ptr = dst_row_ptr[dst_blk_x];
00226 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
00227
00228 for (k = 0; k < DCTSIZE2; k += 2) {
00229 *dst_ptr++ = *src_ptr++;
00230 *dst_ptr++ = - *src_ptr++;
00231 }
00232 } else {
00233
00234 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
00235 dst_row_ptr + dst_blk_x,
00236 (JDIMENSION) 1);
00237 }
00238 }
00239 }
00240 }
00241 }
00242 }
00243
00244
00245 LOCAL(void)
00246 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00247 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00248 jvirt_barray_ptr *src_coef_arrays,
00249 jvirt_barray_ptr *dst_coef_arrays)
00250
00251 {
00252 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
00253 JDIMENSION x_crop_blocks, y_crop_blocks;
00254 int ci, i, j, offset_y;
00255 JBLOCKARRAY src_buffer, dst_buffer;
00256 JBLOCKROW src_row_ptr, dst_row_ptr;
00257 JCOEFPTR src_ptr, dst_ptr;
00258 jpeg_component_info *compptr;
00259
00260
00261
00262
00263
00264
00265
00266
00267 MCU_rows = srcinfo->output_height /
00268 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
00269
00270 for (ci = 0; ci < dstinfo->num_components; ci++) {
00271 compptr = dstinfo->comp_info + ci;
00272 comp_height = MCU_rows * compptr->v_samp_factor;
00273 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00274 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00275 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00276 dst_blk_y += compptr->v_samp_factor) {
00277 dst_buffer = (*srcinfo->mem->access_virt_barray)
00278 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00279 (JDIMENSION) compptr->v_samp_factor, TRUE);
00280 if (y_crop_blocks + dst_blk_y < comp_height) {
00281
00282 src_buffer = (*srcinfo->mem->access_virt_barray)
00283 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00284 comp_height - y_crop_blocks - dst_blk_y -
00285 (JDIMENSION) compptr->v_samp_factor,
00286 (JDIMENSION) compptr->v_samp_factor, FALSE);
00287 } else {
00288
00289 src_buffer = (*srcinfo->mem->access_virt_barray)
00290 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00291 dst_blk_y + y_crop_blocks,
00292 (JDIMENSION) compptr->v_samp_factor, FALSE);
00293 }
00294 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00295 if (y_crop_blocks + dst_blk_y < comp_height) {
00296
00297 dst_row_ptr = dst_buffer[offset_y];
00298 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
00299 src_row_ptr += x_crop_blocks;
00300 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
00301 dst_blk_x++) {
00302 dst_ptr = dst_row_ptr[dst_blk_x];
00303 src_ptr = src_row_ptr[dst_blk_x];
00304 for (i = 0; i < DCTSIZE; i += 2) {
00305
00306 for (j = 0; j < DCTSIZE; j++)
00307 *dst_ptr++ = *src_ptr++;
00308
00309 for (j = 0; j < DCTSIZE; j++)
00310 *dst_ptr++ = - *src_ptr++;
00311 }
00312 }
00313 } else {
00314
00315 jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
00316 dst_buffer[offset_y],
00317 compptr->width_in_blocks);
00318 }
00319 }
00320 }
00321 }
00322 }
00323
00324
00325 LOCAL(void)
00326 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00327 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00328 jvirt_barray_ptr *src_coef_arrays,
00329 jvirt_barray_ptr *dst_coef_arrays)
00330
00331 {
00332 JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
00333 int ci, i, j, offset_x, offset_y;
00334 JBLOCKARRAY src_buffer, dst_buffer;
00335 JCOEFPTR src_ptr, dst_ptr;
00336 jpeg_component_info *compptr;
00337
00338
00339
00340
00341
00342
00343 for (ci = 0; ci < dstinfo->num_components; ci++) {
00344 compptr = dstinfo->comp_info + ci;
00345 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00346 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00347 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00348 dst_blk_y += compptr->v_samp_factor) {
00349 dst_buffer = (*srcinfo->mem->access_virt_barray)
00350 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00351 (JDIMENSION) compptr->v_samp_factor, TRUE);
00352 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00353 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
00354 dst_blk_x += compptr->h_samp_factor) {
00355 src_buffer = (*srcinfo->mem->access_virt_barray)
00356 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00357 dst_blk_x + x_crop_blocks,
00358 (JDIMENSION) compptr->h_samp_factor, FALSE);
00359 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
00360 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
00361 src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
00362 for (i = 0; i < DCTSIZE; i++)
00363 for (j = 0; j < DCTSIZE; j++)
00364 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00365 }
00366 }
00367 }
00368 }
00369 }
00370 }
00371
00372
00373 LOCAL(void)
00374 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00375 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00376 jvirt_barray_ptr *src_coef_arrays,
00377 jvirt_barray_ptr *dst_coef_arrays)
00378
00379
00380
00381
00382
00383 {
00384 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
00385 JDIMENSION x_crop_blocks, y_crop_blocks;
00386 int ci, i, j, offset_x, offset_y;
00387 JBLOCKARRAY src_buffer, dst_buffer;
00388 JCOEFPTR src_ptr, dst_ptr;
00389 jpeg_component_info *compptr;
00390
00391
00392
00393
00394
00395 MCU_cols = srcinfo->output_height /
00396 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
00397
00398 for (ci = 0; ci < dstinfo->num_components; ci++) {
00399 compptr = dstinfo->comp_info + ci;
00400 comp_width = MCU_cols * compptr->h_samp_factor;
00401 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00402 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00403 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00404 dst_blk_y += compptr->v_samp_factor) {
00405 dst_buffer = (*srcinfo->mem->access_virt_barray)
00406 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00407 (JDIMENSION) compptr->v_samp_factor, TRUE);
00408 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00409 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
00410 dst_blk_x += compptr->h_samp_factor) {
00411 if (x_crop_blocks + dst_blk_x < comp_width) {
00412
00413 src_buffer = (*srcinfo->mem->access_virt_barray)
00414 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00415 comp_width - x_crop_blocks - dst_blk_x -
00416 (JDIMENSION) compptr->h_samp_factor,
00417 (JDIMENSION) compptr->h_samp_factor, FALSE);
00418 } else {
00419
00420 src_buffer = (*srcinfo->mem->access_virt_barray)
00421 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00422 dst_blk_x + x_crop_blocks,
00423 (JDIMENSION) compptr->h_samp_factor, FALSE);
00424 }
00425 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
00426 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
00427 if (x_crop_blocks + dst_blk_x < comp_width) {
00428
00429 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
00430 [dst_blk_y + offset_y + y_crop_blocks];
00431 for (i = 0; i < DCTSIZE; i++) {
00432 for (j = 0; j < DCTSIZE; j++)
00433 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00434 i++;
00435 for (j = 0; j < DCTSIZE; j++)
00436 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00437 }
00438 } else {
00439
00440 src_ptr = src_buffer[offset_x]
00441 [dst_blk_y + offset_y + y_crop_blocks];
00442 for (i = 0; i < DCTSIZE; i++)
00443 for (j = 0; j < DCTSIZE; j++)
00444 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00445 }
00446 }
00447 }
00448 }
00449 }
00450 }
00451 }
00452
00453
00454 LOCAL(void)
00455 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00456 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00457 jvirt_barray_ptr *src_coef_arrays,
00458 jvirt_barray_ptr *dst_coef_arrays)
00459
00460
00461
00462
00463
00464 {
00465 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
00466 JDIMENSION x_crop_blocks, y_crop_blocks;
00467 int ci, i, j, offset_x, offset_y;
00468 JBLOCKARRAY src_buffer, dst_buffer;
00469 JCOEFPTR src_ptr, dst_ptr;
00470 jpeg_component_info *compptr;
00471
00472
00473
00474
00475
00476 MCU_rows = srcinfo->output_width /
00477 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
00478
00479 for (ci = 0; ci < dstinfo->num_components; ci++) {
00480 compptr = dstinfo->comp_info + ci;
00481 comp_height = MCU_rows * compptr->v_samp_factor;
00482 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00483 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00484 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00485 dst_blk_y += compptr->v_samp_factor) {
00486 dst_buffer = (*srcinfo->mem->access_virt_barray)
00487 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00488 (JDIMENSION) compptr->v_samp_factor, TRUE);
00489 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00490 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
00491 dst_blk_x += compptr->h_samp_factor) {
00492 src_buffer = (*srcinfo->mem->access_virt_barray)
00493 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00494 dst_blk_x + x_crop_blocks,
00495 (JDIMENSION) compptr->h_samp_factor, FALSE);
00496 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
00497 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
00498 if (y_crop_blocks + dst_blk_y < comp_height) {
00499
00500 src_ptr = src_buffer[offset_x]
00501 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
00502 for (i = 0; i < DCTSIZE; i++) {
00503 for (j = 0; j < DCTSIZE; j++) {
00504 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00505 j++;
00506 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00507 }
00508 }
00509 } else {
00510
00511 src_ptr = src_buffer[offset_x]
00512 [dst_blk_y + offset_y + y_crop_blocks];
00513 for (i = 0; i < DCTSIZE; i++)
00514 for (j = 0; j < DCTSIZE; j++)
00515 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00516 }
00517 }
00518 }
00519 }
00520 }
00521 }
00522 }
00523
00524
00525 LOCAL(void)
00526 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00527 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00528 jvirt_barray_ptr *src_coef_arrays,
00529 jvirt_barray_ptr *dst_coef_arrays)
00530
00531
00532
00533
00534
00535 {
00536 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
00537 JDIMENSION x_crop_blocks, y_crop_blocks;
00538 int ci, i, j, offset_y;
00539 JBLOCKARRAY src_buffer, dst_buffer;
00540 JBLOCKROW src_row_ptr, dst_row_ptr;
00541 JCOEFPTR src_ptr, dst_ptr;
00542 jpeg_component_info *compptr;
00543
00544 MCU_cols = srcinfo->output_width /
00545 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
00546 MCU_rows = srcinfo->output_height /
00547 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
00548
00549 for (ci = 0; ci < dstinfo->num_components; ci++) {
00550 compptr = dstinfo->comp_info + ci;
00551 comp_width = MCU_cols * compptr->h_samp_factor;
00552 comp_height = MCU_rows * compptr->v_samp_factor;
00553 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00554 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00555 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00556 dst_blk_y += compptr->v_samp_factor) {
00557 dst_buffer = (*srcinfo->mem->access_virt_barray)
00558 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00559 (JDIMENSION) compptr->v_samp_factor, TRUE);
00560 if (y_crop_blocks + dst_blk_y < comp_height) {
00561
00562 src_buffer = (*srcinfo->mem->access_virt_barray)
00563 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00564 comp_height - y_crop_blocks - dst_blk_y -
00565 (JDIMENSION) compptr->v_samp_factor,
00566 (JDIMENSION) compptr->v_samp_factor, FALSE);
00567 } else {
00568
00569 src_buffer = (*srcinfo->mem->access_virt_barray)
00570 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00571 dst_blk_y + y_crop_blocks,
00572 (JDIMENSION) compptr->v_samp_factor, FALSE);
00573 }
00574 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00575 dst_row_ptr = dst_buffer[offset_y];
00576 if (y_crop_blocks + dst_blk_y < comp_height) {
00577
00578 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
00579 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
00580 dst_ptr = dst_row_ptr[dst_blk_x];
00581 if (x_crop_blocks + dst_blk_x < comp_width) {
00582
00583 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
00584 for (i = 0; i < DCTSIZE; i += 2) {
00585
00586 for (j = 0; j < DCTSIZE; j += 2) {
00587 *dst_ptr++ = *src_ptr++;
00588 *dst_ptr++ = - *src_ptr++;
00589 }
00590
00591 for (j = 0; j < DCTSIZE; j += 2) {
00592 *dst_ptr++ = - *src_ptr++;
00593 *dst_ptr++ = *src_ptr++;
00594 }
00595 }
00596 } else {
00597
00598 src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
00599 for (i = 0; i < DCTSIZE; i += 2) {
00600 for (j = 0; j < DCTSIZE; j++)
00601 *dst_ptr++ = *src_ptr++;
00602 for (j = 0; j < DCTSIZE; j++)
00603 *dst_ptr++ = - *src_ptr++;
00604 }
00605 }
00606 }
00607 } else {
00608
00609 src_row_ptr = src_buffer[offset_y];
00610 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
00611 if (x_crop_blocks + dst_blk_x < comp_width) {
00612
00613 dst_ptr = dst_row_ptr[dst_blk_x];
00614 src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
00615 for (i = 0; i < DCTSIZE2; i += 2) {
00616 *dst_ptr++ = *src_ptr++;
00617 *dst_ptr++ = - *src_ptr++;
00618 }
00619 } else {
00620
00621 jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
00622 dst_row_ptr + dst_blk_x,
00623 (JDIMENSION) 1);
00624 }
00625 }
00626 }
00627 }
00628 }
00629 }
00630 }
00631
00632
00633 LOCAL(void)
00634 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
00635 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
00636 jvirt_barray_ptr *src_coef_arrays,
00637 jvirt_barray_ptr *dst_coef_arrays)
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 {
00648 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
00649 JDIMENSION x_crop_blocks, y_crop_blocks;
00650 int ci, i, j, offset_x, offset_y;
00651 JBLOCKARRAY src_buffer, dst_buffer;
00652 JCOEFPTR src_ptr, dst_ptr;
00653 jpeg_component_info *compptr;
00654
00655 MCU_cols = srcinfo->output_height /
00656 (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
00657 MCU_rows = srcinfo->output_width /
00658 (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
00659
00660 for (ci = 0; ci < dstinfo->num_components; ci++) {
00661 compptr = dstinfo->comp_info + ci;
00662 comp_width = MCU_cols * compptr->h_samp_factor;
00663 comp_height = MCU_rows * compptr->v_samp_factor;
00664 x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
00665 y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
00666 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
00667 dst_blk_y += compptr->v_samp_factor) {
00668 dst_buffer = (*srcinfo->mem->access_virt_barray)
00669 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
00670 (JDIMENSION) compptr->v_samp_factor, TRUE);
00671 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
00672 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
00673 dst_blk_x += compptr->h_samp_factor) {
00674 if (x_crop_blocks + dst_blk_x < comp_width) {
00675
00676 src_buffer = (*srcinfo->mem->access_virt_barray)
00677 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00678 comp_width - x_crop_blocks - dst_blk_x -
00679 (JDIMENSION) compptr->h_samp_factor,
00680 (JDIMENSION) compptr->h_samp_factor, FALSE);
00681 } else {
00682 src_buffer = (*srcinfo->mem->access_virt_barray)
00683 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
00684 dst_blk_x + x_crop_blocks,
00685 (JDIMENSION) compptr->h_samp_factor, FALSE);
00686 }
00687 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
00688 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
00689 if (y_crop_blocks + dst_blk_y < comp_height) {
00690 if (x_crop_blocks + dst_blk_x < comp_width) {
00691
00692 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
00693 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
00694 for (i = 0; i < DCTSIZE; i++) {
00695 for (j = 0; j < DCTSIZE; j++) {
00696 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00697 j++;
00698 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00699 }
00700 i++;
00701 for (j = 0; j < DCTSIZE; j++) {
00702 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00703 j++;
00704 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00705 }
00706 }
00707 } else {
00708
00709 src_ptr = src_buffer[offset_x]
00710 [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
00711 for (i = 0; i < DCTSIZE; i++) {
00712 for (j = 0; j < DCTSIZE; j++) {
00713 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00714 j++;
00715 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00716 }
00717 }
00718 }
00719 } else {
00720 if (x_crop_blocks + dst_blk_x < comp_width) {
00721
00722 src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
00723 [dst_blk_y + offset_y + y_crop_blocks];
00724 for (i = 0; i < DCTSIZE; i++) {
00725 for (j = 0; j < DCTSIZE; j++)
00726 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00727 i++;
00728 for (j = 0; j < DCTSIZE; j++)
00729 dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
00730 }
00731 } else {
00732
00733 src_ptr = src_buffer[offset_x]
00734 [dst_blk_y + offset_y + y_crop_blocks];
00735 for (i = 0; i < DCTSIZE; i++)
00736 for (j = 0; j < DCTSIZE; j++)
00737 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
00738 }
00739 }
00740 }
00741 }
00742 }
00743 }
00744 }
00745 }
00746
00747
00748
00749
00750
00751
00752
00753 LOCAL(boolean)
00754 jt_read_integer (const char ** strptr, JDIMENSION * result)
00755 {
00756 const char * ptr = *strptr;
00757 JDIMENSION val = 0;
00758
00759 for (; isdigit(*ptr); ptr++) {
00760 val = val * 10 + (JDIMENSION) (*ptr - '0');
00761 }
00762 *result = val;
00763 if (ptr == *strptr)
00764 return FALSE;
00765 *strptr = ptr;
00766 return TRUE;
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 GLOBAL(boolean)
00784 jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
00785 {
00786 info->crop = FALSE;
00787 info->crop_width_set = JCROP_UNSET;
00788 info->crop_height_set = JCROP_UNSET;
00789 info->crop_xoffset_set = JCROP_UNSET;
00790 info->crop_yoffset_set = JCROP_UNSET;
00791
00792 if (isdigit(*spec)) {
00793
00794 if (! jt_read_integer(&spec, &info->crop_width))
00795 return FALSE;
00796 info->crop_width_set = JCROP_POS;
00797 }
00798 if (*spec == 'x' || *spec == 'X') {
00799
00800 spec++;
00801 if (! jt_read_integer(&spec, &info->crop_height))
00802 return FALSE;
00803 info->crop_height_set = JCROP_POS;
00804 }
00805 if (*spec == '+' || *spec == '-') {
00806
00807 info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
00808 spec++;
00809 if (! jt_read_integer(&spec, &info->crop_xoffset))
00810 return FALSE;
00811 }
00812 if (*spec == '+' || *spec == '-') {
00813
00814 info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
00815 spec++;
00816 if (! jt_read_integer(&spec, &info->crop_yoffset))
00817 return FALSE;
00818 }
00819
00820 if (*spec != '\0')
00821 return FALSE;
00822 info->crop = TRUE;
00823 return TRUE;
00824 }
00825
00826
00827
00828
00829 LOCAL(void)
00830 trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
00831 {
00832 JDIMENSION MCU_cols;
00833
00834 MCU_cols = info->output_width / info->iMCU_sample_width;
00835 if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
00836 full_width / info->iMCU_sample_width)
00837 info->output_width = MCU_cols * info->iMCU_sample_width;
00838 }
00839
00840 LOCAL(void)
00841 trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
00842 {
00843 JDIMENSION MCU_rows;
00844
00845 MCU_rows = info->output_height / info->iMCU_sample_height;
00846 if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
00847 full_height / info->iMCU_sample_height)
00848 info->output_height = MCU_rows * info->iMCU_sample_height;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 GLOBAL(boolean)
00870 jtransform_request_workspace (j_decompress_ptr srcinfo,
00871 jpeg_transform_info *info)
00872 {
00873 jvirt_barray_ptr *coef_arrays;
00874 boolean need_workspace, transpose_it;
00875 jpeg_component_info *compptr;
00876 JDIMENSION xoffset, yoffset;
00877 JDIMENSION width_in_iMCUs, height_in_iMCUs;
00878 JDIMENSION width_in_blocks, height_in_blocks;
00879 int ci, h_samp_factor, v_samp_factor;
00880
00881
00882 if (info->force_grayscale &&
00883 srcinfo->jpeg_color_space == JCS_YCbCr &&
00884 srcinfo->num_components == 3)
00885
00886 info->num_components = 1;
00887 else
00888
00889 info->num_components = srcinfo->num_components;
00890
00891
00892 jpeg_core_output_dimensions(srcinfo);
00893
00894
00895
00896 if (info->perfect) {
00897 if (info->num_components == 1) {
00898 if (!jtransform_perfect_transform(srcinfo->output_width,
00899 srcinfo->output_height,
00900 srcinfo->min_DCT_h_scaled_size,
00901 srcinfo->min_DCT_v_scaled_size,
00902 info->transform))
00903 return FALSE;
00904 } else {
00905 if (!jtransform_perfect_transform(srcinfo->output_width,
00906 srcinfo->output_height,
00907 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size,
00908 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size,
00909 info->transform))
00910 return FALSE;
00911 }
00912 }
00913
00914
00915
00916
00917
00918
00919 switch (info->transform) {
00920 case JXFORM_TRANSPOSE:
00921 case JXFORM_TRANSVERSE:
00922 case JXFORM_ROT_90:
00923 case JXFORM_ROT_270:
00924 info->output_width = srcinfo->output_height;
00925 info->output_height = srcinfo->output_width;
00926 if (info->num_components == 1) {
00927 info->iMCU_sample_width = srcinfo->min_DCT_v_scaled_size;
00928 info->iMCU_sample_height = srcinfo->min_DCT_h_scaled_size;
00929 } else {
00930 info->iMCU_sample_width =
00931 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size;
00932 info->iMCU_sample_height =
00933 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size;
00934 }
00935 break;
00936 default:
00937 info->output_width = srcinfo->output_width;
00938 info->output_height = srcinfo->output_height;
00939 if (info->num_components == 1) {
00940 info->iMCU_sample_width = srcinfo->min_DCT_h_scaled_size;
00941 info->iMCU_sample_height = srcinfo->min_DCT_v_scaled_size;
00942 } else {
00943 info->iMCU_sample_width =
00944 srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size;
00945 info->iMCU_sample_height =
00946 srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size;
00947 }
00948 break;
00949 }
00950
00951
00952
00953
00954 if (info->crop) {
00955
00956 if (info->crop_xoffset_set == JCROP_UNSET)
00957 info->crop_xoffset = 0;
00958 if (info->crop_yoffset_set == JCROP_UNSET)
00959 info->crop_yoffset = 0;
00960 if (info->crop_xoffset >= info->output_width ||
00961 info->crop_yoffset >= info->output_height)
00962 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
00963 if (info->crop_width_set == JCROP_UNSET)
00964 info->crop_width = info->output_width - info->crop_xoffset;
00965 if (info->crop_height_set == JCROP_UNSET)
00966 info->crop_height = info->output_height - info->crop_yoffset;
00967
00968 if (info->crop_width <= 0 || info->crop_width > info->output_width ||
00969 info->crop_height <= 0 || info->crop_height > info->output_height ||
00970 info->crop_xoffset > info->output_width - info->crop_width ||
00971 info->crop_yoffset > info->output_height - info->crop_height)
00972 ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
00973
00974 if (info->crop_xoffset_set == JCROP_NEG)
00975 xoffset = info->output_width - info->crop_width - info->crop_xoffset;
00976 else
00977 xoffset = info->crop_xoffset;
00978 if (info->crop_yoffset_set == JCROP_NEG)
00979 yoffset = info->output_height - info->crop_height - info->crop_yoffset;
00980 else
00981 yoffset = info->crop_yoffset;
00982
00983 info->output_width =
00984 info->crop_width + (xoffset % info->iMCU_sample_width);
00985 info->output_height =
00986 info->crop_height + (yoffset % info->iMCU_sample_height);
00987
00988 info->x_crop_offset = xoffset / info->iMCU_sample_width;
00989 info->y_crop_offset = yoffset / info->iMCU_sample_height;
00990 } else {
00991 info->x_crop_offset = 0;
00992 info->y_crop_offset = 0;
00993 }
00994
00995
00996
00997
00998 need_workspace = FALSE;
00999 transpose_it = FALSE;
01000 switch (info->transform) {
01001 case JXFORM_NONE:
01002 if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
01003 need_workspace = TRUE;
01004
01005 break;
01006 case JXFORM_FLIP_H:
01007 if (info->trim)
01008 trim_right_edge(info, srcinfo->output_width);
01009 if (info->y_crop_offset != 0)
01010 need_workspace = TRUE;
01011
01012 break;
01013 case JXFORM_FLIP_V:
01014 if (info->trim)
01015 trim_bottom_edge(info, srcinfo->output_height);
01016
01017 need_workspace = TRUE;
01018 break;
01019 case JXFORM_TRANSPOSE:
01020
01021
01022 need_workspace = TRUE;
01023 transpose_it = TRUE;
01024 break;
01025 case JXFORM_TRANSVERSE:
01026 if (info->trim) {
01027 trim_right_edge(info, srcinfo->output_height);
01028 trim_bottom_edge(info, srcinfo->output_width);
01029 }
01030
01031 need_workspace = TRUE;
01032 transpose_it = TRUE;
01033 break;
01034 case JXFORM_ROT_90:
01035 if (info->trim)
01036 trim_right_edge(info, srcinfo->output_height);
01037
01038 need_workspace = TRUE;
01039 transpose_it = TRUE;
01040 break;
01041 case JXFORM_ROT_180:
01042 if (info->trim) {
01043 trim_right_edge(info, srcinfo->output_width);
01044 trim_bottom_edge(info, srcinfo->output_height);
01045 }
01046
01047 need_workspace = TRUE;
01048 break;
01049 case JXFORM_ROT_270:
01050 if (info->trim)
01051 trim_bottom_edge(info, srcinfo->output_width);
01052
01053 need_workspace = TRUE;
01054 transpose_it = TRUE;
01055 break;
01056 }
01057
01058
01059
01060
01061
01062 if (need_workspace) {
01063 coef_arrays = (jvirt_barray_ptr *)
01064 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
01065 SIZEOF(jvirt_barray_ptr) * info->num_components);
01066 width_in_iMCUs = (JDIMENSION)
01067 jdiv_round_up((long) info->output_width,
01068 (long) info->iMCU_sample_width);
01069 height_in_iMCUs = (JDIMENSION)
01070 jdiv_round_up((long) info->output_height,
01071 (long) info->iMCU_sample_height);
01072 for (ci = 0; ci < info->num_components; ci++) {
01073 compptr = srcinfo->comp_info + ci;
01074 if (info->num_components == 1) {
01075
01076 h_samp_factor = v_samp_factor = 1;
01077 } else if (transpose_it) {
01078 h_samp_factor = compptr->v_samp_factor;
01079 v_samp_factor = compptr->h_samp_factor;
01080 } else {
01081 h_samp_factor = compptr->h_samp_factor;
01082 v_samp_factor = compptr->v_samp_factor;
01083 }
01084 width_in_blocks = width_in_iMCUs * h_samp_factor;
01085 height_in_blocks = height_in_iMCUs * v_samp_factor;
01086 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
01087 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
01088 width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
01089 }
01090 info->workspace_coef_arrays = coef_arrays;
01091 } else
01092 info->workspace_coef_arrays = NULL;
01093
01094 return TRUE;
01095 }
01096
01097
01098
01099
01100 LOCAL(void)
01101 transpose_critical_parameters (j_compress_ptr dstinfo)
01102 {
01103 int tblno, i, j, ci, itemp;
01104 jpeg_component_info *compptr;
01105 JQUANT_TBL *qtblptr;
01106 JDIMENSION jtemp;
01107 UINT16 qtemp;
01108
01109
01110 jtemp = dstinfo->image_width;
01111 dstinfo->image_width = dstinfo->image_height;
01112 dstinfo->image_height = jtemp;
01113 itemp = dstinfo->min_DCT_h_scaled_size;
01114 dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
01115 dstinfo->min_DCT_v_scaled_size = itemp;
01116
01117
01118 for (ci = 0; ci < dstinfo->num_components; ci++) {
01119 compptr = dstinfo->comp_info + ci;
01120 itemp = compptr->h_samp_factor;
01121 compptr->h_samp_factor = compptr->v_samp_factor;
01122 compptr->v_samp_factor = itemp;
01123 }
01124
01125
01126 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
01127 qtblptr = dstinfo->quant_tbl_ptrs[tblno];
01128 if (qtblptr != NULL) {
01129 for (i = 0; i < DCTSIZE; i++) {
01130 for (j = 0; j < i; j++) {
01131 qtemp = qtblptr->quantval[i*DCTSIZE+j];
01132 qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
01133 qtblptr->quantval[j*DCTSIZE+i] = qtemp;
01134 }
01135 }
01136 }
01137 }
01138 }
01139
01140
01141
01142
01143
01144
01145
01146 LOCAL(void)
01147 adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
01148 JDIMENSION new_width, JDIMENSION new_height)
01149 {
01150 boolean is_motorola;
01151 unsigned int number_of_tags, tagnum;
01152 unsigned int firstoffset, offset;
01153 JDIMENSION new_value;
01154
01155 if (length < 12) return;
01156
01157
01158 if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
01159 is_motorola = FALSE;
01160 else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
01161 is_motorola = TRUE;
01162 else
01163 return;
01164
01165
01166 if (is_motorola) {
01167 if (GETJOCTET(data[2]) != 0) return;
01168 if (GETJOCTET(data[3]) != 0x2A) return;
01169 } else {
01170 if (GETJOCTET(data[3]) != 0) return;
01171 if (GETJOCTET(data[2]) != 0x2A) return;
01172 }
01173
01174
01175 if (is_motorola) {
01176 if (GETJOCTET(data[4]) != 0) return;
01177 if (GETJOCTET(data[5]) != 0) return;
01178 firstoffset = GETJOCTET(data[6]);
01179 firstoffset <<= 8;
01180 firstoffset += GETJOCTET(data[7]);
01181 } else {
01182 if (GETJOCTET(data[7]) != 0) return;
01183 if (GETJOCTET(data[6]) != 0) return;
01184 firstoffset = GETJOCTET(data[5]);
01185 firstoffset <<= 8;
01186 firstoffset += GETJOCTET(data[4]);
01187 }
01188 if (firstoffset > length - 2) return;
01189
01190
01191 if (is_motorola) {
01192 number_of_tags = GETJOCTET(data[firstoffset]);
01193 number_of_tags <<= 8;
01194 number_of_tags += GETJOCTET(data[firstoffset+1]);
01195 } else {
01196 number_of_tags = GETJOCTET(data[firstoffset+1]);
01197 number_of_tags <<= 8;
01198 number_of_tags += GETJOCTET(data[firstoffset]);
01199 }
01200 if (number_of_tags == 0) return;
01201 firstoffset += 2;
01202
01203
01204 for (;;) {
01205 if (firstoffset > length - 12) return;
01206
01207 if (is_motorola) {
01208 tagnum = GETJOCTET(data[firstoffset]);
01209 tagnum <<= 8;
01210 tagnum += GETJOCTET(data[firstoffset+1]);
01211 } else {
01212 tagnum = GETJOCTET(data[firstoffset+1]);
01213 tagnum <<= 8;
01214 tagnum += GETJOCTET(data[firstoffset]);
01215 }
01216 if (tagnum == 0x8769) break;
01217 if (--number_of_tags == 0) return;
01218 firstoffset += 12;
01219 }
01220
01221
01222 if (is_motorola) {
01223 if (GETJOCTET(data[firstoffset+8]) != 0) return;
01224 if (GETJOCTET(data[firstoffset+9]) != 0) return;
01225 offset = GETJOCTET(data[firstoffset+10]);
01226 offset <<= 8;
01227 offset += GETJOCTET(data[firstoffset+11]);
01228 } else {
01229 if (GETJOCTET(data[firstoffset+11]) != 0) return;
01230 if (GETJOCTET(data[firstoffset+10]) != 0) return;
01231 offset = GETJOCTET(data[firstoffset+9]);
01232 offset <<= 8;
01233 offset += GETJOCTET(data[firstoffset+8]);
01234 }
01235 if (offset > length - 2) return;
01236
01237
01238 if (is_motorola) {
01239 number_of_tags = GETJOCTET(data[offset]);
01240 number_of_tags <<= 8;
01241 number_of_tags += GETJOCTET(data[offset+1]);
01242 } else {
01243 number_of_tags = GETJOCTET(data[offset+1]);
01244 number_of_tags <<= 8;
01245 number_of_tags += GETJOCTET(data[offset]);
01246 }
01247 if (number_of_tags < 2) return;
01248 offset += 2;
01249
01250
01251 do {
01252 if (offset > length - 12) return;
01253
01254 if (is_motorola) {
01255 tagnum = GETJOCTET(data[offset]);
01256 tagnum <<= 8;
01257 tagnum += GETJOCTET(data[offset+1]);
01258 } else {
01259 tagnum = GETJOCTET(data[offset+1]);
01260 tagnum <<= 8;
01261 tagnum += GETJOCTET(data[offset]);
01262 }
01263 if (tagnum == 0xA002 || tagnum == 0xA003) {
01264 if (tagnum == 0xA002)
01265 new_value = new_width;
01266 else
01267 new_value = new_height;
01268 if (is_motorola) {
01269 data[offset+2] = 0;
01270 data[offset+3] = 4;
01271 data[offset+4] = 0;
01272 data[offset+5] = 0;
01273 data[offset+6] = 0;
01274 data[offset+7] = 1;
01275 data[offset+8] = 0;
01276 data[offset+9] = 0;
01277 data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
01278 data[offset+11] = (JOCTET)(new_value & 0xFF);
01279 } else {
01280 data[offset+2] = 4;
01281 data[offset+3] = 0;
01282 data[offset+4] = 1;
01283 data[offset+5] = 0;
01284 data[offset+6] = 0;
01285 data[offset+7] = 0;
01286 data[offset+8] = (JOCTET)(new_value & 0xFF);
01287 data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
01288 data[offset+10] = 0;
01289 data[offset+11] = 0;
01290 }
01291 }
01292 offset += 12;
01293 } while (--number_of_tags);
01294 }
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 GLOBAL(jvirt_barray_ptr *)
01309 jtransform_adjust_parameters (j_decompress_ptr srcinfo,
01310 j_compress_ptr dstinfo,
01311 jvirt_barray_ptr *src_coef_arrays,
01312 jpeg_transform_info *info)
01313 {
01314
01315 if (info->force_grayscale) {
01316
01317
01318
01319
01320
01321 if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
01322 dstinfo->num_components == 3) ||
01323 (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
01324 dstinfo->num_components == 1)) &&
01325 srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
01326 srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
01327
01328
01329
01330
01331
01332 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
01333 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
01334 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
01335 } else {
01336
01337 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
01338 }
01339 } else if (info->num_components == 1) {
01340
01341
01342
01343
01344 dstinfo->comp_info[0].h_samp_factor = 1;
01345 dstinfo->comp_info[0].v_samp_factor = 1;
01346 }
01347
01348
01349
01350
01351 dstinfo->jpeg_width = info->output_width;
01352 dstinfo->jpeg_height = info->output_height;
01353
01354
01355 switch (info->transform) {
01356 case JXFORM_TRANSPOSE:
01357 case JXFORM_TRANSVERSE:
01358 case JXFORM_ROT_90:
01359 case JXFORM_ROT_270:
01360 transpose_critical_parameters(dstinfo);
01361 break;
01362 default:
01363 break;
01364 }
01365
01366
01367 if (srcinfo->marker_list != NULL &&
01368 srcinfo->marker_list->marker == JPEG_APP0+1 &&
01369 srcinfo->marker_list->data_length >= 6 &&
01370 GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
01371 GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
01372 GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
01373 GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
01374 GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
01375 GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
01376
01377 dstinfo->write_JFIF_header = FALSE;
01378
01379 if (dstinfo->jpeg_width != srcinfo->image_width ||
01380 dstinfo->jpeg_height != srcinfo->image_height)
01381
01382 adjust_exif_parameters(srcinfo->marker_list->data + 6,
01383 srcinfo->marker_list->data_length - 6,
01384 dstinfo->jpeg_width, dstinfo->jpeg_height);
01385 }
01386
01387
01388 if (info->workspace_coef_arrays != NULL)
01389 return info->workspace_coef_arrays;
01390 return src_coef_arrays;
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 GLOBAL(void)
01404 jtransform_execute_transform (j_decompress_ptr srcinfo,
01405 j_compress_ptr dstinfo,
01406 jvirt_barray_ptr *src_coef_arrays,
01407 jpeg_transform_info *info)
01408 {
01409 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
01410
01411
01412
01413
01414 switch (info->transform) {
01415 case JXFORM_NONE:
01416 if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
01417 do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01418 src_coef_arrays, dst_coef_arrays);
01419 break;
01420 case JXFORM_FLIP_H:
01421 if (info->y_crop_offset != 0)
01422 do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01423 src_coef_arrays, dst_coef_arrays);
01424 else
01425 do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
01426 src_coef_arrays);
01427 break;
01428 case JXFORM_FLIP_V:
01429 do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01430 src_coef_arrays, dst_coef_arrays);
01431 break;
01432 case JXFORM_TRANSPOSE:
01433 do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01434 src_coef_arrays, dst_coef_arrays);
01435 break;
01436 case JXFORM_TRANSVERSE:
01437 do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01438 src_coef_arrays, dst_coef_arrays);
01439 break;
01440 case JXFORM_ROT_90:
01441 do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01442 src_coef_arrays, dst_coef_arrays);
01443 break;
01444 case JXFORM_ROT_180:
01445 do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01446 src_coef_arrays, dst_coef_arrays);
01447 break;
01448 case JXFORM_ROT_270:
01449 do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
01450 src_coef_arrays, dst_coef_arrays);
01451 break;
01452 }
01453 }
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 GLOBAL(boolean)
01477 jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
01478 int MCU_width, int MCU_height,
01479 JXFORM_CODE transform)
01480 {
01481 boolean result = TRUE;
01482
01483 switch (transform) {
01484 case JXFORM_FLIP_H:
01485 case JXFORM_ROT_270:
01486 if (image_width % (JDIMENSION) MCU_width)
01487 result = FALSE;
01488 break;
01489 case JXFORM_FLIP_V:
01490 case JXFORM_ROT_90:
01491 if (image_height % (JDIMENSION) MCU_height)
01492 result = FALSE;
01493 break;
01494 case JXFORM_TRANSVERSE:
01495 case JXFORM_ROT_180:
01496 if (image_width % (JDIMENSION) MCU_width)
01497 result = FALSE;
01498 if (image_height % (JDIMENSION) MCU_height)
01499 result = FALSE;
01500 break;
01501 default:
01502 break;
01503 }
01504
01505 return result;
01506 }
01507
01508 #endif
01509
01510
01511
01512
01513
01514
01515 GLOBAL(void)
01516 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
01517 {
01518 #ifdef SAVE_MARKERS_SUPPORTED
01519 int m;
01520
01521
01522 if (option != JCOPYOPT_NONE) {
01523 jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
01524 }
01525
01526 if (option == JCOPYOPT_ALL) {
01527 for (m = 0; m < 16; m++)
01528 jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
01529 }
01530 #endif
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540 GLOBAL(void)
01541 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
01542 JCOPY_OPTION option)
01543 {
01544 jpeg_saved_marker_ptr marker;
01545
01546
01547
01548
01549
01550
01551 for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
01552 if (dstinfo->write_JFIF_header &&
01553 marker->marker == JPEG_APP0 &&
01554 marker->data_length >= 5 &&
01555 GETJOCTET(marker->data[0]) == 0x4A &&
01556 GETJOCTET(marker->data[1]) == 0x46 &&
01557 GETJOCTET(marker->data[2]) == 0x49 &&
01558 GETJOCTET(marker->data[3]) == 0x46 &&
01559 GETJOCTET(marker->data[4]) == 0)
01560 continue;
01561 if (dstinfo->write_Adobe_marker &&
01562 marker->marker == JPEG_APP0+14 &&
01563 marker->data_length >= 5 &&
01564 GETJOCTET(marker->data[0]) == 0x41 &&
01565 GETJOCTET(marker->data[1]) == 0x64 &&
01566 GETJOCTET(marker->data[2]) == 0x6F &&
01567 GETJOCTET(marker->data[3]) == 0x62 &&
01568 GETJOCTET(marker->data[4]) == 0x65)
01569 continue;
01570 #ifdef NEED_FAR_POINTERS
01571
01572 {
01573 unsigned int i;
01574 jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
01575 for (i = 0; i < marker->data_length; i++)
01576 jpeg_write_m_byte(dstinfo, marker->data[i]);
01577 }
01578 #else
01579 jpeg_write_marker(dstinfo, marker->marker,
01580 marker->data, marker->data_length);
01581 #endif
01582 }
01583 }