/* * jdmerge.c * * This file was part of the Independent JPEG Group's software: * Copyright (C) 1994-1996, Thomas G. Lane. * libjpeg-turbo Modifications: * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright (C) 2009, 2011, 2014-2015, 2020, 2022, D. R. Commander. * Copyright (C) 2013, Linaro Limited. * For conditions of distribution and use, see the accompanying README.ijg * 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.)
*/
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 */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); /* Cb=>B value is nearest int to 1.77200 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); /* Cr=>G value is scaled-up -0.71414 * x */
upsample->Cr_g_tab[i] = (-FIX(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 */
upsample->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
}
}
/* Mark the spare buffer empty */
upsample->spare_full = FALSE; /* Initialize total-height counter for detecting bottom of image */
upsample->rows_to_go = cinfo->output_height;
}
/* * Control routine to do upsampling (and color conversion). * * The control routine just handles the row buffering considerations.
*/
METHODDEF(void)
merged_2v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) /* 2:1 vertical sampling case: may need a spare row. */
{
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
_JSAMPROW work_ptrs[2];
JDIMENSION num_rows; /* number of rows returned to caller */
if (upsample->spare_full) { /* If we have a spare row saved from a previous cycle, just return it. */
JDIMENSION size = upsample->out_row_width; if (cinfo->out_color_space == JCS_RGB565)
size = cinfo->output_width * 2;
_jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
1, size);
num_rows = 1;
upsample->spare_full = FALSE;
} else { /* Figure number of rows to return to caller. */
num_rows = 2; /* Not more than the distance to the end of the image. */ if (num_rows > upsample->rows_to_go)
num_rows = upsample->rows_to_go; /* And not more than what the client can accept: */
out_rows_avail -= *out_row_ctr; if (num_rows > out_rows_avail)
num_rows = out_rows_avail; /* Create output pointer array for upsampler. */
work_ptrs[0] = output_buf[*out_row_ctr]; if (num_rows > 1) {
work_ptrs[1] = output_buf[*out_row_ctr + 1];
} else {
work_ptrs[1] = upsample->spare_row;
upsample->spare_full = TRUE;
} /* Now do the upsampling. */
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
}
/* Adjust counts */
*out_row_ctr += num_rows;
upsample->rows_to_go -= num_rows; /* When the buffer is emptied, declare this input row group consumed */ if (!upsample->spare_full)
(*in_row_group_ctr)++;
}
METHODDEF(void)
merged_1v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) /* 1:1 vertical sampling case: much easier, never need a spare row. */
{
my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
/* Just do the upsampling. */
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
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)
h2v1_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
{ switch (cinfo->out_color_space) { case JCS_EXT_RGB:
extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_RGBX: case JCS_EXT_RGBA:
extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_BGR:
extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_BGRX: case JCS_EXT_BGRA:
extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_XBGR: case JCS_EXT_ABGR:
extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_XRGB: case JCS_EXT_ARGB:
extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; default:
h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break;
}
}
/* * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
*/
METHODDEF(void)
h2v2_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf)
{ switch (cinfo->out_color_space) { case JCS_EXT_RGB:
extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_RGBX: case JCS_EXT_RGBA:
extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_BGR:
extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_BGRX: case JCS_EXT_BGRA:
extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_XBGR: case JCS_EXT_ABGR:
extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; case JCS_EXT_XRGB: case JCS_EXT_ARGB:
extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break; default:
h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
output_buf); break;
}
}
/* Declarations for ordered dithering * * We use a 4x4 ordered dither array packed into 32 bits. This array is * sufficient for dithering RGB888 to RGB565.
*/
/* * 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.
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.