1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
59
60
61
62
63
64
65
67
68
69
70
71
72
73
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
96
97
98
99
100
104
105
106
107
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
161
162
169
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
229
230
231
232
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
267
268
269
270
271
272
273
274
275
276
277
280
281
282
283
284
285
286
287
291
292
293
294
295
296
297
298
299
300
301
305
306
307
308
309
310
311
312
313
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
337
338
339
340
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/* ... */
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* ... */
#ifdef INPUT_SMOOTHING_SUPPORTED
#define CONTEXT_ROWS_SUPPORTED
#endif
/* ... */
typedef struct {
struct jpeg_c_prep_controller pub;
/* ... */
JSAMPARRAY color_buf[MAX_COMPONENTS];
JDIMENSION rows_to_go;
int next_buf_row;
#ifdef CONTEXT_ROWS_SUPPORTED
int this_row_group;
int next_buf_stop; /* ... */
#endif
...} my_prep_controller;
typedef my_prep_controller * my_prep_ptr;
/* ... */
METHODDEF(void)
start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
if (pass_mode != JBUF_PASS_THRU)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
prep->rows_to_go = cinfo->image_height;
prep->next_buf_row = 0;
#ifdef CONTEXT_ROWS_SUPPORTED
/* ... */
prep->this_row_group = 0;
prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;/* ... */
#endif
}{ ... }
/* ... */
LOCAL(void)
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
int input_rows, int output_rows)
{
register int row;
for (row = input_rows; row < output_rows; row++) {
jcopy_sample_rows(image_data, input_rows-1, image_data, row,
1, num_cols);
}for (row = input_rows; row < output_rows; row++) { ... }
}{ ... }
/* ... */
METHODDEF(void)
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)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
int numrows, ci;
JDIMENSION inrows;
jpeg_component_info * compptr;
while (*in_row_ctr < in_rows_avail &&
*out_row_group_ctr < out_row_groups_avail) {
inrows = in_rows_avail - *in_row_ctr;
numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
numrows = (int) MIN((JDIMENSION) numrows, inrows);
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
prep->color_buf,
(JDIMENSION) prep->next_buf_row,
numrows);
*in_row_ctr += numrows;
prep->next_buf_row += numrows;
prep->rows_to_go -= numrows;
if (prep->rows_to_go == 0 &&
prep->next_buf_row < cinfo->max_v_samp_factor) {
for (ci = 0; ci < cinfo->num_components; ci++) {
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
prep->next_buf_row, cinfo->max_v_samp_factor);
}for (ci = 0; ci < cinfo->num_components; ci++) { ... }
prep->next_buf_row = cinfo->max_v_samp_factor;
}if (prep->rows_to_go == 0 && prep->next_buf_row < cinfo->max_v_samp_factor) { ... }
if (prep->next_buf_row == cinfo->max_v_samp_factor) {
(*cinfo->downsample->downsample) (cinfo,
prep->color_buf, (JDIMENSION) 0,
output_buf, *out_row_group_ctr);
prep->next_buf_row = 0;
(*out_row_group_ctr)++;
}if (prep->next_buf_row == cinfo->max_v_samp_factor) { ... }
/* ... */
if (prep->rows_to_go == 0 &&
*out_row_group_ctr < out_row_groups_avail) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
numrows = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size;
expand_bottom_edge(output_buf[ci],
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(int) (*out_row_group_ctr * numrows),
(int) (out_row_groups_avail * numrows));
}for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { ... }
*out_row_group_ctr = out_row_groups_avail;
break;
}if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) { ... }
}while (*in_row_ctr < in_rows_avail && *out_row_group_ctr < out_row_groups_avail) { ... }
}{ ... }
#ifdef CONTEXT_ROWS_SUPPORTED
/* ... */
METHODDEF(void)
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)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
int numrows, ci;
int buf_height = cinfo->max_v_samp_factor * 3;
JDIMENSION inrows;
while (*out_row_group_ctr < out_row_groups_avail) {
if (*in_row_ctr < in_rows_avail) {
inrows = in_rows_avail - *in_row_ctr;
numrows = prep->next_buf_stop - prep->next_buf_row;
numrows = (int) MIN((JDIMENSION) numrows, inrows);
(*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
prep->color_buf,
(JDIMENSION) prep->next_buf_row,
numrows);
if (prep->rows_to_go == cinfo->image_height) {
for (ci = 0; ci < cinfo->num_components; ci++) {
int row;
for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
jcopy_sample_rows(prep->color_buf[ci], 0,
prep->color_buf[ci], -row,
1, cinfo->image_width);
}for (row = 1; row <= cinfo->max_v_samp_factor; row++) { ... }
}for (ci = 0; ci < cinfo->num_components; ci++) { ... }
}if (prep->rows_to_go == cinfo->image_height) { ... }
*in_row_ctr += numrows;
prep->next_buf_row += numrows;
prep->rows_to_go -= numrows;
}if (*in_row_ctr < in_rows_avail) { ... } else {
if (prep->rows_to_go != 0)
break;
if (prep->next_buf_row < prep->next_buf_stop) {
for (ci = 0; ci < cinfo->num_components; ci++) {
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
prep->next_buf_row, prep->next_buf_stop);
}for (ci = 0; ci < cinfo->num_components; ci++) { ... }
prep->next_buf_row = prep->next_buf_stop;
}if (prep->next_buf_row < prep->next_buf_stop) { ... }
}else { ... }
if (prep->next_buf_row == prep->next_buf_stop) {
(*cinfo->downsample->downsample) (cinfo,
prep->color_buf,
(JDIMENSION) prep->this_row_group,
output_buf, *out_row_group_ctr);
(*out_row_group_ctr)++;
prep->this_row_group += cinfo->max_v_samp_factor;
if (prep->this_row_group >= buf_height)
prep->this_row_group = 0;
if (prep->next_buf_row >= buf_height)
prep->next_buf_row = 0;
prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
}if (prep->next_buf_row == prep->next_buf_stop) { ... }
}while (*out_row_group_ctr < out_row_groups_avail) { ... }
}{ ... }
/* ... */
LOCAL(void)
create_context_buffer (j_compress_ptr cinfo)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
int rgroup_height = cinfo->max_v_samp_factor;
int ci, i;
jpeg_component_info * compptr;
JSAMPARRAY true_buffer, fake_buffer;
/* ... */
fake_buffer = (JSAMPARRAY)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(cinfo->num_components * 5 * rgroup_height) *
SIZEOF(JSAMPROW));
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* ... */
true_buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (((long) compptr->width_in_blocks *
cinfo->min_DCT_h_scaled_size *
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
(JDIMENSION) (3 * rgroup_height));
MEMCOPY(fake_buffer + rgroup_height, true_buffer,
3 * rgroup_height * SIZEOF(JSAMPROW));
for (i = 0; i < rgroup_height; i++) {
fake_buffer[i] = true_buffer[2 * rgroup_height + i];
fake_buffer[4 * rgroup_height + i] = true_buffer[i];
}for (i = 0; i < rgroup_height; i++) { ... }
prep->color_buf[ci] = fake_buffer + rgroup_height;
fake_buffer += 5 * rgroup_height;
}for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { ... }
}{ ... }
/* ... */#endif
/* ... */
GLOBAL(void)
jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{
my_prep_ptr prep;
int ci;
jpeg_component_info * compptr;
if (need_full_buffer)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
prep = (my_prep_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_prep_controller));
cinfo->prep = (struct jpeg_c_prep_controller *) prep;
prep->pub.start_pass = start_pass_prep;
/* ... */
if (cinfo->downsample->need_context_rows) {
#ifdef CONTEXT_ROWS_SUPPORTED
prep->pub.pre_process_data = pre_process_context;
create_context_buffer(cinfo);/* ... */
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}if (cinfo->downsample->need_context_rows) { ... } else {
prep->pub.pre_process_data = pre_process_data;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (((long) compptr->width_in_blocks *
cinfo->min_DCT_h_scaled_size *
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
(JDIMENSION) cinfo->max_v_samp_factor);
}for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { ... }
}else { ... }
}{ ... }