/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
*
* Copyright (C) 1994-1996, 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 code for merged upsampling/color conversion.
*
* This file combines functions from jdsample.c and jdcolor.c;
* read those files first to understand what's going on.
*
* When the chroma components are to be upsampled by simple replication
* (ie, box filtering), we can save some work in color conversion by
* calculating all the output pixels corresponding to a pair of chroma
* samples at one time. In the conversion equations
* R = Y + K1 * Cr
* G = Y + K2 * Cb + K3 * Cr
* B = Y + K4 * Cb
* only the Y term varies among the group of pixels corresponding to a pair
* of chroma samples, so the rest of the terms can be calculated just once.
* At typical sampling ratios, this eliminates half or three-quarters of the
* multiplications needed for color conversion.
*
* This file currently provides implementations for the following cases:
* YCbCr => RGB color conversion only.
* Sampling ratios of 2h1v or 2h2v.
* No scaling needed at upsample time.
* Corner-aligned (non-CCIR601) sampling alignment.
* Other special cases could be added, but in most applications these are
* the only common cases. (For uncommon cases we fall back on the more
* general code in jdsample.c and jdcolor.c.)
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#ifdef UPSAMPLE_MERGING_SUPPORTED
/* Private subobject */
typedef struct {
/* Pointer to routine to do actual upsampling/conversion of one row group */
/* Private state for YCC->RGB conversion */
/* For 2:1 vertical sampling, we produce two output rows at a time.
* We need a "spare" row buffer to hold the second output row if the
* application provides just a one-row buffer; we also use the spare
* to discard the dummy last row if the image height is odd.
*/
} my_upsampler;
/*
* Initialize tables for YCC->RGB colorspace conversion.
* This is taken directly from jdcolor.c; see that file for more info.
*/
LOCAL(void)
{
int i;
INT32 x;
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.40200 * x */
/* Cb=>B value is nearest int to 1.77200 * x */
/* Cr=>G value is scaled-up -0.71414 * x */
/* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */
}
}
/*
* Initialize for an upsampling pass.
*/
METHODDEF(void)
{
/* Mark the spare buffer empty */
/* Initialize total-height counter for detecting bottom of image */
}
/*
* Control routine to do upsampling (and color conversion).
*
* The control routine just handles the row buffering considerations.
*/
METHODDEF(void)
/* 2:1 vertical sampling case: may need a spare row. */
{
if (upsample->spare_full) {
/* If we have a spare row saved from a previous cycle, just return it. */
num_rows = 1;
} else {
/* Figure number of rows to return to caller. */
num_rows = 2;
/* Not more than the distance to the end of the image. */
/* And not more than what the client can accept: */
if (num_rows > out_rows_avail)
/* Create output pointer array for upsampler. */
if (num_rows > 1) {
} else {
}
/* Now do the upsampling. */
}
/* Adjust counts */
*out_row_ctr += num_rows;
/* When the buffer is emptied, declare this input row group consumed */
if (! upsample->spare_full)
(*in_row_group_ctr)++;
}
METHODDEF(void)
/* 1:1 vertical sampling case: much easier, never need a spare row. */
{
/* Just do the upsampling. */
output_buf + *out_row_ctr);
/* Adjust counts */
(*out_row_ctr)++;
(*in_row_group_ctr)++;
}
/*
* These are the routines invoked by the control routines to do
* the actual upsampling/conversion. One row group is processed per call.
*
* Note: since we may be writing directly into application-supplied buffers,
* we have to be honest about the output width; we can't assume the buffer
* has been rounded up to an even width.
*/
/*
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
*/
METHODDEF(void)
{
/* copy these pointers into registers if possible */
outptr = output_buf[0];
/* Loop for each pair of output pixels */
/* Do the chroma part of the calculation */
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
outptr += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr0++);
outptr += RGB_PIXELSIZE;
}
/* If image width is odd, do the last output column separately */
y = GETJSAMPLE(*inptr0);
}
}
/*
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
*/
METHODDEF(void)
{
/* copy these pointers into registers if possible */
outptr0 = output_buf[0];
/* Loop for each group of output pixels */
/* Do the chroma part of the calculation */
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr00++);
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1 += RGB_PIXELSIZE;
}
/* If image width is odd, do the last output column separately */
y = GETJSAMPLE(*inptr00);
y = GETJSAMPLE(*inptr01);
}
}
/*
* Module initialization routine for merged upsampling/color conversion.
*
* NB: this is called under the conditions determined by use_merged_upsample()
* in jdmaster.c. That routine MUST correspond to the actual capabilities
* of this module; no safety checks are made here.
*/
GLOBAL(void)
{
/* Allocate a spare row buffer */
} else {
/* No spare row needed */
}
}
#endif /* UPSAMPLE_MERGING_SUPPORTED */