3 { This file contains the coefficient buffer controller for compression.
4 This controller is the top level of the JPEG compressor proper.
5 The coefficient buffer lies between forward-DCT and entropy encoding steps.}
7 { Original: jccoefct.c; Copyright (C) 1994-1997, Thomas G. Lane. }
9 interface
11 {$I imjconfig.inc}
13 uses
14 imjmorecfg,
15 imjinclude,
16 imjerror,
17 imjdeferr,
18 imjutils,
19 imjpeglib;
21 { We use a full-image coefficient buffer when doing Huffman optimization,
22 and also for writing multiple-scan JPEG files. In all cases, the DCT
23 step is run during the first pass, and subsequent passes need only read
24 the buffered coefficients. }
25 {$ifdef ENTROPY_OPT_SUPPORTED}
26 {$define FULL_COEF_BUFFER_SUPPORTED}
27 {$else}
28 {$ifdef C_MULTISCAN_FILES_SUPPORTED}
29 {$define FULL_COEF_BUFFER_SUPPORTED}
30 {$endif}
31 {$endif}
33 { Initialize coefficient buffer controller. }
35 {GLOBAL}
39 implementation
41 { Private buffer controller object }
43 type
53 { For single-pass compression, it's sufficient to buffer just one MCU
54 (although this may prove a bit slow in practice). We allocate a
55 workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
56 MCU constructed and sent. (On 80x86, the workspace is FAR even though
57 it's not really very big; this is to keep the module interfaces unchanged
58 when a large coefficient buffer is necessary.)
59 In multi-pass modes, this array points to the current MCU's blocks
60 within the virtual arrays. }
64 { In multi-pass modes, we need a virtual block array for each component. }
69 { Forward declarations }
70 {METHODDEF}
73 {$ifdef FULL_COEF_BUFFER_SUPPORTED}
74 {METHODDEF}
77 {METHODDEF}
80 {$endif}
83 {LOCAL}
85 { Reset within-iMCU-row counters for a new row }
86 var
88 begin
91 { In an interleaved scan, an MCU row is the same as an iMCU row.
92 In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
93 But at the bottom of the image, process only what's left. }
95 begin
97 end
98 else
99 begin
102 else
111 { Initialize for a processing pass. }
113 {METHODDEF}
116 var
118 begin
125 JBUF_PASS_THRU:
126 begin
131 {$ifdef FULL_COEF_BUFFER_SUPPORTED}
132 JBUF_SAVE_AND_PASS:
133 begin
138 JBUF_CRANK_DEST:
139 begin
144 {$endif}
145 else
151 { Process some data in the single-pass case.
152 We process the equivalent of one fully interleaved MCU row ("iMCU" row)
153 per call, ie, v_samp_factor block rows for each component in the image.
154 Returns TRUE if the iMCU row is completed, FALSE if suspended.
156 NB: input_buf contains a plane for each component in image,
157 which we index according to the component's SOF position. }
160 {METHODDEF}
163 var
171 begin
176 { Loop to write as much as one whole iMCU row }
178 begin
180 begin
181 { Determine where data comes from in input_buf and do the DCT thing.
182 Each call on forward_DCT processes a horizontal row of DCT blocks
183 as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
184 sequentially. Dummy blocks at the right or bottom edge are filled in
185 specially. The data in them does not matter for image reconstruction,
186 so we fill them with values that will encode to the smallest amount of
187 data, viz: all zeroes in the AC entries, DC entries equal to previous
188 block's DC value. (Thanks to Thomas Kinsman for this idea.) }
192 begin
196 else
201 begin
204 begin
211 begin
212 { Create some dummy blocks at the right edge of the image. }
216 begin
220 end
221 else
222 begin
223 { Create a row of dummy blocks at the bottom of the image. }
227 begin
235 { Try to write the MCU. In event of a suspension failure, we will
236 re-DCT the MCU on restart (a bit inefficient, could be fixed...) }
239 begin
240 { Suspension forced; update state counters and exit }
244 exit;
247 { Completed an MCU row, but perhaps not an iMCU row }
250 { Completed the iMCU row, advance counters for next one }
257 {$ifdef FULL_COEF_BUFFER_SUPPORTED}
259 { Process some data in the first pass of a multi-pass case.
260 We process the equivalent of one fully interleaved MCU row ("iMCU" row)
261 per call, ie, v_samp_factor block rows for each component in the image.
262 This amount of data is read from the source buffer, DCT'd and quantized,
263 and saved into the virtual arrays. We also generate suitable dummy blocks
264 as needed at the right and lower edges. (The dummy blocks are constructed
265 in the virtual arrays, which have been padded appropriately.) This makes
266 it possible for subsequent passes not to worry about real vs. dummy blocks.
268 We must also emit the data to the entropy encoder. This is conveniently
269 done by calling compress_output() after we've loaded the current strip
270 of the virtual arrays.
272 NB: input_buf contains a plane for each component in image. All
273 components are DCT'd and loaded into the virtual arrays in this pass.
274 However, it may be that only a subset of the components are emitted to
275 the entropy encoder during this first pass; be careful about looking
276 at the scan-dependent variables (MCU dimensions, etc). }
278 {METHODDEF}
281 var
290 begin
296 begin
297 { Align the virtual buffer for this component. }
302 { Count non-dummy DCT block rows in this iMCU row. }
305 else
306 begin
307 { NB: can't use last_row_height here, since may not be set! }
314 { Count number of dummy blocks to be added at the right margin. }
318 { Perform DCT for all non-dummy blocks in this iMCU row. Each call
319 on forward_DCT processes a complete horizontal row of DCT blocks. }
322 begin
326 thisblockrow,
329 blocks_across);
331 begin
332 { Create dummy blocks at the right edge of the image. }
335 {lastDC := thisblockrow^[-1][0];}
336 { work around Range Checking }
342 begin
347 { If at end of image, create dummy block rows as needed.
348 The tricky part here is that within each MCU, we want the DC values
349 of the dummy blocks to match the last real block's DC value.
350 This squeezes a few more bytes out of the resulting file... }
353 begin
357 begin
363 begin
366 begin
376 { NB: compress_output will increment iMCU_row_num if successful.
377 A suspension return will result in redoing all the work above next time.}
380 { Emit data to the entropy encoder, sharing code with subsequent passes }
385 { Process some data in subsequent passes of a multi-pass case.
386 We process the equivalent of one fully interleaved MCU row ("iMCU" row)
387 per call, ie, v_samp_factor block rows for each component in the scan.
388 The data is obtained from the virtual arrays and fed to the entropy coder.
389 Returns TRUE if the iMCU row is completed, FALSE if suspended.
391 NB: input_buf is ignored; it is likely to be a NIL pointer. }
393 {METHODDEF}
396 var
404 begin
407 { Align the virtual buffers for the components used in this scan.
408 NB: during first pass, this is safe only because the buffers will
409 already be aligned properly, so jmemmgr.c won't need to do any I/O. }
412 begin
420 { Loop to process one whole iMCU row }
422 begin
424 begin
425 { Construct list of pointers to DCT blocks belonging to this MCU }
428 begin
432 begin
435 begin
442 { Try to write the MCU. }
444 begin
445 { Suspension forced; update state counters and exit }
449 exit;
452 { Completed an MCU row, but perhaps not an iMCU row }
455 { Completed the iMCU row, advance counters for next one }
464 { Initialize coefficient buffer controller. }
466 {GLOBAL}
469 var
471 var
474 var
477 begin
484 { Create the coefficient buffer. }
486 begin
487 {$ifdef FULL_COEF_BUFFER_SUPPORTED}
488 { Allocate a full-image virtual array for each component, }
489 { padded to a multiple of samp_factor DCT blocks in each direction. }
493 begin
503 {$else}
505 {$endif}
506 end
507 else
508 begin
509 { We only need a single-MCU buffer. }
514 begin