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