Coverage Report

Created: 2026-03-12 08:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjpeg-turbo.main/src/jcprepct.c
Line
Count
Source
1
/*
2
 * jcprepct.c
3
 *
4
 * This file was part of the Independent JPEG Group's software:
5
 * Copyright (C) 1994-1996, Thomas G. Lane.
6
 * Lossless JPEG Modifications:
7
 * Copyright (C) 1999, Ken Murchison.
8
 * libjpeg-turbo Modifications:
9
 * Copyright (C) 2022, 2024, 2026, D. R. Commander.
10
 * For conditions of distribution and use, see the accompanying README.ijg
11
 * file.
12
 *
13
 * This file contains the compression preprocessing controller.
14
 * This controller manages the color conversion, downsampling,
15
 * and edge expansion steps.
16
 *
17
 * Most of the complexity here is associated with buffering input rows
18
 * as required by the downsampler.  See the comments at the head of
19
 * jcsample.c for the downsampler's needs.
20
 */
21
22
#define JPEG_INTERNALS
23
#include "jinclude.h"
24
#include "jpeglib.h"
25
#include "jsamplecomp.h"
26
27
28
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
29
30
/* At present, jcsample.c can request context rows only for smoothing.
31
 * In the future, we might also need context rows for CCIR601 sampling
32
 * or other more-complex downsampling procedures.  The code to support
33
 * context rows should be compiled only if needed.
34
 */
35
#ifdef INPUT_SMOOTHING_SUPPORTED
36
#define CONTEXT_ROWS_SUPPORTED
37
#endif
38
39
40
/*
41
 * For the simple (no-context-row) case, we just need to buffer one row group's
42
 * worth of components for the downsampling step.  At the bottom of the image,
43
 * we pad to a full row group by replicating the last component row(s).  The
44
 * downsampler's last output row is then replicated if needed to pad out to a
45
 * full iMCU row.
46
 *
47
 * When providing context rows, we must buffer three row groups' worth of
48
 * components.  Three row groups are physically allocated, but the row pointer
49
 * arrays are made five row groups high, with the extra pointers above and
50
 * below "wrapping around" to point to the last and first real row groups.
51
 * This allows the downsampler to access the proper context rows.  At the top
52
 * and bottom of the image, we create dummy context rows by copying the first
53
 * or last real component row(s).  This copying could be avoided by pointer
54
 * hacking, as is done in jdmainct.c, but it doesn't seem worth the trouble on
55
 * the compression side.
56
 */
57
58
59
/* Private buffer controller object */
60
61
typedef struct {
62
  struct jpeg_c_prep_controller pub; /* public fields */
63
64
  /* Downsampling input buffer.  This buffer holds color-converted data
65
   * until we have enough to do a downsample step.
66
   */
67
  _JSAMPARRAY color_buf[MAX_COMPONENTS];
68
69
  JDIMENSION rows_to_go;        /* counts rows remaining in source image */
70
  int next_buf_row;             /* index of next row to store in color_buf */
71
72
#ifdef CONTEXT_ROWS_SUPPORTED   /* only needed for context case */
73
  int this_row_group;           /* starting row index of group to process */
74
  int next_buf_stop;            /* downsample when we reach this index */
75
#endif
76
} my_prep_controller;
77
78
typedef my_prep_controller *my_prep_ptr;
79
80
81
/*
82
 * Initialize for a processing pass.
83
 */
