vrshoot
diff libs/libjpeg/jdcolor.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/jdcolor.c Sat Feb 01 19:58:19 2014 +0200 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 +}