3 { Original : jcprepct.c ; Copyright (C) 1994-1996, Thomas G. Lane. }
5 { This file contains the compression preprocessing controller.
6 This controller manages the color conversion, downsampling,
7 and edge expansion steps.
9 Most of the complexity here is associated with buffering input rows
10 as required by the downsampler. See the comments at the head of
11 jcsample.c for the downsampler's needs. }
13 interface
15 {$I imjconfig.inc}
17 uses
18 imjmorecfg,
19 imjpeglib,
20 imjdeferr,
21 imjerror,
22 imjinclude,
23 imjutils;
25 {GLOBAL}
29 implementation
32 { At present, jcsample.c can request context rows only for smoothing.
33 In the future, we might also need context rows for CCIR601 sampling
34 or other more-complex downsampling procedures. The code to support
35 context rows should be compiled only if needed. }
37 {$ifdef INPUT_SMOOTHING_SUPPORTED}
38 {$define CONTEXT_ROWS_SUPPORTED}
39 {$endif}
42 { For the simple (no-context-row) case, we just need to buffer one
43 row group's worth of pixels for the downsampling step. At the bottom of
44 the image, we pad to a full row group by replicating the last pixel row.
45 The downsampler's last output row is then replicated if needed to pad
46 out to a full iMCU row.
48 When providing context rows, we must buffer three row groups' worth of
49 pixels. Three row groups are physically allocated, but the row pointer
50 arrays are made five row groups high, with the extra pointers above and
51 below "wrapping around" to point to the last and first real row groups.
52 This allows the downsampler to access the proper context rows.
53 At the top and bottom of the image, we create dummy context rows by
54 copying the first or last real pixel row. This copying could be avoided
55 by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
56 trouble on the compression side. }
59 { Private buffer controller object }
61 type
66 { Downsampling input buffer. This buffer holds color-converted data
67 until we have enough to do a downsample step. }
77 {$endif}
81 { Initialize for a processing pass. }
83 {METHODDEF}
86 var
88 begin
94 { Initialize total-height counter for detecting bottom of image }
96 { Mark the conversion buffer empty }
98 {$ifdef CONTEXT_ROWS_SUPPORTED}
99 { Preset additional state variables for context mode.
100 These aren't used in non-context mode, so we needn't test which mode. }
102 { Set next_buf_stop to stop after two row groups have been read in. }
104 {$endif}
108 { Expand an image vertically from height input_rows to height output_rows,
109 by duplicating the bottom row. }
111 {LOCAL}
116 var
118 begin
120 begin
127 { Process some data in the simple no-context case.
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. }
134 {METHODDEF}
142 var
147 var
149 begin
154 begin
155 { Do color conversion to fill the conversion buffer. }
158 {numrows := int( MIN(JDIMENSION(numrows), inrows) );}
165 numrows);
169 { If at bottom of image, pad to fill the conversion buffer. }
172 begin
174 begin
180 { If we've filled the conversion buffer, empty it. }
182 begin
186 output_buf,
187 out_row_group_ctr);
191 { If at bottom of image, pad the output to a full iMCU height.
192 Note we assume the caller is providing a one-iMCU-height output buffer! }
195 begin
198 begin
212 {$ifdef CONTEXT_ROWS_SUPPORTED}
214 { Process some data in the context case. }
216 {METHODDEF}
224 var
229 var
232 begin
237 begin
239 begin
240 { Do color conversion to fill the conversion buffer. }
243 {numrows := int ( MIN( JDIMENSION(numrows), inrows) );}
250 numrows);
251 { Pad at top of image, if first time through }
253 begin
255 begin
257 begin
267 end
268 else
269 begin
270 { Return for more data, unless we are at the bottom of the image. }
272 break;
273 { When at bottom of image, pad to fill the conversion buffer. }
275 begin
277 begin
284 { If we've gotten enough data, downsample a row group. }
286 begin
290 output_buf,
291 out_row_group_ctr);
293 { Advance pointers with wraparound as necessary. }
305 { Create the wrapped-around downsampling input buffer needed for context mode. }
307 {LOCAL}
309 var
315 begin
318 { Grab enough space for fake row pointers for all the components;
319 we need five row groups' worth of pointers for each component. }
328 begin
329 { Allocate the actual buffer space (3 row groups) for this component.
330 We make the buffer wide enough to allow the downsampler to edge-expand
331 horizontally within the buffer, if it so chooses. }
337 { Copy true buffer row pointers into the middle of the fake row array }
340 { Fill in the above and below wraparound pointers }
342 begin
355 { Initialize preprocessing controller. }
357 {GLOBAL}
360 var
364 begin
375 { Allocate the color conversion buffer.
376 We make the buffer wide enough to allow the downsampler to edge-expand
377 horizontally within the buffer, if it so chooses. }
380 begin
381 { Set up to provide context rows }
382 {$ifdef CONTEXT_ROWS_SUPPORTED}
385 {$else}
387 {$endif}
388 end
389 else
390 begin
391 { No context, just make it tall enough for one row group }
395 begin