Main MRPT website > C++ reference for MRPT 1.9.9
jcprepct.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 
14 /* At present, jcsample.c can request context rows only for smoothing.
15  * In the future, we might also need context rows for CCIR601 sampling
16  * or other more-complex downsampling procedures. The code to support
17  * context rows should be compiled only if needed.
18  */
19 #ifdef INPUT_SMOOTHING_SUPPORTED
20 #define CONTEXT_ROWS_SUPPORTED
21 #endif
22 
23 /*
24  * For the simple (no-context-row) case, we just need to buffer one
25  * row group's worth of pixels for the downsampling step. At the bottom of
26  * the image, we pad to a full row group by replicating the last pixel row.
27  * The downsampler's last output row is then replicated if needed to pad
28  * out to a full iMCU row.
29  *
30  * When providing context rows, we must buffer three row groups' worth of
31  * pixels. Three row groups are physically allocated, but the row pointer
32  * arrays are made five row groups high, with the extra pointers above and
33  * below "wrapping around" to point to the last and first real row groups.
34  * This allows the downsampler to access the proper context rows.
35  * At the top and bottom of the image, we create dummy context rows by
36  * copying the first or last real pixel row. This copying could be avoided
37  * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
38  * trouble on the compression side.
39  */
40 
41 /* Private buffer controller object */
42 
43 typedef struct
44 {
45  struct jpeg_c_prep_controller pub; /* public fields */
46 
47  /* Downsampling input buffer. This buffer holds color-converted data
48  * until we have enough to do a downsample step.
49  */
51 
52  JDIMENSION rows_to_go; /* counts rows remaining in source image */
53  int next_buf_row; /* index of next row to store in color_buf */
54 
55 #ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
56  int this_row_group; /* starting row index of group to process */
57  int next_buf_stop; /* downsample when we reach this index */
58 #endif
60 
62 
63 /*
64  * Initialize for a processing pass.
65  */
66 
67 METHODDEF(void)
69 {
70  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
71 
72  if (pass_mode != JBUF_PASS_THRU) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
73 
74  /* Initialize total-height counter for detecting bottom of image */
75  prep->rows_to_go = cinfo->image_height;
76  /* Mark the conversion buffer empty */
77  prep->next_buf_row = 0;
78 #ifdef CONTEXT_ROWS_SUPPORTED
79  /* Preset additional state variables for context mode.
80  * These aren't used in non-context mode, so we needn't test which mode.
81  */
82  prep->this_row_group = 0;
83  /* Set next_buf_stop to stop after two row groups have been read in. */
84  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
85 #endif
86 }
87 
88 /*
89  * Expand an image vertically from height input_rows to height output_rows,
90  * by duplicating the bottom row.
91  */
92 
93 LOCAL(void)
95  JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows, int output_rows)
96 {
97  int row;
98 
99  for (row = input_rows; row < output_rows; row++)
100  {
102  image_data, input_rows - 1, image_data, row, 1, num_cols);
103  }
104 }
105 
106 /*
107  * Process some data in the simple no-context case.
108  *
109  * Preprocessor output data is counted in "row groups". A row group
110  * is defined to be v_samp_factor sample rows of each component.
111  * Downsampling will produce this much data from each max_v_samp_factor
112  * input rows.
113  */
114 
115 METHODDEF(void)
117  j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION* in_row_ctr,
118  JDIMENSION in_rows_avail, JSAMPIMAGE output_buf,
119  JDIMENSION* out_row_group_ctr, JDIMENSION out_row_groups_avail)
120 {
121  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
122  int numrows, ci;
123  JDIMENSION inrows;
125 
126  while (*in_row_ctr < in_rows_avail &&
127  *out_row_group_ctr < out_row_groups_avail)
128  {
129  /* Do color conversion to fill the conversion buffer. */
130  inrows = in_rows_avail - *in_row_ctr;
131  numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
132  numrows = (int)MIN((JDIMENSION)numrows, inrows);
133  (*cinfo->cconvert->color_convert)(
134  cinfo, input_buf + *in_row_ctr, prep->color_buf,
135  (JDIMENSION)prep->next_buf_row, numrows);
136  *in_row_ctr += numrows;
137  prep->next_buf_row += numrows;
138  prep->rows_to_go -= numrows;
139  /* If at bottom of image, pad to fill the conversion buffer. */
140  if (prep->rows_to_go == 0 &&
141  prep->next_buf_row < cinfo->max_v_samp_factor)
142  {
143  for (ci = 0; ci < cinfo->num_components; ci++)
144  {
146  prep->color_buf[ci], cinfo->image_width, prep->next_buf_row,
147  cinfo->max_v_samp_factor);
148  }
149  prep->next_buf_row = cinfo->max_v_samp_factor;
150  }
151  /* If we've filled the conversion buffer, empty it. */
152  if (prep->next_buf_row == cinfo->max_v_samp_factor)
153  {
154  (*cinfo->downsample->downsample)(
155  cinfo, prep->color_buf, (JDIMENSION)0, output_buf,
156  *out_row_group_ctr);
157  prep->next_buf_row = 0;
158  (*out_row_group_ctr)++;
159  }
160  /* If at bottom of image, pad the output to a full iMCU height.
161  * Note we assume the caller is providing a one-iMCU-height output
162  * buffer!
163  */
164  if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail)
165  {
166  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
167  ci++, compptr++)
168  {
171  (int)(*out_row_group_ctr * compptr->v_samp_factor),
172  (int)(out_row_groups_avail * compptr->v_samp_factor));
173  }
174  *out_row_group_ctr = out_row_groups_avail;
175  break; /* can exit outer loop without test */
176  }
177  }
178 }
179 
180 #ifdef CONTEXT_ROWS_SUPPORTED
181 
182 /*
183  * Process some data in the context case.
184  */
185 
186 METHODDEF(void)
188  j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION* in_row_ctr,
189  JDIMENSION in_rows_avail, JSAMPIMAGE output_buf,
190  JDIMENSION* out_row_group_ctr, JDIMENSION out_row_groups_avail)
191 {
192  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
193  int numrows, ci;
194  int buf_height = cinfo->max_v_samp_factor * 3;
195  JDIMENSION inrows;
196 
197  while (*out_row_group_ctr < out_row_groups_avail)
198  {
199  if (*in_row_ctr < in_rows_avail)
200  {
201  /* Do color conversion to fill the conversion buffer. */
202  inrows = in_rows_avail - *in_row_ctr;
203  numrows = prep->next_buf_stop - prep->next_buf_row;
204  numrows = (int)MIN((JDIMENSION)numrows, inrows);
205  (*cinfo->cconvert->color_convert)(
206  cinfo, input_buf + *in_row_ctr, prep->color_buf,
207  (JDIMENSION)prep->next_buf_row, numrows);
208  /* Pad at top of image, if first time through */
209  if (prep->rows_to_go == cinfo->image_height)
210  {
211  for (ci = 0; ci < cinfo->num_components; ci++)
212  {
213  int row;
214  for (row = 1; row <= cinfo->max_v_samp_factor; row++)
215  {
217  prep->color_buf[ci], 0, prep->color_buf[ci], -row,
218  1, cinfo->image_width);
219  }
220  }
221  }
222  *in_row_ctr += numrows;
223  prep->next_buf_row += numrows;
224  prep->rows_to_go -= numrows;
225  }
226  else
227  {
228  /* Return for more data, unless we are at the bottom of the image.
229  */
230  if (prep->rows_to_go != 0) break;
231  /* When at bottom of image, pad to fill the conversion buffer. */
232  if (prep->next_buf_row < prep->next_buf_stop)
233  {
234  for (ci = 0; ci < cinfo->num_components; ci++)
235  {
237  prep->color_buf[ci], cinfo->image_width,
238  prep->next_buf_row, prep->next_buf_stop);
239  }
240  prep->next_buf_row = prep->next_buf_stop;
241  }
242  }
243  /* If we've gotten enough data, downsample a row group. */
244  if (prep->next_buf_row == prep->next_buf_stop)
245  {
246  (*cinfo->downsample->downsample)(
247  cinfo, prep->color_buf, (JDIMENSION)prep->this_row_group,
248  output_buf, *out_row_group_ctr);
249  (*out_row_group_ctr)++;
250  /* Advance pointers with wraparound as necessary. */
251  prep->this_row_group += cinfo->max_v_samp_factor;
252  if (prep->this_row_group >= buf_height) prep->this_row_group = 0;
253  if (prep->next_buf_row >= buf_height) prep->next_buf_row = 0;
254  prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
255  }
256  }
257 }
258 
259 /*
260  * Create the wrapped-around downsampling input buffer needed for context mode.
261  */
262 
263 LOCAL(void)
265 {
266  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
267  int rgroup_height = cinfo->max_v_samp_factor;
268  int ci, i;
270  JSAMPARRAY true_buffer, fake_buffer;
271 
272  /* Grab enough space for fake row pointers for all the components;
273  * we need five row groups' worth of pointers for each component.
274  */
275  fake_buffer = (JSAMPARRAY)(*cinfo->mem->alloc_small)(
276  (j_common_ptr)cinfo, JPOOL_IMAGE,
277  (cinfo->num_components * 5 * rgroup_height) * SIZEOF(JSAMPROW));
278 
279  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
280  ci++, compptr++)
281  {
282  /* Allocate the actual buffer space (3 row groups) for this component.
283  * We make the buffer wide enough to allow the downsampler to
284  * edge-expand
285  * horizontally within the buffer, if it so chooses.
286  */
287  true_buffer = (*cinfo->mem->alloc_sarray)(
288  (j_common_ptr)cinfo, JPOOL_IMAGE,
289  (JDIMENSION)(
290  ((long)compptr->width_in_blocks * DCTSIZE *
291  cinfo->max_h_samp_factor) /
293  (JDIMENSION)(3 * rgroup_height));
294  /* Copy true buffer row pointers into the middle of the fake row array
295  */
296  MEMCOPY(
297  fake_buffer + rgroup_height, true_buffer,
298  3 * rgroup_height * SIZEOF(JSAMPROW));
299  /* Fill in the above and below wraparound pointers */
300  for (i = 0; i < rgroup_height; i++)
301  {
302  fake_buffer[i] = true_buffer[2 * rgroup_height + i];
303  fake_buffer[4 * rgroup_height + i] = true_buffer[i];
304  }
305  prep->color_buf[ci] = fake_buffer + rgroup_height;
306  fake_buffer +=
307  5 * rgroup_height; /* point to space for next component */
308  }
309 }
310 
311 #endif /* CONTEXT_ROWS_SUPPORTED */
312 
313 /*
314  * Initialize preprocessing controller.
315  */
316 
317 GLOBAL(void)
318 jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
319 {
320  my_prep_ptr prep;
321  int ci;
323 
324  if (need_full_buffer) /* safety check */
325  ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
326 
327  prep = (my_prep_ptr)(*cinfo->mem->alloc_small)(
329  cinfo->prep = (struct jpeg_c_prep_controller*)prep;
330  prep->pub.start_pass = start_pass_prep;
331 
332  /* Allocate the color conversion buffer.
333  * We make the buffer wide enough to allow the downsampler to edge-expand
334  * horizontally within the buffer, if it so chooses.
335  */
336  if (cinfo->downsample->need_context_rows)
337  {
338 /* Set up to provide context rows */
339 #ifdef CONTEXT_ROWS_SUPPORTED
340  prep->pub.pre_process_data = pre_process_context;
341  create_context_buffer(cinfo);
342 #else
343  ERREXIT(cinfo, JERR_NOT_COMPILED);
344 #endif
345  }
346  else
347  {
348  /* No context, just make it tall enough for one row group */
349  prep->pub.pre_process_data = pre_process_data;
350  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
351  ci++, compptr++)
352  {
353  prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)(
354  (j_common_ptr)cinfo, JPOOL_IMAGE,
355  (JDIMENSION)(
356  ((long)compptr->width_in_blocks * DCTSIZE *
357  cinfo->max_h_samp_factor) /
359  (JDIMENSION)cinfo->max_v_samp_factor);
360  }
361  }
362 }
#define DCTSIZE
Definition: mrpt_jpeglib.h:36
JSAMPARRAY color_buf[MAX_COMPONENTS]
Definition: jcprepct.cpp:50
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
#define MAX_COMPONENTS
Definition: jmorecfg.h:30
#define MIN(a, b)
Definition: jpegint.h:282
#define ERREXIT(cinfo, code)
Definition: jerror.h:451
#define SIZEOF(object)
Definition: jinclude.h:74
JSAMPLE FAR * JSAMPROW
Definition: mrpt_jpeglib.h:60
JDIMENSION width_in_blocks
Definition: mrpt_jpeglib.h:132
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
#define MEMCOPY(dest, src, size)
Definition: jinclude.h:61
expand_bottom_edge(JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows, int output_rows)
Definition: jcprepct.cpp:94
jpeg_component_info JCOEFPTR JSAMPARRAY output_buf
Definition: jidctflt.cpp:36
struct jpeg_c_prep_controller pub
Definition: jcprepct.cpp:45
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:750
#define LOCAL(type)
Definition: jmorecfg.h:175
JSAMPROW * JSAMPARRAY
Definition: mrpt_jpeglib.h:61
jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
Definition: jcprepct.cpp:318
create_context_buffer(j_compress_ptr cinfo)
Definition: jcprepct.cpp:264
pre_process_context(j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail, JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, JDIMENSION out_row_groups_avail)
Definition: jcprepct.cpp:187
JSAMPARRAY * JSAMPIMAGE
Definition: mrpt_jpeglib.h:62
pre_process_data(j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail, JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, JDIMENSION out_row_groups_avail)
Definition: jcprepct.cpp:116
#define GLOBAL(type)
Definition: jmorecfg.h:177
GLenum GLenum GLvoid * row
Definition: glext.h:3576
#define METHODDEF(type)
Definition: jmorecfg.h:173
my_prep_controller * my_prep_ptr
Definition: jcprepct.cpp:61
start_pass_prep(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
Definition: jcprepct.cpp:68
J_BUF_MODE
Definition: jpegint.h:12
unsigned int JDIMENSION
Definition: jmorecfg.h:161
jpeg_component_info * compptr
Definition: jidctflt.cpp:36
JDIMENSION rows_to_go
Definition: jcprepct.cpp:52



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