~ubuntu-branches/ubuntu/gutsy/amsn/gutsy

« back to all changes in this revision

Viewing changes to utils/TkCximage/src/jpeg/jccolor.c

  • Committer: Bazaar Package Importer
  • Author(s): Theodore Karkoulis
  • Date: 2006-01-04 15:26:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060104152602-ipe1yg00rl3nlklv
Tags: 0.95-1
New Upstream Release (closes: #345052, #278575).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * jccolor.c
 
3
 *
 
4
 * Copyright (C) 1991-1996, Thomas G. Lane.
 
5
 * This file is part of the Independent JPEG Group's software.
 
6
 * For conditions of distribution and use, see the accompanying README file.
 
7
 *
 
8
 * This file contains input colorspace conversion routines.
 
9
 */
 
10
 
 
11
#define JPEG_INTERNALS
 
12
#include "jinclude.h"
 
13
#include "jpeglib.h"
 
14
 
 
15
/* Private subobject */
 
16
 
 
17
typedef struct {
 
18
  struct jpeg_color_converter pub; /* public fields */
 
19
 
 
20
  /* Private state for RGB->YCC conversion */
 
21
  INT32 * rgb_ycc_tab;          /* => table for RGB to YCbCr conversion */
 
22
} my_color_converter;
 
23
 
 
24
typedef my_color_converter * my_cconvert_ptr;
 
25
 
 
26
 
 
27
/**************** RGB -> YCbCr conversion: most common case **************/
 
28
 
 
29
/*
 
30
 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
 
31
 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
 
32
 * The conversion equations to be implemented are therefore
 
33
 *      Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
 
34
 *      Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + CENTERJSAMPLE
 
35
 *      Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + CENTERJSAMPLE
 
36
 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
 
37
 * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
 
38
 * rather than CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
 
39
 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
 
40
 * were not represented exactly.  Now we sacrifice exact representation of
 
41
 * maximum red and maximum blue in order to get exact grayscales.
 
42
 *
 
43
 * To avoid floating-point arithmetic, we represent the fractional constants
 
44
 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
 
45
 * the products by 2^16, with appropriate rounding, to get the correct answer.
 
46
 *
 
47
 * For even more speed, we avoid doing any multiplications in the inner loop
 
48
 * by precalculating the constants times R,G,B for all possible values.
 
49
 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
 
50
 * for 12-bit samples it is still acceptable.  It's not very reasonable for
 
51
 * 16-bit samples, but if you want lossless storage you shouldn't be changing
 
52
 * colorspace anyway.
 
53
 * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
 
54
 * in the tables to save adding them separately in the inner loop.
 
55
 */
 
56
 
 
57
#define SCALEBITS       16      /* speediest right-shift on some machines */
 
58
#define CBCR_OFFSET     ((INT32) CENTERJSAMPLE << SCALEBITS)
 
59
#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
 
60
#define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
 
61
 
 
62
/* We allocate one big table and divide it up into eight parts, instead of
 
63
 * doing eight alloc_small requests.  This lets us use a single table base
 
64
 * address, which can be held in a register in the inner loops on many
 
65
 * machines (more than can hold all eight addresses, anyway).
 
66
 */
 
67
 
 
68
#define R_Y_OFF         0                       /* offset to R => Y section */
 
69
#define G_Y_OFF         (1*(MAXJSAMPLE+1))      /* offset to G => Y section */
 
70
#define B_Y_OFF         (2*(MAXJSAMPLE+1))      /* etc. */
 
71
#define R_CB_OFF        (3*(MAXJSAMPLE+1))
 
72
#define G_CB_OFF        (4*(MAXJSAMPLE+1))
 
73
#define B_CB_OFF        (5*(MAXJSAMPLE+1))
 
74
#define R_CR_OFF        B_CB_OFF                /* B=>Cb, R=>Cr are the same */
 
75
#define G_CR_OFF        (6*(MAXJSAMPLE+1))
 
76
#define B_CR_OFF        (7*(MAXJSAMPLE+1))
 
77
#define TABLE_SIZE      (8*(MAXJSAMPLE+1))
 
78
 
 
79
 
 
80
/*
 
81
 * Initialize for RGB->YCC colorspace conversion.
 
82
 */
 
83
 
 
84
METHODDEF(void)
 
85
rgb_ycc_start (j_compress_ptr cinfo)
 
86
{
 
87
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 
88
  INT32 * rgb_ycc_tab;
 
89
  INT32 i;
 
90
 
 
91
  /* Allocate and fill in the conversion tables. */
 
92
  cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
 
93
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 
94
                                (TABLE_SIZE * SIZEOF(INT32)));
 
95
 
 
96
  for (i = 0; i <= MAXJSAMPLE; i++) {
 
97
    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
 
98
    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
 
99
    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
 
100
    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
 
101
    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
 
102
    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
 
103
     * This ensures that the maximum output will round to MAXJSAMPLE
 
104
     * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
 
105
     */
 
106
    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
 
107
/*  B=>Cb and R=>Cr tables are the same
 
108
    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
 
109
*/
 
110
    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
 
111
    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
 
112
  }
 
113
}
 