84
85
METHODDEF(void)
86
start_pass_prep(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
87
94.9k
{
88
94.9k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
89
90
94.9k
  if (pass_mode != JBUF_PASS_THRU)
91
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
92
93
  /* Initialize total-height counter for detecting bottom of image */
94
94.9k
  prep->rows_to_go = cinfo->image_height;
95
  /* Mark the conversion buffer empty */
96
94.9k
  prep->next_buf_row = 0;
97
94.9k
#ifdef CONTEXT_ROWS_SUPPORTED
98
  /* Preset additional state variables for context mode.
99
   * These aren't used in non-context mode, so we needn't test which mode.
100
   */
101
94.9k
  prep->this_row_group = 0;
102
  /* Set next_buf_stop to stop after two row groups have been read in. */
103
94.9k
  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
104
94.9k
#endif
105
94.9k
}
jcprepct-8.c:start_pass_prep
Line
Count
Source
87
46.0k
{
88
46.0k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
89
90
46.0k
  if (pass_mode != JBUF_PASS_THRU)
91
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
92
93
  /* Initialize total-height counter for detecting bottom of image */
94
46.0k
  prep->rows_to_go = cinfo->image_height;
95
  /* Mark the conversion buffer empty */
96
46.0k
  prep->next_buf_row = 0;
97
46.0k
#ifdef CONTEXT_ROWS_SUPPORTED
98
  /* Preset additional state variables for context mode.
99
   * These aren't used in non-context mode, so we needn't test which mode.
100
   */
101
46.0k
  prep->this_row_group = 0;
102
  /* Set next_buf_stop to stop after two row groups have been read in. */
103
46.0k
  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
104
46.0k
#endif
105
46.0k
}
jcprepct-12.c:start_pass_prep
Line
Count
Source
87
37.5k
{
88
37.5k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
89
90
37.5k
  if (pass_mode != JBUF_PASS_THRU)
91
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
92
93
  /* Initialize total-height counter for detecting bottom of image */
94
37.5k
  prep->rows_to_go = cinfo->image_height;
95
  /* Mark the conversion buffer empty */
96
37.5k
  prep->next_buf_row = 0;
97
37.5k
#ifdef CONTEXT_ROWS_SUPPORTED
98
  /* Preset additional state variables for context mode.
99
   * These aren't used in non-context mode, so we needn't test which mode.
100
   */
101
37.5k
  prep->this_row_group = 0;
102
  /* Set next_buf_stop to stop after two row groups have been read in. */
103
37.5k
  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
104
37.5k
#endif
105
37.5k
}
jcprepct-16.c:start_pass_prep
Line
Count
Source
87
11.3k
{
88
11.3k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
89
90
11.3k
  if (pass_mode != JBUF_PASS_THRU)
91
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
92
93
  /* Initialize total-height counter for detecting bottom of image */
94
11.3k
  prep->rows_to_go = cinfo->image_height;
95
  /* Mark the conversion buffer empty */
96
11.3k
  prep->next_buf_row = 0;
97
11.3k
#ifdef CONTEXT_ROWS_SUPPORTED
98
  /* Preset additional state variables for context mode.
99
   * These aren't used in non-context mode, so we needn't test which mode.
100
   */
101
11.3k
  prep->this_row_group = 0;
102
  /* Set next_buf_stop to stop after two row groups have been read in. */
103
11.3k
  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
104
11.3k
#endif
105
11.3k
}
106
107
108
/*
109
 * Expand an image vertically from height input_rows to height output_rows,
110
 * by duplicating the bottom row.
111
 */
112
113
LOCAL(void)
114
expand_bottom_edge(_JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows,
115
                   int output_rows)
116
162k
{
117
162k
  register int row;
118
119
998k
  for (row = input_rows; row < output_rows; row++) {
120
835k
    _jcopy_sample_rows(image_data, input_rows - 1, image_data, row, 1,
121
835k
                       num_cols);
122
835k
  }
123
162k
}
jcprepct-8.c:expand_bottom_edge
Line
Count
Source
116
85.8k
{
117
85.8k
  register int row;
118
119
523k
  for (row = input_rows; row < output_rows; row++) {
120
437k
    _jcopy_sample_rows(image_data, input_rows - 1, image_data, row, 1,
121
437k
                       num_cols);
122
437k
  }
123
85.8k
}
jcprepct-12.c:expand_bottom_edge
Line
Count
Source
116
76.2k
{
117
76.2k
  register int row;
118
119
474k
  for (row = input_rows; row < output_rows; row++) {
120
398k
    _jcopy_sample_rows(image_data, input_rows - 1, image_data, row, 1,
121
398k
                       num_cols);
122
398k
  }
123
76.2k
}
Unexecuted instantiation: jcprepct-16.c:expand_bottom_edge
124
125
126
/*
127
 * Process some data in the simple no-context case.
128
 *
129
 * Preprocessor output data is counted in "row groups".  A row group
130
 * is defined to be v_samp_factor sample rows of each component.
131
 * Downsampling will produce this much data from each max_v_samp_factor
132
 * input rows.
133
 */
134
135
METHODDEF(void)
136
pre_process_data(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
137
                 JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail,
138
                 _JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
139
                 JDIMENSION out_row_groups_avail)
140
113M
{
141
113M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
142
113M
  int numrows, ci;
143
113M
  JDIMENSION inrows;
144
113M
  jpeg_component_info *compptr;
145
113M
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
146
147
355M
  while (*in_row_ctr < in_rows_avail &&
148
351M
         *out_row_group_ctr < out_row_groups_avail) {
149
    /* Do color conversion to fill the conversion buffer. */
150
241M
    inrows = in_rows_avail - *in_row_ctr;
151
241M
    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
152
241M
    numrows = (int)MIN((JDIMENSION)numrows, inrows);
153
241M
    (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
154
241M
                                        prep->color_buf,
155
241M
                                        (JDIMENSION)prep->next_buf_row,
156
241M
                                        numrows);
157
241M
    *in_row_ctr += numrows;
158
241M
    prep->next_buf_row += numrows;
159
241M
    prep->rows_to_go -= numrows;
160
    /* If at bottom of image, pad to fill the conversion buffer. */
161
241M
    if (prep->rows_to_go == 0 &&
162
90.1k
        prep->next_buf_row < cinfo->max_v_samp_factor) {
163
36.2k
      for (ci = 0; ci < cinfo->num_components; ci++) {
164
28.1k
        expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
165
28.1k
                           prep->next_buf_row, cinfo->max_v_samp_factor);
166
28.1k
      }
167
8.08k
      prep->next_buf_row = cinfo->max_v_samp_factor;
168
8.08k
    }
169
    /* If we've filled the conversion buffer, empty it. */
170
241M
    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
171
239M
      (*cinfo->downsample->_downsample) (cinfo,
172
239M
                                         prep->color_buf, (JDIMENSION)0,
173
239M
                                         output_buf, *out_row_group_ctr);
174
239M
      prep->next_buf_row = 0;
175
239M
      (*out_row_group_ctr)++;
176
239M
    }
177
    /* If at bottom of image, pad the output to a full iMCU height.
178
     * Note we assume the caller is providing a one-iMCU-height output buffer!
179
     */
180
241M
    if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) {
181
174k
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
182
125k
           ci++, compptr++) {
183
125k
        expand_bottom_edge(output_buf[ci],
184
125k
                           compptr->width_in_blocks * data_unit,
185
125k
                           (int)(*out_row_group_ctr * compptr->v_samp_factor),
186
125k
                           (int)(out_row_groups_avail * compptr->v_samp_factor));
187
125k
      }
