aboutsummaryrefslogtreecommitdiff
path: root/jdsample.c
diff options
context:
space:
mode:
authorThomas G. Lane <tgl@netcom.com>1992-03-17 00:00:00 +0000
committerDRC <information@libjpeg-turbo.org>2015-07-29 15:21:19 -0500
commit4a6b7303643714d495b9d26742d8a156fd120936 (patch)
tree5997fe7ad49b32b2adc4eeabae49f839ab73f9a5 /jdsample.c
parentbd543f030e7e435c2c6a6a7d52ad927ae97cd927 (diff)
downloadlibjpeg-turbo-4a6b7303643714d495b9d26742d8a156fd120936.tar.gz
The Independent JPEG Group's JPEG software v3
Diffstat (limited to 'jdsample.c')
-rw-r--r--jdsample.c115
1 files changed, 101 insertions, 14 deletions
diff --git a/jdsample.c b/jdsample.c
index 15dbf4f8..71fb4534 100644
--- a/jdsample.c
+++ b/jdsample.c
@@ -1,7 +1,7 @@
/*
* jdsample.c
*
- * Copyright (C) 1991, Thomas G. Lane.
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -26,30 +26,33 @@ unsubsample_init (decompress_info_ptr cinfo)
/*
* Un-subsample pixel values of a single component.
- * This version only handles integral sampling ratios.
+ * This version handles any integral sampling ratios.
+ * This is not used for typical JPEG files, so it need not be fast.
*/
METHODDEF void
-unsubsample (decompress_info_ptr cinfo, int which_component,
- long input_cols, int input_rows,
- long output_cols, int output_rows,
- JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
- JSAMPARRAY output_data)
+int_unsubsample (decompress_info_ptr cinfo, int which_component,
+ long input_cols, int input_rows,
+ long output_cols, int output_rows,
+ JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+ JSAMPARRAY output_data)
{
jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
- short h_expand, v_expand, h, v;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ register short h_expand, h;
+ short v_expand, v;
int inrow, outrow;
- long incol;
- JSAMPROW inptr, outptr;
- JSAMPLE invalue;
+ register long incol;
- /* TEMP FOR DEBUGGING PIPELINE CONTROLLER */
+#ifdef DEBUG /* for debugging pipeline controller */
if (input_rows != compptr->v_samp_factor ||
output_rows != cinfo->max_v_samp_factor ||
(input_cols % compptr->h_samp_factor) != 0 ||
(output_cols % cinfo->max_h_samp_factor) != 0 ||
output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
+#endif
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
@@ -72,6 +75,85 @@ unsubsample (decompress_info_ptr cinfo, int which_component,
/*
* Un-subsample pixel values of a single component.
+ * This version handles the extremely common case of
+ * horizontal expansion by 2 and any integral vertical expansion.
+ */
+
+METHODDEF void
+h2_unsubsample (decompress_info_ptr cinfo, int which_component,
+ long input_cols, int input_rows,
+ long output_cols, int output_rows,
+ JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+ JSAMPARRAY output_data)
+{
+ jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ short v_expand, v;
+ int inrow, outrow;
+ register long incol;
+
+#ifdef DEBUG /* for debugging pipeline controller */
+ if (input_rows != compptr->v_samp_factor ||
+ output_rows != cinfo->max_v_samp_factor ||
+ (input_cols % compptr->h_samp_factor) != 0 ||
+ (output_cols % cinfo->max_h_samp_factor) != 0 ||
+ output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
+ ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
+#endif
+
+ v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+
+/* The subsampled image width will always be a multiple of DCTSIZE,
+ * so we can unroll the inner loop.
+ */
+
+ outrow = 0;
+ for (inrow = 0; inrow < input_rows; inrow++) {
+ for (v = 0; v < v_expand; v++) {
+ inptr = input_data[inrow];
+ outptr = output_data[outrow++];
+#if DCTSIZE == 8
+ for (incol = 0; incol < input_cols; incol += DCTSIZE) {
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+#else /* nonstandard DCTSIZE */
+ for (incol = 0; incol < input_cols; incol++) {
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+#endif
+ }
+ }
+}
+
+
+/*
+ * Un-subsample pixel values of a single component.
* This version handles the special case of a full-size component.
*/
@@ -82,8 +164,10 @@ fullsize_unsubsample (decompress_info_ptr cinfo, int which_component,
JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
JSAMPARRAY output_data)
{
- if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */
+#ifdef DEBUG /* for debugging pipeline controller */
+ if (input_cols != output_cols || input_rows != output_rows)
ERREXIT(cinfo->emethods, "Pipeline controller messed up");
+#endif
jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
}
@@ -121,9 +205,12 @@ jselunsubsample (decompress_info_ptr cinfo)
if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor)
cinfo->methods->unsubsample[ci] = fullsize_unsubsample;
+ else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+ (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
+ cinfo->methods->unsubsample[ci] = h2_unsubsample;
else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
- cinfo->methods->unsubsample[ci] = unsubsample;
+ cinfo->methods->unsubsample[ci] = int_unsubsample;
else
ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
}