Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in src/patchsets/jpeg/6b: 05_all_jpeg-Makefile.patch 06_all_jpeg-libtool.patch 07_all_jpeg-LANG.patch 30_all_jpeg-crop.patch 50_all_jpeg-Debian-rdjpgcom_locale.patch 51_all_jpeg-Debian-jpeglib.h_c++.patch 52_all_jpeg-Debian-rdppm.patch 60_all_jpeg-maxmem-sysconf.patch
Date: Sun, 23 Aug 2009 00:17:38
Message-Id: E1Mf0m2-0004b2-Ui@stork.gentoo.org
1 vapier 09/08/23 00:17:30
2
3 Added: 05_all_jpeg-Makefile.patch
4 06_all_jpeg-libtool.patch 07_all_jpeg-LANG.patch
5 30_all_jpeg-crop.patch
6 50_all_jpeg-Debian-rdjpgcom_locale.patch
7 51_all_jpeg-Debian-jpeglib.h_c++.patch
8 52_all_jpeg-Debian-rdppm.patch
9 60_all_jpeg-maxmem-sysconf.patch
10 Log:
11 rename jpeg-6b patch dir
12
13 Revision Changes Path
14 1.1 src/patchsets/jpeg/6b/05_all_jpeg-Makefile.patch
15
16 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/05_all_jpeg-Makefile.patch?rev=1.1&view=markup
17 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/05_all_jpeg-Makefile.patch?rev=1.1&content-type=text/plain
18
19 Index: 05_all_jpeg-Makefile.patch
20 ===================================================================
21 - Respect options from configure (bindir/libdir/etc...)
22 - Grab AR from the env instead of hardcoding to 'ar'
23 - Fix install to respect $(DESTDIR)
24 - Also install jpegint.h #64254
25
26 --- jpeg/makefile.cfg
27 +++ jpeg/makefile.cfg
28 @@ -11,13 +11,13 @@
29 # Where to install the programs and man pages.
30 prefix = @prefix@
31 exec_prefix = @exec_prefix@
32 -bindir = $(exec_prefix)/bin
33 -libdir = $(exec_prefix)/lib
34 -includedir = $(prefix)/include
35 +bindir = @bindir@
36 +libdir = @libdir@
37 +includedir = @includedir@
38 binprefix =
39 manprefix =
40 manext = 1
41 -mandir = $(prefix)/man/man$(manext)
42 +mandir = @mandir@/man$(manext)
43
44 # The name of your C compiler:
45 CC= @CC@
46 @@ -60,7 +60,8 @@
47 # directory creation command
48 MKDIR= mkdir
49 # library (.a) file creation command
50 -AR= ar rc
51 +AR = @AR@
52 +ARFLAGS = rc
53 # second step in .a creation (use "touch" if not needed)
54 AR2= @RANLIB@
55 # installation program
56 @@ -163,7 +164,7 @@
57 # without libtool:
58 libjpeg.a: @A2K_DEPS@ $(LIBOBJECTS)
59 $(RM) libjpeg.a
60 - $(AR) libjpeg.a $(LIBOBJECTS)
61 + $(AR) $(ARFLAGS) libjpeg.a $(LIBOBJECTS)
62 $(AR2) libjpeg.a
63
64 # with libtool:
65 @@ -191,25 +191,29 @@
66 # Installation rules:
67
68 install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom @FORCE_INSTALL_LIB@
69 - $(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg
70 - $(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg
71 - $(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran
72 - $(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom
73 - $(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom
74 - $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext)
75 - $(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext)
76 - $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext)
77 - $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
78 - $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
79 + mkdir -p $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)
80 + $(INSTALL_PROGRAM) cjpeg $(DESTDIR)$(bindir)/$(binprefix)cjpeg
81 + $(INSTALL_PROGRAM) djpeg $(DESTDIR)$(bindir)/$(binprefix)djpeg
82 + $(INSTALL_PROGRAM) jpegtran $(DESTDIR)$(bindir)/$(binprefix)jpegtran
83 + $(INSTALL_PROGRAM) rdjpgcom $(DESTDIR)$(bindir)/$(binprefix)rdjpgcom
84 + $(INSTALL_PROGRAM) wrjpgcom $(DESTDIR)$(bindir)/$(binprefix)wrjpgcom
85 + $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(DESTDIR)$(mandir)/$(manprefix)cjpeg.$(manext)
86 + $(INSTALL_DATA) $(srcdir)/djpeg.1 $(DESTDIR)$(mandir)/$(manprefix)djpeg.$(manext)
87 + $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(DESTDIR)$(mandir)/$(manprefix)jpegtran.$(manext)
88 + $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(DESTDIR)$(mandir)/$(manprefix)rdjpgcom.$(manext)
89 + $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(DESTDIR)$(mandir)/$(manprefix)wrjpgcom.$(manext)
90
91 install-lib: libjpeg.$(A) install-headers
92 - $(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A)
93 + mkdir -p $(DESTDIR)$(libdir)
94 + $(INSTALL_LIB) libjpeg.$(A) $(DESTDIR)$(libdir)/$(binprefix)libjpeg.$(A)
95
96 install-headers: jconfig.h
97 - $(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
98 - $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h
99 - $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h
100 - $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
101 + mkdir -p $(DESTDIR)$(includedir)
102 + $(INSTALL_DATA) jconfig.h $(DESTDIR)$(includedir)/jconfig.h
103 + $(INSTALL_DATA) $(srcdir)/jpegint.h $(DESTDIR)$(includedir)/jpegint.h
104 + $(INSTALL_DATA) $(srcdir)/jpeglib.h $(DESTDIR)$(includedir)/jpeglib.h
105 + $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(DESTDIR)$(includedir)/jmorecfg.h
106 + $(INSTALL_DATA) $(srcdir)/jerror.h $(DESTDIR)$(includedir)/jerror.h
107
108 clean:
109 $(RM) *.o *.lo libjpeg.a libjpeg.la
110 --- jpeg/configure
111 +++ jpeg/configure
112 @@ -1777,6 +1777,7 @@
113 s%@CPP@%$CPP%g
114 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
115 s%@INSTALL_DATA@%$INSTALL_DATA%g
116 +s%@AR@%${AR-ar}%g
117 s%@RANLIB@%$RANLIB%g
118 s%@LIBTOOL@%$LIBTOOL%g
119 s%@O@%$O%g
120
121
122
123 1.1 src/patchsets/jpeg/6b/06_all_jpeg-libtool.patch
124
125 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/06_all_jpeg-libtool.patch?rev=1.1&view=markup
126 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/06_all_jpeg-libtool.patch?rev=1.1&content-type=text/plain
127
128 Index: 06_all_jpeg-libtool.patch
129 ===================================================================
130 --- jpeg/configure
131 +++ jpeg/configure
132 @@ -1529,7 +1529,8 @@
133
134 if test "x$LTSHARED" != xno -o "x$LTSTATIC" != xno; then
135 USELIBTOOL="yes"
136 - LIBTOOL="./libtool"
137 + LIBTOOL="./libtool-wrap"
138 + chmod a+rx libtool-wrap
139 O="lo"
140 A="la"
141 LN='$(LIBTOOL) --mode=link $(CC)'
142 @@ -1559,7 +1559,7 @@
143 if test "x$LTSTATIC" = xno; then
144 disable_static="--disable-static"
145 fi
146 - $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh
147 + $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh $CHOST
148 fi
149
150 # Select memory manager depending on user input.
151 --- jpeg/libtool-wrap
152 +++ jpeg/libtool-wrap
153 @@ -0,0 +1,18 @@
154 +#!/bin/bash
155 +
156 +export PATH=${PATH}:/usr/bin
157 +
158 +doit=
159 +for x in glibtool libtool ; do
160 + if type -p ${x} > /dev/null ; then
161 + doit=${x}
162 + break
163 + fi
164 +done
165 +
166 +if [ -z "${doit}" ] ; then
167 + echo "Unable to locate libtool :("
168 + exit 1
169 +fi
170 +
171 +exec ${doit} "$@"
172 --- jpeg/ltconfig
173 +++ jpeg/ltconfig
174 @@ -553,7 +553,9 @@
175 # On HP-UX, both CC and GCC only warn that PIC is supported... then they
176 # create non-PIC objects. So, if there were any warnings, we assume that
177 # PIC is not supported.
178 + # Make sure we only test warnings on HP-UX (pic_flag == +Z) or we can
179 + # easily break Linux builds http://bugs.gentoo.org/70947
180 - if test -s conftest.err; then
181 + if test -s conftest.err -a "$pic_flag" = "+Z"; then
182 echo "$ac_t"no 1>&6
183 can_build_shared=no
184 pic_flag=
185 @@ -1210,7 +1210,6 @@
186 else
187 # Only the GNU ld.so supports shared libraries on MkLinux.
188 case "$host_cpu" in
189 - powerpc*) dynamic_linker=no ;;
190 *) dynamic_linker='Linux ld.so' ;;
191 esac
192 fi
193
194
195
196 1.1 src/patchsets/jpeg/6b/07_all_jpeg-LANG.patch
197
198 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/07_all_jpeg-LANG.patch?rev=1.1&view=markup
199 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/07_all_jpeg-LANG.patch?rev=1.1&content-type=text/plain
200
201 Index: 07_all_jpeg-LANG.patch
202 ===================================================================
203 The LANG vars aren't reset early enough so when sed tries to use [a-zA-Z] in
204 option parsing, it may break.
205
206 http://bugs.gentoo.org/103483
207
208 --- jpeg/configure
209 +++ jpeg/configure
210 @@ -54,6 +54,19 @@
211 infodir='${prefix}/info'
212 mandir='${prefix}/man'
213
214 +# NLS nuisances.
215 +for as_var in \
216 + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
217 + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
218 + LC_TELEPHONE LC_TIME
219 +do
220 + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
221 + eval $as_var=C; export $as_var
222 + else
223 + unset $as_var
224 + fi
225 +done
226 +
227 # Initialize some other variables.
228 subdirs=
229 MFLAGS= MAKEFLAGS=
230 @@ -452,16 +463,6 @@
231 esac
232 done
233
234 -# NLS nuisances.
235 -# Only set these to C if already set. These must not be set unconditionally
236 -# because not all systems understand e.g. LANG=C (notably SCO).
237 -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
238 -# Non-C LC_CTYPE values break the ctype check.
239 -if test "${LANG+set}" = set; then LANG=C; export LANG; fi
240 -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
241 -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
242 -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
243 -
244 # confdefs.h avoids OS command line length limits that DEFS can exceed.
245 rm -rf conftest* confdefs.h
246 # AIX cpp loses on an empty file, so make sure it contains at least a newline.
247
248
249
250 1.1 src/patchsets/jpeg/6b/30_all_jpeg-crop.patch
251
252 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/30_all_jpeg-crop.patch?rev=1.1&view=markup
253 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/30_all_jpeg-crop.patch?rev=1.1&content-type=text/plain
254
255 Index: 30_all_jpeg-crop.patch
256 ===================================================================
257 http://sylvana.net/jpegcrop/
258
259 same thing as Debian's 100_crop.dpatch and 200_crop_man.dpatch from
260 libjpeg6b_6b-10
261
262 --- jpeg/jerror.h
263 +++ jpeg/jerror.h
264 @@ -45,6 +45,7 @@ JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYP
265 JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
266 JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
267 JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
268 +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
269 JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
270 JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
271 JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
272 --- jpeg/jpegtran.c
273 +++ jpeg/jpegtran.c
274 @@ -1,7 +1,7 @@
275 /*
276 * jpegtran.c
277 *
278 - * Copyright (C) 1995-1997, Thomas G. Lane.
279 + * Copyright (C) 1995-2001, Thomas G. Lane.
280 * This file is part of the Independent JPEG Group's software.
281 * For conditions of distribution and use, see the accompanying README file.
282 *
283 @@ -64,8 +64,10 @@ usage (void)
284 #endif
285 #if TRANSFORMS_SUPPORTED
286 fprintf(stderr, "Switches for modifying the image:\n");
287 + fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n");
288 fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n");
289 fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n");
290 + fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n");
291 fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n");
292 fprintf(stderr, " -transpose Transpose image\n");
293 fprintf(stderr, " -transverse Transverse transpose image\n");
294 @@ -133,7 +135,9 @@ parse_switches (j_compress_ptr cinfo, in
295 copyoption = JCOPYOPT_DEFAULT;
296 transformoption.transform = JXFORM_NONE;
297 transformoption.trim = FALSE;
298 + transformoption.perfect = FALSE;
299 transformoption.force_grayscale = FALSE;
300 + transformoption.crop = FALSE;
301 cinfo->err->trace_level = 0;
302
303 /* Scan command line options, adjust parameters */
304 @@ -160,7 +164,7 @@ parse_switches (j_compress_ptr cinfo, in
305 exit(EXIT_FAILURE);
306 #endif
307
308 - } else if (keymatch(arg, "copy", 1)) {
309 + } else if (keymatch(arg, "copy", 2)) {
310 /* Select which extra markers to copy. */
311 if (++argn >= argc) /* advance to next argument */
312 usage();
313 @@ -173,6 +177,20 @@ parse_switches (j_compress_ptr cinfo, in
314 } else
315 usage();
316
317 + } else if (keymatch(arg, "crop", 2)) {
318 + /* Perform lossless cropping. */
319 +#if TRANSFORMS_SUPPORTED
320 + if (++argn >= argc) /* advance to next argument */
321 + usage();
322 + if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
323 + fprintf(stderr, "%s: bogus -crop argument '%s'\n",
324 + progname, argv[argn]);
325 + exit(EXIT_FAILURE);
326 + }
327 +#else
328 + select_transform(JXFORM_NONE); /* force an error */
329 +#endif
330 +
331 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
332 /* Enable debug printouts. */
333 /* On first -d, print version identification */
334 @@ -233,7 +251,12 @@ parse_switches (j_compress_ptr cinfo, in
335 usage();
336 outfilename = argv[argn]; /* save it away for later use */
337
338 - } else if (keymatch(arg, "progressive", 1)) {
339 + } else if (keymatch(arg, "perfect", 2)) {
340 + /* Fail if there is any partial edge MCUs that the transform can't
341 + * handle. */
342 + transformoption.perfect = TRUE;
343 +
344 + } else if (keymatch(arg, "progressive", 2)) {
345 /* Select simple progressive mode. */
346 #ifdef C_PROGRESSIVE_SUPPORTED
347 simple_progressive = TRUE;
348 @@ -342,8 +365,10 @@ main (int argc, char **argv)
349 jvirt_barray_ptr * src_coef_arrays;
350 jvirt_barray_ptr * dst_coef_arrays;
351 int file_index;
352 - FILE * input_file;
353 - FILE * output_file;
354 + /* We assume all-in-memory processing and can therefore use only a
355 + * single file pointer for sequential input and output operation.
356 + */
357 + FILE * fp;
358
359 /* On Mac, fetch a command line. */
360 #ifdef USE_CCOMMAND
361 @@ -406,24 +431,13 @@ main (int argc, char **argv)
362
363 /* Open the input file. */
364 if (file_index < argc) {
365 - if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
366 - fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
367 + if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
368 + fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]);
369 exit(EXIT_FAILURE);
370 }
371 } else {
372 /* default input file is stdin */
373 - input_file = read_stdin();
374 - }
375 -
376 - /* Open the output file. */
377 - if (outfilename != NULL) {
378 - if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
379 - fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
380 - exit(EXIT_FAILURE);
381 - }
382 - } else {
383 - /* default output file is stdout */
384 - output_file = write_stdout();
385 + fp = read_stdin();
386 }
387
388 #ifdef PROGRESS_REPORT
389 @@ -431,7 +445,7 @@ main (int argc, char **argv)
390 #endif
391
392 /* Specify data source for decompression */
393 - jpeg_stdio_src(&srcinfo, input_file);
394 + jpeg_stdio_src(&srcinfo, fp);
395
396 /* Enable saving of extra markers that we want to copy */
397 jcopy_markers_setup(&srcinfo, copyoption);
398 @@ -443,6 +457,15 @@ main (int argc, char **argv)
399 * jpeg_read_coefficients so that memory allocation will be done right.
400 */
401 #if TRANSFORMS_SUPPORTED
402 + /* Fails right away if -perfect is given and transformation is not perfect.
403 + */
404 + if (transformoption.perfect &&
405 + !jtransform_perfect_transform(srcinfo.image_width, srcinfo.image_height,
406 + srcinfo.max_h_samp_factor * DCTSIZE, srcinfo.max_v_samp_factor * DCTSIZE,
407 + transformoption.transform)) {
408 + fprintf(stderr, "%s: transformation is not perfect\n", progname);
409 + exit(EXIT_FAILURE);
410 + }
411 jtransform_request_workspace(&srcinfo, &transformoption);
412 #endif
413
414 @@ -463,11 +486,32 @@ main (int argc, char **argv)
415 dst_coef_arrays = src_coef_arrays;
416 #endif
417
418 + /* Close input file, if we opened it.
419 + * Note: we assume that jpeg_read_coefficients consumed all input
420 + * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
421 + * only consume more while (! cinfo->inputctl->eoi_reached).
422 + * We cannot call jpeg_finish_decompress here since we still need the
423 + * virtual arrays allocated from the source object for processing.
424 + */
425 + if (fp != stdin)
426 + fclose(fp);
427 +
428 + /* Open the output file. */
429 + if (outfilename != NULL) {
430 + if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
431 + fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename);
432 + exit(EXIT_FAILURE);
433 + }
434 + } else {
435 + /* default output file is stdout */
436 + fp = write_stdout();
437 + }
438 +
439 /* Adjust default compression parameters by re-parsing the options */
440 file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
441
442 /* Specify data destination for compression */
443 - jpeg_stdio_dest(&dstinfo, output_file);
444 + jpeg_stdio_dest(&dstinfo, fp);
445
446 /* Start compressor (note no image data is actually written here) */
447 jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
448 @@ -488,11 +532,9 @@ main (int argc, char **argv)
449 (void) jpeg_finish_decompress(&srcinfo);
450 jpeg_destroy_decompress(&srcinfo);
451
452 - /* Close files, if we opened them */
453 - if (input_file != stdin)
454 - fclose(input_file);
455 - if (output_file != stdout)
456 - fclose(output_file);
457 + /* Close output file, if we opened it */
458 + if (fp != stdout)
459 + fclose(fp);
460
461 #ifdef PROGRESS_REPORT
462 end_progress_monitor((j_common_ptr) &dstinfo);
463 --- jpeg/transupp.c
464 +++ jpeg/transupp.c
465 @@ -1,7 +1,7 @@
466 /*
467 * transupp.c
468 *
469 - * Copyright (C) 1997, Thomas G. Lane.
470 + * Copyright (C) 1997-2001, Thomas G. Lane.
471 * This file is part of the Independent JPEG Group's software.
472 * For conditions of distribution and use, see the accompanying README file.
473 *
474 @@ -20,6 +20,7 @@
475 #include "jinclude.h"
476 #include "jpeglib.h"
477 #include "transupp.h" /* My own external interface */
478 +#include <ctype.h> /* to declare isdigit() */
479
480
481 #if TRANSFORMS_SUPPORTED
482 @@ -28,7 +29,8 @@
483 * Lossless image transformation routines. These routines work on DCT
484 * coefficient arrays and thus do not require any lossy decompression
485 * or recompression of the image.
486 - * Thanks to Guido Vollbeding for the initial design and code of this feature.
487 + * Thanks to Guido Vollbeding for the initial design and code of this feature,
488 + * and to Ben Jackson for introducing the cropping feature.
489 *
490 * Horizontal flipping is done in-place, using a single top-to-bottom
491 * pass through the virtual source array. It will thus be much the
492 @@ -42,6 +44,13 @@
493 * arrays for most of the transforms. That could result in much thrashing
494 * if the image is larger than main memory.
495 *
496 + * If cropping or trimming is involved, the destination arrays may be smaller
497 + * than the source arrays. Note it is not possible to do horizontal flip
498 + * in-place when a nonzero Y crop offset is specified, since we'd have to move
499 + * data from one block row to another but the virtual array manager doesn't
500 + * guarantee we can touch more than one row at a time. So in that case,
501 + * we have to use a separate destination array.
502 + *
503 * Some notes about the operating environment of the individual transform
504 * routines:
505 * 1. Both the source and destination virtual arrays are allocated from the
506 @@ -54,20 +63,65 @@
507 * and we may as well take that as the effective iMCU size.
508 * 4. When "trim" is in effect, the destination's dimensions will be the
509 * trimmed values but the source's will be untrimmed.
510 - * 5. All the routines assume that the source and destination buffers are
511 + * 5. When "crop" is in effect, the destination's dimensions will be the
512 + * cropped values but the source's will be uncropped. Each transform
513 + * routine is responsible for picking up source data starting at the
514 + * correct X and Y offset for the crop region. (The X and Y offsets
515 + * passed to the transform routines are measured in iMCU blocks of the
516 + * destination.)
517 + * 6. All the routines assume that the source and destination buffers are
518 * padded out to a full iMCU boundary. This is true, although for the
519 * source buffer it is an undocumented property of jdcoefct.c.
520 - * Notes 2,3,4 boil down to this: generally we should use the destination's
521 - * dimensions and ignore the source's.
522 */
523
524
525 LOCAL(void)
526 -do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
527 - jvirt_barray_ptr *src_coef_arrays)
528 -/* Horizontal flip; done in-place, so no separate dest array is required */
529 +do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
530 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
531 + jvirt_barray_ptr *src_coef_arrays,
532 + jvirt_barray_ptr *dst_coef_arrays)
533 +/* Crop. This is only used when no rotate/flip is requested with the crop. */
534 +{
535 + JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
536 + int ci, offset_y;
537 + JBLOCKARRAY src_buffer, dst_buffer;
538 + jpeg_component_info *compptr;
539 +
540 + /* We simply have to copy the right amount of data (the destination's
541 + * image size) starting at the given X and Y offsets in the source.
542 + */
543 + for (ci = 0; ci < dstinfo->num_components; ci++) {
544 + compptr = dstinfo->comp_info + ci;
545 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
546 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
547 + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
548 + dst_blk_y += compptr->v_samp_factor) {
549 + dst_buffer = (*srcinfo->mem->access_virt_barray)
550 + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
551 + (JDIMENSION) compptr->v_samp_factor, TRUE);
552 + src_buffer = (*srcinfo->mem->access_virt_barray)
553 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
554 + dst_blk_y + y_crop_blocks,
555 + (JDIMENSION) compptr->v_samp_factor, FALSE);
556 + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
557 + jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
558 + dst_buffer[offset_y],
559 + compptr->width_in_blocks);
560 + }
561 + }
562 + }
563 +}
564 +
565 +
566 +LOCAL(void)
567 +do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
568 + JDIMENSION x_crop_offset,
569 + jvirt_barray_ptr *src_coef_arrays)
570 +/* Horizontal flip; done in-place, so no separate dest array is required.
571 + * NB: this only works when y_crop_offset is zero.
572 + */
573 {
574 - JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
575 + JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
576 int ci, k, offset_y;
577 JBLOCKARRAY buffer;
578 JCOEFPTR ptr1, ptr2;
579 @@ -79,17 +133,19 @@ do_flip_h (j_decompress_ptr srcinfo, j_c
580 * mirroring by changing the signs of odd-numbered columns.
581 * Partial iMCUs at the right edge are left untouched.
582 */
583 - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
584 + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
585
586 for (ci = 0; ci < dstinfo->num_components; ci++) {
587 compptr = dstinfo->comp_info + ci;
588 comp_width = MCU_cols * compptr->h_samp_factor;
589 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
590 for (blk_y = 0; blk_y < compptr->height_in_blocks;
591 blk_y += compptr->v_samp_factor) {
592 buffer = (*srcinfo->mem->access_virt_barray)
593 ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
594 (JDIMENSION) compptr->v_samp_factor, TRUE);
595 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
596 + /* Do the mirroring */
597 for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
598 ptr1 = buffer[offset_y][blk_x];
599 ptr2 = buffer[offset_y][comp_width - blk_x - 1];
600 @@ -105,6 +161,79 @@ do_flip_h (j_decompress_ptr srcinfo, j_c
601 *ptr2++ = -temp1;
602 }
603 }
604 + if (x_crop_blocks > 0) {
605 + /* Now left-justify the portion of the data to be kept.
606 + * We can't use a single jcopy_block_row() call because that routine
607 + * depends on memcpy(), whose behavior is unspecified for overlapping
608 + * source and destination areas. Sigh.
609 + */
610 + for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
611 + jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
612 + buffer[offset_y] + blk_x,
613 + (JDIMENSION) 1);
614 + }
615 + }
616 + }
617 + }
618 + }
619 +}
620 +
621 +
622 +LOCAL(void)
623 +do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
624 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
625 + jvirt_barray_ptr *src_coef_arrays,
626 + jvirt_barray_ptr *dst_coef_arrays)
627 +/* Horizontal flip in general cropping case */
628 +{
629 + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
630 + JDIMENSION x_crop_blocks, y_crop_blocks;
631 + int ci, k, offset_y;
632 + JBLOCKARRAY src_buffer, dst_buffer;
633 + JBLOCKROW src_row_ptr, dst_row_ptr;
634 + JCOEFPTR src_ptr, dst_ptr;
635 + jpeg_component_info *compptr;
636 +
637 + /* Here we must output into a separate array because we can't touch
638 + * different rows of a single virtual array simultaneously. Otherwise,
639 + * this is essentially the same as the routine above.
640 + */
641 + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
642 +
643 + for (ci = 0; ci < dstinfo->num_components; ci++) {
644 + compptr = dstinfo->comp_info + ci;
645 + comp_width = MCU_cols * compptr->h_samp_factor;
646 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
647 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
648 + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
649 + dst_blk_y += compptr->v_samp_factor) {
650 + dst_buffer = (*srcinfo->mem->access_virt_barray)
651 + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
652 + (JDIMENSION) compptr->v_samp_factor, TRUE);
653 + src_buffer = (*srcinfo->mem->access_virt_barray)
654 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
655 + dst_blk_y + y_crop_blocks,
656 + (JDIMENSION) compptr->v_samp_factor, FALSE);
657 + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
658 + dst_row_ptr = dst_buffer[offset_y];
659 + src_row_ptr = src_buffer[offset_y];
660 + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
661 + if (x_crop_blocks + dst_blk_x < comp_width) {
662 + /* Do the mirrorable blocks */
663 + dst_ptr = dst_row_ptr[dst_blk_x];
664 + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
665 + /* this unrolled loop doesn't need to know which row it's on... */
666 + for (k = 0; k < DCTSIZE2; k += 2) {
667 + *dst_ptr++ = *src_ptr++; /* copy even column */
668 + *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
669 + }
670 + } else {
671 + /* Copy last partial block(s) verbatim */
672 + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
673 + dst_row_ptr + dst_blk_x,
674 + (JDIMENSION) 1);
675 + }
676 + }
677 }
678 }
679 }
680 @@ -113,11 +242,13 @@ do_flip_h (j_decompress_ptr srcinfo, j_c
681
682 LOCAL(void)
683 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
684 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
685 jvirt_barray_ptr *src_coef_arrays,
686 jvirt_barray_ptr *dst_coef_arrays)
687 /* Vertical flip */
688 {
689 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
690 + JDIMENSION x_crop_blocks, y_crop_blocks;
691 int ci, i, j, offset_y;
692 JBLOCKARRAY src_buffer, dst_buffer;
693 JBLOCKROW src_row_ptr, dst_row_ptr;
694 @@ -131,33 +262,38 @@ do_flip_v (j_decompress_ptr srcinfo, j_c
695 * of odd-numbered rows.
696 * Partial iMCUs at the bottom edge are copied verbatim.
697 */
698 - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
699 + MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
700
701 for (ci = 0; ci < dstinfo->num_components; ci++) {
702 compptr = dstinfo->comp_info + ci;
703 comp_height = MCU_rows * compptr->v_samp_factor;
704 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
705 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
706 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
707 dst_blk_y += compptr->v_samp_factor) {
708 dst_buffer = (*srcinfo->mem->access_virt_barray)
709 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
710 (JDIMENSION) compptr->v_samp_factor, TRUE);
711 - if (dst_blk_y < comp_height) {
712 + if (y_crop_blocks + dst_blk_y < comp_height) {
713 /* Row is within the mirrorable area. */
714 src_buffer = (*srcinfo->mem->access_virt_barray)
715 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
716 - comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
717 + comp_height - y_crop_blocks - dst_blk_y -
718 + (JDIMENSION) compptr->v_samp_factor,
719 (JDIMENSION) compptr->v_samp_factor, FALSE);
720 } else {
721 /* Bottom-edge blocks will be copied verbatim. */
722 src_buffer = (*srcinfo->mem->access_virt_barray)
723 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
724 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
725 + dst_blk_y + y_crop_blocks,
726 (JDIMENSION) compptr->v_samp_factor, FALSE);
727 }
728 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
729 - if (dst_blk_y < comp_height) {
730 + if (y_crop_blocks + dst_blk_y < comp_height) {
731 /* Row is within the mirrorable area. */
732 dst_row_ptr = dst_buffer[offset_y];
733 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
734 + src_row_ptr += x_crop_blocks;
735 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
736 dst_blk_x++) {
737 dst_ptr = dst_row_ptr[dst_blk_x];
738 @@ -173,7 +309,8 @@ do_flip_v (j_decompress_ptr srcinfo, j_c
739 }
740 } else {
741 /* Just copy row verbatim. */
742 - jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
743 + jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
744 + dst_buffer[offset_y],
745 compptr->width_in_blocks);
746 }
747 }
748 @@ -184,11 +321,12 @@ do_flip_v (j_decompress_ptr srcinfo, j_c
749
750 LOCAL(void)
751 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
752 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
753 jvirt_barray_ptr *src_coef_arrays,
754 jvirt_barray_ptr *dst_coef_arrays)
755 /* Transpose source into destination */
756 {
757 - JDIMENSION dst_blk_x, dst_blk_y;
758 + JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
759 int ci, i, j, offset_x, offset_y;
760 JBLOCKARRAY src_buffer, dst_buffer;
761 JCOEFPTR src_ptr, dst_ptr;
762 @@ -201,6 +339,8 @@ do_transpose (j_decompress_ptr srcinfo,
763 */
764 for (ci = 0; ci < dstinfo->num_components; ci++) {
765 compptr = dstinfo->comp_info + ci;
766 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
767 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
768 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
769 dst_blk_y += compptr->v_samp_factor) {
770 dst_buffer = (*srcinfo->mem->access_virt_barray)
771 @@ -210,11 +350,12 @@ do_transpose (j_decompress_ptr srcinfo,
772 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
773 dst_blk_x += compptr->h_samp_factor) {
774 src_buffer = (*srcinfo->mem->access_virt_barray)
775 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
776 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
777 + dst_blk_x + x_crop_blocks,
778 (JDIMENSION) compptr->h_samp_factor, FALSE);
779 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
780 - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
781 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
782 + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
783 for (i = 0; i < DCTSIZE; i++)
784 for (j = 0; j < DCTSIZE; j++)
785 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
786 @@ -228,6 +369,7 @@ do_transpose (j_decompress_ptr srcinfo,
787
788 LOCAL(void)
789 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
790 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
791 jvirt_barray_ptr *src_coef_arrays,
792 jvirt_barray_ptr *dst_coef_arrays)
793 /* 90 degree rotation is equivalent to
794 @@ -237,6 +379,7 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c
795 */
796 {
797 JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
798 + JDIMENSION x_crop_blocks, y_crop_blocks;
799 int ci, i, j, offset_x, offset_y;
800 JBLOCKARRAY src_buffer, dst_buffer;
801 JCOEFPTR src_ptr, dst_ptr;
802 @@ -246,11 +389,13 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c
803 * at the (output) right edge properly. They just get transposed and
804 * not mirrored.
805 */
806 - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
807 + MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE);
808
809 for (ci = 0; ci < dstinfo->num_components; ci++) {
810 compptr = dstinfo->comp_info + ci;
811 comp_width = MCU_cols * compptr->h_samp_factor;
812 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
813 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
814 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
815 dst_blk_y += compptr->v_samp_factor) {
816 dst_buffer = (*srcinfo->mem->access_virt_barray)
817 @@ -259,15 +404,26 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c
818 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
819 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
820 dst_blk_x += compptr->h_samp_factor) {
821 - src_buffer = (*srcinfo->mem->access_virt_barray)
822 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
823 - (JDIMENSION) compptr->h_samp_factor, FALSE);
824 + if (x_crop_blocks + dst_blk_x < comp_width) {
825 + /* Block is within the mirrorable area. */
826 + src_buffer = (*srcinfo->mem->access_virt_barray)
827 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
828 + comp_width - x_crop_blocks - dst_blk_x -
829 + (JDIMENSION) compptr->h_samp_factor,
830 + (JDIMENSION) compptr->h_samp_factor, FALSE);
831 + } else {
832 + /* Edge blocks are transposed but not mirrored. */
833 + src_buffer = (*srcinfo->mem->access_virt_barray)
834 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
835 + dst_blk_x + x_crop_blocks,
836 + (JDIMENSION) compptr->h_samp_factor, FALSE);
837 + }
838 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
839 - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
840 - if (dst_blk_x < comp_width) {
841 + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
842 + if (x_crop_blocks + dst_blk_x < comp_width) {
843 /* Block is within the mirrorable area. */
844 - dst_ptr = dst_buffer[offset_y]
845 - [comp_width - dst_blk_x - offset_x - 1];
846 + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
847 + [dst_blk_y + offset_y + y_crop_blocks];
848 for (i = 0; i < DCTSIZE; i++) {
849 for (j = 0; j < DCTSIZE; j++)
850 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
851 @@ -277,7 +433,8 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c
852 }
853 } else {
854 /* Edge blocks are transposed but not mirrored. */
855 - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
856 + src_ptr = src_buffer[offset_x]
857 + [dst_blk_y + offset_y + y_crop_blocks];
858 for (i = 0; i < DCTSIZE; i++)
859 for (j = 0; j < DCTSIZE; j++)
860 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
861 @@ -292,6 +449,7 @@ do_rot_90 (j_decompress_ptr srcinfo, j_c
862
863 LOCAL(void)
864 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
865 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
866 jvirt_barray_ptr *src_coef_arrays,
867 jvirt_barray_ptr *dst_coef_arrays)
868 /* 270 degree rotation is equivalent to
869 @@ -301,6 +459,7 @@ do_rot_270 (j_decompress_ptr srcinfo, j_
870 */
871 {
872 JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
873 + JDIMENSION x_crop_blocks, y_crop_blocks;
874 int ci, i, j, offset_x, offset_y;
875 JBLOCKARRAY src_buffer, dst_buffer;
876 JCOEFPTR src_ptr, dst_ptr;
877 @@ -310,11 +469,13 @@ do_rot_270 (j_decompress_ptr srcinfo, j_
878 * at the (output) bottom edge properly. They just get transposed and
879 * not mirrored.
880 */
881 - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
882 + MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE);
883
884 for (ci = 0; ci < dstinfo->num_components; ci++) {
885 compptr = dstinfo->comp_info + ci;
886 comp_height = MCU_rows * compptr->v_samp_factor;
887 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
888 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
889 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
890 dst_blk_y += compptr->v_samp_factor) {
891 dst_buffer = (*srcinfo->mem->access_virt_barray)
892 @@ -324,14 +485,15 @@ do_rot_270 (j_decompress_ptr srcinfo, j_
893 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
894 dst_blk_x += compptr->h_samp_factor) {
895 src_buffer = (*srcinfo->mem->access_virt_barray)
896 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
897 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
898 + dst_blk_x + x_crop_blocks,
899 (JDIMENSION) compptr->h_samp_factor, FALSE);
900 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
901 dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
902 - if (dst_blk_y < comp_height) {
903 + if (y_crop_blocks + dst_blk_y < comp_height) {
904 /* Block is within the mirrorable area. */
905 src_ptr = src_buffer[offset_x]
906 - [comp_height - dst_blk_y - offset_y - 1];
907 + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
908 for (i = 0; i < DCTSIZE; i++) {
909 for (j = 0; j < DCTSIZE; j++) {
910 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
911 @@ -341,7 +503,8 @@ do_rot_270 (j_decompress_ptr srcinfo, j_
912 }
913 } else {
914 /* Edge blocks are transposed but not mirrored. */
915 - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
916 + src_ptr = src_buffer[offset_x]
917 + [dst_blk_y + offset_y + y_crop_blocks];
918 for (i = 0; i < DCTSIZE; i++)
919 for (j = 0; j < DCTSIZE; j++)
920 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
921 @@ -356,6 +519,7 @@ do_rot_270 (j_decompress_ptr srcinfo, j_
922
923 LOCAL(void)
924 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
925 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
926 jvirt_barray_ptr *src_coef_arrays,
927 jvirt_barray_ptr *dst_coef_arrays)
928 /* 180 degree rotation is equivalent to
929 @@ -365,89 +529,93 @@ do_rot_180 (j_decompress_ptr srcinfo, j_
930 */
931 {
932 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
933 + JDIMENSION x_crop_blocks, y_crop_blocks;
934 int ci, i, j, offset_y;
935 JBLOCKARRAY src_buffer, dst_buffer;
936 JBLOCKROW src_row_ptr, dst_row_ptr;
937 JCOEFPTR src_ptr, dst_ptr;
938 jpeg_component_info *compptr;
939
940 - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
941 - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
942 + MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
943 + MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
944
945 for (ci = 0; ci < dstinfo->num_components; ci++) {
946 compptr = dstinfo->comp_info + ci;
947 comp_width = MCU_cols * compptr->h_samp_factor;
948 comp_height = MCU_rows * compptr->v_samp_factor;
949 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
950 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
951 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
952 dst_blk_y += compptr->v_samp_factor) {
953 dst_buffer = (*srcinfo->mem->access_virt_barray)
954 ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
955 (JDIMENSION) compptr->v_samp_factor, TRUE);
956 - if (dst_blk_y < comp_height) {
957 + if (y_crop_blocks + dst_blk_y < comp_height) {
958 /* Row is within the vertically mirrorable area. */
959 src_buffer = (*srcinfo->mem->access_virt_barray)
960 ((j_common_ptr) srcinfo, src_coef_arrays[ci],
961 - comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
962 + comp_height - y_crop_blocks - dst_blk_y -
963 + (JDIMENSION) compptr->v_samp_factor,
964 (JDIMENSION) compptr->v_samp_factor, FALSE);
965 } else {
966 /* Bottom-edge rows are only mirrored horizontally. */
967 src_buffer = (*srcinfo->mem->access_virt_barray)
968 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
969 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
970 + dst_blk_y + y_crop_blocks,
971 (JDIMENSION) compptr->v_samp_factor, FALSE);
972 }
973 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
974 - if (dst_blk_y < comp_height) {
975 + dst_row_ptr = dst_buffer[offset_y];
976 + if (y_crop_blocks + dst_blk_y < comp_height) {
977 /* Row is within the mirrorable area. */
978 - dst_row_ptr = dst_buffer[offset_y];
979 src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
980 - /* Process the blocks that can be mirrored both ways. */
981 - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
982 + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
983 dst_ptr = dst_row_ptr[dst_blk_x];
984 - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
985 - for (i = 0; i < DCTSIZE; i += 2) {
986 - /* For even row, negate every odd column. */
987 - for (j = 0; j < DCTSIZE; j += 2) {
988 - *dst_ptr++ = *src_ptr++;
989 - *dst_ptr++ = - *src_ptr++;
990 + if (x_crop_blocks + dst_blk_x < comp_width) {
991 + /* Process the blocks that can be mirrored both ways. */
992 + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
993 + for (i = 0; i < DCTSIZE; i += 2) {
994 + /* For even row, negate every odd column. */
995 + for (j = 0; j < DCTSIZE; j += 2) {
996 + *dst_ptr++ = *src_ptr++;
997 + *dst_ptr++ = - *src_ptr++;
998 + }
999 + /* For odd row, negate every even column. */
1000 + for (j = 0; j < DCTSIZE; j += 2) {
1001 + *dst_ptr++ = - *src_ptr++;
1002 + *dst_ptr++ = *src_ptr++;
1003 + }
1004 }
1005 - /* For odd row, negate every even column. */
1006 - for (j = 0; j < DCTSIZE; j += 2) {
1007 - *dst_ptr++ = - *src_ptr++;
1008 - *dst_ptr++ = *src_ptr++;
1009 + } else {
1010 + /* Any remaining right-edge blocks are only mirrored vertically. */
1011 + src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
1012 + for (i = 0; i < DCTSIZE; i += 2) {
1013 + for (j = 0; j < DCTSIZE; j++)
1014 + *dst_ptr++ = *src_ptr++;
1015 + for (j = 0; j < DCTSIZE; j++)
1016 + *dst_ptr++ = - *src_ptr++;
1017 }
1018 }
1019 }
1020 - /* Any remaining right-edge blocks are only mirrored vertically. */
1021 - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
1022 - dst_ptr = dst_row_ptr[dst_blk_x];
1023 - src_ptr = src_row_ptr[dst_blk_x];
1024 - for (i = 0; i < DCTSIZE; i += 2) {
1025 - for (j = 0; j < DCTSIZE; j++)
1026 - *dst_ptr++ = *src_ptr++;
1027 - for (j = 0; j < DCTSIZE; j++)
1028 - *dst_ptr++ = - *src_ptr++;
1029 - }
1030 - }
1031 } else {
1032 /* Remaining rows are just mirrored horizontally. */
1033 - dst_row_ptr = dst_buffer[offset_y];
1034 src_row_ptr = src_buffer[offset_y];
1035 - /* Process the blocks that can be mirrored. */
1036 - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
1037 - dst_ptr = dst_row_ptr[dst_blk_x];
1038 - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
1039 - for (i = 0; i < DCTSIZE2; i += 2) {
1040 - *dst_ptr++ = *src_ptr++;
1041 - *dst_ptr++ = - *src_ptr++;
1042 + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
1043 + if (x_crop_blocks + dst_blk_x < comp_width) {
1044 + /* Process the blocks that can be mirrored. */
1045 + dst_ptr = dst_row_ptr[dst_blk_x];
1046 + src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
1047 + for (i = 0; i < DCTSIZE2; i += 2) {
1048 + *dst_ptr++ = *src_ptr++;
1049 + *dst_ptr++ = - *src_ptr++;
1050 + }
1051 + } else {
1052 + /* Any remaining right-edge blocks are only copied. */
1053 + jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
1054 + dst_row_ptr + dst_blk_x,
1055 + (JDIMENSION) 1);
1056 }
1057 }
1058 - /* Any remaining right-edge blocks are only copied. */
1059 - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
1060 - dst_ptr = dst_row_ptr[dst_blk_x];
1061 - src_ptr = src_row_ptr[dst_blk_x];
1062 - for (i = 0; i < DCTSIZE2; i++)
1063 - *dst_ptr++ = *src_ptr++;
1064 - }
1065 }
1066 }
1067 }
1068 @@ -457,6 +625,7 @@ do_rot_180 (j_decompress_ptr srcinfo, j_
1069
1070 LOCAL(void)
1071 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1072 + JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
1073 jvirt_barray_ptr *src_coef_arrays,
1074 jvirt_barray_ptr *dst_coef_arrays)
1075 /* Transverse transpose is equivalent to
1076 @@ -470,18 +639,21 @@ do_transverse (j_decompress_ptr srcinfo,
1077 */
1078 {
1079 JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
1080 + JDIMENSION x_crop_blocks, y_crop_blocks;
1081 int ci, i, j, offset_x, offset_y;
1082 JBLOCKARRAY src_buffer, dst_buffer;
1083 JCOEFPTR src_ptr, dst_ptr;
1084 jpeg_component_info *compptr;
1085
1086 - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
1087 - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
1088 + MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE);
1089 + MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE);
1090
1091 for (ci = 0; ci < dstinfo->num_components; ci++) {
1092 compptr = dstinfo->comp_info + ci;
1093 comp_width = MCU_cols * compptr->h_samp_factor;
1094 comp_height = MCU_rows * compptr->v_samp_factor;
1095 + x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
1096 + y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
1097 for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
1098 dst_blk_y += compptr->v_samp_factor) {
1099 dst_buffer = (*srcinfo->mem->access_virt_barray)
1100 @@ -490,17 +662,26 @@ do_transverse (j_decompress_ptr srcinfo,
1101 for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
1102 for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
1103 dst_blk_x += compptr->h_samp_factor) {
1104 - src_buffer = (*srcinfo->mem->access_virt_barray)
1105 - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
1106 - (JDIMENSION) compptr->h_samp_factor, FALSE);
1107 + if (x_crop_blocks + dst_blk_x < comp_width) {
1108 + /* Block is within the mirrorable area. */
1109 + src_buffer = (*srcinfo->mem->access_virt_barray)
1110 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
1111 + comp_width - x_crop_blocks - dst_blk_x -
1112 + (JDIMENSION) compptr->h_samp_factor,
1113 + (JDIMENSION) compptr->h_samp_factor, FALSE);
1114 + } else {
1115 + src_buffer = (*srcinfo->mem->access_virt_barray)
1116 + ((j_common_ptr) srcinfo, src_coef_arrays[ci],
1117 + dst_blk_x + x_crop_blocks,
1118 + (JDIMENSION) compptr->h_samp_factor, FALSE);
1119 + }
1120 for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
1121 - if (dst_blk_y < comp_height) {
1122 - src_ptr = src_buffer[offset_x]
1123 - [comp_height - dst_blk_y - offset_y - 1];
1124 - if (dst_blk_x < comp_width) {
1125 + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
1126 + if (y_crop_blocks + dst_blk_y < comp_height) {
1127 + if (x_crop_blocks + dst_blk_x < comp_width) {
1128 /* Block is within the mirrorable area. */
1129 - dst_ptr = dst_buffer[offset_y]
1130 - [comp_width - dst_blk_x - offset_x - 1];
1131 + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
1132 + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
1133 for (i = 0; i < DCTSIZE; i++) {
1134 for (j = 0; j < DCTSIZE; j++) {
1135 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
1136 @@ -516,7 +697,8 @@ do_transverse (j_decompress_ptr srcinfo,
1137 }
1138 } else {
1139 /* Right-edge blocks are mirrored in y only */
1140 - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
1141 + src_ptr = src_buffer[offset_x]
1142 + [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
1143 for (i = 0; i < DCTSIZE; i++) {
1144 for (j = 0; j < DCTSIZE; j++) {
1145 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
1146 @@ -526,11 +708,10 @@ do_transverse (j_decompress_ptr srcinfo,
1147 }
1148 }
1149 } else {
1150 - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
1151 - if (dst_blk_x < comp_width) {
1152 + if (x_crop_blocks + dst_blk_x < comp_width) {
1153 /* Bottom-edge blocks are mirrored in x only */
1154 - dst_ptr = dst_buffer[offset_y]
1155 - [comp_width - dst_blk_x - offset_x - 1];
1156 + src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
1157 + [dst_blk_y + offset_y + y_crop_blocks];
1158 for (i = 0; i < DCTSIZE; i++) {
1159 for (j = 0; j < DCTSIZE; j++)
1160 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
1161 @@ -540,7 +721,8 @@ do_transverse (j_decompress_ptr srcinfo,
1162 }
1163 } else {
1164 /* At lower right corner, just transpose, no mirroring */
1165 - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
1166 + src_ptr = src_buffer[offset_x]
1167 + [dst_blk_y + offset_y + y_crop_blocks];
1168 for (i = 0; i < DCTSIZE; i++)
1169 for (j = 0; j < DCTSIZE; j++)
1170 dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
1171 @@ -554,8 +736,116 @@ do_transverse (j_decompress_ptr srcinfo,
1172 }
1173
1174
1175 +/* Parse an unsigned integer: subroutine for jtransform_parse_crop_spec.
1176 + * Returns TRUE if valid integer found, FALSE if not.
1177 + * *strptr is advanced over the digit string, and *result is set to its value.
1178 + */
1179 +
1180 +LOCAL(boolean)
1181 +jt_read_integer (const char ** strptr, JDIMENSION * result)
1182 +{
1183 + const char * ptr = *strptr;
1184 + JDIMENSION val = 0;
1185 +
1186 + for (; isdigit(*ptr); ptr++) {
1187 + val = val * 10 + (JDIMENSION) (*ptr - '0');
1188 + }
1189 + *result = val;
1190 + if (ptr == *strptr)
1191 + return FALSE; /* oops, no digits */
1192 + *strptr = ptr;
1193 + return TRUE;
1194 +}
1195 +
1196 +
1197 +/* Parse a crop specification (written in X11 geometry style).
1198 + * The routine returns TRUE if the spec string is valid, FALSE if not.
1199 + *
1200 + * The crop spec string should have the format
1201 + * <width>x<height>{+-}<xoffset>{+-}<yoffset>
1202 + * where width, height, xoffset, and yoffset are unsigned integers.
1203 + * Each of the elements can be omitted to indicate a default value.
1204 + * (A weakness of this style is that it is not possible to omit xoffset
1205 + * while specifying yoffset, since they look alike.)
1206 + *
1207 + * This code is loosely based on XParseGeometry from the X11 distribution.
1208 + */
1209 +
1210 +GLOBAL(boolean)
1211 +jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
1212 +{
1213 + info->crop = FALSE;
1214 + info->crop_width_set = JCROP_UNSET;
1215 + info->crop_height_set = JCROP_UNSET;
1216 + info->crop_xoffset_set = JCROP_UNSET;
1217 + info->crop_yoffset_set = JCROP_UNSET;
1218 +
1219 + if (isdigit(*spec)) {
1220 + /* fetch width */
1221 + if (! jt_read_integer(&spec, &info->crop_width))
1222 + return FALSE;
1223 + info->crop_width_set = JCROP_POS;
1224 + }
1225 + if (*spec == 'x' || *spec == 'X') {
1226 + /* fetch height */
1227 + spec++;
1228 + if (! jt_read_integer(&spec, &info->crop_height))
1229 + return FALSE;
1230 + info->crop_height_set = JCROP_POS;
1231 + }
1232 + if (*spec == '+' || *spec == '-') {
1233 + /* fetch xoffset */
1234 + info->crop_xoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
1235 + spec++;
1236 + if (! jt_read_integer(&spec, &info->crop_xoffset))
1237 + return FALSE;
1238 + }
1239 + if (*spec == '+' || *spec == '-') {
1240 + /* fetch yoffset */
1241 + info->crop_yoffset_set = (*spec == '-') ? JCROP_NEG : JCROP_POS;
1242 + spec++;
1243 + if (! jt_read_integer(&spec, &info->crop_yoffset))
1244 + return FALSE;
1245 + }
1246 + /* We had better have gotten to the end of the string. */
1247 + if (*spec != '\0')
1248 + return FALSE;
1249 + info->crop = TRUE;
1250 + return TRUE;
1251 +}
1252 +
1253 +
1254 +/* Trim off any partial iMCUs on the indicated destination edge */
1255 +
1256 +LOCAL(void)
1257 +trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
1258 +{
1259 + JDIMENSION MCU_cols;
1260 +
1261 + MCU_cols = info->output_width / (info->max_h_samp_factor * DCTSIZE);
1262 + if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
1263 + full_width / (info->max_h_samp_factor * DCTSIZE))
1264 + info->output_width = MCU_cols * (info->max_h_samp_factor * DCTSIZE);
1265 +}
1266 +
1267 +LOCAL(void)
1268 +trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
1269 +{
1270 + JDIMENSION MCU_rows;
1271 +
1272 + MCU_rows = info->output_height / (info->max_v_samp_factor * DCTSIZE);
1273 + if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
1274 + full_height / (info->max_v_samp_factor * DCTSIZE))
1275 + info->output_height = MCU_rows * (info->max_v_samp_factor * DCTSIZE);
1276 +}
1277 +
1278 +
1279 /* Request any required workspace.
1280 *
1281 + * This routine figures out the size that the output image will be
1282 + * (which implies that all the transform parameters must be set before
1283 + * it is called).
1284 + *
1285 * We allocate the workspace virtual arrays from the source decompression
1286 * object, so that all the arrays (both the original data and the workspace)
1287 * will be taken into account while making memory management decisions.
1288 @@ -569,9 +859,13 @@ jtransform_request_workspace (j_decompre
1289 jpeg_transform_info *info)
1290 {
1291 jvirt_barray_ptr *coef_arrays = NULL;
1292 + boolean need_workspace, transpose_it;
1293 jpeg_component_info *compptr;
1294 - int ci;
1295 + JDIMENSION xoffset, yoffset, width_in_iMCUs, height_in_iMCUs;
1296 + JDIMENSION width_in_blocks, height_in_blocks;
1297 + int ci, h_samp_factor, v_samp_factor;
1298
1299 + /* Determine number of components in output image */
1300 if (info->force_grayscale &&
1301 srcinfo->jpeg_color_space == JCS_YCbCr &&
1302 srcinfo->num_components == 3) {
1303 @@ -581,55 +875,181 @@ jtransform_request_workspace (j_decompre
1304 /* Process all the components */
1305 info->num_components = srcinfo->num_components;
1306 }
1307 + /* If there is only one output component, force the iMCU size to be 1;
1308 + * else use the source iMCU size. (This allows us to do the right thing
1309 + * when reducing color to grayscale, and also provides a handy way of
1310 + * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
1311 + */
1312 +
1313 + switch (info->transform) {
1314 + case JXFORM_TRANSPOSE:
1315 + case JXFORM_TRANSVERSE:
1316 + case JXFORM_ROT_90:
1317 + case JXFORM_ROT_270:
1318 + info->output_width = srcinfo->image_height;
1319 + info->output_height = srcinfo->image_width;
1320 + if (info->num_components == 1) {
1321 + info->max_h_samp_factor = 1;
1322 + info->max_v_samp_factor = 1;
1323 + } else {
1324 + info->max_h_samp_factor = srcinfo->max_v_samp_factor;
1325 + info->max_v_samp_factor = srcinfo->max_h_samp_factor;
1326 + }
1327 + break;
1328 + default:
1329 + info->output_width = srcinfo->image_width;
1330 + info->output_height = srcinfo->image_height;
1331 + if (info->num_components == 1) {
1332 + info->max_h_samp_factor = 1;
1333 + info->max_v_samp_factor = 1;
1334 + } else {
1335 + info->max_h_samp_factor = srcinfo->max_h_samp_factor;
1336 + info->max_v_samp_factor = srcinfo->max_v_samp_factor;
1337 + }
1338 + break;
1339 + }
1340 +
1341 + /* If cropping has been requested, compute the crop area's position and
1342 + * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
1343 + */
1344 + if (info->crop) {
1345 + /* Insert default values for unset crop parameters */
1346 + if (info->crop_xoffset_set == JCROP_UNSET)
1347 + info->crop_xoffset = 0; /* default to +0 */
1348 + if (info->crop_yoffset_set == JCROP_UNSET)
1349 + info->crop_yoffset = 0; /* default to +0 */
1350 + if (info->crop_xoffset >= info->output_width ||
1351 + info->crop_yoffset >= info->output_height)
1352 + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
1353 + if (info->crop_width_set == JCROP_UNSET)
1354 + info->crop_width = info->output_width - info->crop_xoffset;
1355 + if (info->crop_height_set == JCROP_UNSET)
1356 + info->crop_height = info->output_height - info->crop_yoffset;
1357 + /* Ensure parameters are valid */
1358 + if (info->crop_width <= 0 || info->crop_width > info->output_width ||
1359 + info->crop_height <= 0 || info->crop_height > info->output_height ||
1360 + info->crop_xoffset > info->output_width - info->crop_width ||
1361 + info->crop_yoffset > info->output_height - info->crop_height)
1362 + ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
1363 + /* Convert negative crop offsets into regular offsets */
1364 + if (info->crop_xoffset_set == JCROP_NEG)
1365 + xoffset = info->output_width - info->crop_width - info->crop_xoffset;
1366 + else
1367 + xoffset = info->crop_xoffset;
1368 + if (info->crop_yoffset_set == JCROP_NEG)
1369 + yoffset = info->output_height - info->crop_height - info->crop_yoffset;
1370 + else
1371 + yoffset = info->crop_yoffset;
1372 + /* Now adjust so that upper left corner falls at an iMCU boundary */
1373 + info->output_width =
1374 + info->crop_width + (xoffset % (info->max_h_samp_factor * DCTSIZE));
1375 + info->output_height =
1376 + info->crop_height + (yoffset % (info->max_v_samp_factor * DCTSIZE));
1377 + /* Save x/y offsets measured in iMCUs */
1378 + info->x_crop_offset = xoffset / (info->max_h_samp_factor * DCTSIZE);
1379 + info->y_crop_offset = yoffset / (info->max_v_samp_factor * DCTSIZE);
1380 + } else {
1381 + info->x_crop_offset = 0;
1382 + info->y_crop_offset = 0;
1383 + }
1384
1385 + /* Figure out whether we need workspace arrays,
1386 + * and if so whether they are transposed relative to the source.
1387 + */
1388 + need_workspace = FALSE;
1389 + transpose_it = FALSE;
1390 switch (info->transform) {
1391 case JXFORM_NONE:
1392 + if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1393 + need_workspace = TRUE;
1394 + /* No workspace needed if neither cropping nor transforming */
1395 + break;
1396 case JXFORM_FLIP_H:
1397 - /* Don't need a workspace array */
1398 + if (info->trim)
1399 + trim_right_edge(info, srcinfo->image_width);
1400 + if (info->y_crop_offset != 0)
1401 + need_workspace = TRUE;
1402 + /* do_flip_h_no_crop doesn't need a workspace array */
1403 break;
1404 case JXFORM_FLIP_V:
1405 - case JXFORM_ROT_180:
1406 - /* Need workspace arrays having same dimensions as source image.
1407 - * Note that we allocate arrays padded out to the next iMCU boundary,
1408 - * so that transform routines need not worry about missing edge blocks.
1409 - */
1410 - coef_arrays = (jvirt_barray_ptr *)
1411 - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1412 - SIZEOF(jvirt_barray_ptr) * info->num_components);
1413 - for (ci = 0; ci < info->num_components; ci++) {
1414 - compptr = srcinfo->comp_info + ci;
1415 - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1416 - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
1417 - (JDIMENSION) jround_up((long) compptr->width_in_blocks,
1418 - (long) compptr->h_samp_factor),
1419 - (JDIMENSION) jround_up((long) compptr->height_in_blocks,
1420 - (long) compptr->v_samp_factor),
1421 - (JDIMENSION) compptr->v_samp_factor);
1422 - }
1423 + if (info->trim)
1424 + trim_bottom_edge(info, srcinfo->image_height);
1425 + /* Need workspace arrays having same dimensions as source image. */
1426 + need_workspace = TRUE;
1427 break;
1428 case JXFORM_TRANSPOSE:
1429 + /* transpose does NOT have to trim anything */
1430 + /* Need workspace arrays having transposed dimensions. */
1431 + need_workspace = TRUE;
1432 + transpose_it = TRUE;
1433 + break;
1434 case JXFORM_TRANSVERSE:
1435 + if (info->trim) {
1436 + trim_right_edge(info, srcinfo->image_height);
1437 + trim_bottom_edge(info, srcinfo->image_width);
1438 + }
1439 + /* Need workspace arrays having transposed dimensions. */
1440 + need_workspace = TRUE;
1441 + transpose_it = TRUE;
1442 + break;
1443 case JXFORM_ROT_90:
1444 + if (info->trim)
1445 + trim_right_edge(info, srcinfo->image_height);
1446 + /* Need workspace arrays having transposed dimensions. */
1447 + need_workspace = TRUE;
1448 + transpose_it = TRUE;
1449 + break;
1450 + case JXFORM_ROT_180:
1451 + if (info->trim) {
1452 + trim_right_edge(info, srcinfo->image_width);
1453 + trim_bottom_edge(info, srcinfo->image_height);
1454 + }
1455 + /* Need workspace arrays having same dimensions as source image. */
1456 + need_workspace = TRUE;
1457 + break;
1458 case JXFORM_ROT_270:
1459 - /* Need workspace arrays having transposed dimensions.
1460 - * Note that we allocate arrays padded out to the next iMCU boundary,
1461 - * so that transform routines need not worry about missing edge blocks.
1462 - */
1463 + if (info->trim)
1464 + trim_bottom_edge(info, srcinfo->image_width);
1465 + /* Need workspace arrays having transposed dimensions. */
1466 + need_workspace = TRUE;
1467 + transpose_it = TRUE;
1468 + break;
1469 + }
1470 +
1471 + /* Allocate workspace if needed.
1472 + * Note that we allocate arrays padded out to the next iMCU boundary,
1473 + * so that transform routines need not worry about missing edge blocks.
1474 + */
1475 + if (need_workspace) {
1476 coef_arrays = (jvirt_barray_ptr *)
1477 (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1478 - SIZEOF(jvirt_barray_ptr) * info->num_components);
1479 + SIZEOF(jvirt_barray_ptr) * info->num_components);
1480 + width_in_iMCUs = (JDIMENSION)
1481 + jdiv_round_up((long) info->output_width,
1482 + (long) (info->max_h_samp_factor * DCTSIZE));
1483 + height_in_iMCUs = (JDIMENSION)
1484 + jdiv_round_up((long) info->output_height,
1485 + (long) (info->max_v_samp_factor * DCTSIZE));
1486 for (ci = 0; ci < info->num_components; ci++) {
1487 compptr = srcinfo->comp_info + ci;
1488 + if (info->num_components == 1) {
1489 + /* we're going to force samp factors to 1x1 in this case */
1490 + h_samp_factor = v_samp_factor = 1;
1491 + } else if (transpose_it) {
1492 + h_samp_factor = compptr->v_samp_factor;
1493 + v_samp_factor = compptr->h_samp_factor;
1494 + } else {
1495 + h_samp_factor = compptr->h_samp_factor;
1496 + v_samp_factor = compptr->v_samp_factor;
1497 + }
1498 + width_in_blocks = width_in_iMCUs * h_samp_factor;
1499 + height_in_blocks = height_in_iMCUs * v_samp_factor;
1500 coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1501 ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
1502 - (JDIMENSION) jround_up((long) compptr->height_in_blocks,
1503 - (long) compptr->v_samp_factor),
1504 - (JDIMENSION) jround_up((long) compptr->width_in_blocks,
1505 - (long) compptr->h_samp_factor),
1506 - (JDIMENSION) compptr->h_samp_factor);
1507 + width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
1508 }
1509 - break;
1510 }
1511 +
1512 info->workspace_coef_arrays = coef_arrays;
1513 }
1514
1515 @@ -642,14 +1062,8 @@ transpose_critical_parameters (j_compres
1516 int tblno, i, j, ci, itemp;
1517 jpeg_component_info *compptr;
1518 JQUANT_TBL *qtblptr;
1519 - JDIMENSION dtemp;
1520 UINT16 qtemp;
1521
1522 - /* Transpose basic image dimensions */
1523 - dtemp = dstinfo->image_width;
1524 - dstinfo->image_width = dstinfo->image_height;
1525 - dstinfo->image_height = dtemp;
1526 -
1527 /* Transpose sampling factors */
1528 for (ci = 0; ci < dstinfo->num_components; ci++) {
1529 compptr = dstinfo->comp_info + ci;
1530 @@ -674,46 +1088,159 @@ transpose_critical_parameters (j_compres
1531 }
1532
1533
1534 -/* Trim off any partial iMCUs on the indicated destination edge */
1535 +/* Adjust Exif image parameters.
1536 + *
1537 + * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1538 + */
1539
1540 LOCAL(void)
1541 -trim_right_edge (j_compress_ptr dstinfo)
1542 +adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
1543 + JDIMENSION new_width, JDIMENSION new_height)
1544 {
1545 - int ci, max_h_samp_factor;
1546 - JDIMENSION MCU_cols;
1547 + boolean is_motorola; /* Flag for byte order */
1548 + unsigned int number_of_tags, tagnum;
1549 + unsigned int firstoffset, offset;
1550 + JDIMENSION new_value;
1551 +
1552 + if (length < 12) return; /* Length of an IFD entry */
1553 +
1554 + /* Discover byte order */
1555 + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
1556 + is_motorola = FALSE;
1557 + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
1558 + is_motorola = TRUE;
1559 + else
1560 + return;
1561 +
1562 + /* Check Tag Mark */
1563 + if (is_motorola) {
1564 + if (GETJOCTET(data[2]) != 0) return;
1565 + if (GETJOCTET(data[3]) != 0x2A) return;
1566 + } else {
1567 + if (GETJOCTET(data[3]) != 0) return;
1568 + if (GETJOCTET(data[2]) != 0x2A) return;
1569 + }
1570
1571 - /* We have to compute max_h_samp_factor ourselves,
1572 - * because it hasn't been set yet in the destination
1573 - * (and we don't want to use the source's value).
1574 - */
1575 - max_h_samp_factor = 1;
1576 - for (ci = 0; ci < dstinfo->num_components; ci++) {
1577 - int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
1578 - max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
1579 + /* Get first IFD offset (offset to IFD0) */
1580 + if (is_motorola) {
1581 + if (GETJOCTET(data[4]) != 0) return;
1582 + if (GETJOCTET(data[5]) != 0) return;
1583 + firstoffset = GETJOCTET(data[6]);
1584 + firstoffset <<= 8;
1585 + firstoffset += GETJOCTET(data[7]);
1586 + } else {
1587 + if (GETJOCTET(data[7]) != 0) return;
1588 + if (GETJOCTET(data[6]) != 0) return;
1589 + firstoffset = GETJOCTET(data[5]);
1590 + firstoffset <<= 8;
1591 + firstoffset += GETJOCTET(data[4]);
1592 }
1593 - MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
1594 - if (MCU_cols > 0) /* can't trim to 0 pixels */
1595 - dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
1596 -}
1597 + if (firstoffset > length - 2) return; /* check end of data segment */
1598
1599 -LOCAL(void)
1600 -trim_bottom_edge (j_compress_ptr dstinfo)
1601 -{
1602 - int ci, max_v_samp_factor;
1603 - JDIMENSION MCU_rows;
1604 + /* Get the number of directory entries contained in this IFD */
1605 + if (is_motorola) {
1606 + number_of_tags = GETJOCTET(data[firstoffset]);
1607 + number_of_tags <<= 8;
1608 + number_of_tags += GETJOCTET(data[firstoffset+1]);
1609 + } else {
1610 + number_of_tags = GETJOCTET(data[firstoffset+1]);
1611 + number_of_tags <<= 8;
1612 + number_of_tags += GETJOCTET(data[firstoffset]);
1613 + }
1614 + if (number_of_tags == 0) return;
1615 + firstoffset += 2;
1616
1617 - /* We have to compute max_v_samp_factor ourselves,
1618 - * because it hasn't been set yet in the destination
1619 - * (and we don't want to use the source's value).
1620 - */
1621 - max_v_samp_factor = 1;
1622 - for (ci = 0; ci < dstinfo->num_components; ci++) {
1623 - int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
1624 - max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
1625 + /* Search for ExifSubIFD offset Tag in IFD0 */
1626 + for (;;) {
1627 + if (firstoffset > length - 12) return; /* check end of data segment */
1628 + /* Get Tag number */
1629 + if (is_motorola) {
1630 + tagnum = GETJOCTET(data[firstoffset]);
1631 + tagnum <<= 8;
1632 + tagnum += GETJOCTET(data[firstoffset+1]);
1633 + } else {
1634 + tagnum = GETJOCTET(data[firstoffset+1]);
1635 + tagnum <<= 8;
1636 + tagnum += GETJOCTET(data[firstoffset]);
1637 + }
1638 + if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
1639 + if (--number_of_tags == 0) return;
1640 + firstoffset += 12;
1641 }
1642 - MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
1643 - if (MCU_rows > 0) /* can't trim to 0 pixels */
1644 - dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
1645 +
1646 + /* Get the ExifSubIFD offset */
1647 + if (is_motorola) {
1648 + if (GETJOCTET(data[firstoffset+8]) != 0) return;
1649 + if (GETJOCTET(data[firstoffset+9]) != 0) return;
1650 + offset = GETJOCTET(data[firstoffset+10]);
1651 + offset <<= 8;
1652 + offset += GETJOCTET(data[firstoffset+11]);
1653 + } else {
1654 + if (GETJOCTET(data[firstoffset+11]) != 0) return;
1655 + if (GETJOCTET(data[firstoffset+10]) != 0) return;
1656 + offset = GETJOCTET(data[firstoffset+9]);
1657 + offset <<= 8;
1658 + offset += GETJOCTET(data[firstoffset+8]);
1659 + }
1660 + if (offset > length - 2) return; /* check end of data segment */
1661 +
1662 + /* Get the number of directory entries contained in this SubIFD */
1663 + if (is_motorola) {
1664 + number_of_tags = GETJOCTET(data[offset]);
1665 + number_of_tags <<= 8;
1666 + number_of_tags += GETJOCTET(data[offset+1]);
1667 + } else {
1668 + number_of_tags = GETJOCTET(data[offset+1]);
1669 + number_of_tags <<= 8;
1670 + number_of_tags += GETJOCTET(data[offset]);
1671 + }
1672 + if (number_of_tags < 2) return;
1673 + offset += 2;
1674 +
1675 + /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1676 + do {
1677 + if (offset > length - 12) return; /* check end of data segment */
1678 + /* Get Tag number */
1679 + if (is_motorola) {
1680 + tagnum = GETJOCTET(data[offset]);
1681 + tagnum <<= 8;
1682 + tagnum += GETJOCTET(data[offset+1]);
1683 + } else {
1684 + tagnum = GETJOCTET(data[offset+1]);
1685 + tagnum <<= 8;
1686 + tagnum += GETJOCTET(data[offset]);
1687 + }
1688 + if (tagnum == 0xA002 || tagnum == 0xA003) {
1689 + if (tagnum == 0xA002)
1690 + new_value = new_width; /* ExifImageWidth Tag */
1691 + else
1692 + new_value = new_height; /* ExifImageHeight Tag */
1693 + if (is_motorola) {
1694 + data[offset+2] = 0; /* Format = unsigned long (4 octets) */
1695 + data[offset+3] = 4;
1696 + data[offset+4] = 0; /* Number Of Components = 1 */
1697 + data[offset+5] = 0;
1698 + data[offset+6] = 0;
1699 + data[offset+7] = 1;
1700 + data[offset+8] = 0;
1701 + data[offset+9] = 0;
1702 + data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
1703 + data[offset+11] = (JOCTET)(new_value & 0xFF);
1704 + } else {
1705 + data[offset+2] = 4; /* Format = unsigned long (4 octets) */
1706 + data[offset+3] = 0;
1707 + data[offset+4] = 1; /* Number Of Components = 1 */
1708 + data[offset+5] = 0;
1709 + data[offset+6] = 0;
1710 + data[offset+7] = 0;
1711 + data[offset+8] = (JOCTET)(new_value & 0xFF);
1712 + data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
1713 + data[offset+10] = 0;
1714 + data[offset+11] = 0;
1715 + }
1716 + }
1717 + offset += 12;
1718 + } while (--number_of_tags);
1719 }
1720
1721
1722 @@ -736,18 +1263,22 @@ jtransform_adjust_parameters (j_decompre
1723 {
1724 /* If force-to-grayscale is requested, adjust destination parameters */
1725 if (info->force_grayscale) {
1726 - /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1727 - * properly. Among other things, the target h_samp_factor & v_samp_factor
1728 - * will get set to 1, which typically won't match the source.
1729 - * In fact we do this even if the source is already grayscale; that
1730 - * provides an easy way of coercing a grayscale JPEG with funny sampling
1731 - * factors to the customary 1,1. (Some decoders fail on other factors.)
1732 + /* First, ensure we have YCbCr or grayscale data, and that the source's
1733 + * Y channel is full resolution. (No reasonable person would make Y
1734 + * be less than full resolution, so actually coping with that case
1735 + * isn't worth extra code space. But we check it to avoid crashing.)
1736 */
1737 - if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
1738 - dstinfo->num_components == 3) ||
1739 - (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
1740 - dstinfo->num_components == 1)) {
1741 - /* We have to preserve the source's quantization table number. */
1742 + if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
1743 + dstinfo->num_components == 3) ||
1744 + (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
1745 + dstinfo->num_components == 1)) &&
1746 + srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
1747 + srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
1748 + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1749 + * properly. Among other things, it sets the target h_samp_factor &
1750 + * v_samp_factor to 1, which typically won't match the source.
1751 + * We have to preserve the source's quantization table number, however.
1752 + */
1753 int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
1754 jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
1755 dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
1756 @@ -755,50 +1286,52 @@ jtransform_adjust_parameters (j_decompre
1757 /* Sorry, can't do it */
1758 ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
1759 }
1760 + } else if (info->num_components == 1) {
1761 + /* For a single-component source, we force the destination sampling factors
1762 + * to 1x1, with or without force_grayscale. This is useful because some
1763 + * decoders choke on grayscale images with other sampling factors.
1764 + */
1765 + dstinfo->comp_info[0].h_samp_factor = 1;
1766 + dstinfo->comp_info[0].v_samp_factor = 1;
1767 }
1768
1769 - /* Correct the destination's image dimensions etc if necessary */
1770 + /* Correct the destination's image dimensions as necessary
1771 + * for crop and rotate/flip operations.
1772 + */
1773 + dstinfo->image_width = info->output_width;
1774 + dstinfo->image_height = info->output_height;
1775 +
1776 + /* Transpose destination image parameters */
1777 switch (info->transform) {
1778 - case JXFORM_NONE:
1779 - /* Nothing to do */
1780 - break;
1781 - case JXFORM_FLIP_H:
1782 - if (info->trim)
1783 - trim_right_edge(dstinfo);
1784 - break;
1785 - case JXFORM_FLIP_V:
1786 - if (info->trim)
1787 - trim_bottom_edge(dstinfo);
1788 - break;
1789 case JXFORM_TRANSPOSE:
1790 - transpose_critical_parameters(dstinfo);
1791 - /* transpose does NOT have to trim anything */
1792 - break;
1793 case JXFORM_TRANSVERSE:
1794 - transpose_critical_parameters(dstinfo);
1795 - if (info->trim) {
1796 - trim_right_edge(dstinfo);
1797 - trim_bottom_edge(dstinfo);
1798 - }
1799 - break;
1800 case JXFORM_ROT_90:
1801 - transpose_critical_parameters(dstinfo);
1802 - if (info->trim)
1803 - trim_right_edge(dstinfo);
1804 - break;
1805 - case JXFORM_ROT_180:
1806 - if (info->trim) {
1807 - trim_right_edge(dstinfo);
1808 - trim_bottom_edge(dstinfo);
1809 - }
1810 - break;
1811 case JXFORM_ROT_270:
1812 transpose_critical_parameters(dstinfo);
1813 - if (info->trim)
1814 - trim_bottom_edge(dstinfo);
1815 break;
1816 }
1817
1818 + /* Adjust Exif properties */
1819 + if (srcinfo->marker_list != NULL &&
1820 + srcinfo->marker_list->marker == JPEG_APP0+1 &&
1821 + srcinfo->marker_list->data_length >= 6 &&
1822 + GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
1823 + GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
1824 + GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
1825 + GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
1826 + GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
1827 + GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
1828 + /* Suppress output of JFIF marker */
1829 + dstinfo->write_JFIF_header = FALSE;
1830 + /* Adjust Exif image parameters */
1831 + if (dstinfo->image_width != srcinfo->image_width ||
1832 + dstinfo->image_height != srcinfo->image_height)
1833 + /* Align data segment to start of TIFF structure for parsing */
1834 + adjust_exif_parameters(srcinfo->marker_list->data + 6,
1835 + srcinfo->marker_list->data_length - 6,
1836 + dstinfo->image_width, dstinfo->image_height);
1837 + }
1838 +
1839 /* Return the appropriate output data set */
1840 if (info->workspace_coef_arrays != NULL)
1841 return info->workspace_coef_arrays;
1842 @@ -816,40 +1349,108 @@ jtransform_adjust_parameters (j_decompre
1843 */
1844
1845 GLOBAL(void)
1846 -jtransform_execute_transformation (j_decompress_ptr srcinfo,
1847 - j_compress_ptr dstinfo,
1848 - jvirt_barray_ptr *src_coef_arrays,
1849 - jpeg_transform_info *info)
1850 +jtransform_execute_transform (j_decompress_ptr srcinfo,
1851 + j_compress_ptr dstinfo,
1852 + jvirt_barray_ptr *src_coef_arrays,
1853 + jpeg_transform_info *info)
1854 {
1855 jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
1856
1857 + /* Note: conditions tested here should match those in switch statement
1858 + * in jtransform_request_workspace()
1859 + */
1860 switch (info->transform) {
1861 case JXFORM_NONE:
1862 + if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1863 + do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1864 + src_coef_arrays, dst_coef_arrays);
1865 break;
1866 case JXFORM_FLIP_H:
1867 - do_flip_h(srcinfo, dstinfo, src_coef_arrays);
1868 + if (info->y_crop_offset != 0)
1869 + do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1870 + src_coef_arrays, dst_coef_arrays);
1871 + else
1872 + do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
1873 + src_coef_arrays);
1874 break;
1875 case JXFORM_FLIP_V:
1876 - do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1877 + do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1878 + src_coef_arrays, dst_coef_arrays);
1879 break;
1880 case JXFORM_TRANSPOSE:
1881 - do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1882 + do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1883 + src_coef_arrays, dst_coef_arrays);
1884 break;
1885 case JXFORM_TRANSVERSE:
1886 - do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1887 + do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1888 + src_coef_arrays, dst_coef_arrays);
1889 break;
1890 case JXFORM_ROT_90:
1891 - do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1892 + do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1893 + src_coef_arrays, dst_coef_arrays);
1894 break;
1895 case JXFORM_ROT_180:
1896 - do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1897 + do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1898 + src_coef_arrays, dst_coef_arrays);
1899 break;
1900 case JXFORM_ROT_270:
1901 - do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
1902 + do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1903 + src_coef_arrays, dst_coef_arrays);
1904 break;
1905 }
1906 }
1907
1908 +/* jtransform_perfect_transform
1909 + *
1910 + * Determine whether lossless transformation is perfectly
1911 + * possible for a specified image and transformation.
1912 + *
1913 + * Inputs:
1914 + * image_width, image_height: source image dimensions.
1915 + * MCU_width, MCU_height: pixel dimensions of MCU.
1916 + * transform: transformation identifier.
1917 + * Parameter sources from initialized jpeg_struct
1918 + * (after reading source header):
1919 + * image_width = cinfo.image_width
1920 + * image_height = cinfo.image_height
1921 + * MCU_width = cinfo.max_h_samp_factor * DCTSIZE
1922 + * MCU_height = cinfo.max_v_samp_factor * DCTSIZE
1923 + * Result:
1924 + * TRUE = perfect transformation possible
1925 + * FALSE = perfect transformation not possible
1926 + * (may use custom action then)
1927 + */
1928 +
1929 +GLOBAL(boolean)
1930 +jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
1931 + int MCU_width, int MCU_height,
1932 + JXFORM_CODE transform)
1933 +{
1934 + boolean result = TRUE; /* initialize TRUE */
1935 +
1936 + switch (transform) {
1937 + case JXFORM_FLIP_H:
1938 + case JXFORM_ROT_270:
1939 + if (image_width % (JDIMENSION) MCU_width)
1940 + result = FALSE;
1941 + break;
1942 + case JXFORM_FLIP_V:
1943 + case JXFORM_ROT_90:
1944 + if (image_height % (JDIMENSION) MCU_height)
1945 + result = FALSE;
1946 + break;
1947 + case JXFORM_TRANSVERSE:
1948 + case JXFORM_ROT_180:
1949 + if (image_width % (JDIMENSION) MCU_width)
1950 + result = FALSE;
1951 + if (image_height % (JDIMENSION) MCU_height)
1952 + result = FALSE;
1953 + break;
1954 + }
1955 +
1956 + return result;
1957 +}
1958 +
1959 #endif /* TRANSFORMS_SUPPORTED */
1960
1961
1962 --- jpeg/transupp.h
1963 +++ jpeg/transupp.h
1964 @@ -1,7 +1,7 @@
1965 /*
1966 * transupp.h
1967 *
1968 - * Copyright (C) 1997, Thomas G. Lane.
1969 + * Copyright (C) 1997-2001, Thomas G. Lane.
1970 * This file is part of the Independent JPEG Group's software.
1971 * For conditions of distribution and use, see the accompanying README file.
1972 *
1973 @@ -22,32 +22,6 @@
1974 #define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */
1975 #endif
1976
1977 -/* Short forms of external names for systems with brain-damaged linkers. */
1978 -
1979 -#ifdef NEED_SHORT_EXTERNAL_NAMES
1980 -#define jtransform_request_workspace jTrRequest
1981 -#define jtransform_adjust_parameters jTrAdjust
1982 -#define jtransform_execute_transformation jTrExec
1983 -#define jcopy_markers_setup jCMrkSetup
1984 -#define jcopy_markers_execute jCMrkExec
1985 -#endif /* NEED_SHORT_EXTERNAL_NAMES */
1986 -
1987 -
1988 -/*
1989 - * Codes for supported types of image transformations.
1990 - */
1991 -
1992 -typedef enum {
1993 - JXFORM_NONE, /* no transformation */
1994 - JXFORM_FLIP_H, /* horizontal flip */
1995 - JXFORM_FLIP_V, /* vertical flip */
1996 - JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
1997 - JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
1998 - JXFORM_ROT_90, /* 90-degree clockwise rotation */
1999 - JXFORM_ROT_180, /* 180-degree rotation */
2000 - JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
2001 -} JXFORM_CODE;
2002 -
2003 /*
2004 * Although rotating and flipping data expressed as DCT coefficients is not
2005 * hard, there is an asymmetry in the JPEG format specification for images
2006 @@ -75,6 +49,19 @@ typedef enum {
2007 * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
2008 * followed by -rot 180 -trim trims both edges.)
2009 *
2010 + * We also offer a lossless-crop option, which discards data outside a given
2011 + * image region but losslessly preserves what is inside. Like the rotate and
2012 + * flip transforms, lossless crop is restricted by the JPEG format: the upper
2013 + * left corner of the selected region must fall on an iMCU boundary. If this
2014 + * does not hold for the given crop parameters, we silently move the upper left
2015 + * corner up and/or left to make it so, simultaneously increasing the region
2016 + * dimensions to keep the lower right crop corner unchanged. (Thus, the
2017 + * output image covers at least the requested region, but may cover more.)
2018 + *
2019 + * If both crop and a rotate/flip transform are requested, the crop is applied
2020 + * last --- that is, the crop region is specified in terms of the destination
2021 + * image.
2022 + *
2023 * We also offer a "force to grayscale" option, which simply discards the
2024 * chrominance channels of a YCbCr image. This is lossless in the sense that
2025 * the luminance channel is preserved exactly. It's not the same kind of
2026 @@ -83,20 +70,89 @@ typedef enum {
2027 * be aware of the option to know how many components to work on.
2028 */
2029
2030 +
2031 +/* Short forms of external names for systems with brain-damaged linkers. */
2032 +
2033 +#ifdef NEED_SHORT_EXTERNAL_NAMES
2034 +#define jtransform_parse_crop_spec jTrParCrop
2035 +#define jtransform_request_workspace jTrRequest
2036 +#define jtransform_adjust_parameters jTrAdjust
2037 +#define jtransform_execute_transform jTrExec
2038 +#define jtransform_perfect_transform jTrPerfect
2039 +#define jcopy_markers_setup jCMrkSetup
2040 +#define jcopy_markers_execute jCMrkExec
2041 +#endif /* NEED_SHORT_EXTERNAL_NAMES */
2042 +
2043 +
2044 +/*
2045 + * Codes for supported types of image transformations.
2046 + */
2047 +
2048 +typedef enum {
2049 + JXFORM_NONE, /* no transformation */
2050 + JXFORM_FLIP_H, /* horizontal flip */
2051 + JXFORM_FLIP_V, /* vertical flip */
2052 + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */
2053 + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */
2054 + JXFORM_ROT_90, /* 90-degree clockwise rotation */
2055 + JXFORM_ROT_180, /* 180-degree rotation */
2056 + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */
2057 +} JXFORM_CODE;
2058 +
2059 +/*
2060 + * Codes for crop parameters, which can individually be unspecified,
2061 + * positive, or negative. (Negative width or height makes no sense, though.)
2062 + */
2063 +
2064 +typedef enum {
2065 + JCROP_UNSET,
2066 + JCROP_POS,
2067 + JCROP_NEG
2068 +} JCROP_CODE;
2069 +
2070 +/*
2071 + * Transform parameters struct.
2072 + * NB: application must not change any elements of this struct after
2073 + * calling jtransform_request_workspace.
2074 + */
2075 +
2076 typedef struct {
2077 /* Options: set by caller */
2078 JXFORM_CODE transform; /* image transform operator */
2079 + boolean perfect; /* if TRUE, fail if partial MCUs are requested */
2080 boolean trim; /* if TRUE, trim partial MCUs as needed */
2081 boolean force_grayscale; /* if TRUE, convert color image to grayscale */
2082 + boolean crop; /* if TRUE, crop source image */
2083 +
2084 + /* Crop parameters: application need not set these unless crop is TRUE.
2085 + * These can be filled in by jtransform_parse_crop_spec().
2086 + */
2087 + JDIMENSION crop_width; /* Width of selected region */
2088 + JCROP_CODE crop_width_set;
2089 + JDIMENSION crop_height; /* Height of selected region */
2090 + JCROP_CODE crop_height_set;
2091 + JDIMENSION crop_xoffset; /* X offset of selected region */
2092 + JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */
2093 + JDIMENSION crop_yoffset; /* Y offset of selected region */
2094 + JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */
2095
2096 /* Internal workspace: caller should not touch these */
2097 int num_components; /* # of components in workspace */
2098 jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
2099 + JDIMENSION output_width; /* cropped destination dimensions */
2100 + JDIMENSION output_height;
2101 + JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */
2102 + JDIMENSION y_crop_offset;
2103 + int max_h_samp_factor; /* destination iMCU size */
2104 + int max_v_samp_factor;
2105 } jpeg_transform_info;
2106
2107
2108 #if TRANSFORMS_SUPPORTED
2109
2110 +/* Parse a crop specification (written in X11 geometry style) */
2111 +EXTERN(boolean) jtransform_parse_crop_spec
2112 + JPP((jpeg_transform_info *info, const char *spec));
2113 /* Request any required workspace */
2114 EXTERN(void) jtransform_request_workspace
2115 JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
2116 @@ -106,10 +162,24 @@ EXTERN(jvirt_barray_ptr *) jtransform_ad
2117 jvirt_barray_ptr *src_coef_arrays,
2118 jpeg_transform_info *info));
2119 /* Execute the actual transformation, if any */
2120 -EXTERN(void) jtransform_execute_transformation
2121 +EXTERN(void) jtransform_execute_transform
2122 JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
2123 jvirt_barray_ptr *src_coef_arrays,
2124 jpeg_transform_info *info));
2125 +/* Determine whether lossless transformation is perfectly
2126 + * possible for a specified image and transformation.
2127 + */
2128 +EXTERN(boolean) jtransform_perfect_transform
2129 + JPP((JDIMENSION image_width, JDIMENSION image_height,
2130 + int MCU_width, int MCU_height,
2131 + JXFORM_CODE transform));
2132 +
2133 +/* jtransform_execute_transform used to be called
2134 + * jtransform_execute_transformation, but some compilers complain about
2135 + * routine names that long. This macro is here to avoid breaking any
2136 + * old source code that uses the original name...
2137 + */
2138 +#define jtransform_execute_transformation jtransform_execute_transform
2139
2140 #endif /* TRANSFORMS_SUPPORTED */
2141
2142 --- jpeg/jpegtran.1
2143 +++ jpeg/jpegtran.1
2144 @@ -131,6 +131,40 @@
2145 .B \-rot 180 -trim
2146 trims both edges.
2147 .PP
2148 +If you are only interested by perfect transformation, add the
2149 +.B \-perfect
2150 +switch:
2151 +.TP
2152 +.B \-perfect
2153 +Fails with an error if the transformation is not perfect. For example
2154 +you may want to do
2155 +.TP
2156 +.B (jpegtran \-rot 90 -perfect foo.jpg || djpeg foo.jpg| pnmflip \-r90 | cjpeg)
2157 +to do a perfect rotation if available or an approximated one if
2158 +not.
2159 +.PP
2160 +We also offer a lossless-crop option, which discards data outside a given
2161 +image region but losslessly preserves what is inside. Like the rotate and
2162 +flip transforms, lossless crop is restricted by the JPEG format: the upper
2163 +left corner of the selected region must fall on an iMCU boundary. If this
2164 +does not hold for the given crop parameters, we silently move the upper left
2165 +corner up and/or left to make it so, simultaneously increasing the region
2166 +dimensions to keep the lower right crop corner unchanged. (Thus, the
2167 +output image covers at least the requested region, but may cover more.)
2168 +
2169 +Note:
2170 +.B \-perfect
2171 +and
2172 +.B lossless-crop
2173 +are enhancements from http://sylvana.net/jpegcrop/ that may not be available on
2174 +non-Debian systems.
2175 +
2176 +The image can be losslessly cropped by giving the switch:
2177 +.TP
2178 +.B \-crop WxH+X+Y
2179 +Crop to a rectangular subarea of width W, height H starting at point X,Y.
2180 +.PP
2181 +.PP
2182 Another not-strictly-lossless transformation switch is:
2183 .TP
2184 .B \-grayscale
2185 @@ -231,7 +265,9 @@
2186 .PP
2187 The transform options can't transform odd-size images perfectly. Use
2188 .B \-trim
2189 -if you don't like the results without it.
2190 +or
2191 +.B \-perfect
2192 +if you don't like the results.
2193 .PP
2194 The entire image is read into memory and then written out again, even in
2195 cases where this isn't really necessary. Expect swapping on large images,
2196
2197
2198
2199 1.1 src/patchsets/jpeg/6b/50_all_jpeg-Debian-rdjpgcom_locale.patch
2200
2201 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/50_all_jpeg-Debian-rdjpgcom_locale.patch?rev=1.1&view=markup
2202 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/50_all_jpeg-Debian-rdjpgcom_locale.patch?rev=1.1&content-type=text/plain
2203
2204 Index: 50_all_jpeg-Debian-rdjpgcom_locale.patch
2205 ===================================================================
2206 #! /bin/sh -e
2207
2208 # DP: Make rdjpegcom locale aware.
2209
2210 case "$1" in
2211 -patch) patch -f --no-backup-if-mismatch -p1 < $0;;
2212 -unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;;
2213 *)
2214 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
2215 exit 1
2216 esac
2217 exit 0
2218 @DPATCH@
2219 --- jpeg-6b/rdjpgcom.c Sun Oct 12 00:41:04 1997
2220 +++ libjpeg6b-6b/rdjpgcom.c Wed Feb 26 01:04:42 2003
2221 @@ -14,6 +14,7 @@
2222 #define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */
2223 #include "jinclude.h" /* get auto-config symbols, <stdio.h> */
2224
2225 +#include <locale.h> /*ballombe@××××××.org: use locale for isprint*/
2226 #include <ctype.h> /* to declare isupper(), tolower() */
2227 #ifdef USE_SETMODE
2228 #include <fcntl.h> /* to declare setmode()'s parameter macros */
2229 @@ -223,7 +224,10 @@
2230 unsigned int length;
2231 int ch;
2232 int lastch = 0;
2233 -
2234 +/* ballombe@××××××.org Thu, 15 Nov 2001 20:04:47 +0100*/
2235 +/* Set locale properly for isprint*/
2236 + setlocale(LC_CTYPE,"");
2237 +
2238 /* Get the marker parameter length count */
2239 length = read_2_bytes();
2240 /* Length includes itself, so must be at least 2 */
2241 @@ -254,6 +258,8 @@
2242 length--;
2243 }
2244 printf("\n");
2245 +/*ballombe@××××××.org: revert to C locale*/
2246 + setlocale(LC_CTYPE,"C");
2247 }
2248
2249
2250
2251
2252
2253 1.1 src/patchsets/jpeg/6b/51_all_jpeg-Debian-jpeglib.h_c++.patch
2254
2255 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/51_all_jpeg-Debian-jpeglib.h_c++.patch?rev=1.1&view=markup
2256 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/51_all_jpeg-Debian-jpeglib.h_c++.patch?rev=1.1&content-type=text/plain
2257
2258 Index: 51_all_jpeg-Debian-jpeglib.h_c++.patch
2259 ===================================================================
2260 #! /bin/sh -e
2261
2262 # DP: Add extern "C" to jpeglib.h
2263
2264 case "$1" in
2265 -patch) patch -f --no-backup-if-mismatch -p1 < $0;;
2266 -unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;;
2267 *)
2268 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
2269 exit 1
2270 esac
2271 exit 0
2272 @DPATCH@
2273 diff -ur -x debian/* jpeg-6b/jpeglib.h libjpeg6b-6b/jpeglib.h
2274 --- jpeg-6b/jpeglib.h Sat Feb 21 20:48:14 1998
2275 +++ libjpeg6b-6b/jpeglib.h Wed Feb 26 01:04:42 2003
2276 @@ -13,6 +13,10 @@
2277 #ifndef JPEGLIB_H
2278 #define JPEGLIB_H
2279
2280 +#ifdef __cplusplus
2281 +extern "C" {
2282 +#endif
2283 +
2284 /*
2285 * First we include the configuration files that record how this
2286 * installation of the JPEG library is set up. jconfig.h can be
2287 @@ -1091,6 +1095,10 @@
2288 #ifdef JPEG_INTERNALS
2289 #include "jpegint.h" /* fetch private declarations */
2290 #include "jerror.h" /* fetch error codes too */
2291 +#endif
2292 +
2293 +#ifdef __cplusplus
2294 +}
2295 #endif
2296
2297 #endif /* JPEGLIB_H */
2298
2299
2300
2301 1.1 src/patchsets/jpeg/6b/52_all_jpeg-Debian-rdppm.patch
2302
2303 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/52_all_jpeg-Debian-rdppm.patch?rev=1.1&view=markup
2304 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/52_all_jpeg-Debian-rdppm.patch?rev=1.1&content-type=text/plain
2305
2306 Index: 52_all_jpeg-Debian-rdppm.patch
2307 ===================================================================
2308 #!/bin/sh -e
2309 ## debian/patches/203_rdppm.dpatch by Bill Allombert <ballombe@××××××.org>
2310 ##
2311 ## DP: Fix byte order issue with 16bit PPM/PGM files in rdppm.c
2312
2313 if [ $# -ne 1 ]; then
2314 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
2315 exit 1
2316 fi
2317
2318 [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
2319 patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
2320
2321 case "$1" in
2322 -patch) patch $patch_opts -p1 < $0;;
2323 -unpatch) patch $patch_opts -p1 -R < $0;;
2324 *)
2325 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
2326 exit 1;;
2327 esac
2328
2329 exit 0
2330
2331 @DPATCH@
2332 diff -urNad /home/bill/debian/libjpeg/libjpeg6b-6b/rdppm.c libjpeg6b-6b/rdppm.c
2333 --- /home/bill/debian/libjpeg/libjpeg6b-6b/rdppm.c 2003-09-08 16:44:20.000000000 +0200
2334 +++ libjpeg6b-6b/rdppm.c 2003-09-08 16:47:19.000000000 +0200
2335 @@ -250,8 +250,8 @@
2336 bufferptr = source->iobuffer;
2337 for (col = cinfo->image_width; col > 0; col--) {
2338 register int temp;
2339 - temp = UCH(*bufferptr++);
2340 - temp |= UCH(*bufferptr++) << 8;
2341 + temp = UCH(*bufferptr++) << 8;
2342 + temp |= UCH(*bufferptr++);
2343 *ptr++ = rescale[temp];
2344 }
2345 return 1;
2346 @@ -274,14 +274,14 @@
2347 bufferptr = source->iobuffer;
2348 for (col = cinfo->image_width; col > 0; col--) {
2349 register int temp;
2350 - temp = UCH(*bufferptr++);
2351 - temp |= UCH(*bufferptr++) << 8;
2352 + temp = UCH(*bufferptr++) << 8;
2353 + temp |= UCH(*bufferptr++);
2354 *ptr++ = rescale[temp];
2355 - temp = UCH(*bufferptr++);
2356 - temp |= UCH(*bufferptr++) << 8;
2357 + temp = UCH(*bufferptr++) << 8;
2358 + temp |= UCH(*bufferptr++);
2359 *ptr++ = rescale[temp];
2360 - temp = UCH(*bufferptr++);
2361 - temp |= UCH(*bufferptr++) << 8;
2362 + temp = UCH(*bufferptr++) << 8;
2363 + temp |= UCH(*bufferptr++);
2364 *ptr++ = rescale[temp];
2365 }
2366 return 1;
2367
2368
2369
2370 1.1 src/patchsets/jpeg/6b/60_all_jpeg-maxmem-sysconf.patch
2371
2372 file : http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/60_all_jpeg-maxmem-sysconf.patch?rev=1.1&view=markup
2373 plain: http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/jpeg/6b/60_all_jpeg-maxmem-sysconf.patch?rev=1.1&content-type=text/plain
2374
2375 Index: 60_all_jpeg-maxmem-sysconf.patch
2376 ===================================================================
2377 # Make a reasonable guess about memory limits using sysconf().
2378 # includes 5% slop factor as suggested in documentation.
2379
2380 --- jpeg-6b/jmemansi.c
2381 +++ jpeg-6b/jmemansi.c
2382 @@ -12,6 +12,15 @@
2383 * is shoved onto the user.
2384 */
2385
2386 +#include <unistd.h>
2387 +
2388 +#ifdef __FreeBSD__
2389 +# include <sys/types.h>
2390 +# include <sys/sysctl.h>
2391 +# include <sys/vmmeter.h>
2392 +# include <vm/vm_param.h>
2393 +#endif
2394 +
2395 #define JPEG_INTERNALS
2396 #include "jinclude.h"
2397 #include "jpeglib.h"
2398 @@ -157,7 +166,26 @@
2399 GLOBAL(long)
2400 jpeg_mem_init (j_common_ptr cinfo)
2401 {
2402 - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
2403 +#ifdef _SC_AVPHYS_PAGES
2404 + long phys_size;
2405 +
2406 + if ((phys_size = sysconf(_SC_AVPHYS_PAGES)) == -1)
2407 + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
2408 + if ((phys_size *= sysconf(_SC_PAGESIZE)) < 0)
2409 + return DEFAULT_MAX_MEM;
2410 + return (long) (phys_size * 0.95);
2411 +#elif defined(HAVE_SYSCTL) && defined(HW_PHYSMEM)
2412 + /* This works on *bsd and darwin. */
2413 + unsigned int physmem;
2414 + size_t len = sizeof physmem;
2415 + static int mib[2] = { CTL_HW, HW_PHYSMEM };
2416 +
2417 + if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0
2418 + && len == sizeof (physmem))
2419 + return (long) (physmem * 0.95);
2420 +#endif
2421 +
2422 + return DEFAULT_MAX_MEM;
2423 }
2424
2425 GLOBAL(void)