diff options
author | Rene Wagner <rw@handhelds.org> | 2006-05-13 15:42:03 +0200 |
---|---|---|
committer | Rene Wagner <rw@handhelds.org> | 2006-05-13 15:42:03 +0200 |
commit | 5a5346dfbec459c10d9e61e16e125b83975a1ef1 (patch) | |
tree | 342e16f3fe790d03b93294344e6154459888939f /org.handhelds.familiar/packages/jpeg |
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e35772d79306d1d9de19c12b23681618532d.
Diffstat (limited to 'org.handhelds.familiar/packages/jpeg')
5 files changed, 10156 insertions, 0 deletions
diff --git a/org.handhelds.familiar/packages/jpeg/jpeg-6b/debian.patch b/org.handhelds.familiar/packages/jpeg/jpeg-6b/debian.patch new file mode 100644 index 0000000..823c8e0 --- /dev/null +++ b/org.handhelds.familiar/packages/jpeg/jpeg-6b/debian.patch @@ -0,0 +1,10014 @@ + +# +# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +--- jpeg-6b/jpegtran.1~libjpeg6bb-5 ++++ jpeg-6b/jpegtran.1 +@@ -131,6 +131,24 @@ + .B \-rot 180 -trim + trims both edges. + .PP ++We also offer a lossless-crop option, which discards data outside a given ++image region but losslessly preserves what is inside. Like the rotate and ++flip transforms, lossless crop is restricted by the JPEG format: the upper ++left corner of the selected region must fall on an iMCU boundary. If this ++does not hold for the given crop parameters, we silently move the upper left ++corner up and/or left to make it so, simultaneously increasing the region ++dimensions to keep the lower right crop corner unchanged. (Thus, the ++output image covers at least the requested region, but may cover more.) ++ ++Note: lossless-crop is an enhancement from http://sylvana.net/jpegcrop/ ++that may not be available on non-Debian systems. ++ ++The image can be losslessly cropped by giving the switch: ++.TP ++.B \-crop WxH+X+Y ++Crop to a rectangular subarea of width W, height H starting at point X,Y. ++.PP ++.PP + Another not-strictly-lossless transformation switch is: + .TP + .B \-grayscale +--- jpeg-6b/configure~libjpeg6bb-5 ++++ jpeg-6b/configure +@@ -52,7 +52,7 @@ + includedir='${prefix}/include' + oldincludedir='/usr/include' + infodir='${prefix}/info' +-mandir='${prefix}/man' ++mandir='${prefix}/share/man' + + # Initialize some other variables. + subdirs= +@@ -1559,7 +1559,8 @@ + if test "x$LTSTATIC" = xno; then + disable_static="--disable-static" + fi +- $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh ++ chmod a+x $srcdir/ltconfig.new ++ $srcdir/ltconfig.new $disable_shared $disable_static $srcdir/ltmain.new.sh $host + fi + + # Select memory manager depending on user input. +--- jpeg-6b/makefile.cfg~libjpeg6bb-5 ++++ jpeg-6b/makefile.cfg +@@ -17,7 +17,7 @@ + binprefix = + manprefix = + manext = 1 +-mandir = $(prefix)/man/man$(manext) ++mandir = $(prefix)/share/man/man$(manext) + + # The name of your C compiler: + CC= @CC@ +@@ -210,6 +210,11 @@ + $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h + $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h + $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h ++#<ballombe@debian.org>:mjpegtools require this file to build and header say: ++# * These declarations are considered internal to the JPEG library; most ++# * applications using the library shouldn't need to include this file. ++# So it is not forbidden to use it, therefore it must be installed. ++ $(INSTALL_DATA) $(srcdir)/jpegint.h $(includedir)/jpegint.h + + clean: + $(RM) *.o *.lo libjpeg.a libjpeg.la +--- jpeg-6b/jpegtran.c~libjpeg6bb-5 ++++ jpeg-6b/jpegtran.c +@@ -1,7 +1,7 @@ + /* + * jpegtran.c + * +- * Copyright (C) 1995-1997, Thomas G. Lane. ++ * Copyright (C) 1995-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * +@@ -64,6 +64,7 @@ + #endif + #if TRANSFORMS_SUPPORTED + fprintf(stderr, "Switches for modifying the image:\n"); ++ fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n"); + fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n"); + fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n"); + fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n"); +@@ -134,6 +135,7 @@ + transformoption.transform = JXFORM_NONE; + transformoption.trim = FALSE; + transformoption.force_grayscale = FALSE; ++ transformoption.crop = FALSE; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ +@@ -160,7 +162,7 @@ + exit(EXIT_FAILURE); + #endif + +- } else if (keymatch(arg, "copy", 1)) { ++ } else if (keymatch(arg, "copy", 2)) { + /* Select which extra markers to copy. */ + if (++argn >= argc) /* advance to next argument */ + usage(); +@@ -173,6 +175,20 @@ + } else + usage(); + ++ } else if (keymatch(arg, "crop", 2)) { ++ /* Perform lossless cropping. */ ++#if TRANSFORMS_SUPPORTED ++ if (++argn >= argc) /* advance to next argument */ ++ usage(); ++ if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) { ++ fprintf(stderr, "%s: bogus -crop argument '%s'\n", ++ progname, argv[argn]); ++ exit(EXIT_FAILURE); ++ } ++#else ++ select_transform(JXFORM_NONE); /* force an error */ ++#endif ++ + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ +@@ -342,8 +358,10 @@ + jvirt_barray_ptr * src_coef_arrays; + jvirt_barray_ptr * dst_coef_arrays; + int file_index; +- FILE * input_file; +- FILE * output_file; ++ /* We assume all-in-memory processing and can therefore use only a ++ * single file pointer for sequential input and output operation. ++ */ ++ FILE * fp; + + /* On Mac, fetch a command line. */ + #ifdef USE_CCOMMAND +@@ -406,24 +424,13 @@ + + /* Open the input file. */ + if (file_index < argc) { +- if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { ++ if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ +- input_file = read_stdin(); +- } +- +- /* Open the output file. */ +- if (outfilename != NULL) { +- if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { +- fprintf(stderr, "%s: can't open %s\n", progname, outfilename); +- exit(EXIT_FAILURE); +- } +- } else { +- /* default output file is stdout */ +- output_file = write_stdout(); ++ fp = read_stdin(); + } + + #ifdef PROGRESS_REPORT +@@ -431,7 +438,7 @@ + #endif + + /* Specify data source for decompression */ +- jpeg_stdio_src(&srcinfo, input_file); ++ jpeg_stdio_src(&srcinfo, fp); + + /* Enable saving of extra markers that we want to copy */ + jcopy_markers_setup(&srcinfo, copyoption); +@@ -463,11 +470,32 @@ + dst_coef_arrays = src_coef_arrays; + #endif + ++ /* Close input file, if we opened it. ++ * Note: we assume that jpeg_read_coefficients consumed all input ++ * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will ++ * only consume more while (! cinfo->inputctl->eoi_reached). ++ * We cannot call jpeg_finish_decompress here since we still need the ++ * virtual arrays allocated from the source object for processing. ++ */ ++ if (fp != stdin) ++ fclose(fp); ++ ++ /* Open the output file. */ ++ if (outfilename != NULL) { ++ if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) { ++ fprintf(stderr, "%s: can't open %s\n", progname, outfilename); ++ exit(EXIT_FAILURE); ++ } ++ } else { ++ /* default output file is stdout */ ++ fp = write_stdout(); ++ } ++ + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ +- jpeg_stdio_dest(&dstinfo, output_file); ++ jpeg_stdio_dest(&dstinfo, fp); + + /* Start compressor (note no image data is actually written here) */ + jpeg_write_coefficients(&dstinfo, dst_coef_arrays); +@@ -488,11 +516,9 @@ + (void) jpeg_finish_decompress(&srcinfo); + jpeg_destroy_decompress(&srcinfo); + +- /* Close files, if we opened them */ +- if (input_file != stdin) +- fclose(input_file); +- if (output_file != stdout) +- fclose(output_file); ++ /* Close output file, if we opened it */ ++ if (fp != stdout) ++ fclose(fp); + + #ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &dstinfo); +--- jpeg-6b/rdjpgcom.c~libjpeg6bb-5 ++++ jpeg-6b/rdjpgcom.c +@@ -14,6 +14,7 @@ + #define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ + #include "jinclude.h" /* get auto-config symbols, <stdio.h> */ + ++#include <locale.h> /*ballombe@debian.org: use locale for isprint*/ + #include <ctype.h> /* to declare isupper(), tolower() */ + #ifdef USE_SETMODE + #include <fcntl.h> /* to declare setmode()'s parameter macros */ +@@ -223,7 +224,10 @@ + unsigned int length; + int ch; + int lastch = 0; +- ++/* ballombe@debian.org Thu, 15 Nov 2001 20:04:47 +0100*/ ++/* Set locale properly for isprint*/ ++ setlocale(LC_CTYPE,""); ++ + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ +@@ -254,6 +258,8 @@ + length--; + } + printf("\n"); ++/*ballombe@debian.org: revert to C locale*/ ++ setlocale(LC_CTYPE,"C"); + } + + +--- jpeg-6b/transupp.c~libjpeg6bb-5 ++++ jpeg-6b/transupp.c +@@ -1,7 +1,7 @@ + /* + * transupp.c + * +- * Copyright (C) 1997, Thomas G. Lane. ++ * Copyright (C) 1997-2001, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * +@@ -20,6 +20,7 @@ + #include "jinclude.h" + #include "jpeglib.h" + #include "transupp.h" /* My own external interface */ ++#include <ctype.h> /* to declare isdigit() */ + + + #if TRANSFORMS_SUPPORTED +@@ -28,7 +29,8 @@ + * Lossless image transformation routines. These routines work on DCT + * coefficient arrays and thus do not require any lossy decompression + * or recompression of the image. +- * Thanks to Guido Vollbeding for the initial design and code of this feature. ++ * Thanks to Guido Vollbeding for the initial design and code of this feature, ++ * and to Ben Jackson for introducing the cropping feature. + * + * Horizontal flipping is done in-place, using a single top-to-bottom + * pass through the virtual source array. It will thus be much the +@@ -42,6 +44,13 @@ + * arrays for most of the transforms. That could result in much thrashing + * if the image is larger than main memory. + * ++ * If cropping or trimming is involved, the destination arrays may be smaller ++ * than the source arrays. Note it is not possible to do horizontal flip ++ * in-place when a nonzero Y crop offset is specified, since we'd have to move ++ * data from one block row to another but the virtual array manager doesn't ++ * guarantee we can touch more than one row at a time. So in that case, ++ * we have to use a separate destination array. ++ * + * Some notes about the operating environment of the individual transform + * routines: + * 1. Both the source and destination virtual arrays are allocated from the +@@ -54,20 +63,65 @@ + * and we may as well take that as the effective iMCU size. + * 4. When "trim" is in effect, the destination's dimensions will be the + * trimmed values but the source's will be untrimmed. +- * 5. All the routines assume that the source and destination buffers are ++ * 5. When "crop" is in effect, the destination's dimensions will be the ++ * cropped values but the source's will be uncropped. Each transform ++ * routine is responsible for picking up source data starting at the ++ * correct X and Y offset for the crop region. (The X and Y offsets ++ * passed to the transform routines are measured in iMCU blocks of the ++ * destination.) ++ * 6. All the routines assume that the source and destination buffers are + * padded out to a full iMCU boundary. This is true, although for the + * source buffer it is an undocumented property of jdcoefct.c. +- * Notes 2,3,4 boil down to this: generally we should use the destination's +- * dimensions and ignore the source's. + */ + + + LOCAL(void) +-do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, +- jvirt_barray_ptr *src_coef_arrays) +-/* Horizontal flip; done in-place, so no separate dest array is required */ ++do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, ++ jvirt_barray_ptr *src_coef_arrays, ++ jvirt_barray_ptr *dst_coef_arrays) ++/* Crop. This is only used when no rotate/flip is requested with the crop. */ + { +- JDIMENSION MCU_cols, comp_width, blk_x, blk_y; ++ JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks; ++ int ci, offset_y; ++ JBLOCKARRAY src_buffer, dst_buffer; ++ jpeg_component_info *compptr; ++ ++ /* We simply have to copy the right amount of data (the destination's ++ * image size) starting at the given X and Y offsets in the source. ++ */ ++ for (ci = 0; ci < dstinfo->num_components; ci++) { ++ compptr = dstinfo->comp_info + ci; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; ++ for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; ++ dst_blk_y += compptr->v_samp_factor) { ++ dst_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, ++ (JDIMENSION) compptr->v_samp_factor, TRUE); ++ src_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_y + y_crop_blocks, ++ (JDIMENSION) compptr->v_samp_factor, FALSE); ++ for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { ++ jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, ++ dst_buffer[offset_y], ++ compptr->width_in_blocks); ++ } ++ } ++ } ++} ++ ++ ++LOCAL(void) ++do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, ++ jvirt_barray_ptr *src_coef_arrays) ++/* Horizontal flip; done in-place, so no separate dest array is required. ++ * NB: this only works when y_crop_offset is zero. ++ */ ++{ ++ JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks; + int ci, k, offset_y; + JBLOCKARRAY buffer; + JCOEFPTR ptr1, ptr2; +@@ -79,17 +133,19 @@ + * mirroring by changing the signs of odd-numbered columns. + * Partial iMCUs at the right edge are left untouched. + */ +- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); ++ MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; + for (blk_y = 0; blk_y < compptr->height_in_blocks; + blk_y += compptr->v_samp_factor) { + buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { ++ /* Do the mirroring */ + for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { + ptr1 = buffer[offset_y][blk_x]; + ptr2 = buffer[offset_y][comp_width - blk_x - 1]; +@@ -105,6 +161,79 @@ + *ptr2++ = -temp1; + } + } ++ if (x_crop_blocks > 0) { ++ /* Now left-justify the portion of the data to be kept. ++ * We can't use a single jcopy_block_row() call because that routine ++ * depends on memcpy(), whose behavior is unspecified for overlapping ++ * source and destination areas. Sigh. ++ */ ++ for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) { ++ jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks, ++ buffer[offset_y] + blk_x, ++ (JDIMENSION) 1); ++ } ++ } ++ } ++ } ++ } ++} ++ ++ ++LOCAL(void) ++do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, ++ jvirt_barray_ptr *src_coef_arrays, ++ jvirt_barray_ptr *dst_coef_arrays) ++/* Horizontal flip in general cropping case */ ++{ ++ JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; ++ int ci, k, offset_y; ++ JBLOCKARRAY src_buffer, dst_buffer; ++ JBLOCKROW src_row_ptr, dst_row_ptr; ++ JCOEFPTR src_ptr, dst_ptr; ++ jpeg_component_info *compptr; ++ ++ /* Here we must output into a separate array because we can't touch ++ * different rows of a single virtual array simultaneously. Otherwise, ++ * this is essentially the same as the routine above. ++ */ ++ MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); ++ ++ for (ci = 0; ci < dstinfo->num_components; ci++) { ++ compptr = dstinfo->comp_info + ci; ++ comp_width = MCU_cols * compptr->h_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; ++ for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; ++ dst_blk_y += compptr->v_samp_factor) { ++ dst_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, ++ (JDIMENSION) compptr->v_samp_factor, TRUE); ++ src_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_y + y_crop_blocks, ++ (JDIMENSION) compptr->v_samp_factor, FALSE); ++ for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { ++ dst_row_ptr = dst_buffer[offset_y]; ++ src_row_ptr = src_buffer[offset_y]; ++ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { ++ if (x_crop_blocks + dst_blk_x < comp_width) { ++ /* Do the mirrorable blocks */ ++ dst_ptr = dst_row_ptr[dst_blk_x]; ++ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; ++ /* this unrolled loop doesn't need to know which row it's on... */ ++ for (k = 0; k < DCTSIZE2; k += 2) { ++ *dst_ptr++ = *src_ptr++; /* copy even column */ ++ *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */ ++ } ++ } else { ++ /* Copy last partial block(s) verbatim */ ++ jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, ++ dst_row_ptr + dst_blk_x, ++ (JDIMENSION) 1); ++ } ++ } + } + } + } +@@ -113,11 +242,13 @@ + + LOCAL(void) + do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* Vertical flip */ + { + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; +@@ -131,33 +262,38 @@ + * of odd-numbered rows. + * Partial iMCUs at the bottom edge are copied verbatim. + */ +- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); ++ MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); +- if (dst_blk_y < comp_height) { ++ if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], +- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, ++ comp_height - y_crop_blocks - dst_blk_y - ++ (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge blocks will be copied verbatim. */ + src_buffer = (*srcinfo->mem->access_virt_barray) +- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { +- if (dst_blk_y < comp_height) { ++ if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; ++ src_row_ptr += x_crop_blocks; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; +@@ -173,7 +309,8 @@ + } + } else { + /* Just copy row verbatim. */ +- jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], ++ jcopy_block_row(src_buffer[offset_y] + x_crop_blocks, ++ dst_buffer[offset_y], + compptr->width_in_blocks); + } + } +@@ -184,11 +321,12 @@ + + LOCAL(void) + do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* Transpose source into destination */ + { +- JDIMENSION dst_blk_x, dst_blk_y; ++ JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; +@@ -201,6 +339,8 @@ + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) +@@ -210,11 +350,12 @@ + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) +- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { +- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; ++ src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; +@@ -228,6 +369,7 @@ + + LOCAL(void) + do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* 90 degree rotation is equivalent to +@@ -237,6 +379,7 @@ + */ + { + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; +@@ -246,11 +389,13 @@ + * at the (output) right edge properly. They just get transposed and + * not mirrored. + */ +- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); ++ MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) +@@ -259,15 +404,26 @@ + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { +- src_buffer = (*srcinfo->mem->access_virt_barray) +- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, +- (JDIMENSION) compptr->h_samp_factor, FALSE); ++ if (x_crop_blocks + dst_blk_x < comp_width) { ++ /* Block is within the mirrorable area. */ ++ src_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ comp_width - x_crop_blocks - dst_blk_x - ++ (JDIMENSION) compptr->h_samp_factor, ++ (JDIMENSION) compptr->h_samp_factor, FALSE); ++ } else { ++ /* Edge blocks are transposed but not mirrored. */ ++ src_buffer = (*srcinfo->mem->access_virt_barray) ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_x + x_crop_blocks, ++ (JDIMENSION) compptr->h_samp_factor, FALSE); ++ } + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { +- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; +- if (dst_blk_x < comp_width) { ++ dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; ++ if (x_crop_blocks + dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ +- dst_ptr = dst_buffer[offset_y] +- [comp_width - dst_blk_x - offset_x - 1]; ++ src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1] ++ [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; +@@ -277,7 +433,8 @@ + } + } else { + /* Edge blocks are transposed but not mirrored. */ +- dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; ++ src_ptr = src_buffer[offset_x] ++ [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; +@@ -292,6 +449,7 @@ + + LOCAL(void) + do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* 270 degree rotation is equivalent to +@@ -301,6 +459,7 @@ + */ + { + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; +@@ -310,11 +469,13 @@ + * at the (output) bottom edge properly. They just get transposed and + * not mirrored. + */ +- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); ++ MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) +@@ -324,14 +485,15 @@ + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) +- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_x + x_crop_blocks, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; +- if (dst_blk_y < comp_height) { ++ if (y_crop_blocks + dst_blk_y < comp_height) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[offset_x] +- [comp_height - dst_blk_y - offset_y - 1]; ++ [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; +@@ -341,7 +503,8 @@ + } + } else { + /* Edge blocks are transposed but not mirrored. */ +- src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; ++ src_ptr = src_buffer[offset_x] ++ [dst_blk_y + offset_y + y_crop_blocks]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; +@@ -356,6 +519,7 @@ + + LOCAL(void) + do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* 180 degree rotation is equivalent to +@@ -365,89 +529,93 @@ + */ + { + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + +- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); +- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); ++ MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); ++ MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); +- if (dst_blk_y < comp_height) { ++ if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the vertically mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], +- comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, ++ comp_height - y_crop_blocks - dst_blk_y - ++ (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge rows are only mirrored horizontally. */ + src_buffer = (*srcinfo->mem->access_virt_barray) +- ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, ++ ((j_common_ptr) srcinfo, src_coef_arrays[ci], ++ dst_blk_y + y_crop_blocks, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { +- if (dst_blk_y < comp_height) { ++ dst_row_ptr = dst_buffer[offset_y]; ++ if (y_crop_blocks + dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ +- dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; +- /* Process the blocks that can be mirrored both ways. */ +- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { ++ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; +- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; +- for (i = 0; i < DCTSIZE; i += 2) { +- /* For even row, negate every odd column. */ +- for (j = 0; j < DCTSIZE; j += 2) { +- *dst_ptr++ = *src_ptr++; +- *dst_ptr++ = - *src_ptr++; ++ if (x_crop_blocks + dst_blk_x < comp_width) { ++ /* Process the blocks that can be mirrored both ways. */ ++ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; ++ for (i = 0; i < DCTSIZE; i += 2) { ++ /* For even row, negate every odd column. */ ++ for (j = 0; j < DCTSIZE; j += 2) { ++ *dst_ptr++ = *src_ptr++; ++ *dst_ptr++ = - *src_ptr++; ++ } ++ /* For odd row, negate every even column. */ ++ for (j = 0; j < DCTSIZE; j += 2) { ++ *dst_ptr++ = - *src_ptr++; ++ *dst_ptr++ = *src_ptr++; ++ } + } +- /* For odd row, negate every even column. */ +- for (j = 0; j < DCTSIZE; j += 2) { +- *dst_ptr++ = - *src_ptr++; +- *dst_ptr++ = *src_ptr++; ++ } else { ++ /* Any remaining right-edge blocks are only mirrored vertically. */ ++ src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x]; ++ for (i = 0; i < DCTSIZE; i += 2) { ++ for (j = 0; j < DCTSIZE; j++) ++ *dst_ptr++ = *src_ptr++; ++ for (j = 0; j < DCTSIZE; j++) ++ *dst_ptr++ = - *src_ptr++; + } + } + } +- /* Any remaining right-edge blocks are only mirrored vertically. */ +- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { +- dst_ptr = dst_row_ptr[dst_blk_x]; +- src_ptr = src_row_ptr[dst_blk_x]; +- for (i = 0; i < DCTSIZE; i += 2) { +- for (j = 0; j < DCTSIZE; j++) +- *dst_ptr++ = *src_ptr++; +- for (j = 0; j < DCTSIZE; j++) +- *dst_ptr++ = - *src_ptr++; +- } +- } + } else { + /* Remaining rows are just mirrored horizontally. */ +- dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[offset_y]; +- /* Process the blocks that can be mirrored. */ +- for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { +- dst_ptr = dst_row_ptr[dst_blk_x]; +- src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; +- for (i = 0; i < DCTSIZE2; i += 2) { +- *dst_ptr++ = *src_ptr++; +- *dst_ptr++ = - *src_ptr++; ++ for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { ++ if (x_crop_blocks + dst_blk_x < comp_width) { ++ /* Process the blocks that can be mirrored. */ ++ dst_ptr = dst_row_ptr[dst_blk_x]; ++ src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1]; ++ for (i = 0; i < DCTSIZE2; i += 2) { ++ *dst_ptr++ = *src_ptr++; ++ *dst_ptr++ = - *src_ptr++; ++ } ++ } else { ++ /* Any remaining right-edge blocks are only copied. */ ++ jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks, ++ dst_row_ptr + dst_blk_x, ++ (JDIMENSION) 1); + } + } +- /* Any remaining right-edge blocks are only copied. */ +- for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { +- dst_ptr = dst_row_ptr[dst_blk_x]; +- src_ptr = src_row_ptr[dst_blk_x]; +- for (i = 0; i < DCTSIZE2; i++) +- *dst_ptr++ = *src_ptr++; +- } + } + } + } +@@ -457,6 +625,7 @@ + + LOCAL(void) + do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JDIMENSION x_crop_offset, JDIMENSION y_crop_offset, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) + /* Transverse transpose is equivalent to +@@ -470,18 +639,21 @@ + */ + { + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; ++ JDIMENSION x_crop_blocks, y_crop_blocks; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + +- MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); +- MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); ++ MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE); ++ MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; ++ x_crop_blocks = x_crop_offset * compptr->h_samp_factor; ++ y_crop_blocks = y_crop_offset * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compp |