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



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019