188
48.2k
      *out_row_group_ctr = out_row_groups_avail;
189
48.2k
      break;                    /* can exit outer loop without test */
190
48.2k
    }
191
241M
  }
192
113M
}
jcprepct-8.c:pre_process_data
Line
Count
Source
140
42.3M
{
141
42.3M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
142
42.3M
  int numrows, ci;
143
42.3M
  JDIMENSION inrows;
144
42.3M
  jpeg_component_info *compptr;
145
42.3M
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
146
147
143M
  while (*in_row_ctr < in_rows_avail &&
148
139M
         *out_row_group_ctr < out_row_groups_avail) {
149
    /* Do color conversion to fill the conversion buffer. */
150
101M
    inrows = in_rows_avail - *in_row_ctr;
151
101M
    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
152
101M
    numrows = (int)MIN((JDIMENSION)numrows, inrows);
153
101M
    (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
154
101M
                                        prep->color_buf,
155
101M
                                        (JDIMENSION)prep->next_buf_row,
156
101M
                                        numrows);
157
101M
    *in_row_ctr += numrows;
158
101M
    prep->next_buf_row += numrows;
159
101M
    prep->rows_to_go -= numrows;
160
    /* If at bottom of image, pad to fill the conversion buffer. */
161
101M
    if (prep->rows_to_go == 0 &&
162
41.2k
        prep->next_buf_row < cinfo->max_v_samp_factor) {
163
17.7k
      for (ci = 0; ci < cinfo->num_components; ci++) {
164
13.7k
        expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
165
13.7k
                           prep->next_buf_row, cinfo->max_v_samp_factor);
166
13.7k
      }
167
3.96k
      prep->next_buf_row = cinfo->max_v_samp_factor;
168
3.96k
    }
169
    /* If we've filled the conversion buffer, empty it. */
170
101M
    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
171
99.3M
      (*cinfo->downsample->_downsample) (cinfo,
172
99.3M
                                         prep->color_buf, (JDIMENSION)0,
173
99.3M
                                         output_buf, *out_row_group_ctr);
174
99.3M
      prep->next_buf_row = 0;
175
99.3M
      (*out_row_group_ctr)++;
176
99.3M
    }
177
    /* If at bottom of image, pad the output to a full iMCU height.
178
     * Note we assume the caller is providing a one-iMCU-height output buffer!
179
     */
180
101M
    if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) {
181
88.4k
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
182
63.9k
           ci++, compptr++) {
183
63.9k
        expand_bottom_edge(output_buf[ci],
184
63.9k
                           compptr->width_in_blocks * data_unit,
185
63.9k
                           (int)(*out_row_group_ctr * compptr->v_samp_factor),
186
63.9k
                           (int)(out_row_groups_avail * compptr->v_samp_factor));
187
63.9k
      }
188
24.5k
      *out_row_group_ctr = out_row_groups_avail;
189
24.5k
      break;                    /* can exit outer loop without test */
190
24.5k
    }
191
101M
  }
192
42.3M
}
jcprepct-12.c:pre_process_data
Line
Count
Source
140
39.5M
{
141
39.5M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
142
39.5M
  int numrows, ci;
143
39.5M
  JDIMENSION inrows;
144
39.5M
  jpeg_component_info *compptr;
145
39.5M
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
146
147
148M
  while (*in_row_ctr < in_rows_avail &&
148
148M
         *out_row_group_ctr < out_row_groups_avail) {
149
    /* Do color conversion to fill the conversion buffer. */
150
108M
    inrows = in_rows_avail - *in_row_ctr;
151
108M
    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
152
108M
    numrows = (int)MIN((JDIMENSION)numrows, inrows);
153
108M
    (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
154
108M
                                        prep->color_buf,
155
108M
                                        (JDIMENSION)prep->next_buf_row,
156
108M
                                        numrows);
157
108M
    *in_row_ctr += numrows;
158
108M
    prep->next_buf_row += numrows;
159
108M
    prep->rows_to_go -= numrows;
160
    /* If at bottom of image, pad to fill the conversion buffer. */
161
108M
    if (prep->rows_to_go == 0 &&
162
37.5k
        prep->next_buf_row < cinfo->max_v_samp_factor) {
163
18.5k
      for (ci = 0; ci < cinfo->num_components; ci++) {
164
14.4k
        expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
165
14.4k
                           prep->next_buf_row, cinfo->max_v_samp_factor);
166
14.4k
      }
167
4.11k
      prep->next_buf_row = cinfo->max_v_samp_factor;
168
4.11k
    }
169
    /* If we've filled the conversion buffer, empty it. */
170
108M
    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
171
108M
      (*cinfo->downsample->_downsample) (cinfo,
172
108M
                                         prep->color_buf, (JDIMENSION)0,
173
108M
                                         output_buf, *out_row_group_ctr);
174
108M
      prep->next_buf_row = 0;
175
108M
      (*out_row_group_ctr)++;
176
108M
    }
