DEADSOFTWARE

hopefully no more windows
[d2df-editor.git] / src / lib / vampimg / JpegLib / imjcmaster.pas
1 unit imjcmaster;
3 { This file contains master control logic for the JPEG compressor.
4 These routines are concerned with parameter validation, initial setup,
5 and inter-pass control (determining the number of passes and the work
6 to be done in each pass). }
8 { Original: jcmaster.c ; Copyright (C) 1991-1997, Thomas G. Lane. }
10 interface
12 {$I imjconfig.inc}
14 uses
15 imjmorecfg,
16 imjinclude,
17 imjdeferr,
18 imjerror,
19 imjutils,
20 imjpeglib;
22 { Initialize master compression control. }
24 {GLOBAL}
25 procedure jinit_c_master_control (cinfo : j_compress_ptr;
26 transcode_only : boolean);
28 implementation
30 { Private state }
32 type
33 c_pass_type = (
34 main_pass, { input data, also do first output step }
35 huff_opt_pass, { Huffman code optimization pass }
36 output_pass { data output pass }
37 );
39 type
40 my_master_ptr = ^my_comp_master;
41 my_comp_master = record
42 pub : jpeg_comp_master; { public fields }
44 pass_type : c_pass_type; { the type of the current pass }
46 pass_number : int; { # of passes completed }
47 total_passes : int; { total # of passes needed }
49 scan_number : int; { current index in scan_info[] }
50 end;
53 { Support routines that do various essential calculations. }
55 {LOCAL}
56 procedure initial_setup (cinfo : j_compress_ptr);
57 { Do computations that are needed before master selection phase }
58 var
59 ci : int;
60 compptr : jpeg_component_info_ptr;
61 samplesperrow : long;
62 jd_samplesperrow : JDIMENSION;
63 begin
65 { Sanity check on image dimensions }
66 if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0) or
67 (cinfo^.num_components <= 0) or (cinfo^.input_components <= 0) then
68 ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE);
70 { Make sure image isn't bigger than I can handle }
71 if ( long(cinfo^.image_height) > long(JPEG_MAX_DIMENSION)) or
72 ( long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then
73 ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG,
74 uInt(JPEG_MAX_DIMENSION));
76 { Width of an input scanline must be representable as JDIMENSION. }
77 samplesperrow := long (cinfo^.image_width) * long (cinfo^.input_components);
78 jd_samplesperrow := JDIMENSION (samplesperrow);
79 if ( long(jd_samplesperrow) <> samplesperrow) then
80 ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW);
82 { For now, precision must match compiled-in value... }
83 if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then
84 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision);
86 { Check that number of components won't exceed internal array sizes }
87 if (cinfo^.num_components > MAX_COMPONENTS) then
88 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components,
89 MAX_COMPONENTS);
91 { Compute maximum sampling factors; check factor validity }
92 cinfo^.max_h_samp_factor := 1;
93 cinfo^.max_v_samp_factor := 1;
94 compptr := jpeg_component_info_ptr(cinfo^.comp_info);
95 for ci := 0 to pred(cinfo^.num_components) do
96 begin
97 if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR)
98 or (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then
99 ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING);
100 { MAX }
101 if cinfo^.max_h_samp_factor > compptr^.h_samp_factor then
102 cinfo^.max_h_samp_factor := cinfo^.max_h_samp_factor
103 else
104 cinfo^.max_h_samp_factor := compptr^.h_samp_factor;
105 { MAX }
106 if cinfo^.max_v_samp_factor > compptr^.v_samp_factor then
107 cinfo^.max_v_samp_factor := cinfo^.max_v_samp_factor
108 else
109 cinfo^.max_v_samp_factor := compptr^.v_samp_factor;
110 Inc(compptr);
111 end;
113 { Compute dimensions of components }
114 compptr := jpeg_component_info_ptr(cinfo^.comp_info);
115 for ci := 0 to pred(cinfo^.num_components) do
116 begin
117 { Fill in the correct component_index value; don't rely on application }
118 compptr^.component_index := ci;
119 { For compression, we never do DCT scaling. }
120 compptr^.DCT_scaled_size := DCTSIZE;
121 { Size in DCT blocks }
122 compptr^.width_in_blocks := JDIMENSION (
123 jdiv_round_up(long (cinfo^.image_width) * long (compptr^.h_samp_factor),
124 long (cinfo^.max_h_samp_factor * DCTSIZE)) );
125 compptr^.height_in_blocks := JDIMENSION (
126 jdiv_round_up(long (cinfo^.image_height) * long (compptr^.v_samp_factor),
127 long (cinfo^.max_v_samp_factor * DCTSIZE)) );
128 { Size in samples }
129 compptr^.downsampled_width := JDIMENSION (
130 jdiv_round_up(long(cinfo^.image_width) * long(compptr^.h_samp_factor),
131 long(cinfo^.max_h_samp_factor)) );
132 compptr^.downsampled_height := JDIMENSION (
133 jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor),
134 long (cinfo^.max_v_samp_factor)) );
135 { Mark component needed (this flag isn't actually used for compression) }
136 compptr^.component_needed := TRUE;
137 Inc(compptr);
138 end;
140 { Compute number of fully interleaved MCU rows (number of times that
141 main controller will call coefficient controller). }
143 cinfo^.total_iMCU_rows := JDIMENSION (
144 jdiv_round_up(long (cinfo^.image_height),
145 long (cinfo^.max_v_samp_factor*DCTSIZE)) );
146 end;
149 {$ifdef C_MULTISCAN_FILES_SUPPORTED}
151 {LOCAL}
152 procedure validate_script (cinfo : j_compress_ptr);
153 { Verify that the scan script in cinfo^.scan_info[] is valid; also
154 determine whether it uses progressive JPEG, and set cinfo^.progressive_mode. }
155 type
156 IntRow = array[0..DCTSIZE2-1] of int;
157 introw_ptr = ^IntRow;
158 var
159 {const}scanptr : jpeg_scan_info_ptr;
160 scanno, ncomps, ci, coefi, thisi : int;
161 Ss, Se, Ah, Al : int;
162 component_sent : array[0..MAX_COMPONENTS-1] of boolean;
163 {$ifdef C_PROGRESSIVE_SUPPORTED}
164 last_bitpos_int_ptr : int_ptr;
165 last_bitpos_ptr : introw_ptr;
166 last_bitpos : array[0..MAX_COMPONENTS-1] of IntRow;
167 { -1 until that coefficient has been seen; then last Al for it }
168 { The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
169 seems wrong: the upper bound ought to depend on data precision.
170 Perhaps they really meant 0..N+1 for N-bit precision.
171 Here we allow 0..10 for 8-bit data; Al larger than 10 results in
172 out-of-range reconstructed DC values during the first DC scan,
173 which might cause problems for some decoders. }
174 {$ifdef BITS_IN_JSAMPLE_IS_8}
175 const
176 MAX_AH_AL = 10;
177 {$else}
178 const
179 MAX_AH_AL = 13;
180 {$endif}
181 {$endif}
182 begin
184 if (cinfo^.num_scans <= 0) then
185 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, 0);
187 { For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
188 for progressive JPEG, no scan can have this. }
190 scanptr := cinfo^.scan_info;
191 if (scanptr^.Ss <> 0) or (scanptr^.Se <> DCTSIZE2-1) then
192 begin
193 {$ifdef C_PROGRESSIVE_SUPPORTED}
194 cinfo^.progressive_mode := TRUE;
195 last_bitpos_int_ptr := @(last_bitpos[0][0]);
196 for ci := 0 to pred(cinfo^.num_components) do
197 for coefi := 0 to pred(DCTSIZE2) do
198 begin
199 last_bitpos_int_ptr^ := -1;
200 Inc(last_bitpos_int_ptr);
201 end;
202 {$else}
203 ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
204 {$endif}
205 end
206 else
207 begin
208 cinfo^.progressive_mode := FALSE;
209 for ci := 0 to pred(cinfo^.num_components) do
210 component_sent[ci] := FALSE;
211 end;
213 for scanno := 1 to cinfo^.num_scans do
214 begin
215 { Validate component indexes }
216 ncomps := scanptr^.comps_in_scan;
217 if (ncomps <= 0) or (ncomps > MAX_COMPS_IN_SCAN) then
218 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
219 for ci := 0 to pred(ncomps) do
220 begin
221 thisi := scanptr^.component_index[ci];
222 if (thisi < 0) or (thisi >= cinfo^.num_components) then
223 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno);
224 { Components must appear in SOF order within each scan }
225 if (ci > 0) and (thisi <= scanptr^.component_index[ci-1]) then
226 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno);
227 end;
228 { Validate progression parameters }
229 Ss := scanptr^.Ss;
230 Se := scanptr^.Se;
231 Ah := scanptr^.Ah;
232 Al := scanptr^.Al;
233 if (cinfo^.progressive_mode) then
234 begin
235 {$ifdef C_PROGRESSIVE_SUPPORTED}
236 if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2) or
237 (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then
238 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
240 if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2)
241 or (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then
242 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
243 if (Ss = 0) then
244 begin
245 if (Se <> 0) then { DC and AC together not OK }
246 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
247 end
248 else
249 begin
250 if (ncomps <> 1) then { AC scans must be for only one component }
251 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
252 end;
253 for ci := 0 to pred(ncomps) do
254 begin
255 last_bitpos_ptr := @( last_bitpos[scanptr^.component_index[ci]]);
256 if (Ss <> 0) and (last_bitpos_ptr^[0] < 0) then { AC without prior DC scan }
257 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
258 for coefi := Ss to Se do
259 begin
260 if (last_bitpos_ptr^[coefi] < 0) then
261 begin
262 { first scan of this coefficient }
263 if (Ah <> 0) then
264 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
265 end
266 else
267 begin
268 { not first scan }
269 if (Ah <> last_bitpos_ptr^[coefi]) or (Al <> Ah-1) then
270 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
271 end;
272 last_bitpos_ptr^[coefi] := Al;
273 end;
274 end;
275 {$endif}
276 end
277 else
278 begin
279 { For sequential JPEG, all progression parameters must be these: }
280 if (Ss <> 0) or (Se <> DCTSIZE2-1) or (Ah <> 0) or (Al <> 0) then
281 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno);
282 { Make sure components are not sent twice }
283 for ci := 0 to pred(ncomps) do
284 begin
285 thisi := scanptr^.component_index[ci];
286 if (component_sent[thisi]) then
287 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno);
288 component_sent[thisi] := TRUE;
289 end;
290 end;
291 Inc(scanptr);
292 end;
294 { Now verify that everything got sent. }
295 if (cinfo^.progressive_mode) then
296 begin
297 {$ifdef C_PROGRESSIVE_SUPPORTED}
298 { For progressive mode, we only check that at least some DC data
299 got sent for each component; the spec does not require that all bits
300 of all coefficients be transmitted. Would it be wiser to enforce
301 transmission of all coefficient bits?? }
303 for ci := 0 to pred(cinfo^.num_components) do
304 begin
305 if (last_bitpos[ci][0] < 0) then
306 ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA);
307 end;
308 {$endif}
309 end
310 else
311 begin
312 for ci := 0 to pred(cinfo^.num_components) do
313 begin
314 if (not component_sent[ci]) then
315 ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA);
316 end;
317 end;
318 end;
320 {$endif} { C_MULTISCAN_FILES_SUPPORTED }
323 {LOCAL}
324 procedure select_scan_parameters (cinfo : j_compress_ptr);
325 { Set up the scan parameters for the current scan }
326 var
327 master : my_master_ptr;
328 {const} scanptr : jpeg_scan_info_ptr;
329 ci : int;
330 var
331 comp_infos : jpeg_component_info_list_ptr;
332 begin
333 {$ifdef C_MULTISCAN_FILES_SUPPORTED}
334 if (cinfo^.scan_info <> NIL) then
335 begin
336 { Prepare for current scan --- the script is already validated }
337 master := my_master_ptr (cinfo^.master);
338 scanptr := cinfo^.scan_info;
339 Inc(scanptr, master^.scan_number);
341 cinfo^.comps_in_scan := scanptr^.comps_in_scan;
342 comp_infos := cinfo^.comp_info;
343 for ci := 0 to pred(scanptr^.comps_in_scan) do
344 begin
345 cinfo^.cur_comp_info[ci] :=
346 @(comp_infos^[scanptr^.component_index[ci]]);
347 end;
348 cinfo^.Ss := scanptr^.Ss;
349 cinfo^.Se := scanptr^.Se;
350 cinfo^.Ah := scanptr^.Ah;
351 cinfo^.Al := scanptr^.Al;
352 end
353 else
354 {$endif}
355 begin
356 { Prepare for single sequential-JPEG scan containing all components }
357 if (cinfo^.num_components > MAX_COMPS_IN_SCAN) then
358 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components,
359 MAX_COMPS_IN_SCAN);
360 cinfo^.comps_in_scan := cinfo^.num_components;
361 comp_infos := cinfo^.comp_info;
362 for ci := 0 to pred(cinfo^.num_components) do
363 begin
364 cinfo^.cur_comp_info[ci] := @(comp_infos^[ci]);
365 end;
366 cinfo^.Ss := 0;
367 cinfo^.Se := DCTSIZE2-1;
368 cinfo^.Ah := 0;
369 cinfo^.Al := 0;
370 end;
371 end;
374 {LOCAL}
375 procedure per_scan_setup (cinfo : j_compress_ptr);
376 { Do computations that are needed before processing a JPEG scan }
377 { cinfo^.comps_in_scan and cinfo^.cur_comp_info[] are already set }
378 var
379 ci, mcublks, tmp : int;
380 compptr : jpeg_component_info_ptr;
381 nominal : long;
382 begin
383 if (cinfo^.comps_in_scan = 1) then
384 begin
386 { Noninterleaved (single-component) scan }
387 compptr := cinfo^.cur_comp_info[0];
389 { Overall image size in MCUs }
390 cinfo^.MCUs_per_row := compptr^.width_in_blocks;
391 cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks;
393 { For noninterleaved scan, always one block per MCU }
394 compptr^.MCU_width := 1;
395 compptr^.MCU_height := 1;
396 compptr^.MCU_blocks := 1;
397 compptr^.MCU_sample_width := DCTSIZE;
398 compptr^.last_col_width := 1;
399 { For noninterleaved scans, it is convenient to define last_row_height
400 as the number of block rows present in the last iMCU row. }
402 tmp := int (compptr^.height_in_blocks) mod compptr^.v_samp_factor;
403 if (tmp = 0) then
404 tmp := compptr^.v_samp_factor;
405 compptr^.last_row_height := tmp;
407 { Prepare array describing MCU composition }
408 cinfo^.blocks_in_MCU := 1;
409 cinfo^.MCU_membership[0] := 0;
411 end
412 else
413 begin
415 { Interleaved (multi-component) scan }
416 if (cinfo^.comps_in_scan <= 0) or
417 (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then
418 ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT,
419 cinfo^.comps_in_scan, MAX_COMPS_IN_SCAN);
421 { Overall image size in MCUs }
422 cinfo^.MCUs_per_row := JDIMENSION (
423 jdiv_round_up( long (cinfo^.image_width),
424 long (cinfo^.max_h_samp_factor*DCTSIZE)) );
425 cinfo^.MCU_rows_in_scan := JDIMENSION (
426 jdiv_round_up( long (cinfo^.image_height),
427 long (cinfo^.max_v_samp_factor*DCTSIZE)) );
429 cinfo^.blocks_in_MCU := 0;
431 for ci := 0 to pred(cinfo^.comps_in_scan) do
432 begin
433 compptr := cinfo^.cur_comp_info[ci];
434 { Sampling factors give # of blocks of component in each MCU }
435 compptr^.MCU_width := compptr^.h_samp_factor;
436 compptr^.MCU_height := compptr^.v_samp_factor;
437 compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height;
438 compptr^.MCU_sample_width := compptr^.MCU_width * DCTSIZE;
439 { Figure number of non-dummy blocks in last MCU column & row }
440 tmp := int (compptr^.width_in_blocks) mod compptr^.MCU_width;
441 if (tmp = 0) then
442 tmp := compptr^.MCU_width;
443 compptr^.last_col_width := tmp;
444 tmp := int (compptr^.height_in_blocks) mod compptr^.MCU_height;
445 if (tmp = 0) then
446 tmp := compptr^.MCU_height;
447 compptr^.last_row_height := tmp;
448 { Prepare array describing MCU composition }
449 mcublks := compptr^.MCU_blocks;
450 if (cinfo^.blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) then
451 ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE);
452 while (mcublks > 0) do
453 begin
454 Dec(mcublks);
455 cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci;
456 Inc(cinfo^.blocks_in_MCU);
457 end;
458 end;
460 end;
462 { Convert restart specified in rows to actual MCU count. }
463 { Note that count must fit in 16 bits, so we provide limiting. }
464 if (cinfo^.restart_in_rows > 0) then
465 begin
466 nominal := long(cinfo^.restart_in_rows) * long(cinfo^.MCUs_per_row);
467 if nominal < long(65535) then
468 cinfo^.restart_interval := uInt (nominal)
469 else
470 cinfo^.restart_interval := long(65535);
471 end;
472 end;
475 { Per-pass setup.
476 This is called at the beginning of each pass. We determine which modules
477 will be active during this pass and give them appropriate start_pass calls.
478 We also set is_last_pass to indicate whether any more passes will be
479 required. }
481 {METHODDEF}
482 procedure prepare_for_pass (cinfo : j_compress_ptr);
483 var
484 master : my_master_ptr;
485 var
486 fallthrough : boolean;
487 begin
488 master := my_master_ptr (cinfo^.master);
489 fallthrough := true;
491 case (master^.pass_type) of
492 main_pass:
493 begin
494 { Initial pass: will collect input data, and do either Huffman
495 optimization or data output for the first scan. }
496 select_scan_parameters(cinfo);
497 per_scan_setup(cinfo);
498 if (not cinfo^.raw_data_in) then
499 begin
500 cinfo^.cconvert^.start_pass (cinfo);
501 cinfo^.downsample^.start_pass (cinfo);
502 cinfo^.prep^.start_pass (cinfo, JBUF_PASS_THRU);
503 end;
504 cinfo^.fdct^.start_pass (cinfo);
505 cinfo^.entropy^.start_pass (cinfo, cinfo^.optimize_coding);
506 if master^.total_passes > 1 then
507 cinfo^.coef^.start_pass (cinfo, JBUF_SAVE_AND_PASS)
508 else
509 cinfo^.coef^.start_pass (cinfo, JBUF_PASS_THRU);
510 cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU);
511 if (cinfo^.optimize_coding) then
512 begin
513 { No immediate data output; postpone writing frame/scan headers }
514 master^.pub.call_pass_startup := FALSE;
515 end
516 else
517 begin
518 { Will write frame/scan headers at first jpeg_write_scanlines call }
519 master^.pub.call_pass_startup := TRUE;
520 end;
521 end;
522 {$ifdef ENTROPY_OPT_SUPPORTED}
523 huff_opt_pass,
524 output_pass:
525 begin
526 if (master^.pass_type = huff_opt_pass) then
527 begin
528 { Do Huffman optimization for a scan after the first one. }
529 select_scan_parameters(cinfo);
530 per_scan_setup(cinfo);
531 if (cinfo^.Ss <> 0) or (cinfo^.Ah = 0) or (cinfo^.arith_code) then
532 begin
533 cinfo^.entropy^.start_pass (cinfo, TRUE);
534 cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST);
535 master^.pub.call_pass_startup := FALSE;
536 fallthrough := false;
537 end;
538 { Special case: Huffman DC refinement scans need no Huffman table
539 and therefore we can skip the optimization pass for them. }
540 if fallthrough then
541 begin
542 master^.pass_type := output_pass;
543 Inc(master^.pass_number);
544 {FALLTHROUGH}
545 end;
546 end;
547 {$else}
548 output_pass:
549 begin
550 {$endif}
551 if fallthrough then
552 begin
553 { Do a data-output pass. }
554 { We need not repeat per-scan setup if prior optimization pass did it. }
555 if (not cinfo^.optimize_coding) then
556 begin
557 select_scan_parameters(cinfo);
558 per_scan_setup(cinfo);
559 end;
560 cinfo^.entropy^.start_pass (cinfo, FALSE);
561 cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST);
562 { We emit frame/scan headers now }
563 if (master^.scan_number = 0) then
564 cinfo^.marker^.write_frame_header (cinfo);
565 cinfo^.marker^.write_scan_header (cinfo);
566 master^.pub.call_pass_startup := FALSE;
567 end;
568 end;
569 else
570 ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
571 end;
573 master^.pub.is_last_pass := (master^.pass_number = master^.total_passes-1);
575 { Set up progress monitor's pass info if present }
576 if (cinfo^.progress <> NIL) then
577 begin
578 cinfo^.progress^.completed_passes := master^.pass_number;
579 cinfo^.progress^.total_passes := master^.total_passes;
580 end;
581 end;
584 { Special start-of-pass hook.
585 This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
586 In single-pass processing, we need this hook because we don't want to
587 write frame/scan headers during jpeg_start_compress; we want to let the
588 application write COM markers etc. between jpeg_start_compress and the
589 jpeg_write_scanlines loop.
590 In multi-pass processing, this routine is not used. }
592 {METHODDEF}
593 procedure pass_startup (cinfo : j_compress_ptr);
594 begin
595 cinfo^.master^.call_pass_startup := FALSE; { reset flag so call only once }
597 cinfo^.marker^.write_frame_header (cinfo);
598 cinfo^.marker^.write_scan_header (cinfo);
599 end;
602 { Finish up at end of pass. }
604 {METHODDEF}
605 procedure finish_pass_master (cinfo : j_compress_ptr);
606 var
607 master : my_master_ptr;
608 begin
609 master := my_master_ptr (cinfo^.master);
611 { The entropy coder always needs an end-of-pass call,
612 either to analyze statistics or to flush its output buffer. }
613 cinfo^.entropy^.finish_pass (cinfo);
615 { Update state for next pass }
616 case (master^.pass_type) of
617 main_pass:
618 begin
619 { next pass is either output of scan 0 (after optimization)
620 or output of scan 1 (if no optimization). }
622 master^.pass_type := output_pass;
623 if (not cinfo^.optimize_coding) then
624 Inc(master^.scan_number);
625 end;
626 huff_opt_pass:
627 { next pass is always output of current scan }
628 master^.pass_type := output_pass;
629 output_pass:
630 begin
631 { next pass is either optimization or output of next scan }
632 if (cinfo^.optimize_coding) then
633 master^.pass_type := huff_opt_pass;
634 Inc(master^.scan_number);
635 end;
636 end;
638 Inc(master^.pass_number);
639 end;
642 { Initialize master compression control. }
644 {GLOBAL}
645 procedure jinit_c_master_control (cinfo : j_compress_ptr;
646 transcode_only : boolean);
647 var
648 master : my_master_ptr;
649 begin
650 master := my_master_ptr(
651 cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
652 SIZEOF(my_comp_master)) );
653 cinfo^.master := jpeg_comp_master_ptr(master);
654 master^.pub.prepare_for_pass := prepare_for_pass;
655 master^.pub.pass_startup := pass_startup;
656 master^.pub.finish_pass := finish_pass_master;
657 master^.pub.is_last_pass := FALSE;
659 { Validate parameters, determine derived values }
660 initial_setup(cinfo);
662 if (cinfo^.scan_info <> NIL) then
663 begin
664 {$ifdef C_MULTISCAN_FILES_SUPPORTED}
665 validate_script(cinfo);
666 {$else}
667 ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
668 {$endif}
669 end
670 else
671 begin
672 cinfo^.progressive_mode := FALSE;
673 cinfo^.num_scans := 1;
674 end;
676 if (cinfo^.progressive_mode) then { TEMPORARY HACK ??? }
677 cinfo^.optimize_coding := TRUE; { assume default tables no good for progressive mode }
679 { Initialize my private state }
680 if (transcode_only) then
681 begin
682 { no main pass in transcoding }
683 if (cinfo^.optimize_coding) then
684 master^.pass_type := huff_opt_pass
685 else
686 master^.pass_type := output_pass;
687 end
688 else
689 begin
690 { for normal compression, first pass is always this type: }
691 master^.pass_type := main_pass;
692 end;
693 master^.scan_number := 0;
694 master^.pass_number := 0;
695 if (cinfo^.optimize_coding) then
696 master^.total_passes := cinfo^.num_scans * 2
697 else
698 master^.total_passes := cinfo^.num_scans;
699 end;
701 end.