vrshoot

diff libs/libjpeg/jdmerge.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/libjpeg/jdmerge.c	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,400 @@
     1.4 +/*
     1.5 + * jdmerge.c
     1.6 + *
     1.7 + * Copyright (C) 1994-1996, Thomas G. Lane.
     1.8 + * This file is part of the Independent JPEG Group's software.
     1.9 + * For conditions of distribution and use, see the accompanying README file.
    1.10 + *
    1.11 + * This file contains code for merged upsampling/color conversion.
    1.12 + *
    1.13 + * This file combines functions from jdsample.c and jdcolor.c;
    1.14 + * read those files first to understand what's going on.
    1.15 + *
    1.16 + * When the chroma components are to be upsampled by simple replication
    1.17 + * (ie, box filtering), we can save some work in color conversion by
    1.18 + * calculating all the output pixels corresponding to a pair of chroma
    1.19 + * samples at one time.  In the conversion equations
    1.20 + *	R = Y           + K1 * Cr
    1.21 + *	G = Y + K2 * Cb + K3 * Cr
    1.22 + *	B = Y + K4 * Cb
    1.23 + * only the Y term varies among the group of pixels corresponding to a pair
    1.24 + * of chroma samples, so the rest of the terms can be calculated just once.
    1.25 + * At typical sampling ratios, this eliminates half or three-quarters of the
    1.26 + * multiplications needed for color conversion.
    1.27 + *
    1.28 + * This file currently provides implementations for the following cases:
    1.29 + *	YCbCr => RGB color conversion only.
    1.30 + *	Sampling ratios of 2h1v or 2h2v.
    1.31 + *	No scaling needed at upsample time.
    1.32 + *	Corner-aligned (non-CCIR601) sampling alignment.
    1.33 + * Other special cases could be added, but in most applications these are
    1.34 + * the only common cases.  (For uncommon cases we fall back on the more
    1.35 + * general code in jdsample.c and jdcolor.c.)
    1.36 + */
    1.37 +
    1.38 +#define JPEG_INTERNALS
    1.39 +#include "jinclude.h"
    1.40 +#include "jpeglib.h"
    1.41 +
    1.42 +#ifdef UPSAMPLE_MERGING_SUPPORTED
    1.43 +
    1.44 +
    1.45 +/* Private subobject */
    1.46 +
    1.47 +typedef struct {
    1.48 +  struct jpeg_upsampler pub;	/* public fields */
    1.49 +
    1.50 +  /* Pointer to routine to do actual upsampling/conversion of one row group */
    1.51 +  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
    1.52 +			   JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    1.53 +			   JSAMPARRAY output_buf));
    1.54 +
    1.55 +  /* Private state for YCC->RGB conversion */
    1.56 +  int * Cr_r_tab;		/* => table for Cr to R conversion */
    1.57 +  int * Cb_b_tab;		/* => table for Cb to B conversion */
    1.58 +  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
    1.59 +  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
    1.60 +
    1.61 +  /* For 2:1 vertical sampling, we produce two output rows at a time.
    1.62 +   * We need a "spare" row buffer to hold the second output row if the
    1.63 +   * application provides just a one-row buffer; we also use the spare
    1.64 +   * to discard the dummy last row if the image height is odd.
    1.65 +   */
    1.66 +  JSAMPROW spare_row;
    1.67 +  boolean spare_full;		/* T if spare buffer is occupied */
    1.68 +
    1.69 +  JDIMENSION out_row_width;	/* samples per output row */
    1.70 +  JDIMENSION rows_to_go;	/* counts rows remaining in image */
    1.71 +} my_upsampler;
    1.72 +
    1.73 +typedef my_upsampler * my_upsample_ptr;
    1.74 +
    1.75 +#define SCALEBITS	16	/* speediest right-shift on some machines */
    1.76 +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
    1.77 +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
    1.78 +
    1.79 +
    1.80 +/*
    1.81 + * Initialize tables for YCC->RGB colorspace conversion.
    1.82 + * This is taken directly from jdcolor.c; see that file for more info.
    1.83 + */
    1.84 +
    1.85 +LOCAL(void)
    1.86 +build_ycc_rgb_table (j_decompress_ptr cinfo)
    1.87 +{
    1.88 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    1.89 +  int i;
    1.90 +  INT32 x;
    1.91 +  SHIFT_TEMPS
    1.92 +
    1.93 +  upsample->Cr_r_tab = (int *)
    1.94 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.95 +				(MAXJSAMPLE+1) * SIZEOF(int));
    1.96 +  upsample->Cb_b_tab = (int *)
    1.97 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.98 +				(MAXJSAMPLE+1) * SIZEOF(int));
    1.99 +  upsample->Cr_g_tab = (INT32 *)
   1.100 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   1.101 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
   1.102 +  upsample->Cb_g_tab = (INT32 *)
   1.103 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   1.104 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
   1.105 +
   1.106 +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
   1.107 +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
   1.108 +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
   1.109 +    /* Cr=>R value is nearest int to 1.40200 * x */
   1.110 +    upsample->Cr_r_tab[i] = (int)
   1.111 +		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
   1.112 +    /* Cb=>B value is nearest int to 1.77200 * x */
   1.113 +    upsample->Cb_b_tab[i] = (int)
   1.114 +		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
   1.115 +    /* Cr=>G value is scaled-up -0.71414 * x */
   1.116 +    upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
   1.117 +    /* Cb=>G value is scaled-up -0.34414 * x */
   1.118 +    /* We also add in ONE_HALF so that need not do it in inner loop */
   1.119 +    upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
   1.120 +  }
   1.121 +}
   1.122 +
   1.123 +
   1.124 +/*
   1.125 + * Initialize for an upsampling pass.
   1.126 + */
   1.127 +
   1.128 +METHODDEF(void)
   1.129 +start_pass_merged_upsample (j_decompress_ptr cinfo)
   1.130 +{
   1.131 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   1.132 +
   1.133 +  /* Mark the spare buffer empty */
   1.134 +  upsample->spare_full = FALSE;
   1.135 +  /* Initialize total-height counter for detecting bottom of image */
   1.136 +  upsample->rows_to_go = cinfo->output_height;
   1.137 +}
   1.138 +
   1.139 +
   1.140 +/*
   1.141 + * Control routine to do upsampling (and color conversion).
   1.142 + *
   1.143 + * The control routine just handles the row buffering considerations.
   1.144 + */
   1.145 +
   1.146 +METHODDEF(void)
   1.147 +merged_2v_upsample (j_decompress_ptr cinfo,
   1.148 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
   1.149 +		    JDIMENSION in_row_groups_avail,
   1.150 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
   1.151 +		    JDIMENSION out_rows_avail)
   1.152 +/* 2:1 vertical sampling case: may need a spare row. */
   1.153 +{
   1.154 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   1.155 +  JSAMPROW work_ptrs[2];
   1.156 +  JDIMENSION num_rows;		/* number of rows returned to caller */
   1.157 +
   1.158 +  if (upsample->spare_full) {
   1.159 +    /* If we have a spare row saved from a previous cycle, just return it. */
   1.160 +    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
   1.161 +		      1, upsample->out_row_width);
   1.162 +    num_rows = 1;
   1.163 +    upsample->spare_full = FALSE;
   1.164 +  } else {
   1.165 +    /* Figure number of rows to return to caller. */
   1.166 +    num_rows = 2;
   1.167 +    /* Not more than the distance to the end of the image. */
   1.168 +    if (num_rows > upsample->rows_to_go)
   1.169 +      num_rows = upsample->rows_to_go;
   1.170 +    /* And not more than what the client can accept: */
   1.171 +    out_rows_avail -= *out_row_ctr;
   1.172 +    if (num_rows > out_rows_avail)
   1.173 +      num_rows = out_rows_avail;
   1.174 +    /* Create output pointer array for upsampler. */
   1.175 +    work_ptrs[0] = output_buf[*out_row_ctr];
   1.176 +    if (num_rows > 1) {
   1.177 +      work_ptrs[1] = output_buf[*out_row_ctr + 1];
   1.178 +    } else {
   1.179 +      work_ptrs[1] = upsample->spare_row;
   1.180 +      upsample->spare_full = TRUE;
   1.181 +    }
   1.182 +    /* Now do the upsampling. */
   1.183 +    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
   1.184 +  }
   1.185 +
   1.186 +  /* Adjust counts */
   1.187 +  *out_row_ctr += num_rows;
   1.188 +  upsample->rows_to_go -= num_rows;
   1.189 +  /* When the buffer is emptied, declare this input row group consumed */
   1.190 +  if (! upsample->spare_full)
   1.191 +    (*in_row_group_ctr)++;
   1.192 +}
   1.193 +
   1.194 +
   1.195 +METHODDEF(void)
   1.196 +merged_1v_upsample (j_decompress_ptr cinfo,
   1.197 +		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
   1.198 +		    JDIMENSION in_row_groups_avail,
   1.199 +		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
   1.200 +		    JDIMENSION out_rows_avail)
   1.201 +/* 1:1 vertical sampling case: much easier, never need a spare row. */
   1.202 +{
   1.203 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   1.204 +
   1.205 +  /* Just do the upsampling. */
   1.206 +  (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
   1.207 +			 output_buf + *out_row_ctr);
   1.208 +  /* Adjust counts */
   1.209 +  (*out_row_ctr)++;
   1.210 +  (*in_row_group_ctr)++;
   1.211 +}
   1.212 +
   1.213 +
   1.214 +/*
   1.215 + * These are the routines invoked by the control routines to do
   1.216 + * the actual upsampling/conversion.  One row group is processed per call.
   1.217 + *
   1.218 + * Note: since we may be writing directly into application-supplied buffers,
   1.219 + * we have to be honest about the output width; we can't assume the buffer
   1.220 + * has been rounded up to an even width.
   1.221 + */
   1.222 +
   1.223 +
   1.224 +/*
   1.225 + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
   1.226 + */
   1.227 +
   1.228 +METHODDEF(void)
   1.229 +h2v1_merged_upsample (j_decompress_ptr cinfo,
   1.230 +		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
   1.231 +		      JSAMPARRAY output_buf)
   1.232 +{
   1.233 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   1.234 +  register int y, cred, cgreen, cblue;
   1.235 +  int cb, cr;
   1.236 +  register JSAMPROW outptr;
   1.237 +  JSAMPROW inptr0, inptr1, inptr2;
   1.238 +  JDIMENSION col;
   1.239 +  /* copy these pointers into registers if possible */
   1.240 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
   1.241 +  int * Crrtab = upsample->Cr_r_tab;
   1.242 +  int * Cbbtab = upsample->Cb_b_tab;
   1.243 +  INT32 * Crgtab = upsample->Cr_g_tab;
   1.244 +  INT32 * Cbgtab = upsample->Cb_g_tab;
   1.245 +  SHIFT_TEMPS
   1.246 +
   1.247 +  inptr0 = input_buf[0][in_row_group_ctr];
   1.248 +  inptr1 = input_buf[1][in_row_group_ctr];
   1.249 +  inptr2 = input_buf[2][in_row_group_ctr];
   1.250 +  outptr = output_buf[0];
   1.251 +  /* Loop for each pair of output pixels */
   1.252 +  for (col = cinfo->output_width >> 1; col > 0; col--) {
   1.253 +    /* Do the chroma part of the calculation */
   1.254 +    cb = GETJSAMPLE(*inptr1++);
   1.255 +    cr = GETJSAMPLE(*inptr2++);
   1.256 +    cred = Crrtab[cr];
   1.257 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
   1.258 +    cblue = Cbbtab[cb];
   1.259 +    /* Fetch 2 Y values and emit 2 pixels */
   1.260 +    y  = GETJSAMPLE(*inptr0++);
   1.261 +    outptr[RGB_RED] =   range_limit[y + cred];
   1.262 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
   1.263 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
   1.264 +    outptr += RGB_PIXELSIZE;
   1.265 +    y  = GETJSAMPLE(*inptr0++);
   1.266 +    outptr[RGB_RED] =   range_limit[y + cred];
   1.267 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
   1.268 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
   1.269 +    outptr += RGB_PIXELSIZE;
   1.270 +  }
   1.271 +  /* If image width is odd, do the last output column separately */
   1.272 +  if (cinfo->output_width & 1) {
   1.273 +    cb = GETJSAMPLE(*inptr1);
   1.274 +    cr = GETJSAMPLE(*inptr2);
   1.275 +    cred = Crrtab[cr];
   1.276 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
   1.277 +    cblue = Cbbtab[cb];
   1.278 +    y  = GETJSAMPLE(*inptr0);
   1.279 +    outptr[RGB_RED] =   range_limit[y + cred];
   1.280 +    outptr[RGB_GREEN] = range_limit[y + cgreen];
   1.281 +    outptr[RGB_BLUE] =  range_limit[y + cblue];
   1.282 +  }
   1.283 +}
   1.284 +
   1.285 +
   1.286 +/*
   1.287 + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
   1.288 + */
   1.289 +
   1.290 +METHODDEF(void)
   1.291 +h2v2_merged_upsample (j_decompress_ptr cinfo,
   1.292 +		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
   1.293 +		      JSAMPARRAY output_buf)
   1.294 +{
   1.295 +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   1.296 +  register int y, cred, cgreen, cblue;
   1.297 +  int cb, cr;
   1.298 +  register JSAMPROW outptr0, outptr1;
   1.299 +  JSAMPROW inptr00, inptr01, inptr1, inptr2;
   1.300 +  JDIMENSION col;
   1.301 +  /* copy these pointers into registers if possible */
   1.302 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
   1.303 +  int * Crrtab = upsample->Cr_r_tab;
   1.304 +  int * Cbbtab = upsample->Cb_b_tab;
   1.305 +  INT32 * Crgtab = upsample->Cr_g_tab;
   1.306 +  INT32 * Cbgtab = upsample->Cb_g_tab;
   1.307 +  SHIFT_TEMPS
   1.308 +
   1.309 +  inptr00 = input_buf[0][in_row_group_ctr*2];
   1.310 +  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
   1.311 +  inptr1 = input_buf[1][in_row_group_ctr];
   1.312 +  inptr2 = input_buf[2][in_row_group_ctr];
   1.313 +  outptr0 = output_buf[0];
   1.314 +  outptr1 = output_buf[1];
   1.315 +  /* Loop for each group of output pixels */
   1.316 +  for (col = cinfo->output_width >> 1; col > 0; col--) {
   1.317 +    /* Do the chroma part of the calculation */
   1.318 +    cb = GETJSAMPLE(*inptr1++);
   1.319 +    cr = GETJSAMPLE(*inptr2++);
   1.320 +    cred = Crrtab[cr];
   1.321 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
   1.322 +    cblue = Cbbtab[cb];
   1.323 +    /* Fetch 4 Y values and emit 4 pixels */
   1.324 +    y  = GETJSAMPLE(*inptr00++);
   1.325 +    outptr0[RGB_RED] =   range_limit[y + cred];
   1.326 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
   1.327 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
   1.328 +    outptr0 += RGB_PIXELSIZE;
   1.329 +    y  = GETJSAMPLE(*inptr00++);
   1.330 +    outptr0[RGB_RED] =   range_limit[y + cred];
   1.331 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
   1.332 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
   1.333 +    outptr0 += RGB_PIXELSIZE;
   1.334 +    y  = GETJSAMPLE(*inptr01++);
   1.335 +    outptr1[RGB_RED] =   range_limit[y + cred];
   1.336 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
   1.337 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
   1.338 +    outptr1 += RGB_PIXELSIZE;
   1.339 +    y  = GETJSAMPLE(*inptr01++);
   1.340 +    outptr1[RGB_RED] =   range_limit[y + cred];
   1.341 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
   1.342 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
   1.343 +    outptr1 += RGB_PIXELSIZE;
   1.344 +  }
   1.345 +  /* If image width is odd, do the last output column separately */
   1.346 +  if (cinfo->output_width & 1) {
   1.347 +    cb = GETJSAMPLE(*inptr1);
   1.348 +    cr = GETJSAMPLE(*inptr2);
   1.349 +    cred = Crrtab[cr];
   1.350 +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
   1.351 +    cblue = Cbbtab[cb];
   1.352 +    y  = GETJSAMPLE(*inptr00);
   1.353 +    outptr0[RGB_RED] =   range_limit[y + cred];
   1.354 +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
   1.355 +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
   1.356 +    y  = GETJSAMPLE(*inptr01);
   1.357 +    outptr1[RGB_RED] =   range_limit[y + cred];
   1.358 +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
   1.359 +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
   1.360 +  }
   1.361 +}
   1.362 +
   1.363 +
   1.364 +/*
   1.365 + * Module initialization routine for merged upsampling/color conversion.
   1.366 + *
   1.367 + * NB: this is called under the conditions determined by use_merged_upsample()
   1.368 + * in jdmaster.c.  That routine MUST correspond to the actual capabilities
   1.369 + * of this module; no safety checks are made here.
   1.370 + */
   1.371 +
   1.372 +GLOBAL(void)
   1.373 +jinit_merged_upsampler (j_decompress_ptr cinfo)
   1.374 +{
   1.375 +  my_upsample_ptr upsample;
   1.376 +
   1.377 +  upsample = (my_upsample_ptr)
   1.378 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   1.379 +				SIZEOF(my_upsampler));
   1.380 +  cinfo->upsample = (struct jpeg_upsampler *) upsample;
   1.381 +  upsample->pub.start_pass = start_pass_merged_upsample;
   1.382 +  upsample->pub.need_context_rows = FALSE;
   1.383 +
   1.384 +  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
   1.385 +
   1.386 +  if (cinfo->max_v_samp_factor == 2) {
   1.387 +    upsample->pub.upsample = merged_2v_upsample;
   1.388 +    upsample->upmethod = h2v2_merged_upsample;
   1.389 +    /* Allocate a spare row buffer */
   1.390 +    upsample->spare_row = (JSAMPROW)
   1.391 +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   1.392 +		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
   1.393 +  } else {
   1.394 +    upsample->pub.upsample = merged_1v_upsample;
   1.395 +    upsample->upmethod = h2v1_merged_upsample;
   1.396 +    /* No spare row needed */
   1.397 +    upsample->spare_row = NULL;
   1.398 +  }
   1.399 +
   1.400 +  build_ycc_rgb_table(cinfo);
   1.401 +}
   1.402 +
   1.403 +#endif /* UPSAMPLE_MERGING_SUPPORTED */