Main MRPT website > C++ reference for MRPT 1.9.9
jdmerge.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 |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #define JPEG_INTERNALS
11 #include "jinclude.h"
12 #include "mrpt_jpeglib.h"
13 #include <mrpt/utils/mrpt_macros.h>
14 
15 #ifdef UPSAMPLE_MERGING_SUPPORTED
16 
17 /* Private subobject */
18 
19 typedef struct
20 {
21  struct jpeg_upsampler pub; /* public fields */
22 
23  /* Pointer to routine to do actual upsampling/conversion of one row group */
24  JMETHOD(
25  void, upmethod, (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
26  JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
27 
28  /* Private state for YCC->RGB conversion */
29  int* Cr_r_tab; /* => table for Cr to R conversion */
30  int* Cb_b_tab; /* => table for Cb to B conversion */
31  INT32* Cr_g_tab; /* => table for Cr to G conversion */
32  INT32* Cb_g_tab; /* => table for Cb to G conversion */
33 
34  /* For 2:1 vertical sampling, we produce two output rows at a time.
35  * We need a "spare" row buffer to hold the second output row if the
36  * application provides just a one-row buffer; we also use the spare
37  * to discard the dummy last row if the image height is odd.
38  */
40  boolean spare_full; /* T if spare buffer is occupied */
41 
42  JDIMENSION out_row_width; /* samples per output row */
43  JDIMENSION rows_to_go; /* counts rows remaining in image */
44 } my_upsampler;
45 
47 
48 #define SCALEBITS 16 /* speediest right-shift on some machines */
49 #define ONE_HALF ((INT32)1 << (SCALEBITS - 1))
50 #define FIX(x) ((INT32)((x) * (1L << SCALEBITS) + 0.5))
51 
52 /*
53  * Initialize tables for YCC->RGB colorspace conversion.
54  * This is taken directly from jdcolor.c; see that file for more info.
55  */
56 
57 LOCAL(void)
59 {
60  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
61  int i;
62  INT32 x;
64 
65  upsample->Cr_r_tab = (int*)(*cinfo->mem->alloc_small)(
66  (j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE + 1) * SIZEOF(int));
67  upsample->Cb_b_tab = (int*)(*cinfo->mem->alloc_small)(
68  (j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE + 1) * SIZEOF(int));
69  upsample->Cr_g_tab = (INT32*)(*cinfo->mem->alloc_small)(
70  (j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE + 1) * SIZEOF(INT32));
71  upsample->Cb_g_tab = (INT32*)(*cinfo->mem->alloc_small)(
72  (j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE + 1) * SIZEOF(INT32));
73 
74  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++)
75  {
76  /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
77  /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
78  /* Cr=>R value is nearest int to 1.40200 * x */
79  upsample->Cr_r_tab[i] =
80  (int)RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
81  /* Cb=>B value is nearest int to 1.77200 * x */
82  upsample->Cb_b_tab[i] =
83  (int)RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
84  /* Cr=>G value is scaled-up -0.71414 * x */
85  upsample->Cr_g_tab[i] = (-FIX(0.71414)) * x;
86  /* Cb=>G value is scaled-up -0.34414 * x */
87  /* We also add in ONE_HALF so that need not do it in inner loop */
88  upsample->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
89  }
90 }
91 
92 /*
93  * Initialize for an upsampling pass.
94  */
95 
96 METHODDEF(void)
98 {
99  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
100 
101  /* Mark the spare buffer empty */
102  upsample->spare_full = FALSE;
103  /* Initialize total-height counter for detecting bottom of image */
104  upsample->rows_to_go = cinfo->output_height;
105 }
106 
107 /*
108  * Control routine to do upsampling (and color conversion).
109  *
110  * The control routine just handles the row buffering considerations.
111  */
112 
113 METHODDEF(void)
115  j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION* in_row_group_ctr,
116  JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
117  JDIMENSION* out_row_ctr, JDIMENSION out_rows_avail)
118 /* 2:1 vertical sampling case: may need a spare row. */
119 {
120  MRPT_UNUSED_PARAM(in_row_group_ctr);
121  MRPT_UNUSED_PARAM(in_row_groups_avail);
122  MRPT_UNUSED_PARAM(out_rows_avail);
123  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
124  JSAMPROW work_ptrs[2];
125  JDIMENSION num_rows; /* number of rows returned to caller */
126 
127  if (upsample->spare_full)
128  {
129  /* If we have a spare row saved from a previous cycle, just return it.
130  */
132  &upsample->spare_row, 0, output_buf + *out_row_ctr, 0, 1,
133  upsample->out_row_width);
134  num_rows = 1;
135  upsample->spare_full = FALSE;
136  }
137  else
138  {
139  /* Figure number of rows to return to caller. */
140  num_rows = 2;
141  /* Not more than the distance to the end of the image. */
142  if (num_rows > upsample->rows_to_go) num_rows = upsample->rows_to_go;
143  /* And not more than what the client can accept: */
144  out_rows_avail -= *out_row_ctr;
145  if (num_rows > out_rows_avail) num_rows = out_rows_avail;
146  /* Create output pointer array for upsampler. */
147  work_ptrs[0] = output_buf[*out_row_ctr];
148  if (num_rows > 1)
149  {
150  work_ptrs[1] = output_buf[*out_row_ctr + 1];
151  }
152  else
153  {
154  work_ptrs[1] = upsample->spare_row;
155  upsample->spare_full = TRUE;
156  }
157  /* Now do the upsampling. */
158  (*upsample->upmethod)(cinfo, input_buf, *in_row_group_ctr, work_ptrs);
159  }
160 
161  /* Adjust counts */
162  *out_row_ctr += num_rows;
163  upsample->rows_to_go -= num_rows;
164  /* When the buffer is emptied, declare this input row group consumed */
165  if (!upsample->spare_full) (*in_row_group_ctr)++;
166 }
167 
168 METHODDEF(void)
170  j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION* in_row_group_ctr,
171  JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
172  JDIMENSION* out_row_ctr, JDIMENSION out_rows_avail)
173 /* 1:1 vertical sampling case: much easier, never need a spare row. */
174 {
175  MRPT_UNUSED_PARAM(in_row_groups_avail);
176  MRPT_UNUSED_PARAM(out_rows_avail);
177  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
178 
179  /* Just do the upsampling. */
180  (*upsample->upmethod)(
181  cinfo, input_buf, *in_row_group_ctr, output_buf + *out_row_ctr);
182  /* Adjust counts */
183  (*out_row_ctr)++;
184  (*in_row_group_ctr)++;
185 }
186 
187 /*
188  * These are the routines invoked by the control routines to do
189  * the actual upsampling/conversion. One row group is processed per call.
190  *
191  * Note: since we may be writing directly into application-supplied buffers,
192  * we have to be honest about the output width; we can't assume the buffer
193  * has been rounded up to an even width.
194  */
195 
196 /*
197  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
198  */
199 
200 METHODDEF(void)
202  j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
204 {
205  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
206  int y, cred, cgreen, cblue;
207  int cb, cr;
209  JSAMPROW inptr0, inptr1, inptr2;
210  JDIMENSION col;
211  /* copy these pointers into registers if possible */
212  JSAMPLE* range_limit = cinfo->sample_range_limit;
213  int* Crrtab = upsample->Cr_r_tab;
214  int* Cbbtab = upsample->Cb_b_tab;
215  INT32* Crgtab = upsample->Cr_g_tab;
216  INT32* Cbgtab = upsample->Cb_g_tab;
218 
219  inptr0 = input_buf[0][in_row_group_ctr];
220  inptr1 = input_buf[1][in_row_group_ctr];
221  inptr2 = input_buf[2][in_row_group_ctr];
222  outptr = output_buf[0];
223  /* Loop for each pair of output pixels */
224  for (col = cinfo->output_width >> 1; col > 0; col--)
225  {
226  /* Do the chroma part of the calculation */
227  cb = GETJSAMPLE(*inptr1++);
228  cr = GETJSAMPLE(*inptr2++);
229  cred = Crrtab[cr];
230  cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
231  cblue = Cbbtab[cb];
232  /* Fetch 2 Y values and emit 2 pixels */
233  y = GETJSAMPLE(*inptr0++);
234  outptr[RGB_RED] = range_limit[y + cred];
235  outptr[RGB_GREEN] = range_limit[y + cgreen];
236  outptr[RGB_BLUE] = range_limit[y + cblue];
237  outptr += RGB_PIXELSIZE;
238  y = GETJSAMPLE(*inptr0++);
239  outptr[RGB_RED] = range_limit[y + cred];
240  outptr[RGB_GREEN] = range_limit[y + cgreen];
241  outptr[RGB_BLUE] = range_limit[y + cblue];
242  outptr += RGB_PIXELSIZE;
243  }
244  /* If image width is odd, do the last output column separately */
245  if (cinfo->output_width & 1)
246  {
247  cb = GETJSAMPLE(*inptr1);
248  cr = GETJSAMPLE(*inptr2);
249  cred = Crrtab[cr];
250  cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
251  cblue = Cbbtab[cb];
252  y = GETJSAMPLE(*inptr0);
253  outptr[RGB_RED] = range_limit[y + cred];
254  outptr[RGB_GREEN] = range_limit[y + cgreen];
255  outptr[RGB_BLUE] = range_limit[y + cblue];
256  }
257 }
258 
259 /*
260  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
261  */
262 
263 METHODDEF(void)
265  j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
267 {
268  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
269  int y, cred, cgreen, cblue;
270  int cb, cr;
271  JSAMPROW outptr0, outptr1;
272  JSAMPROW inptr00, inptr01, inptr1, inptr2;
273  JDIMENSION col;
274  /* copy these pointers into registers if possible */
275  JSAMPLE* range_limit = cinfo->sample_range_limit;
276  int* Crrtab = upsample->Cr_r_tab;
277  int* Cbbtab = upsample->Cb_b_tab;
278  INT32* Crgtab = upsample->Cr_g_tab;
279  INT32* Cbgtab = upsample->Cb_g_tab;
281 
282  inptr00 = input_buf[0][in_row_group_ctr * 2];
283  inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
284  inptr1 = input_buf[1][in_row_group_ctr];
285  inptr2 = input_buf[2][in_row_group_ctr];
286  outptr0 = output_buf[0];
287  outptr1 = output_buf[1];
288  /* Loop for each group of output pixels */
289  for (col = cinfo->output_width >> 1; col > 0; col--)
290  {
291  /* Do the chroma part of the calculation */
292  cb = GETJSAMPLE(*inptr1++);
293  cr = GETJSAMPLE(*inptr2++);
294  cred = Crrtab[cr];
295  cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
296  cblue = Cbbtab[cb];
297  /* Fetch 4 Y values and emit 4 pixels */
298  y = GETJSAMPLE(*inptr00++);
299  outptr0[RGB_RED] = range_limit[y + cred];
300  outptr0[RGB_GREEN] = range_limit[y + cgreen];
301  outptr0[RGB_BLUE] = range_limit[y + cblue];
302  outptr0 += RGB_PIXELSIZE;
303  y = GETJSAMPLE(*inptr00++);
304  outptr0[RGB_RED] = range_limit[y + cred];
305  outptr0[RGB_GREEN] = range_limit[y + cgreen];
306  outptr0[RGB_BLUE] = range_limit[y + cblue];
307  outptr0 += RGB_PIXELSIZE;
308  y = GETJSAMPLE(*inptr01++);
309  outptr1[RGB_RED] = range_limit[y + cred];
310  outptr1[RGB_GREEN] = range_limit[y + cgreen];
311  outptr1[RGB_BLUE] = range_limit[y + cblue];
312  outptr1 += RGB_PIXELSIZE;
313  y = GETJSAMPLE(*inptr01++);
314  outptr1[RGB_RED] = range_limit[y + cred];
315  outptr1[RGB_GREEN] = range_limit[y + cgreen];
316  outptr1[RGB_BLUE] = range_limit[y + cblue];
317  outptr1 += RGB_PIXELSIZE;
318  }
319  /* If image width is odd, do the last output column separately */
320  if (cinfo->output_width & 1)
321  {
322  cb = GETJSAMPLE(*inptr1);
323  cr = GETJSAMPLE(*inptr2);
324  cred = Crrtab[cr];
325  cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
326  cblue = Cbbtab[cb];
327  y = GETJSAMPLE(*inptr00);
328  outptr0[RGB_RED] = range_limit[y + cred];
329  outptr0[RGB_GREEN] = range_limit[y + cgreen];
330  outptr0[RGB_BLUE] = range_limit[y + cblue];
331  y = GETJSAMPLE(*inptr01);
332  outptr1[RGB_RED] = range_limit[y + cred];
333  outptr1[RGB_GREEN] = range_limit[y + cgreen];
334  outptr1[RGB_BLUE] = range_limit[y + cblue];
335  }
336 }
337 
338 /*
339  * Module initialization routine for merged upsampling/color conversion.
340  *
341  * NB: this is called under the conditions determined by use_merged_upsample()
342  * in jdmaster.c. That routine MUST correspond to the actual capabilities
343  * of this module; no safety checks are made here.
344  */
345 
346 GLOBAL(void)
348 {
349  my_upsample_ptr upsample;
350 
351  upsample = (my_upsample_ptr)(*cinfo->mem->alloc_small)(
353  cinfo->upsample = (struct jpeg_upsampler*)upsample;
354  upsample->pub.start_pass = start_pass_merged_upsample;
355  upsample->pub.need_context_rows = FALSE;
356 
357  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
358 
359  if (cinfo->max_v_samp_factor == 2)
360  {
361  upsample->pub.upsample = merged_2v_upsample;
362  upsample->upmethod = h2v2_merged_upsample;
363  /* Allocate a spare row buffer */
364  upsample->spare_row = (JSAMPROW)(*cinfo->mem->alloc_large)(
365  (j_common_ptr)cinfo, JPOOL_IMAGE,
366  (size_t)(upsample->out_row_width * SIZEOF(JSAMPLE)));
367  }
368  else
369  {
370  upsample->pub.upsample = merged_1v_upsample;
371  upsample->upmethod = h2v1_merged_upsample;
372  /* No spare row needed */
373  upsample->spare_row = nullptr;
374  }
375 
376  build_ycc_rgb_table(cinfo);
377 }
378 
379 #endif /* UPSAMPLE_MERGING_SUPPORTED */
JSAMPLE * range_limit
Definition: jidctflt.cpp:46
#define CENTERJSAMPLE
Definition: jmorecfg.h:68
h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
Definition: jdmerge.cpp:264
build_ycc_rgb_table(j_decompress_ptr cinfo)
Definition: jdmerge.cpp:58
#define FIX(x)
Definition: jdmerge.cpp:50
char JSAMPLE
Definition: jmorecfg.h:58
jinit_merged_upsampler(j_decompress_ptr cinfo)
Definition: jdmerge.cpp:347
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
#define ONE_HALF
Definition: jdmerge.cpp:49
#define GETJSAMPLE(value)
Definition: jmorecfg.h:62
int * Cr_r_tab
Definition: jdmerge.cpp:29
for(ctr=DCTSIZE;ctr > 0;ctr--)
Definition: jidctflt.cpp:56
#define SIZEOF(object)
Definition: jinclude.h:74
#define MAXJSAMPLE
Definition: jmorecfg.h:67
JSAMPLE FAR * JSAMPROW
Definition: mrpt_jpeglib.h:60
struct jpeg_upsampler pub
Definition: jdmerge.cpp:21
long INT32
Definition: jmorecfg.h:151
#define SHIFT_TEMPS
Definition: jpegint.h:301
jcopy_sample_rows(JSAMPARRAY input_array, int source_row, JSAMPARRAY output_array, int dest_row, int num_rows, JDIMENSION num_cols)
Definition: jutils.cpp:96
JDIMENSION rows_to_go
Definition: jdmerge.cpp:43
int * Cb_b_tab
Definition: jdmerge.cpp:30
#define SCALEBITS
Definition: jdmerge.cpp:48
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
JSAMPROW outptr
Definition: jidctflt.cpp:45
#define FALSE
Definition: jmorecfg.h:216
jpeg_component_info JCOEFPTR JSAMPARRAY output_buf
Definition: jidctflt.cpp:36
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:750
#define LOCAL(type)
Definition: jmorecfg.h:175
INT32 * Cr_g_tab
Definition: jdmerge.cpp:31
JSAMPROW * JSAMPARRAY
Definition: mrpt_jpeglib.h:61
start_pass_merged_upsample(j_decompress_ptr cinfo)
Definition: jdmerge.cpp:97
boolean spare_full
Definition: jdmerge.cpp:40
#define JMETHOD(type, methodname, arglist)
Definition: jmorecfg.h:190
merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
Definition: jdmerge.cpp:169
merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
Definition: jdmerge.cpp:114
#define TRUE
Definition: jmorecfg.h:219
INT32 * Cb_g_tab
Definition: jdmerge.cpp:32
JSAMPROW spare_row
Definition: jdmerge.cpp:39
JSAMPARRAY * JSAMPIMAGE
Definition: mrpt_jpeglib.h:62
h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
Definition: jdmerge.cpp:201
#define GLOBAL(type)
Definition: jmorecfg.h:177
#define METHODDEF(type)
Definition: jmorecfg.h:173
#define RIGHT_SHIFT(x, shft)
Definition: jpegint.h:302
GLenum GLint GLint y
Definition: glext.h:3538
boolean need_context_rows
Definition: jpegint.h:253
my_upsampler * my_upsample_ptr
Definition: jdmerge.cpp:46
unsigned int JDIMENSION
Definition: jmorecfg.h:161
GLenum GLint x
Definition: glext.h:3538
JDIMENSION out_row_width
Definition: jdmerge.cpp:42



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019