177
    /* If at bottom of image, pad the output to a full iMCU height.
178
     * Note we assume the caller is providing a one-iMCU-height output buffer!
179
     */
180
108M
    if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) {
181
85.5k
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
182
61.8k
           ci++, compptr++) {
183
61.8k
        expand_bottom_edge(output_buf[ci],
184
61.8k
                           compptr->width_in_blocks * data_unit,
185
61.8k
                           (int)(*out_row_group_ctr * compptr->v_samp_factor),
186
61.8k
                           (int)(out_row_groups_avail * compptr->v_samp_factor));
187
61.8k
      }
188
23.7k
      *out_row_group_ctr = out_row_groups_avail;
189
23.7k
      break;                    /* can exit outer loop without test */
190
23.7k
    }
191
108M
  }
192
39.5M
}
jcprepct-16.c:pre_process_data
Line
Count
Source
140
31.6M
{
141
31.6M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
142
31.6M
  int numrows, ci;
143
31.6M
  JDIMENSION inrows;
144
31.6M
  jpeg_component_info *compptr;
145
31.6M
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
146
147
63.2M
  while (*in_row_ctr < in_rows_avail &&
148
63.2M
         *out_row_group_ctr < out_row_groups_avail) {
149
    /* Do color conversion to fill the conversion buffer. */
150
31.6M
    inrows = in_rows_avail - *in_row_ctr;
151
31.6M
    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
152
31.6M
    numrows = (int)MIN((JDIMENSION)numrows, inrows);
153
31.6M
    (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
154
31.6M
                                        prep->color_buf,
155
31.6M
                                        (JDIMENSION)prep->next_buf_row,
156
31.6M
                                        numrows);
157
31.6M
    *in_row_ctr += numrows;
158
31.6M
    prep->next_buf_row += numrows;
159
31.6M
    prep->rows_to_go -= numrows;
160
    /* If at bottom of image, pad to fill the conversion buffer. */
161
31.6M
    if (prep->rows_to_go == 0 &&
162
11.3k
        prep->next_buf_row < cinfo->max_v_samp_factor) {
163
0
      for (ci = 0; ci < cinfo->num_components; ci++) {
164
0
        expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
165
0
                           prep->next_buf_row, cinfo->max_v_samp_factor);
166
0
      }
167
0
      prep->next_buf_row = cinfo->max_v_samp_factor;
168
0
    }
169
    /* If we've filled the conversion buffer, empty it. */
170
31.6M
    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
171
31.6M
      (*cinfo->downsample->_downsample) (cinfo,
172
31.6M
                                         prep->color_buf, (JDIMENSION)0,
173
31.6M
                                         output_buf, *out_row_group_ctr);
174
31.6M
      prep->next_buf_row = 0;
175
31.6M
      (*out_row_group_ctr)++;
176
31.6M
    }
177
    /* If at bottom of image, pad the output to a full iMCU height.
178
     * Note we assume the caller is providing a one-iMCU-height output buffer!
179
     */
180
31.6M
    if (prep->rows_to_go == 0 && *out_row_group_ctr < out_row_groups_avail) {
181
0
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
182
0
           ci++, compptr++) {
183
0
        expand_bottom_edge(output_buf[ci],
184
0
                           compptr->width_in_blocks * data_unit,
185
0
                           (int)(*out_row_group_ctr * compptr->v_samp_factor),
186
0
                           (int)(out_row_groups_avail * compptr->v_samp_factor));
187
0
      }
188
0
      *out_row_group_ctr = out_row_groups_avail;
189
0
      break;                    /* can exit outer loop without test */
190
0
    }
191
31.6M
  }
192
31.6M
}
193
194
195
#ifdef CONTEXT_ROWS_SUPPORTED
196
197
/*
198
 * Process some data in the context case.
199
 */
200
201
METHODDEF(void)
202
pre_process_context(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
203
                    JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail,
204
                    _JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
205
                    JDIMENSION out_row_groups_avail)
