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