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

 Page generated by Doxygen 1.8.14 for MRPT 1.5.5 Git: e06b63dbf Fri Dec 1 14:41:11 2017 +0100 at lun oct 28 01:31:35 CET 2019