114
 
 
115
 
 
116
/*
 
117
 * Convert some rows of samples to the JPEG colorspace.
 
118
 *
 
119
 * Note that we change from the application's interleaved-pixel format
 
120
 * to our internal noninterleaved, one-plane-per-component format.
 
121
 * The input buffer is therefore three times as wide as the output buffer.
 
122
 *
 
123
 * A starting row offset is provided only for the output buffer.  The caller
 
124
 * can easily adjust the passed input_buf value to accommodate any row
 
125
 * offset required on that side.
 
126
 */
 
127
 
 
128
METHODDEF(void)
 
129
rgb_ycc_convert (j_compress_ptr cinfo,
 
130
                 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 
131
                 JDIMENSION output_row, int num_rows)
 
132
{
 
133
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 
134
  register int r, g, b;
 
135
  register INT32 * ctab = cconvert->rgb_ycc_tab;
 
136
  register JSAMPROW inptr;
 
137
  register JSAMPROW outptr0, outptr1, outptr2;
 
138
  register JDIMENSION col;
 
139
  JDIMENSION num_cols = cinfo->image_width;
 
140
 
 
141
  while (--num_rows >= 0) {
 
142
    inptr = *input_buf++;
 
143
    outptr0 = output_buf[0][output_row];
 
144
    outptr1 = output_buf[1][output_row];
 
145
    outptr2 = output_buf[2][output_row];
 
146
    output_row++;
 
147
    for (col = 0; col < num_cols; col++) {
 
148
      r = GETJSAMPLE(inptr[RGB_RED]);
 
149
      g = GETJSAMPLE(inptr[RGB_GREEN]);
 
150
      b = GETJSAMPLE(inptr[RGB_BLUE]);
 
151
      inptr += RGB_PIXELSIZE;
 
152
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
 
153
       * must be too; we do not need an explicit range-limiting operation.
 
154
       * Hence the value being shifted is never negative, and we don't
 
155
       * need the general RIGHT_SHIFT macro.
 
156
       */
 
157
      /* Y */
 
158
      outptr0[col] = (JSAMPLE)
 
159
                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 
160
                 >> SCALEBITS);
 
161
      /* Cb */
 
162
      outptr1[col] = (JSAMPLE)
 
163
                ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
 
164
                 >> SCALEBITS);
 
165
      /* Cr */
 
166
      outptr2[col] = (JSAMPLE)
 
167
                ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 
168
                 >> SCALEBITS);
 
169
    }
 
170
  }
 
171
}
 
172
 
 
173
 
 
174
/**************** Cases other than RGB -> YCbCr **************/
 
175
 
 
176
 
 
177
/*
 
178
 * Convert some rows of samples to the JPEG colorspace.
 
179
 * This version handles RGB->grayscale conversion, which is the same
 
180
 * as the RGB->Y portion of RGB->YCbCr.
 
181
 * We assume rgb_ycc_start has been called (we only use the Y tables).
 
182
 */
 
183
 
 
184
METHODDEF(void)
 
185
rgb_gray_convert (j_compress_ptr cinfo,
 
186
                  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 
187
                  JDIMENSION output_row, int num_rows)
 
188
{
 
189
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 
190
  register int r, g, b;
 
191
  register INT32 * ctab = cconvert->rgb_ycc_tab;
 
192
  register JSAMPROW inptr;
 
193
  register JSAMPROW outptr;
 
194
  register JDIMENSION col;
 
195
  JDIMENSION num_cols = cinfo->image_width;
 
196
 
 
197
  while (--num_rows >= 0) {
 
198
    inptr = *input_buf++;
 
199
    outptr = output_buf[0][output_row];
 
200
    output_row++;
 
201
    for (col = 0; col < num_cols; col++) {
 
202
      r = GETJSAMPLE(inptr[RGB_RED]);
 
203
      g = GETJSAMPLE(inptr[RGB_GREEN]);
 
204
      b = GETJSAMPLE(inptr[RGB_BLUE]);
 
205
      inptr += RGB_PIXELSIZE;
 
206
      /* Y */
 
207
      outptr[col] = (JSAMPLE)
 
208
                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 
209
                 >> SCALEBITS);
 
210
    }
 
211
  }
 
212
}
 
