source: golgotha/src/i4/loaders/jpg/jdcolor.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 12.7 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9/*
10 * jdcolor.c
11 *
12 * Copyright (C) 1991-1996, Thomas G. Lane.
13 * This file is part of the Independent JPEG Group's software.
14 * For conditions of distribution and use, see the accompanying README file.
15 *
16 * This file contains output colorspace conversion routines.
17 */
18
19#define JPEG_INTERNALS
20#include "loaders/jpg/jinclude.h"
21#include "loaders/jpg/jpeglib.h"
22
23
24/* Private subobject */
25
26typedef struct {
27  struct jpeg_color_deconverter pub; /* public fields */
28
29  /* Private state for YCC->RGB conversion */
30  int * Cr_r_tab;               /* => table for Cr to R conversion */
31  int * Cb_b_tab;               /* => table for Cb to B conversion */
32  INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
33  INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
34} my_color_deconverter;
35
36typedef my_color_deconverter * my_cconvert_ptr;
37
38
39/**************** YCbCr -> RGB conversion: most common case **************/
40
41/*
42 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
43 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
44 * The conversion equations to be implemented are therefore
45 *      R = Y                + 1.40200 * Cr
46 *      G = Y - 0.34414 * Cb - 0.71414 * Cr
47 *      B = Y + 1.77200 * Cb
48 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
49 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
50 *
51 * To avoid floating-point arithmetic, we represent the fractional constants
52 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
53 * the products by 2^16, with appropriate rounding, to get the correct answer.
54 * Notice that Y, being an integral input, does not contribute any fraction
55 * so it need not participate in the rounding.
56 *
57 * For even more speed, we avoid doing any multiplications in the inner loop
58 * by precalculating the constants times Cb and Cr for all possible values.
59 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
60 * for 12-bit samples it is still acceptable.  It's not very reasonable for
61 * 16-bit samples, but if you want lossless storage you shouldn't be changing
62 * colorspace anyway.
63 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
64 * values for the G calculation are left scaled up, since we must add them
65 * together before rounding.
66 */
67
68#define SCALEBITS       16      /* speediest right-shift on some machines */
69#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
70#define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
71
72
73/*
74 * Initialize tables for YCC->RGB colorspace conversion.
75 */
76
77LOCAL(void)
78build_ycc_rgb_table (j_decompress_ptr cinfo)
79{
80  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
81  int i;
82  INT32 x;
83  SHIFT_TEMPS
84
85  cconvert->Cr_r_tab = (int *)
86    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
87                                (MAXJSAMPLE+1) * SIZEOF(int));
88  cconvert->Cb_b_tab = (int *)
89    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
90                                (MAXJSAMPLE+1) * SIZEOF(int));
91  cconvert->Cr_g_tab = (INT32 *)
92    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
93                                (MAXJSAMPLE+1) * SIZEOF(INT32));
94  cconvert->Cb_g_tab = (INT32 *)
95    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
96                                (MAXJSAMPLE+1) * SIZEOF(INT32));
97
98  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
99    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
100    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
101    /* Cr=>R value is nearest int to 1.40200 * x */
102    cconvert->Cr_r_tab[i] = (int)
103                    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
104    /* Cb=>B value is nearest int to 1.77200 * x */
105    cconvert->Cb_b_tab[i] = (int)
106                    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
107    /* Cr=>G value is scaled-up -0.71414 * x */
108    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
109    /* Cb=>G value is scaled-up -0.34414 * x */
110    /* We also add in ONE_HALF so that need not do it in inner loop */
111    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
112  }
113}
114
115
116/*
117 * Convert some rows of samples to the output colorspace.
118 *
119 * Note that we change from noninterleaved, one-plane-per-component format
120 * to interleaved-pixel format.  The output buffer is therefore three times
121 * as wide as the input buffer.
122 * A starting row offset is provided only for the input buffer.  The caller
123 * can easily adjust the passed output_buf value to accommodate any row
124 * offset required on that side.
125 */
126
127METHODDEF(void)
128ycc_rgb_convert (j_decompress_ptr cinfo,
129                 JSAMPIMAGE input_buf, JDIMENSION input_row,
130                 JSAMPARRAY output_buf, int num_rows)
131{
132  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
133  register int y, cb, cr;
134  register JSAMPROW outptr;
135  register JSAMPROW inptr0, inptr1, inptr2;
136  register JDIMENSION col;
137  JDIMENSION num_cols = cinfo->output_width;
138  /* copy these pointers into registers if possible */
139  register JSAMPLE * range_limit = cinfo->sample_range_limit;
140  register int * Crrtab = cconvert->Cr_r_tab;
141  register int * Cbbtab = cconvert->Cb_b_tab;
142  register INT32 * Crgtab = cconvert->Cr_g_tab;
143  register INT32 * Cbgtab = cconvert->Cb_g_tab;
144  SHIFT_TEMPS
145
146  while (--num_rows >= 0) {
147    inptr0 = input_buf[0][input_row];
148    inptr1 = input_buf[1][input_row];
149    inptr2 = input_buf[2][input_row];
150    input_row++;
151    outptr = *output_buf++;
152    for (col = 0; col < num_cols; col++) {
153      y  = GETJSAMPLE(inptr0[col]);
154      cb = GETJSAMPLE(inptr1[col]);
155      cr = GETJSAMPLE(inptr2[col]);
156      /* Range-limiting is essential due to noise introduced by DCT losses. */
157      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
158      outptr[RGB_GREEN] = range_limit[y +
159                              ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
160                                                 SCALEBITS))];
161      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
162      outptr += RGB_PIXELSIZE;
163    }
164  }
165}
166
167
168/**************** Cases other than YCbCr -> RGB **************/
169
170
171/*
172 * Color conversion for no colorspace change: just copy the data,
173 * converting from separate-planes to interleaved representation.
174 */
175
176METHODDEF(void)
177null_convert (j_decompress_ptr cinfo,
178              JSAMPIMAGE input_buf, JDIMENSION input_row,
179              JSAMPARRAY output_buf, int num_rows)
180{
181  register JSAMPROW inptr, outptr;
182  register JDIMENSION count;
183  register int num_components = cinfo->num_components;
184  JDIMENSION num_cols = cinfo->output_width;
185  int ci;
186
187  while (--num_rows >= 0) {
188    for (ci = 0; ci < num_components; ci++) {
189      inptr = input_buf[ci][input_row];
190      outptr = output_buf[0] + ci;
191      for (count = num_cols; count > 0; count--) {
192        *outptr = *inptr++;     /* needn't bother with GETJSAMPLE() here */
193        outptr += num_components;
194      }
195    }
196    input_row++;
197    output_buf++;
198  }
199}
200
201
202/*
203 * Color conversion for grayscale: just copy the data.
204 * This also works for YCbCr -> grayscale conversion, in which
205 * we just copy the Y (luminance) component and ignore chrominance.
206 */
207
208METHODDEF(void)
209grayscale_convert (j_decompress_ptr cinfo,
210                   JSAMPIMAGE input_buf, JDIMENSION input_row,
211                   JSAMPARRAY output_buf, int num_rows)
212{
213  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
214                    num_rows, cinfo->output_width);
215}
216
217
218/*
219 * Adobe-style YCCK->CMYK conversion.
220 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
221 * conversion as above, while passing K (black) unchanged.
222 * We assume build_ycc_rgb_table has been called.
223 */
224
225METHODDEF(void)
226ycck_cmyk_convert (j_decompress_ptr cinfo,
227                   JSAMPIMAGE input_buf, JDIMENSION input_row,
228                   JSAMPARRAY output_buf, int num_rows)
229{
230  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
231  register int y, cb, cr;
232  register JSAMPROW outptr;
233  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
234  register JDIMENSION col;
235  JDIMENSION num_cols = cinfo->output_width;
236  /* copy these pointers into registers if possible */
237  register JSAMPLE * range_limit = cinfo->sample_range_limit;
238  register int * Crrtab = cconvert->Cr_r_tab;
239  register int * Cbbtab = cconvert->Cb_b_tab;
240  register INT32 * Crgtab = cconvert->Cr_g_tab;
241  register INT32 * Cbgtab = cconvert->Cb_g_tab;
242  SHIFT_TEMPS
243
244  while (--num_rows >= 0) {
245    inptr0 = input_buf[0][input_row];
246    inptr1 = input_buf[1][input_row];
247    inptr2 = input_buf[2][input_row];
248    inptr3 = input_buf[3][input_row];
249    input_row++;
250    outptr = *output_buf++;
251    for (col = 0; col < num_cols; col++) {
252      y  = GETJSAMPLE(inptr0[col]);
253      cb = GETJSAMPLE(inptr1[col]);
254      cr = GETJSAMPLE(inptr2[col]);
255      /* Range-limiting is essential due to noise introduced by DCT losses. */
256      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
257      outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
258                              ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
259                                                 SCALEBITS)))];
260      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
261      /* K passes through unchanged */
262      outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
263      outptr += 4;
264    }
265  }
266}
267
268
269/*
270 * Empty method for start_pass.
271 */
272
273METHODDEF(void)
274start_pass_dcolor (j_decompress_ptr cinfo)
275{
276  /* no work needed */
277}
278
279
280/*
281 * Module initialization routine for output colorspace conversion.
282 */
283
284GLOBAL(void)
285jinit_color_deconverter (j_decompress_ptr cinfo)
286{
287  my_cconvert_ptr cconvert;
288  int ci;
289
290  cconvert = (my_cconvert_ptr)
291    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
292                                SIZEOF(my_color_deconverter));
293  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
294  cconvert->pub.start_pass = start_pass_dcolor;
295
296  /* Make sure num_components agrees with jpeg_color_space */
297  switch (cinfo->jpeg_color_space) {
298  case JCS_GRAYSCALE:
299    if (cinfo->num_components != 1)
300      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
301    break;
302
303  case JCS_RGB:
304  case JCS_YCbCr:
305    if (cinfo->num_components != 3)
306      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
307    break;
308
309  case JCS_CMYK:
310  case JCS_YCCK:
311    if (cinfo->num_components != 4)
312      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
313    break;
314
315  default:                      /* JCS_UNKNOWN can be anything */
316    if (cinfo->num_components < 1)
317      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
318    break;
319  }
320
321  /* Set out_color_components and conversion method based on requested space.
322   * Also clear the component_needed flags for any unused components,
323   * so that earlier pipeline stages can avoid useless computation.
324   */
325
326  switch (cinfo->out_color_space) {
327  case JCS_GRAYSCALE:
328    cinfo->out_color_components = 1;
329    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
330        cinfo->jpeg_color_space == JCS_YCbCr) {
331      cconvert->pub.color_convert = grayscale_convert;
332      /* For color->grayscale conversion, only the Y (0) component is needed */
333      for (ci = 1; ci < cinfo->num_components; ci++)
334        cinfo->comp_info[ci].component_needed = FALSE;
335    } else
336      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
337    break;
338
339  case JCS_RGB:
340    cinfo->out_color_components = RGB_PIXELSIZE;
341    if (cinfo->jpeg_color_space == JCS_YCbCr) {
342      cconvert->pub.color_convert = ycc_rgb_convert;
343      build_ycc_rgb_table(cinfo);
344    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
345      cconvert->pub.color_convert = null_convert;
346    } else
347      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
348    break;
349
350  case JCS_CMYK:
351    cinfo->out_color_components = 4;
352    if (cinfo->jpeg_color_space == JCS_YCCK) {
353      cconvert->pub.color_convert = ycck_cmyk_convert;
354      build_ycc_rgb_table(cinfo);
355    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
356      cconvert->pub.color_convert = null_convert;
357    } else
358      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
359    break;
360
361  default:
362    /* Permit null conversion to same output space */
363    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
364      cinfo->out_color_components = cinfo->num_components;
365      cconvert->pub.color_convert = null_convert;
366    } else                      /* unsupported non-null conversion */
367      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
368    break;
369  }
370
371  if (cinfo->quantize_colors)
372    cinfo->output_components = 1; /* single colormapped output component */
373  else
374    cinfo->output_components = cinfo->out_color_components;
375}
Note: See TracBrowser for help on using the repository browser.