206
3.86M
{
207
3.86M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
208
3.86M
  int numrows, ci;
209
3.86M
  int buf_height = cinfo->max_v_samp_factor * 3;
210
3.86M
  JDIMENSION inrows;
211
212
7.49M
  while (*out_row_group_ctr < out_row_groups_avail) {
213
7.24M
    if (*in_row_ctr < in_rows_avail) {
214
      /* Do color conversion to fill the conversion buffer. */
215
3.62M
      inrows = in_rows_avail - *in_row_ctr;
216
3.62M
      numrows = prep->next_buf_stop - prep->next_buf_row;
217
3.62M
      numrows = (int)MIN((JDIMENSION)numrows, inrows);
218
3.62M
      (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
219
3.62M
                                          prep->color_buf,
220
3.62M
                                          (JDIMENSION)prep->next_buf_row,
221
3.62M
                                          numrows);
222
      /* Pad at top of image, if first time through */
223
3.62M
      if (prep->rows_to_go == cinfo->image_height) {
224
3.78k
        for (ci = 0; ci < cinfo->num_components; ci++) {
225
2.59k
          int row;
226
7.28k
          for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
227
4.69k
            _jcopy_sample_rows(prep->color_buf[ci], 0, prep->color_buf[ci],
228
4.69k
                               -row, 1, cinfo->image_width);
229
4.69k
          }
230
2.59k
        }
231
1.18k
      }
232
3.62M
      *in_row_ctr += numrows;
233
3.62M
      prep->next_buf_row += numrows;
234
3.62M
      prep->rows_to_go -= numrows;
235
3.62M
    } else {
236
      /* Return for more data, unless we are at the bottom of the image. */
237
3.62M
      if (prep->rows_to_go != 0)
238
3.62M
        break;
239
      /* When at bottom of image, pad to fill the conversion buffer. */
240
3.47k
      if (prep->next_buf_row < prep->next_buf_stop) {
241
11.5k
        for (ci = 0; ci < cinfo->num_components; ci++) {
242
8.05k
          expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
243
8.05k
                             prep->next_buf_row, prep->next_buf_stop);
244
8.05k
        }
245
3.47k
        prep->next_buf_row = prep->next_buf_stop;
246
3.47k
      }
247
3.47k
    }
248
    /* If we've gotten enough data, downsample a row group. */
249
3.62M
    if (prep->next_buf_row == prep->next_buf_stop) {
250
1.98M
      (*cinfo->downsample->_downsample) (cinfo, prep->color_buf,
251
1.98M
                                         (JDIMENSION)prep->this_row_group,
252
1.98M
                                         output_buf, *out_row_group_ctr);
253
1.98M
      (*out_row_group_ctr)++;
254
      /* Advance pointers with wraparound as necessary. */
255
1.98M
      prep->this_row_group += cinfo->max_v_samp_factor;
256
1.98M
      if (prep->this_row_group >= buf_height)
257
661k
        prep->this_row_group = 0;
258
1.98M
      if (prep->next_buf_row >= buf_height)
259
661k
        prep->next_buf_row = 0;
260
1.98M
      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
261
1.98M
    }
262
3.62M
  }
263
3.86M
}
jcprepct-8.c:pre_process_context
Line
Count
Source
206
3.86M
{
207
3.86M
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
208
3.86M
  int numrows, ci;
209
3.86M
  int buf_height = cinfo->max_v_samp_factor * 3;
210
3.86M
  JDIMENSION inrows;
211
212
7.49M
  while (*out_row_group_ctr < out_row_groups_avail) {
213
7.24M
    if (*in_row_ctr < in_rows_avail) {
214
      /* Do color conversion to fill the conversion buffer. */
215
3.62M
      inrows = in_rows_avail - *in_row_ctr;
216
3.62M
      numrows = prep->next_buf_stop - prep->next_buf_row;
217
3.62M
      numrows = (int)MIN((JDIMENSION)numrows, inrows);
218
3.62M
      (*cinfo->cconvert->_color_convert) (cinfo, input_buf + *in_row_ctr,
219
3.62M
                                          prep->color_buf,
220
3.62M
                                          (JDIMENSION)prep->next_buf_row,
221
3.62M
                                          numrows);
222
      /* Pad at top of image, if first time through */
223
3.62M
      if (prep->rows_to_go == cinfo->image_height) {
224
3.78k
        for (ci = 0; ci < cinfo->num_components; ci++) {
225
2.59k
          int row;
226
7.28k
          for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
227
4.69k
            _jcopy_sample_rows(prep->color_buf[ci], 0, prep->color_buf[ci],
228
4.69k
                               -row, 1, cinfo->image_width);
229
4.69k
          }
230
2.59k
        }
231
1.18k
      }
232
3.62M
      *in_row_ctr += numrows;
233
3.62M
      prep->next_buf_row += numrows;
234
3.62M
      prep->rows_to_go -= numrows;
235
3.62M
    } else {
236
      /* Return for more data, unless we are at the bottom of the image. */
237
3.62M
      if (prep->rows_to_go != 0)
238
3.62M
        break;
239
      /* When at bottom of image, pad to fill the conversion buffer. */
240
3.47k
      if (prep->next_buf_row < prep->next_buf_stop) {
241
11.5k
        for (ci = 0; ci < cinfo->num_components; ci++) {
242
8.05k
          expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
243
8.05k
                             prep->next_buf_row, prep->next_buf_stop);
244
8.05k
        }
245
3.47k
        prep->next_buf_row = prep->next_buf_stop;
246
3.47k
      }
247
3.47k
    }