213
 
 
214
 
 
215
/*
 
216
 * Convert some rows of samples to the JPEG colorspace.
 
217
 * This version handles Adobe-style CMYK->YCCK conversion,
 
218
 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
 
219
 * conversion as above, while passing K (black) unchanged.
 
220
 * We assume rgb_ycc_start has been called.
 
221
 */
 
222
 
 
223
METHODDEF(void)
 
224
cmyk_ycck_convert (j_compress_ptr cinfo,
 
225
                   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 
226
                   JDIMENSION output_row, int num_rows)
 
227
{
 
228
  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
 
229
  register int r, g, b;
 
230
  register INT32 * ctab = cconvert->rgb_ycc_tab;
 
231
  register JSAMPROW inptr;
 
232
  register JSAMPROW outptr0, outptr1, outptr2, outptr3;
 
233
  register JDIMENSION col;
 
234
  JDIMENSION num_cols = cinfo->image_width;
 
235
 
 
236
  while (--num_rows >= 0) {
 
237
    inptr = *input_buf++;
 
238
    outptr0 = output_buf[0][output_row];
 
239
    outptr1 = output_buf[1][output_row];
 
240
    outptr2 = output_buf[2][output_row];
 
241
    outptr3 = output_buf[3][output_row];
 
242
    output_row++;
 
243
    for (col = 0; col < num_cols; col++) {
 
244
      r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
 
245
      g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
 
246
      b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
 
247
      /* K passes through as-is */
 
248
      outptr3[col] = inptr[3];  /* don't need GETJSAMPLE here */
 
249
      inptr += 4;
 
250
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
 
251
       * must be too; we do not need an explicit range-limiting operation.
 
252
       * Hence the value being shifted is never negative, and we don't
 
253
       * need the general RIGHT_SHIFT macro.
 
254
       */
 
255
      /* Y */
 
256
      outptr0[col] = (JSAMPLE)
 
257
                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
 
258
                 >> SCALEBITS);
 
259
      /* Cb */
 
260
      outptr1[col] = (JSAMPLE)
 
261
                ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
 
262
                 >> SCALEBITS);
 
263
      /* Cr */
 
264
      outptr2[col] = (JSAMPLE)
 
265
                ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
 
266
                 >> SCALEBITS);
 
267
    }
 
268
  }
 
269
}
 
270
 
 
271
 
 
272
/*
 
273
 * Convert some rows of samples to the JPEG colorspace.
 
274
 * This version handles grayscale output with no conversion.
 
275
 * The source can be either plain grayscale or YCbCr (since Y == gray).
 
276
 */
 
277
 
 
278
METHODDEF(void)
 
279
grayscale_convert (j_compress_ptr cinfo,
 
280
                   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 
281
                   JDIMENSION output_row, int num_rows)
 
282
{
 
283
  register JSAMPROW inptr;
 
284
  register JSAMPROW outptr;
 
285
  register JDIMENSION col;
 
286
  JDIMENSION num_cols = cinfo->image_width;
 
287
  int instride = cinfo->input_components;
 
288
 
 
289
  while (--num_rows >= 0) {
 
290
    inptr = *input_buf++;
 
291
    outptr = output_buf[0][output_row];
 
292
    output_row++;
 
293
    for (col = 0; col < num_cols; col++) {
 
294
      outptr[col] = inptr[0];   /* don't need GETJSAMPLE() here */
 
295
      inptr += instride;
 
296
    }
 
297
  }
 
298
}
 
299
 
 
300
 
 
301
/*
 
302
 * Convert some rows of samples to the JPEG colorspace.
 
303
 * This version handles multi-component colorspaces without conversion.
 
304
 * We assume input_components == num_components.
 
305
 */
 
306
 
 
307
METHODDEF(void)
 
308
null_convert (j_compress_ptr cinfo,
 
309
              JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
 
310
              JDIMENSION output_row, int num_rows)
 
311
{
 
312
  register JSAMPROW inptr;
 
313
  register JSAMPROW outptr;
 
314
  register JDIMENSION col;
 
315
  register int ci;
 
316
  int nc = cinfo->num_components;
 
317
  JDIMENSION num_cols = cinfo->image_width;
 
318
 
 
319
  while (--num_rows >= 0) {
 
320
    /* It seems fastest to make a separate pass for each component. */
 
321
    for (ci = 0; ci < nc; ci++) {
 
322
      inptr = *input_buf;
 
323
      outptr = output_buf[ci][output_row];
 
324
      for (col = 0; col < num_cols; col++) {
 
325
        outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
 
326
        inptr += nc;
 
327
      }
 
328
    }
 
329
    input_buf++;
 
330
    output_row++;
 
331
  }
 
332
}
 
