home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 upsampling routines.
- * These routines are invoked via the upsample and
- * upsample_init/term methods.
- *
- * An excellent reference for image resampling is
- * Digital Image Warping, George Wolberg, 1990.
- * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
- */
-
- #include "jinclude.h"
-
-
- /*
- * Initialize for upsampling a scan.
- */
-
- METHODDEF void
- upsample_init (decompress_info_ptr cinfo)
- {
- /* no work for now */
- }
-
-
- /*
- * Upsample 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.
- * Nor, for that matter, is it particularly accurate: the algorithm is
- * simple replication of the input pixel onto the corresponding output
- * pixels. The hi-falutin sampling literature refers to this as a
- * "box filter". A box filter tends to introduce visible artifacts,
- * so if you are actually going to use 3:1 or 4:1 sampling ratios
- * you would be well advised to improve this code.
- */
-
- METHODDEF void
- int_upsample (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 upsample 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;
- }
- }
- }
- }
- }
-
-
- /*
- * Upsample pixel values of a single component.
- * This version handles the common case of 2:1 horizontal and 1:1 vertical.
- *
- * The upsampling algorithm is linear interpolation between pixel centers,
- * also known as a "triangle filter". This is a good compromise between
- * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
- * of the way between input pixel centers.
- */
-
- METHODDEF void
- h2v1_upsample (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)
- {
- register JSAMPROW inptr, outptr;
- register int invalue;
- int inrow;
- register long colctr;
-
- #ifdef DEBUG /* for debugging pipeline controller */
- jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
- 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 upsample parameters");
- #endif
-
- for (inrow = 0; inrow < input_rows; inrow++) {
- inptr = input_data[inrow];
- outptr = output_data[inrow];
- /* Special case for first column */
- invalue = GETJSAMPLE(*inptr++);
- *outptr++ = (JSAMPLE) invalue;
- *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
-
- for (colctr = input_cols - 2; colctr > 0; colctr--) {
- /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
- invalue = GETJSAMPLE(*inptr++) * 3;
- *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 2) >> 2);
- *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
- }
-
- /* Special case for last column */
- invalue = GETJSAMPLE(*inptr);
- *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 2) >> 2);
- *outptr++ = (JSAMPLE) invalue;
- }
- }
-
-
- /*
- * Upsample pixel values of a single component.
- * This version handles the common case of 2:1 horizontal and 2:1 vertical.
- *
- * The upsampling algorithm is linear interpolation between pixel centers,
- * also known as a "triangle filter". This is a good compromise between
- * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
- * of the way between input pixel centers.
- */
-
- METHODDEF void
- h2v2_upsample (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)
- {
- register JSAMPROW inptr0, inptr1, outptr;
- #ifdef EIGHT_BIT_SAMPLES
- register int thiscolsum, lastcolsum, nextcolsum;
- #else
- register INT32 thiscolsum, lastcolsum, nextcolsum;
- #endif
- int inrow, outrow, v;
- register long colctr;
-
- #ifdef DEBUG /* for debugging pipeline controller */
- jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
- 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 upsample parameters");
- #endif
-
- outrow = 0;
- for (inrow = 0; inrow < input_rows; inrow++) {
- for (v = 0; v < 2; v++) {
- /* inptr0 points to nearest input row, inptr1 points to next nearest */
- inptr0 = input_data[inrow];
- if (v == 0) { /* next nearest is row above */
- if (inrow == 0)
- inptr1 = above[input_rows-1];
- else
- inptr1 = input_data[inrow-1];
- } else { /* next nearest is row below */
- if (inrow == input_rows-1)
- inptr1 = below[0];
- else
- inptr1 = input_data[inrow+1];
- }
- outptr = output_data[outrow++];
-
- /* Special case for first column */
- thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 8) >> 4);
- lastcolsum = thiscolsum; thiscolsum = nextcolsum;
-
- for (colctr = input_cols - 2; colctr > 0; colctr--) {
- /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
- /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
- nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 8) >> 4);
- lastcolsum = thiscolsum; thiscolsum = nextcolsum;
- }
-
- /* Special case for last column */
- *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
- *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
- }
- }
- }
-
-
- /*
- * Upsample pixel values of a single component.
- * This version handles the special case of a full-size component.
- */
-
- METHODDEF void
- fullsize_upsample (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
- upsample_term (decompress_info_ptr cinfo)
- {
- /* no work for now */
- }
-
-
-
- /*
- * The method selection routine for upsampling.
- * Note that we must select a routine for each component.
- */
-
- GLOBAL void
- jselupsample (decompress_info_ptr cinfo)
- {
- short ci;
- jpeg_component_info * compptr;
-
- if (cinfo->CCIR601_sampling)
- ERREXIT(cinfo->emethods, "CCIR601 upsampling 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->upsample[ci] = fullsize_upsample;
- else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
- compptr->v_samp_factor == cinfo->max_v_samp_factor)
- cinfo->methods->upsample[ci] = h2v1_upsample;
- else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
- compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor)
- cinfo->methods->upsample[ci] = h2v2_upsample;
- else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
- (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
- cinfo->methods->upsample[ci] = int_upsample;
- else
- ERREXIT(cinfo->emethods, "Fractional upsampling not implemented yet");
- }
-
- cinfo->methods->upsample_init = upsample_init;
- cinfo->methods->upsample_term = upsample_term;
- }
-