---
codecs/jpegcomp.h | 30 +++++++
codecs/jpegint.h | 9 +++
codecs/transupp.c | 233 ++++++++++++++++++++++++++++++++++++++----------------
codecs/transupp.h | 41 +++++++---
4 files changed, 231 insertions(+), 82 deletions(-)
create mode 100644 codecs/jpegcomp.h
diff --git a/codecs/jpegcomp.h b/codecs/jpegcomp.h
new file mode 100644
index 0000000..ed9eeab
--- /dev/null
+++ b/codecs/jpegcomp.h
@@ -0,0 +1,30 @@
+/*
+ * jpegcomp.h
+ *
+ * Copyright (C) 2010, D. R. Commander
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * JPEG compatibility macros
+ * These declarations are considered internal to the JPEG library; most
+ * applications using the library shouldn't need to include this file.
+ */
+
+#if JPEG_LIB_VERSION >= 70
+#define _DCT_scaled_size DCT_h_scaled_size
+#define _DCT_h_scaled_size DCT_h_scaled_size
+#define _DCT_v_scaled_size DCT_v_scaled_size
+#define _min_DCT_scaled_size min_DCT_h_scaled_size
+#define _min_DCT_h_scaled_size min_DCT_h_scaled_size
+#define _min_DCT_v_scaled_size min_DCT_v_scaled_size
+#define _jpeg_width jpeg_width
+#define _jpeg_height jpeg_height
+#else
+#define _DCT_scaled_size DCT_scaled_size
+#define _DCT_h_scaled_size DCT_scaled_size
+#define _DCT_v_scaled_size DCT_scaled_size
+#define _min_DCT_scaled_size min_DCT_scaled_size
+#define _min_DCT_h_scaled_size min_DCT_scaled_size
+#define _min_DCT_v_scaled_size min_DCT_scaled_size
+#define _jpeg_width image_width
+#define _jpeg_height image_height
+#endif
diff --git a/codecs/jpegint.h b/codecs/jpegint.h
index 95b00d4..7871748 100644
--- a/codecs/jpegint.h
+++ b/codecs/jpegint.h
@@ -2,6 +2,7 @@
* jpegint.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -304,6 +305,7 @@ struct jpeg_color_quantizer {
#define jinit_forward_dct jIFDCT
#define jinit_huff_encoder jIHEncoder
#define jinit_phuff_encoder jIPHEncoder
+#define jinit_arith_encoder jIAEncoder
#define jinit_marker_writer jIMWriter
#define jinit_master_decompress jIDMaster
#define jinit_d_main_controller jIDMainC
@@ -313,6 +315,7 @@ struct jpeg_color_quantizer {
#define jinit_marker_reader jIMReader
#define jinit_huff_decoder jIHDecoder
#define jinit_phuff_decoder jIPHDecoder
+#define jinit_arith_decoder jIADecoder
#define jinit_inverse_dct jIIDCT
#define jinit_upsampler jIUpsampler
#define jinit_color_deconverter jIDColor
@@ -327,6 +330,7 @@ struct jpeg_color_quantizer {
#define jzero_far jZeroFar
#define jpeg_zigzag_order jZIGTable
#define jpeg_natural_order jZAGTable
+#define jpeg_aritab jAriTab
#endif /* NEED_SHORT_EXTERNAL_NAMES */
@@ -345,6 +349,7 @@ EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
/* Decompression module initialization routines */
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
@@ -358,6 +363,7 @@ EXTERN(void) jinit_input_controller JPP((j_decompress_ptr
cinfo));
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
@@ -382,6 +388,9 @@ extern const int jpeg_zigzag_order[]; /* natural coef order
to zigzag order */
#endif
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
+/* Arithmetic coding probability estimation tables in jaricom.c */
+extern const INT32 jpeg_aritab[];
+
/* Suppress undefined-structure complaints if necessary. */
#ifdef INCOMPLETE_TYPES_BROKEN
diff --git a/codecs/transupp.c b/codecs/transupp.c
index e6bb936..9e80583 100644
--- a/codecs/transupp.c
+++ b/codecs/transupp.c
@@ -1,8 +1,10 @@
/*
* transupp.c
*
- * Copyright (C) 1997-2001, Thomas G. Lane.
- * This file is part of the Independent JPEG Group's software.
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
+ * Modifications:
+ * Copyright (C) 2010, D. R. Commander.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains image transformation routines and other utility code
@@ -20,9 +22,19 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "transupp.h" /* My own external interface */
+#include "jpegcomp.h"
#include <ctype.h> /* to declare isdigit() */
+#if JPEG_LIB_VERSION >= 70
+#define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
+#define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
+#else
+#define dstinfo_min_DCT_h_scaled_size DCTSIZE
+#define dstinfo_min_DCT_v_scaled_size DCTSIZE
+#endif
+
+
#if TRANSFORMS_SUPPORTED
/*
@@ -133,7 +145,8 @@ do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr
dstinfo,
* mirroring by changing the signs of odd-numbered columns.
* Partial iMCUs at the right edge are left untouched.
*/
- MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+ MCU_cols = srcinfo->output_width /
+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -198,7 +211,8 @@ do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
* different rows of a single virtual array simultaneously. Otherwise,
* this is essentially the same as the routine above.
*/
- MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+ MCU_cols = srcinfo->output_width /
+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -262,7 +276,8 @@ do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
* of odd-numbered rows.
* Partial iMCUs at the bottom edge are copied verbatim.
*/
- MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+ MCU_rows = srcinfo->output_height /
+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -389,7 +404,8 @@ do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
* at the (output) right edge properly. They just get transposed and
* not mirrored.
*/
- MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE);
+ MCU_cols = srcinfo->output_height /
+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -469,7 +485,8 @@ do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr
dstinfo,
* at the (output) bottom edge properly. They just get transposed and
* not mirrored.
*/
- MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE);
+ MCU_rows = srcinfo->output_width /
+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -536,8 +553,10 @@ do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr
dstinfo,
JCOEFPTR src_ptr, dst_ptr;
jpeg_component_info *compptr;
- MCU_cols = srcinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
- MCU_rows = srcinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+ MCU_cols = srcinfo->output_width /
+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
+ MCU_rows = srcinfo->output_height /
+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -645,8 +664,10 @@ do_transverse (j_decompress_ptr srcinfo, j_compress_ptr
dstinfo,
JCOEFPTR src_ptr, dst_ptr;
jpeg_component_info *compptr;
- MCU_cols = srcinfo->image_height / (dstinfo->max_h_samp_factor * DCTSIZE);
- MCU_rows = srcinfo->image_width / (dstinfo->max_v_samp_factor * DCTSIZE);
+ MCU_cols = srcinfo->output_height /
+ (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
+ MCU_rows = srcinfo->output_width /
+ (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -762,7 +783,7 @@ jt_read_integer (const char ** strptr, JDIMENSION * result)
* The routine returns TRUE if the spec string is valid, FALSE if not.
*
* The crop spec string should have the format
- * <width>x<height>{+-}<xoffset>{+-}<yoffset>
+ * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
* where width, height, xoffset, and yoffset are unsigned integers.
* Each of the elements can be omitted to indicate a default value.
* (A weakness of this style is that it is not possible to omit xoffset
@@ -784,14 +805,22 @@ jtransform_parse_crop_spec (jpeg_transform_info *info,
const char *spec)
/* fetch width */
if (! jt_read_integer(&spec, &info->crop_width))
return FALSE;
- info->crop_width_set = JCROP_POS;
+ if (*spec == 'f' || *spec == 'F') {
+ spec++;
+ info->crop_width_set = JCROP_FORCE;
+ } else
+ info->crop_width_set = JCROP_POS;
}
- if (*spec == 'x' || *spec == 'X') {
+ if (*spec == 'x' || *spec == 'X') {
/* fetch height */
spec++;
if (! jt_read_integer(&spec, &info->crop_height))
return FALSE;
- info->crop_height_set = JCROP_POS;
+ if (*spec == 'f' || *spec == 'F') {
+ spec++;
+ info->crop_height_set = JCROP_FORCE;
+ } else
+ info->crop_height_set = JCROP_POS;
}
if (*spec == '+' || *spec == '-') {
/* fetch xoffset */
@@ -822,10 +851,10 @@ trim_right_edge (jpeg_transform_info *info, JDIMENSION
full_width)
{
JDIMENSION MCU_cols;
- MCU_cols = info->output_width / (info->max_h_samp_factor * DCTSIZE);
+ MCU_cols = info->output_width / info->iMCU_sample_width;
if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
- full_width / (info->max_h_samp_factor * DCTSIZE))
- info->output_width = MCU_cols * (info->max_h_samp_factor * DCTSIZE);
+ full_width / info->iMCU_sample_width)
+ info->output_width = MCU_cols * info->iMCU_sample_width;
}
LOCAL(void)
@@ -833,10 +862,10 @@ trim_bottom_edge (jpeg_transform_info *info, JDIMENSION
full_height)
{
JDIMENSION MCU_rows;
- MCU_rows = info->output_height / (info->max_v_samp_factor * DCTSIZE);
+ MCU_rows = info->output_height / info->iMCU_sample_height;
if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
- full_height / (info->max_v_samp_factor * DCTSIZE))
- info->output_height = MCU_rows * (info->max_v_samp_factor * DCTSIZE);
+ full_height / info->iMCU_sample_height)
+ info->output_height = MCU_rows * info->iMCU_sample_height;
}
@@ -852,59 +881,94 @@ trim_bottom_edge (jpeg_transform_info *info, JDIMENSION
full_height)
* Hence, this routine must be called after jpeg_read_header (which reads
* the image dimensions) and before jpeg_read_coefficients (which realizes
* the source's virtual arrays).
+ *
+ * This function returns FALSE right away if -perfect is given
+ * and transformation is not perfect. Otherwise returns TRUE.
*/
-GLOBAL(void)
+GLOBAL(boolean)
jtransform_request_workspace (j_decompress_ptr srcinfo,
jpeg_transform_info *info)
{
- jvirt_barray_ptr *coef_arrays = NULL;
+ jvirt_barray_ptr *coef_arrays;
boolean need_workspace, transpose_it;
jpeg_component_info *compptr;
- JDIMENSION xoffset, yoffset, width_in_iMCUs, height_in_iMCUs;
+ JDIMENSION xoffset, yoffset;
+ JDIMENSION width_in_iMCUs, height_in_iMCUs;
JDIMENSION width_in_blocks, height_in_blocks;
int ci, h_samp_factor, v_samp_factor;
/* Determine number of components in output image */
if (info->force_grayscale &&
srcinfo->jpeg_color_space == JCS_YCbCr &&
- srcinfo->num_components == 3) {
+ srcinfo->num_components == 3)
/* We'll only process the first component */
info->num_components = 1;
- } else {
+ else
/* Process all the components */
info->num_components = srcinfo->num_components;
+
+ /* Compute output image dimensions and related values. */
+#if JPEG_LIB_VERSION >= 80
+ jpeg_core_output_dimensions(srcinfo);
+#else
+ srcinfo->output_width = srcinfo->image_width;
+ srcinfo->output_height = srcinfo->image_height;
+#endif
+
+ /* Return right away if -perfect is given and transformation is not perfect.
+ */
+ if (info->perfect) {
+ if (info->num_components == 1) {
+ if (!jtransform_perfect_transform(srcinfo->output_width,
+ srcinfo->output_height,
+ srcinfo->_min_DCT_h_scaled_size,
+ srcinfo->_min_DCT_v_scaled_size,
+ info->transform))
+ return FALSE;
+ } else {
+ if (!jtransform_perfect_transform(srcinfo->output_width,
+ srcinfo->output_height,
+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size,
+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size,
+ info->transform))
+ return FALSE;
+ }
}
+
/* If there is only one output component, force the iMCU size to be 1;
* else use the source iMCU size. (This allows us to do the right thing
* when reducing color to grayscale, and also provides a handy way of
* cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
*/
-
switch (info->transform) {
case JXFORM_TRANSPOSE:
case JXFORM_TRANSVERSE:
case JXFORM_ROT_90:
case JXFORM_ROT_270:
- info->output_width = srcinfo->image_height;
- info->output_height = srcinfo->image_width;
+ info->output_width = srcinfo->output_height;
+ info->output_height = srcinfo->output_width;
if (info->num_components == 1) {
- info->max_h_samp_factor = 1;
- info->max_v_samp_factor = 1;
+ info->iMCU_sample_width = srcinfo->_min_DCT_v_scaled_size;
+ info->iMCU_sample_height = srcinfo->_min_DCT_h_scaled_size;
} else {
- info->max_h_samp_factor = srcinfo->max_v_samp_factor;
- info->max_v_samp_factor = srcinfo->max_h_samp_factor;
+ info->iMCU_sample_width =
+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
+ info->iMCU_sample_height =
+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
}
break;
default:
- info->output_width = srcinfo->image_width;
- info->output_height = srcinfo->image_height;
+ info->output_width = srcinfo->output_width;
+ info->output_height = srcinfo->output_height;
if (info->num_components == 1) {
- info->max_h_samp_factor = 1;
- info->max_v_samp_factor = 1;
+ info->iMCU_sample_width = srcinfo->_min_DCT_h_scaled_size;
+ info->iMCU_sample_height = srcinfo->_min_DCT_v_scaled_size;
} else {
- info->max_h_samp_factor = srcinfo->max_h_samp_factor;
- info->max_v_samp_factor = srcinfo->max_v_samp_factor;
+ info->iMCU_sample_width =
+ srcinfo->max_h_samp_factor * srcinfo->_min_DCT_h_scaled_size;
+ info->iMCU_sample_height =
+ srcinfo->max_v_samp_factor * srcinfo->_min_DCT_v_scaled_size;
}
break;
}
@@ -920,7 +984,7 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
info->crop_yoffset = 0; /* default to +0 */
if (info->crop_xoffset >= info->output_width ||
info->crop_yoffset >= info->output_height)
- ERREXIT(srcinfo, "Invalid crop request"); /* was: JERR_BAD_CROP_SPEC */
+ ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
if (info->crop_width_set == JCROP_UNSET)
info->crop_width = info->output_width - info->crop_xoffset;
if (info->crop_height_set == JCROP_UNSET)
@@ -930,7 +994,7 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
info->crop_height <= 0 || info->crop_height > info->output_height ||
info->crop_xoffset > info->output_width - info->crop_width ||
info->crop_yoffset > info->output_height - info->crop_height)
- ERREXIT(srcinfo, "Invalid crop request"); /* was: JERR_BAD_CROP_SPEC */
+ ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
/* Convert negative crop offsets into regular offsets */
if (info->crop_xoffset_set == JCROP_NEG)
xoffset = info->output_width - info->crop_width - info->crop_xoffset;
@@ -941,13 +1005,19 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
else
yoffset = info->crop_yoffset;
/* Now adjust so that upper left corner falls at an iMCU boundary */
- info->output_width =
- info->crop_width + (xoffset % (info->max_h_samp_factor * DCTSIZE));
- info->output_height =
- info->crop_height + (yoffset % (info->max_v_samp_factor * DCTSIZE));
+ if (info->crop_width_set == JCROP_FORCE)
+ info->output_width = info->crop_width;
+ else
+ info->output_width =
+ info->crop_width + (xoffset % info->iMCU_sample_width);
+ if (info->crop_height_set == JCROP_FORCE)
+ info->output_height = info->crop_height;
+ else
+ info->output_height =
+ info->crop_height + (yoffset % info->iMCU_sample_height);
/* Save x/y offsets measured in iMCUs */
- info->x_crop_offset = xoffset / (info->max_h_samp_factor * DCTSIZE);
- info->y_crop_offset = yoffset / (info->max_v_samp_factor * DCTSIZE);
+ info->x_crop_offset = xoffset / info->iMCU_sample_width;
+ info->y_crop_offset = yoffset / info->iMCU_sample_height;
} else {
info->x_crop_offset = 0;
info->y_crop_offset = 0;
@@ -966,14 +1036,14 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
break;
case JXFORM_FLIP_H:
if (info->trim)
- trim_right_edge(info, srcinfo->image_width);
- if (info->y_crop_offset != 0)
+ trim_right_edge(info, srcinfo->output_width);
+ if (info->y_crop_offset != 0 || info->slow_hflip)
need_workspace = TRUE;
/* do_flip_h_no_crop doesn't need a workspace array */
break;
case JXFORM_FLIP_V:
if (info->trim)
- trim_bottom_edge(info, srcinfo->image_height);
+ trim_bottom_edge(info, srcinfo->output_height);
/* Need workspace arrays having same dimensions as source image. */
need_workspace = TRUE;
break;
@@ -985,8 +1055,8 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
break;
case JXFORM_TRANSVERSE:
if (info->trim) {
- trim_right_edge(info, srcinfo->image_height);
- trim_bottom_edge(info, srcinfo->image_width);
+ trim_right_edge(info, srcinfo->output_height);
+ trim_bottom_edge(info, srcinfo->output_width);
}
/* Need workspace arrays having transposed dimensions. */
need_workspace = TRUE;
@@ -994,22 +1064,22 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
break;
case JXFORM_ROT_90:
if (info->trim)
- trim_right_edge(info, srcinfo->image_height);
+ trim_right_edge(info, srcinfo->output_height);
/* Need workspace arrays having transposed dimensions. */
need_workspace = TRUE;
transpose_it = TRUE;
break;
case JXFORM_ROT_180:
if (info->trim) {
- trim_right_edge(info, srcinfo->image_width);
- trim_bottom_edge(info, srcinfo->image_height);
+ trim_right_edge(info, srcinfo->output_width);
+ trim_bottom_edge(info, srcinfo->output_height);
}
/* Need workspace arrays having same dimensions as source image. */
need_workspace = TRUE;
break;
case JXFORM_ROT_270:
if (info->trim)
- trim_bottom_edge(info, srcinfo->image_width);
+ trim_bottom_edge(info, srcinfo->output_width);
/* Need workspace arrays having transposed dimensions. */
need_workspace = TRUE;
transpose_it = TRUE;
@@ -1026,10 +1096,10 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
SIZEOF(jvirt_barray_ptr) * info->num_components);
width_in_iMCUs = (JDIMENSION)
jdiv_round_up((long) info->output_width,
- (long) (info->max_h_samp_factor * DCTSIZE));
+ (long) info->iMCU_sample_width);
height_in_iMCUs = (JDIMENSION)
jdiv_round_up((long) info->output_height,
- (long) (info->max_v_samp_factor * DCTSIZE));
+ (long) info->iMCU_sample_height);
for (ci = 0; ci < info->num_components; ci++) {
compptr = srcinfo->comp_info + ci;
if (info->num_components == 1) {
@@ -1048,9 +1118,11 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
}
- }
+ info->workspace_coef_arrays = coef_arrays;
+ } else
+ info->workspace_coef_arrays = NULL;
- info->workspace_coef_arrays = coef_arrays;
+ return TRUE;
}
@@ -1062,8 +1134,19 @@ transpose_critical_parameters (j_compress_ptr dstinfo)
int tblno, i, j, ci, itemp;
jpeg_component_info *compptr;
JQUANT_TBL *qtblptr;
+ JDIMENSION jtemp;
UINT16 qtemp;
+ /* Transpose image dimensions */
+ jtemp = dstinfo->image_width;
+ dstinfo->image_width = dstinfo->image_height;
+ dstinfo->image_height = jtemp;
+#if JPEG_LIB_VERSION >= 70
+ itemp = dstinfo->min_DCT_h_scaled_size;
+ dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
+ dstinfo->min_DCT_v_scaled_size = itemp;
+#endif
+
/* Transpose sampling factors */
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
@@ -1296,10 +1379,12 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
}
/* Correct the destination's image dimensions as necessary
- * for crop and rotate/flip operations.
+ * for rotate/flip, resize, and crop operations.
*/
- dstinfo->image_width = info->output_width;
- dstinfo->image_height = info->output_height;
+#if JPEG_LIB_VERSION >= 70
+ dstinfo->jpeg_width = info->output_width;
+ dstinfo->jpeg_height = info->output_height;
+#endif
/* Transpose destination image parameters */
switch (info->transform) {
@@ -1307,9 +1392,17 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
case JXFORM_TRANSVERSE:
case JXFORM_ROT_90:
case JXFORM_ROT_270:
+#if JPEG_LIB_VERSION < 70
+ dstinfo->image_width = info->output_height;
+ dstinfo->image_height = info->output_width;
+#endif
transpose_critical_parameters(dstinfo);
break;
default:
+#if JPEG_LIB_VERSION < 70
+ dstinfo->image_width = info->output_width;
+ dstinfo->image_height = info->output_height;
+#endif
break;
}
@@ -1325,13 +1418,15 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
/* Suppress output of JFIF marker */
dstinfo->write_JFIF_header = FALSE;
+#if JPEG_LIB_VERSION >= 70
/* Adjust Exif image parameters */
- if (dstinfo->image_width != srcinfo->image_width ||
- dstinfo->image_height != srcinfo->image_height)
+ if (dstinfo->jpeg_width != srcinfo->image_width ||
+ dstinfo->jpeg_height != srcinfo->image_height)
/* Align data segment to start of TIFF structure for parsing */
adjust_exif_parameters(srcinfo->marker_list->data + 6,
srcinfo->marker_list->data_length - 6,
- dstinfo->image_width, dstinfo->image_height);
+ dstinfo->jpeg_width, dstinfo->jpeg_height);
+#endif
}
/* Return the appropriate output data set */
@@ -1368,7 +1463,7 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_FLIP_H:
- if (info->y_crop_offset != 0)
+ if (info->y_crop_offset != 0 || info->slow_hflip)
do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else
@@ -1415,8 +1510,8 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
* (after reading source header):
* image_width = cinfo.image_width
* image_height = cinfo.image_height
- * MCU_width = cinfo.max_h_samp_factor * DCTSIZE
- * MCU_height = cinfo.max_v_samp_factor * DCTSIZE
+ * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
+ * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
* Result:
* TRUE = perfect transformation possible
* FALSE = perfect transformation not possible
diff --git a/codecs/transupp.h b/codecs/transupp.h
index 981b1ce..cfbaca4 100644
--- a/codecs/transupp.h
+++ b/codecs/transupp.h
@@ -1,7 +1,7 @@
/*
* transupp.h
*
- * Copyright (C) 1997-2001, Thomas G. Lane.
+ * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -57,10 +57,16 @@
* corner up and/or left to make it so, simultaneously increasing the region
* dimensions to keep the lower right crop corner unchanged. (Thus, the
* output image covers at least the requested region, but may cover more.)
+ * The adjustment of the region dimensions may be optionally disabled.
*
- * If both crop and a rotate/flip transform are requested, the crop is applied
- * last --- that is, the crop region is specified in terms of the destination
- * image.
+ * We also provide a lossless-resize option, which is kind of a lossless-crop
+ * operation in the DCT coefficient block domain - it discards higher-order
+ * coefficients and losslessly preserves lower-order coefficients of a
+ * sub-block.
+ *
+ * Rotate/flip transform, resize, and crop can be requested together in a
+ * single invocation. The crop is applied last --- that is, the crop region
+ * is specified in terms of the destination image after transform/resize.
*
* We also offer a "force to grayscale" option, which simply discards the
* chrominance channels of a YCbCr image. This is lossless in the sense that
@@ -101,13 +107,15 @@ typedef enum {
/*
* Codes for crop parameters, which can individually be unspecified,
- * positive, or negative. (Negative width or height makes no sense, though.)
+ * positive or negative for xoffset or yoffset,
+ * positive or forced for width or height.
*/
typedef enum {
- JCROP_UNSET,
- JCROP_POS,
- JCROP_NEG
+ JCROP_UNSET,
+ JCROP_POS,
+ JCROP_NEG,
+ JCROP_FORCE
} JCROP_CODE;
/*
@@ -123,14 +131,21 @@ typedef struct {
boolean trim; /* if TRUE, trim partial MCUs as needed
*/
boolean force_grayscale; /* if TRUE, convert color image to grayscale */
boolean crop; /* if TRUE, crop source image */
+ boolean slow_hflip; /* For best performance, the JXFORM_FLIP_H transform
+ normally modifies the source coefficients in place.
+ Setting this to TRUE will instead use a slower,
+ double-buffered algorithm, which leaves the source
+ coefficients in tact (necessary if other transformed
+ images must be generated from the same set of
+ coefficients. */
/* Crop parameters: application need not set these unless crop is TRUE.
* These can be filled in by jtransform_parse_crop_spec().
*/
JDIMENSION crop_width; /* Width of selected region */
- JCROP_CODE crop_width_set;
+ JCROP_CODE crop_width_set; /* (forced disables adjustment) */
JDIMENSION crop_height; /* Height of selected region */
- JCROP_CODE crop_height_set;
+ JCROP_CODE crop_height_set; /* (forced disables adjustment) */
JDIMENSION crop_xoffset; /* X offset of selected region */
JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */
JDIMENSION crop_yoffset; /* Y offset of selected region */
@@ -143,8 +158,8 @@ typedef struct {
JDIMENSION output_height;
JDIMENSION x_crop_offset; /* destination crop offsets measured in iMCUs */
JDIMENSION y_crop_offset;
- int max_h_samp_factor; /* destination iMCU size */
- int max_v_samp_factor;
+ int iMCU_sample_width; /* destination iMCU size */
+ int iMCU_sample_height;
} jpeg_transform_info;
@@ -154,7 +169,7 @@ typedef struct {
EXTERN(boolean) jtransform_parse_crop_spec
JPP((jpeg_transform_info *info, const char *spec));
/* Request any required workspace */
-EXTERN(void) jtransform_request_workspace
+EXTERN(boolean) jtransform_request_workspace
JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
/* Adjust output image parameters */
EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
--
2.1.4
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[email protected] with a subject of: unsubscribe exact-image