333
 
 
334
 
 
335
/*
 
336
 * Empty method for start_pass.
 
337
 */
 
338
 
 
339
METHODDEF(void)
 
340
null_method (j_compress_ptr cinfo)
 
341
{
 
342
  /* no work needed */
 
343
}
 
344
 
 
345
 
 
346
/*
 
347
 * Module initialization routine for input colorspace conversion.
 
348
 */
 
349
 
 
350
GLOBAL(void)
 
351
jinit_color_converter (j_compress_ptr cinfo)
 
352
{
 
353
  my_cconvert_ptr cconvert;
 
354
 
 
355
  cconvert = (my_cconvert_ptr)
 
356
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 
357
                                SIZEOF(my_color_converter));
 
358
  cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
 
359
  /* set start_pass to null method until we find out differently */
 
360
  cconvert->pub.start_pass = null_method;
 
361
 
 
362
  /* Make sure input_components agrees with in_color_space */
 
363
  switch (cinfo->in_color_space) {
 
364
  case JCS_GRAYSCALE:
 
365
    if (cinfo->input_components != 1)
 
366
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 
367
    break;
 
368
 
 
369
  case JCS_RGB:
 
370
#if RGB_PIXELSIZE != 3
 
371
    if (cinfo->input_components != RGB_PIXELSIZE)
 
372
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 
373
    break;
 
374
#endif /* else share code with YCbCr */
 
375
 
 
376
  case JCS_YCbCr:
 
377
    if (cinfo->input_components != 3)
 
378
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 
379
    break;
 
380
 
 
381
  case JCS_CMYK:
 
382
  case JCS_YCCK:
 
383
    if (cinfo->input_components != 4)
 
384
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 
385
    break;
 
386
 
 
387
  default:                      /* JCS_UNKNOWN can be anything */
 
388
    if (cinfo->input_components < 1)
 
389
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
 
390
    break;
 
391
  }
 
392
 
 
393
  /* Check num_components, set conversion method based on requested space */
 
394
  switch (cinfo->jpeg_color_space) {
 
395
  case JCS_GRAYSCALE:
 
396
    if (cinfo->num_components != 1)
 
397
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 
398
    if (cinfo->in_color_space == JCS_GRAYSCALE)
 
399
      cconvert->pub.color_convert = grayscale_convert;
 
400
    else if (cinfo->in_color_space == JCS_RGB) {
 
401
      cconvert->pub.start_pass = rgb_ycc_start;
 
402
      cconvert->pub.color_convert = rgb_gray_convert;
 
403
    } else if (cinfo->in_color_space == JCS_YCbCr)
 
404
      cconvert->pub.color_convert = grayscale_convert;
 
405
    else
 
406
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
407
    break;
 
408
 
 
409
  case JCS_RGB:
 
410
    if (cinfo->num_components != 3)
 
411
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 
412
    if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
 
413
      cconvert->pub.color_convert = null_convert;
 
414
    else
 
415
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
416
    break;
 
417
 
 
418
  case JCS_YCbCr:
 
419
    if (cinfo->num_components != 3)
 
420
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 
421
    if (cinfo->in_color_space == JCS_RGB) {
 
422
      cconvert->pub.start_pass = rgb_ycc_start;
 
423
      cconvert->pub.color_convert = rgb_ycc_convert;
 
424
    } else if (cinfo->in_color_space == JCS_YCbCr)
 
425
      cconvert->pub.color_convert = null_convert;
 
426
    else
 
427
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
428
    break;
 
429
 
 
430
  case JCS_CMYK:
 
431
    if (cinfo->num_components != 4)
 
432
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 
433
    if (cinfo->in_color_space == JCS_CMYK)
 
434
      cconvert->pub.color_convert = null_convert;
 
435
    else
 
436
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
437
    break;
 
438
 
 
439
  case JCS_YCCK:
 
440
    if (cinfo->num_components != 4)
 
441
      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
 
442
    if (cinfo->in_color_space == JCS_CMYK) {
 
443
      cconvert->pub.start_pass = rgb_ycc_start;
 
444
      cconvert->pub.color_convert = cmyk_ycck_convert;
 
445
    } else if (cinfo->in_color_space == JCS_YCCK)
 
446
      cconvert->pub.color_convert = null_convert;
 
447
    else
 
448
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
449
    break;
 
450
 
 
451
  default:                      /* allow null conversion of JCS_UNKNOWN */
 
452
    if (cinfo->jpeg_color_space != cinfo->in_color_space ||
 
453
        cinfo->num_components != cinfo->input_components)
 
454
      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
 
455
    cconvert->pub.color_convert = null_convert;
 
456
    break;
 
457
  }
 
458
}