248
    /* If we've gotten enough data, downsample a row group. */
249
3.62M
    if (prep->next_buf_row == prep->next_buf_stop) {
250
1.98M
      (*cinfo->downsample->_downsample) (cinfo, prep->color_buf,
251
1.98M
                                         (JDIMENSION)prep->this_row_group,
252
1.98M
                                         output_buf, *out_row_group_ctr);
253
1.98M
      (*out_row_group_ctr)++;
254
      /* Advance pointers with wraparound as necessary. */
255
1.98M
      prep->this_row_group += cinfo->max_v_samp_factor;
256
1.98M
      if (prep->this_row_group >= buf_height)
257
661k
        prep->this_row_group = 0;
258
1.98M
      if (prep->next_buf_row >= buf_height)
259
661k
        prep->next_buf_row = 0;
260
1.98M
      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
261
1.98M
    }
262
3.62M
  }
263
3.86M
}
Unexecuted instantiation: jcprepct-12.c:pre_process_context
Unexecuted instantiation: jcprepct-16.c:pre_process_context
264
265
266
/*
267
 * Create the wrapped-around downsampling input buffer needed for context mode.
268
 */
269
270
LOCAL(void)
271
create_context_buffer(j_compress_ptr cinfo)
272
2.72k
{
273
2.72k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
274
2.72k
  int rgroup_height = cinfo->max_v_samp_factor;
275
2.72k
  int ci, i;
276
2.72k
  jpeg_component_info *compptr;
277
2.72k
  _JSAMPARRAY true_buffer, fake_buffer;
278
2.72k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
279
280
  /* Grab enough space for fake row pointers for all the components;
281
   * we need five row groups' worth of pointers for each component.
282
   */
283
2.72k
  fake_buffer = (_JSAMPARRAY)
284
2.72k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
285
2.72k
                                (cinfo->num_components * 5 * rgroup_height) *
286
2.72k
                                sizeof(_JSAMPROW));
287
288
8.95k
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
289
6.23k
       ci++, compptr++) {
290
    /* Allocate the actual buffer space (3 row groups) for this component.
291
     * We make the buffer wide enough to allow the downsampler to edge-expand
292
     * horizontally within the buffer, if it so chooses.
293
     */
294
6.23k
    true_buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
295
6.23k
      ((j_common_ptr)cinfo, JPOOL_IMAGE,
296
6.23k
       (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
297
6.23k
                     cinfo->max_h_samp_factor) / compptr->h_samp_factor),
298
6.23k
       (JDIMENSION)(3 * rgroup_height));
299
    /* Copy true buffer row pointers into the middle of the fake row array */
300
6.23k
    memcpy(fake_buffer + rgroup_height, true_buffer,
301
6.23k
           3 * rgroup_height * sizeof(_JSAMPROW));
302
    /* Fill in the above and below wraparound pointers */
303
17.7k
    for (i = 0; i < rgroup_height; i++) {
304
11.4k
      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
305
11.4k
      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
306
11.4k
    }
307
6.23k
    prep->color_buf[ci] = fake_buffer + rgroup_height;
308
6.23k
    fake_buffer += 5 * rgroup_height; /* point to space for next component */
309
6.23k
  }
310
2.72k
}
jcprepct-8.c:create_context_buffer
Line
Count
Source
272
2.72k
{
273
2.72k
  my_prep_ptr prep = (my_prep_ptr)cinfo->prep;
274
2.72k
  int rgroup_height = cinfo->max_v_samp_factor;
275
2.72k
  int ci, i;
276
2.72k
  jpeg_component_info *compptr;
277
2.72k
  _JSAMPARRAY true_buffer, fake_buffer;
278
2.72k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
279
280
  /* Grab enough space for fake row pointers for all the components;
281
   * we need five row groups' worth of pointers for each component.
282
   */
283
2.72k
  fake_buffer = (_JSAMPARRAY)
284
2.72k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
285
2.72k
                                (cinfo->num_components * 5 * rgroup_height) *
286
2.72k
                                sizeof(_JSAMPROW));
287
288
8.95k
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
289
6.23k
       ci++, compptr++) {
290
    /* Allocate the actual buffer space (3 row groups) for this component.
291
     * We make the buffer wide enough to allow the downsampler to edge-expand
292
     * horizontally within the buffer, if it so chooses.
293
     */
294
6.23k
    true_buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
295
6.23k
      ((j_common_ptr)cinfo, JPOOL_IMAGE,
296
6.23k
       (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
297
6.23k
                     cinfo->max_h_samp_factor) / compptr->h_samp_factor),
298
6.23k
       (JDIMENSION)(3 * rgroup_height));
299
    /* Copy true buffer row pointers into the middle of the fake row array */
300
6.23k
    memcpy(fake_buffer + rgroup_height, true_buffer,
301
6.23k
           3 * rgroup_height * sizeof(_JSAMPROW));
302
    /* Fill in the above and below wraparound pointers */
303
17.7k
    for (i = 0; i < rgroup_height; i++) {
304
11.4k
      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
305
11.4k
      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
306
11.4k
    }
