221 lines
6.1 KiB
C
221 lines
6.1 KiB
C
/*
|
|
* jdsample.c
|
|
*
|
|
* 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.
|
|
*
|
|
* This file contains un-subsampling routines.
|
|
* These routines are invoked via the unsubsample and
|
|
* unsubsample_init/term methods.
|
|
*/
|
|
|
|
#include "jinclude.h"
|
|
|
|
|
|
/*
|
|
* Initialize for un-subsampling a scan.
|
|
*/
|
|
|
|
METHODDEF void
|
|
unsubsample_init (decompress_info_ptr cinfo)
|
|
{
|
|
/* no work for now */
|
|
}
|
|
|
|
|
|
/*
|
|
* Un-subsample pixel values of a single component.
|
|
* This version handles any integral sampling ratios.
|
|
* This is not used for typical JPEG files, so it need not be fast.
|
|
*/
|
|
|
|
METHODDEF void
|
|
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];
|
|
register JSAMPROW inptr, outptr;
|
|
register JSAMPLE invalue;
|
|
register short h_expand, h;
|
|
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
|
|
|
|
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
|
|
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
|
|
|
|
outrow = 0;
|
|
for (inrow = 0; inrow < input_rows; inrow++) {
|
|
for (v = 0; v < v_expand; v++) {
|
|
inptr = input_data[inrow];
|
|
outptr = output_data[outrow++];
|
|
for (incol = 0; incol < input_cols; incol++) {
|
|
invalue = GETJSAMPLE(*inptr++);
|
|
for (h = 0; h < h_expand; h++) {
|
|
*outptr++ = invalue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
METHODDEF void
|
|
fullsize_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)
|
|
{
|
|
#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);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Clean up after a scan.
|
|
*/
|
|
|
|
METHODDEF void
|
|
unsubsample_term (decompress_info_ptr cinfo)
|
|
{
|
|
/* no work for now */
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* The method selection routine for unsubsampling.
|
|
* Note that we must select a routine for each component.
|
|
*/
|
|
|
|
GLOBAL void
|
|
jselunsubsample (decompress_info_ptr cinfo)
|
|
{
|
|
short ci;
|
|
jpeg_component_info * compptr;
|
|
|
|
if (cinfo->CCIR601_sampling)
|
|
ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");
|
|
|
|
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
compptr = cinfo->cur_comp_info[ci];
|
|
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] = int_unsubsample;
|
|
else
|
|
ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
|
|
}
|
|
|
|
cinfo->methods->unsubsample_init = unsubsample_init;
|
|
cinfo->methods->unsubsample_term = unsubsample_term;
|
|
}
|