istereo

diff libs/libjpeg/jdcolor.c @ 26:862a3329a8f0

wohooo, added a shitload of code from zlib/libpng/libjpeg. When the good lord was raining shared libraries the iphone held a fucking umbrella...
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 08 Sep 2011 06:28:38 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/libjpeg/jdcolor.c	Thu Sep 08 06:28:38 2011 +0300
     1.3 @@ -0,0 +1,396 @@
     1.4 +/*
     1.5 + * jdcolor.c
     1.6 + *
     1.7 + * Copyright (C) 1991-1997, 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 output colorspace conversion routines.
    1.12 + */
    1.13 +
    1.14 +#define JPEG_INTERNALS
    1.15 +#include "jinclude.h"
    1.16 +#include "jpeglib.h"
    1.17 +
    1.18 +
    1.19 +/* Private subobject */
    1.20 +
    1.21 +typedef struct {
    1.22 +  struct jpeg_color_deconverter pub; /* public fields */
    1.23 +
    1.24 +  /* Private state for YCC->RGB conversion */
    1.25 +  int * Cr_r_tab;		/* => table for Cr to R conversion */
    1.26 +  int * Cb_b_tab;		/* => table for Cb to B conversion */
    1.27 +  INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
    1.28 +  INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
    1.29 +} my_color_deconverter;
    1.30 +
    1.31 +typedef my_color_deconverter * my_cconvert_ptr;
    1.32 +
    1.33 +
    1.34 +/**************** YCbCr -> RGB conversion: most common case **************/
    1.35 +
    1.36 +/*
    1.37 + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
    1.38 + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
    1.39 + * The conversion equations to be implemented are therefore
    1.40 + *	R = Y                + 1.40200 * Cr
    1.41 + *	G = Y - 0.34414 * Cb - 0.71414 * Cr
    1.42 + *	B = Y + 1.77200 * Cb
    1.43 + * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
    1.44 + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
    1.45 + *
    1.46 + * To avoid floating-point arithmetic, we represent the fractional constants
    1.47 + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
    1.48 + * the products by 2^16, with appropriate rounding, to get the correct answer.
    1.49 + * Notice that Y, being an integral input, does not contribute any fraction
    1.50 + * so it need not participate in the rounding.
    1.51 + *
    1.52 + * For even more speed, we avoid doing any multiplications in the inner loop
    1.53 + * by precalculating the constants times Cb and Cr for all possible values.
    1.54 + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
    1.55 + * for 12-bit samples it is still acceptable.  It's not very reasonable for
    1.56 + * 16-bit samples, but if you want lossless storage you shouldn't be changing
    1.57 + * colorspace anyway.
    1.58 + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
    1.59 + * values for the G calculation are left scaled up, since we must add them
    1.60 + * together before rounding.
    1.61 + */
    1.62 +
    1.63 +#define SCALEBITS	16	/* speediest right-shift on some machines */
    1.64 +#define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
    1.65 +#define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
    1.66 +
    1.67 +
    1.68 +/*
    1.69 + * Initialize tables for YCC->RGB colorspace conversion.
    1.70 + */
    1.71 +
    1.72 +LOCAL(void)
    1.73 +build_ycc_rgb_table (j_decompress_ptr cinfo)
    1.74 +{
    1.75 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    1.76 +  int i;
    1.77 +  INT32 x;
    1.78 +  SHIFT_TEMPS
    1.79 +
    1.80 +  cconvert->Cr_r_tab = (int *)
    1.81 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.82 +				(MAXJSAMPLE+1) * SIZEOF(int));
    1.83 +  cconvert->Cb_b_tab = (int *)
    1.84 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.85 +				(MAXJSAMPLE+1) * SIZEOF(int));
    1.86 +  cconvert->Cr_g_tab = (INT32 *)
    1.87 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.88 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
    1.89 +  cconvert->Cb_g_tab = (INT32 *)
    1.90 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    1.91 +				(MAXJSAMPLE+1) * SIZEOF(INT32));
    1.92 +
    1.93 +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    1.94 +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    1.95 +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    1.96 +    /* Cr=>R value is nearest int to 1.40200 * x */
    1.97 +    cconvert->Cr_r_tab[i] = (int)
    1.98 +		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    1.99 +    /* Cb=>B value is nearest int to 1.77200 * x */
   1.100 +    cconvert->Cb_b_tab[i] = (int)
   1.101 +		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
   1.102 +    /* Cr=>G value is scaled-up -0.71414 * x */
   1.103 +    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
   1.104 +    /* Cb=>G value is scaled-up -0.34414 * x */
   1.105 +    /* We also add in ONE_HALF so that need not do it in inner loop */
   1.106 +    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
   1.107 +  }
   1.108 +}
   1.109 +
   1.110 +
   1.111 +/*
   1.112 + * Convert some rows of samples to the output colorspace.
   1.113 + *
   1.114 + * Note that we change from noninterleaved, one-plane-per-component format
   1.115 + * to interleaved-pixel format.  The output buffer is therefore three times
   1.116 + * as wide as the input buffer.
   1.117 + * A starting row offset is provided only for the input buffer.  The caller
   1.118 + * can easily adjust the passed output_buf value to accommodate any row
   1.119 + * offset required on that side.
   1.120 + */
   1.121 +
   1.122 +METHODDEF(void)
   1.123 +ycc_rgb_convert (j_decompress_ptr cinfo,
   1.124 +		 JSAMPIMAGE input_buf, JDIMENSION input_row,
   1.125 +		 JSAMPARRAY output_buf, int num_rows)
   1.126 +{
   1.127 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
   1.128 +  register int y, cb, cr;
   1.129 +  register JSAMPROW outptr;
   1.130 +  register JSAMPROW inptr0, inptr1, inptr2;
   1.131 +  register JDIMENSION col;
   1.132 +  JDIMENSION num_cols = cinfo->output_width;
   1.133 +  /* copy these pointers into registers if possible */
   1.134 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
   1.135 +  register int * Crrtab = cconvert->Cr_r_tab;
   1.136 +  register int * Cbbtab = cconvert->Cb_b_tab;
   1.137 +  register INT32 * Crgtab = cconvert->Cr_g_tab;
   1.138 +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
   1.139 +  SHIFT_TEMPS
   1.140 +
   1.141 +  while (--num_rows >= 0) {
   1.142 +    inptr0 = input_buf[0][input_row];
   1.143 +    inptr1 = input_buf[1][input_row];
   1.144 +    inptr2 = input_buf[2][input_row];
   1.145 +    input_row++;
   1.146 +    outptr = *output_buf++;
   1.147 +    for (col = 0; col < num_cols; col++) {
   1.148 +      y  = GETJSAMPLE(inptr0[col]);
   1.149 +      cb = GETJSAMPLE(inptr1[col]);
   1.150 +      cr = GETJSAMPLE(inptr2[col]);
   1.151 +      /* Range-limiting is essential due to noise introduced by DCT losses. */
   1.152 +      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
   1.153 +      outptr[RGB_GREEN] = range_limit[y +
   1.154 +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
   1.155 +						 SCALEBITS))];
   1.156 +      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
   1.157 +      outptr += RGB_PIXELSIZE;
   1.158 +    }
   1.159 +  }
   1.160 +}
   1.161 +
   1.162 +
   1.163 +/**************** Cases other than YCbCr -> RGB **************/
   1.164 +
   1.165 +
   1.166 +/*
   1.167 + * Color conversion for no colorspace change: just copy the data,
   1.168 + * converting from separate-planes to interleaved representation.
   1.169 + */
   1.170 +
   1.171 +METHODDEF(void)
   1.172 +null_convert (j_decompress_ptr cinfo,
   1.173 +	      JSAMPIMAGE input_buf, JDIMENSION input_row,
   1.174 +	      JSAMPARRAY output_buf, int num_rows)
   1.175 +{
   1.176 +  register JSAMPROW inptr, outptr;
   1.177 +  register JDIMENSION count;
   1.178 +  register int num_components = cinfo->num_components;
   1.179 +  JDIMENSION num_cols = cinfo->output_width;
   1.180 +  int ci;
   1.181 +
   1.182 +  while (--num_rows >= 0) {
   1.183 +    for (ci = 0; ci < num_components; ci++) {
   1.184 +      inptr = input_buf[ci][input_row];
   1.185 +      outptr = output_buf[0] + ci;
   1.186 +      for (count = num_cols; count > 0; count--) {
   1.187 +	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
   1.188 +	outptr += num_components;
   1.189 +      }
   1.190 +    }
   1.191 +    input_row++;
   1.192 +    output_buf++;
   1.193 +  }
   1.194 +}
   1.195 +
   1.196 +
   1.197 +/*
   1.198 + * Color conversion for grayscale: just copy the data.
   1.199 + * This also works for YCbCr -> grayscale conversion, in which
   1.200 + * we just copy the Y (luminance) component and ignore chrominance.
   1.201 + */
   1.202 +
   1.203 +METHODDEF(void)
   1.204 +grayscale_convert (j_decompress_ptr cinfo,
   1.205 +		   JSAMPIMAGE input_buf, JDIMENSION input_row,
   1.206 +		   JSAMPARRAY output_buf, int num_rows)
   1.207 +{
   1.208 +  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
   1.209 +		    num_rows, cinfo->output_width);
   1.210 +}
   1.211 +
   1.212 +
   1.213 +/*
   1.214 + * Convert grayscale to RGB: just duplicate the graylevel three times.
   1.215 + * This is provided to support applications that don't want to cope
   1.216 + * with grayscale as a separate case.
   1.217 + */
   1.218 +
   1.219 +METHODDEF(void)
   1.220 +gray_rgb_convert (j_decompress_ptr cinfo,
   1.221 +		  JSAMPIMAGE input_buf, JDIMENSION input_row,
   1.222 +		  JSAMPARRAY output_buf, int num_rows)
   1.223 +{
   1.224 +  register JSAMPROW inptr, outptr;
   1.225 +  register JDIMENSION col;
   1.226 +  JDIMENSION num_cols = cinfo->output_width;
   1.227 +
   1.228 +  while (--num_rows >= 0) {
   1.229 +    inptr = input_buf[0][input_row++];
   1.230 +    outptr = *output_buf++;
   1.231 +    for (col = 0; col < num_cols; col++) {
   1.232 +      /* We can dispense with GETJSAMPLE() here */
   1.233 +      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
   1.234 +      outptr += RGB_PIXELSIZE;
   1.235 +    }
   1.236 +  }
   1.237 +}
   1.238 +
   1.239 +
   1.240 +/*
   1.241 + * Adobe-style YCCK->CMYK conversion.
   1.242 + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
   1.243 + * conversion as above, while passing K (black) unchanged.
   1.244 + * We assume build_ycc_rgb_table has been called.
   1.245 + */
   1.246 +
   1.247 +METHODDEF(void)
   1.248 +ycck_cmyk_convert (j_decompress_ptr cinfo,
   1.249 +		   JSAMPIMAGE input_buf, JDIMENSION input_row,
   1.250 +		   JSAMPARRAY output_buf, int num_rows)
   1.251 +{
   1.252 +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
   1.253 +  register int y, cb, cr;
   1.254 +  register JSAMPROW outptr;
   1.255 +  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
   1.256 +  register JDIMENSION col;
   1.257 +  JDIMENSION num_cols = cinfo->output_width;
   1.258 +  /* copy these pointers into registers if possible */
   1.259 +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
   1.260 +  register int * Crrtab = cconvert->Cr_r_tab;
   1.261 +  register int * Cbbtab = cconvert->Cb_b_tab;
   1.262 +  register INT32 * Crgtab = cconvert->Cr_g_tab;
   1.263 +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
   1.264 +  SHIFT_TEMPS
   1.265 +
   1.266 +  while (--num_rows >= 0) {
   1.267 +    inptr0 = input_buf[0][input_row];
   1.268 +    inptr1 = input_buf[1][input_row];
   1.269 +    inptr2 = input_buf[2][input_row];
   1.270 +    inptr3 = input_buf[3][input_row];
   1.271 +    input_row++;
   1.272 +    outptr = *output_buf++;
   1.273 +    for (col = 0; col < num_cols; col++) {
   1.274 +      y  = GETJSAMPLE(inptr0[col]);
   1.275 +      cb = GETJSAMPLE(inptr1[col]);
   1.276 +      cr = GETJSAMPLE(inptr2[col]);
   1.277 +      /* Range-limiting is essential due to noise introduced by DCT losses. */
   1.278 +      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
   1.279 +      outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
   1.280 +			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
   1.281 +						 SCALEBITS)))];
   1.282 +      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
   1.283 +      /* K passes through unchanged */
   1.284 +      outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
   1.285 +      outptr += 4;
   1.286 +    }
   1.287 +  }
   1.288 +}
   1.289 +
   1.290 +
   1.291 +/*
   1.292 + * Empty method for start_pass.
   1.293 + */
   1.294 +
   1.295 +METHODDEF(void)
   1.296 +start_pass_dcolor (j_decompress_ptr cinfo)
   1.297 +{
   1.298 +  /* no work needed */
   1.299 +}
   1.300 +
   1.301 +
   1.302 +/*
   1.303 + * Module initialization routine for output colorspace conversion.
   1.304 + */
   1.305 +
   1.306 +GLOBAL(void)
   1.307 +jinit_color_deconverter (j_decompress_ptr cinfo)
   1.308 +{
   1.309 +  my_cconvert_ptr cconvert;
   1.310 +  int ci;
   1.311 +
   1.312 +  cconvert = (my_cconvert_ptr)
   1.313 +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
   1.314 +				SIZEOF(my_color_deconverter));
   1.315 +  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
   1.316 +  cconvert->pub.start_pass = start_pass_dcolor;
   1.317 +
   1.318 +  /* Make sure num_components agrees with jpeg_color_space */
   1.319 +  switch (cinfo->jpeg_color_space) {
   1.320 +  case JCS_GRAYSCALE:
   1.321 +    if (cinfo->num_components != 1)
   1.322 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
   1.323 +    break;
   1.324 +
   1.325 +  case JCS_RGB:
   1.326 +  case JCS_YCbCr:
   1.327 +    if (cinfo->num_components != 3)
   1.328 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
   1.329 +    break;
   1.330 +
   1.331 +  case JCS_CMYK:
   1.332 +  case JCS_YCCK:
   1.333 +    if (cinfo->num_components != 4)
   1.334 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
   1.335 +    break;
   1.336 +
   1.337 +  default:			/* JCS_UNKNOWN can be anything */
   1.338 +    if (cinfo->num_components < 1)
   1.339 +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
   1.340 +    break;
   1.341 +  }
   1.342 +
   1.343 +  /* Set out_color_components and conversion method based on requested space.
   1.344 +   * Also clear the component_needed flags for any unused components,
   1.345 +   * so that earlier pipeline stages can avoid useless computation.
   1.346 +   */
   1.347 +
   1.348 +  switch (cinfo->out_color_space) {
   1.349 +  case JCS_GRAYSCALE:
   1.350 +    cinfo->out_color_components = 1;
   1.351 +    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
   1.352 +	cinfo->jpeg_color_space == JCS_YCbCr) {
   1.353 +      cconvert->pub.color_convert = grayscale_convert;
   1.354 +      /* For color->grayscale conversion, only the Y (0) component is needed */
   1.355 +      for (ci = 1; ci < cinfo->num_components; ci++)
   1.356 +	cinfo->comp_info[ci].component_needed = FALSE;
   1.357 +    } else
   1.358 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
   1.359 +    break;
   1.360 +
   1.361 +  case JCS_RGB:
   1.362 +    cinfo->out_color_components = RGB_PIXELSIZE;
   1.363 +    if (cinfo->jpeg_color_space == JCS_YCbCr) {
   1.364 +      cconvert->pub.color_convert = ycc_rgb_convert;
   1.365 +      build_ycc_rgb_table(cinfo);
   1.366 +    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
   1.367 +      cconvert->pub.color_convert = gray_rgb_convert;
   1.368 +    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
   1.369 +      cconvert->pub.color_convert = null_convert;
   1.370 +    } else
   1.371 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
   1.372 +    break;
   1.373 +
   1.374 +  case JCS_CMYK:
   1.375 +    cinfo->out_color_components = 4;
   1.376 +    if (cinfo->jpeg_color_space == JCS_YCCK) {
   1.377 +      cconvert->pub.color_convert = ycck_cmyk_convert;
   1.378 +      build_ycc_rgb_table(cinfo);
   1.379 +    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
   1.380 +      cconvert->pub.color_convert = null_convert;
   1.381 +    } else
   1.382 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
   1.383 +    break;
   1.384 +
   1.385 +  default:
   1.386 +    /* Permit null conversion to same output space */
   1.387 +    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
   1.388 +      cinfo->out_color_components = cinfo->num_components;
   1.389 +      cconvert->pub.color_convert = null_convert;
   1.390 +    } else			/* unsupported non-null conversion */
   1.391 +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
   1.392 +    break;
   1.393 +  }
   1.394 +
   1.395 +  if (cinfo->quantize_colors)
   1.396 +    cinfo->output_components = 1; /* single colormapped output component */
   1.397 +  else
   1.398 +    cinfo->output_components = cinfo->out_color_components;
   1.399 +}