307
6.23k
    prep->color_buf[ci] = fake_buffer + rgroup_height;
308
6.23k
    fake_buffer += 5 * rgroup_height; /* point to space for next component */
309
6.23k
  }
310
2.72k
}
Unexecuted instantiation: jcprepct-12.c:create_context_buffer
Unexecuted instantiation: jcprepct-16.c:create_context_buffer
311
312
#endif /* CONTEXT_ROWS_SUPPORTED */
313
314
315
/*
316
 * Initialize preprocessing controller.
317
 */
318
319
GLOBAL(void)
320
_jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
321
94.9k
{
322
94.9k
  my_prep_ptr prep;
323
94.9k
  int ci;
324
94.9k
  jpeg_component_info *compptr;
325
94.9k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
326
327
94.9k
#ifdef C_LOSSLESS_SUPPORTED
328
94.9k
  if (cinfo->master->lossless) {
329
#if BITS_IN_JSAMPLE == 8
330
12.9k
    if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
331
#else
332
22.3k
    if (cinfo->data_precision > BITS_IN_JSAMPLE ||
333
22.3k
        cinfo->data_precision < BITS_IN_JSAMPLE - 3)
334
0
#endif
335
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
336
35.2k
  } else
337
59.6k
#endif
338
59.6k
  {
339
59.6k
    if (cinfo->data_precision != BITS_IN_JSAMPLE)
340
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
341
59.6k
  }
342
343
94.9k
  if (need_full_buffer)         /* safety check */
344
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
345
346
94.9k
  prep = (my_prep_ptr)
347
94.9k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
348
94.9k
                                sizeof(my_prep_controller));
349
94.9k
  cinfo->prep = (struct jpeg_c_prep_controller *)prep;
350
94.9k
  prep->pub.start_pass = start_pass_prep;
351
352
  /* Allocate the color conversion buffer.
353
   * We make the buffer wide enough to allow the downsampler to edge-expand
354
   * horizontally within the buffer, if it so chooses.
355
   */
356
94.9k
  if (cinfo->downsample->need_context_rows) {
357
    /* Set up to provide context rows */
358
2.72k
#ifdef CONTEXT_ROWS_SUPPORTED
359
2.72k
    prep->pub._pre_process_data = pre_process_context;
360
2.72k
    create_context_buffer(cinfo);
361
#else
362
    ERREXIT(cinfo, JERR_NOT_COMPILED);
363
#endif
364
92.2k
  } else {
365
    /* No context, just make it tall enough for one row group */
366
92.2k
    prep->pub._pre_process_data = pre_process_data;
367
337k
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
368
244k
         ci++, compptr++) {
369
244k
      prep->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
370
244k
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
371
244k
         (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
372
244k
                       cinfo->max_h_samp_factor) / compptr->h_samp_factor),
373
244k
         (JDIMENSION)cinfo->max_v_samp_factor);
374
244k
    }
375
92.2k
  }
376
94.9k
}
jinit_c_prep_controller
Line
Count
Source
321
46.0k
{
322
46.0k
  my_prep_ptr prep;
323
46.0k
  int ci;
324
46.0k
  jpeg_component_info *compptr;
325
46.0k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
326
327
46.0k
#ifdef C_LOSSLESS_SUPPORTED
328
46.0k
  if (cinfo->master->lossless) {
329
12.9k
#if BITS_IN_JSAMPLE == 8
330
12.9k
    if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
331
#else
332
    if (cinfo->data_precision > BITS_IN_JSAMPLE ||
333
        cinfo->data_precision < BITS_IN_JSAMPLE - 3)
334
#endif
335
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
336
12.9k
  } else
337
33.1k
#endif
338
33.1k
  {
339
33.1k
    if (cinfo->data_precision != BITS_IN_JSAMPLE)
340
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
341
33.1k
  }
342
343
46.0k
  if (need_full_buffer)         /* safety check */
344
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
345
346
46.0k
  prep = (my_prep_ptr)
347
46.0k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
348
46.0k
                                sizeof(my_prep_controller));
349
46.0k
  cinfo->prep = (struct jpeg_c_prep_controller *)prep;
350
46.0k
  prep->pub.start_pass = start_pass_prep;
351
352
  /* Allocate the color conversion buffer.
353
   * We make the buffer wide enough to allow the downsampler to edge-expand
354
   * horizontally within the buffer, if it so chooses.
355
   */
356
46.0k
  if (cinfo->downsample->need_context_rows) {
357
    /* Set up to provide context rows */
358
2.72k
#ifdef CONTEXT_ROWS_SUPPORTED
359
2.72k
    prep->pub._pre_process_data = pre_process_context;
360
2.72k
    create_context_buffer(cinfo);
361
#else
362
    ERREXIT(cinfo, JERR_NOT_COMPILED);
363
#endif
364
43.3k
  } else {
365
    /* No context, just make it tall enough for one row group */
366
43.3k
    prep->pub._pre_process_data = pre_process_data;
367
156k
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
368
113k
         ci++, compptr++) {
369
113k
      prep->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
370
113k
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
371
113k
         (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
372
113k
                       cinfo->max_h_samp_factor) / compptr->h_samp_factor),
373
113k
         (JDIMENSION)cinfo->max_v_samp_factor);
374
113k
    }
375
43.3k
  }
376
46.0k
}
j12init_c_prep_controller
Line
Count
Source
321
37.5k
{
322
37.5k
  my_prep_ptr prep;
323
37.5k
  int ci;
324
37.5k
  jpeg_component_info *compptr;
325
37.5k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
326
327
37.5k
#ifdef C_LOSSLESS_SUPPORTED
328
37.5k
  if (cinfo->master->lossless) {
329
#if BITS_IN_JSAMPLE == 8
330
    if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
331
#else
332
10.9k
    if (cinfo->data_precision > BITS_IN_JSAMPLE ||
333
10.9k
        cinfo->data_precision < BITS_IN_JSAMPLE - 3)
334
0
#endif
335
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
336
10.9k
  } else
337
26.5k
#endif
338
26.5k
  {
339
26.5k
    if (cinfo->data_precision != BITS_IN_JSAMPLE)
340
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
341
26.5k
  }
342
343
37.5k
  if (need_full_buffer)         /* safety check */
344
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
345
346
37.5k
  prep = (my_prep_ptr)
347
37.5k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
348
37.5k
                                sizeof(my_prep_controller));
349
37.5k
  cinfo->prep = (struct jpeg_c_prep_controller *)prep;
350
37.5k
  prep->pub.start_pass = start_pass_prep;
351
352
  /* Allocate the color conversion buffer.
353
   * We make the buffer wide enough to allow the downsampler to edge-expand
354
   * horizontally within the buffer, if it so chooses.
355
   */
356
37.5k
  if (cinfo->downsample->need_context_rows) {
357
    /* Set up to provide context rows */
358
0
#ifdef CONTEXT_ROWS_SUPPORTED
359
0
    prep->pub._pre_process_data = pre_process_context;
360
0
    create_context_buffer(cinfo);
361
#else
362
    ERREXIT(cinfo, JERR_NOT_COMPILED);
363
#endif
364
37.5k
  } else {
365
    /* No context, just make it tall enough for one row group */
366
37.5k
    prep->pub._pre_process_data = pre_process_data;
367
136k
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
368
99.4k
         ci++, compptr++) {
369
99.4k
      prep->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
370
99.4k
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
371
99.4k
         (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
372
99.4k
                       cinfo->max_h_samp_factor) / compptr->h_samp_factor),
373
99.4k
         (JDIMENSION)cinfo->max_v_samp_factor);
374
99.4k
    }
375
37.5k
  }
376
37.5k
}
j16init_c_prep_controller
Line
Count
Source
321
11.3k
{
322
11.3k
  my_prep_ptr prep;
323
11.3k
  int ci;
324
11.3k
  jpeg_component_info *compptr;
325
11.3k
  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
326
327
11.3k
#ifdef C_LOSSLESS_SUPPORTED
328
11.3k
  if (cinfo->master->lossless) {
329
#if BITS_IN_JSAMPLE == 8
330
    if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
331
#else
332
11.3k
    if (cinfo->data_precision > BITS_IN_JSAMPLE ||
333
11.3k
        cinfo->data_precision < BITS_IN_JSAMPLE - 3)
334
0
#endif
335
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
336
11.3k
  } else
337
0
#endif
338
0
  {
339
0
    if (cinfo->data_precision != BITS_IN_JSAMPLE)
340
0
      ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
341
0
  }
342
343
11.3k
  if (need_full_buffer)         /* safety check */
344
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
345
346
11.3k
  prep = (my_prep_ptr)
347
11.3k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
348
11.3k
                                sizeof(my_prep_controller));
349
11.3k
  cinfo->prep = (struct jpeg_c_prep_controller *)prep;
350
11.3k
  prep->pub.start_pass = start_pass_prep;
351
352
  /* Allocate the color conversion buffer.
353
   * We make the buffer wide enough to allow the downsampler to edge-expand
354
   * horizontally within the buffer, if it so chooses.
355
   */
356
11.3k
  if (cinfo->downsample->need_context_rows) {
357
    /* Set up to provide context rows */
358
0
#ifdef CONTEXT_ROWS_SUPPORTED
359
0
    prep->pub._pre_process_data = pre_process_context;
360
0
    create_context_buffer(cinfo);
361
#else
362
    ERREXIT(cinfo, JERR_NOT_COMPILED);
363
#endif
364
11.3k
  } else {
365
    /* No context, just make it tall enough for one row group */
366
11.3k
    prep->pub._pre_process_data = pre_process_data;
367
43.4k
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
368
32.1k
         ci++, compptr++) {
369
32.1k
      prep->color_buf[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
370
32.1k
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
371
32.1k
         (JDIMENSION)(((long)compptr->width_in_blocks * data_unit *
372
32.1k
                       cinfo->max_h_samp_factor) / compptr->h_samp_factor),
373
32.1k
         (JDIMENSION)cinfo->max_v_samp_factor);
374
32.1k
    }
375
11.3k
  }
376
11.3k
}
377
378
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */