summaryrefslogtreecommitdiff
path: root/packages/pasjpeg/src/jdmaster.pas
diff options
context:
space:
mode:
Diffstat (limited to 'packages/pasjpeg/src/jdmaster.pas')
-rw-r--r--packages/pasjpeg/src/jdmaster.pas678
1 files changed, 678 insertions, 0 deletions
diff --git a/packages/pasjpeg/src/jdmaster.pas b/packages/pasjpeg/src/jdmaster.pas
new file mode 100644
index 0000000000..0206c48211
--- /dev/null
+++ b/packages/pasjpeg/src/jdmaster.pas
@@ -0,0 +1,678 @@
+Unit JdMaster;
+
+{ This file contains master control logic for the JPEG decompressor.
+ These routines are concerned with selecting the modules to be executed
+ and with determining the number of passes and the work to be done in each
+ pass. }
+
+{ Original: jdmaster.c ; Copyright (C) 1991-1998, Thomas G. Lane. }
+
+interface
+
+{$I jconfig.inc}
+
+uses
+ jmorecfg,
+ jinclude,
+ jutils,
+ jerror,
+ jdeferr,
+ jdcolor, jdsample, jdpostct, jddctmgr, jdphuff, jdhuff, jdcoefct, jdmainct,
+{$ifdef QUANT_1PASS_SUPPORTED}
+ jquant1,
+{$endif}
+{$ifdef QUANT_2PASS_SUPPORTED}
+ jquant2,
+{$endif}
+{$ifdef UPSAMPLE_MERGING_SUPPORTED}
+ jdmerge,
+{$endif}
+ jpeglib;
+
+
+{ Compute output image dimensions and related values.
+ NOTE: this is exported for possible use by application.
+ Hence it mustn't do anything that can't be done twice.
+ Also note that it may be called before the master module is initialized! }
+
+{GLOBAL}
+procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr);
+{ Do computations that are needed before master selection phase }
+
+
+{$ifdef D_MULTISCAN_FILES_SUPPORTED}
+
+{GLOBAL}
+procedure jpeg_new_colormap (cinfo : j_decompress_ptr);
+
+{$endif}
+
+{ Initialize master decompression control and select active modules.
+ This is performed at the start of jpeg_start_decompress. }
+
+{GLOBAL}
+procedure jinit_master_decompress (cinfo : j_decompress_ptr);
+
+implementation
+
+{ Private state }
+
+type
+ my_master_ptr = ^my_decomp_master;
+ my_decomp_master = record
+ pub : jpeg_decomp_master; { public fields }
+
+ pass_number : int; { # of passes completed }
+
+ using_merged_upsample : boolean; { TRUE if using merged upsample/cconvert }
+
+ { Saved references to initialized quantizer modules,
+ in case we need to switch modes. }
+
+ quantizer_1pass : jpeg_color_quantizer_ptr;
+ quantizer_2pass : jpeg_color_quantizer_ptr;
+ end;
+
+{ Determine whether merged upsample/color conversion should be used.
+ CRUCIAL: this must match the actual capabilities of jdmerge.c! }
+
+{LOCAL}
+function use_merged_upsample (cinfo : j_decompress_ptr) : boolean;
+var
+ compptr : jpeg_component_info_list_ptr;
+begin
+ compptr := cinfo^.comp_info;
+
+{$ifdef UPSAMPLE_MERGING_SUPPORTED}
+ { Merging is the equivalent of plain box-filter upsampling }
+ if (cinfo^.do_fancy_upsampling) or (cinfo^.CCIR601_sampling) then
+ begin
+ use_merged_upsample := FALSE;
+ exit;
+ end;
+ { jdmerge.c only supports YCC=>RGB color conversion }
+ if (cinfo^.jpeg_color_space <> JCS_YCbCr) or (cinfo^.num_components <> 3)
+ or (cinfo^.out_color_space <> JCS_RGB)
+ or (cinfo^.out_color_components <> RGB_PIXELSIZE) then
+ begin
+ use_merged_upsample := FALSE;
+ exit;
+ end;
+
+ { and it only handles 2h1v or 2h2v sampling ratios }
+ if (compptr^[0].h_samp_factor <> 2) or
+ (compptr^[1].h_samp_factor <> 1) or
+ (compptr^[2].h_samp_factor <> 1) or
+ (compptr^[0].v_samp_factor > 2) or
+ (compptr^[1].v_samp_factor <> 1) or
+ (compptr^[2].v_samp_factor <> 1) then
+ begin
+ use_merged_upsample := FALSE;
+ exit;
+ end;
+ { furthermore, it doesn't work if we've scaled the IDCTs differently }
+ if (compptr^[0].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or
+ (compptr^[1].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or
+ (compptr^[2].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) then
+ begin
+ use_merged_upsample := FALSE;
+ exit;
+ end;
+ { ??? also need to test for upsample-time rescaling, when & if supported }
+ use_merged_upsample := TRUE; { by golly, it'll work... }
+{$else}
+ use_merged_upsample := FALSE;
+{$endif}
+end;
+
+
+{ Compute output image dimensions and related values.
+ NOTE: this is exported for possible use by application.
+ Hence it mustn't do anything that can't be done twice.
+ Also note that it may be called before the master module is initialized! }
+
+{GLOBAL}
+procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr);
+{ Do computations that are needed before master selection phase }
+{$ifdef IDCT_SCALING_SUPPORTED}
+var
+ ci : int;
+ compptr : jpeg_component_info_ptr;
+{$endif}
+var
+ ssize : int;
+begin
+ { Prevent application from calling me at wrong times }
+ if (cinfo^.global_state <> DSTATE_READY) then
+ ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
+
+{$ifdef IDCT_SCALING_SUPPORTED}
+
+ { Compute actual output image dimensions and DCT scaling choices. }
+ if (cinfo^.scale_num * 8 <= cinfo^.scale_denom) then
+ begin
+ { Provide 1/8 scaling }
+ cinfo^.output_width := JDIMENSION (
+ jdiv_round_up( long(cinfo^.image_width), long(8)) );
+ cinfo^.output_height := JDIMENSION (
+ jdiv_round_up( long(cinfo^.image_height), long(8)) );
+ cinfo^.min_DCT_scaled_size := 1;
+ end
+ else
+ if (cinfo^.scale_num * 4 <= cinfo^.scale_denom) then
+ begin
+ { Provide 1/4 scaling }
+ cinfo^.output_width := JDIMENSION (
+ jdiv_round_up( long (cinfo^.image_width), long(4)) );
+ cinfo^.output_height := JDIMENSION (
+ jdiv_round_up( long (cinfo^.image_height), long(4)) );
+ cinfo^.min_DCT_scaled_size := 2;
+ end
+ else
+ if (cinfo^.scale_num * 2 <= cinfo^.scale_denom) then
+ begin
+ { Provide 1/2 scaling }
+ cinfo^.output_width := JDIMENSION (
+ jdiv_round_up( long(cinfo^.image_width), long(2)) );
+ cinfo^.output_height := JDIMENSION (
+ jdiv_round_up( long(cinfo^.image_height), long(2)) );
+ cinfo^.min_DCT_scaled_size := 4;
+ end
+ else
+ begin
+ { Provide 1/1 scaling }
+ cinfo^.output_width := cinfo^.image_width;
+ cinfo^.output_height := cinfo^.image_height;
+ cinfo^.min_DCT_scaled_size := DCTSIZE;
+ end;
+ { In selecting the actual DCT scaling for each component, we try to
+ scale up the chroma components via IDCT scaling rather than upsampling.
+ This saves time if the upsampler gets to use 1:1 scaling.
+ Note this code assumes that the supported DCT scalings are powers of 2. }
+
+ compptr := jpeg_component_info_ptr(cinfo^.comp_info);
+ for ci := 0 to pred(cinfo^.num_components) do
+ begin
+ ssize := cinfo^.min_DCT_scaled_size;
+ while (ssize < DCTSIZE) and
+ ((compptr^.h_samp_factor * ssize * 2 <=
+ cinfo^.max_h_samp_factor * cinfo^.min_DCT_scaled_size) and
+ (compptr^.v_samp_factor * ssize * 2 <=
+ cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size)) do
+ begin
+ ssize := ssize * 2;
+ end;
+ compptr^.DCT_scaled_size := ssize;
+ Inc(compptr);
+ end;
+
+ { Recompute downsampled dimensions of components;
+ application needs to know these if using raw downsampled data. }
+
+ compptr := jpeg_component_info_ptr(cinfo^.comp_info);
+ for ci := 0 to pred(cinfo^.num_components) do
+ begin
+ { Size in samples, after IDCT scaling }
+ compptr^.downsampled_width := JDIMENSION (
+ jdiv_round_up(long (cinfo^.image_width) *
+ long (compptr^.h_samp_factor * compptr^.DCT_scaled_size),
+ long (cinfo^.max_h_samp_factor * DCTSIZE)) );
+ compptr^.downsampled_height := JDIMENSION (
+ jdiv_round_up(long (cinfo^.image_height) *
+ long (compptr^.v_samp_factor * compptr^.DCT_scaled_size),
+ long (cinfo^.max_v_samp_factor * DCTSIZE)) );
+ Inc(compptr);
+ end;
+
+{$else} { !IDCT_SCALING_SUPPORTED }
+
+ { Hardwire it to "no scaling" }
+ cinfo^.output_width := cinfo^.image_width;
+ cinfo^.output_height := cinfo^.image_height;
+ { jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
+ and has computed unscaled downsampled_width and downsampled_height. }
+
+{$endif} { IDCT_SCALING_SUPPORTED }
+
+ { Report number of components in selected colorspace. }
+ { Probably this should be in the color conversion module... }
+ case (cinfo^.out_color_space) of
+ JCS_GRAYSCALE:
+ cinfo^.out_color_components := 1;
+{$ifndef RGB_PIXELSIZE_IS_3}
+ JCS_RGB:
+ cinfo^.out_color_components := RGB_PIXELSIZE;
+{$else}
+ JCS_RGB,
+{$endif} { else share code with YCbCr }
+ JCS_YCbCr:
+ cinfo^.out_color_components := 3;
+ JCS_CMYK,
+ JCS_YCCK:
+ cinfo^.out_color_components := 4;
+ else { else must be same colorspace as in file }
+ cinfo^.out_color_components := cinfo^.num_components;
+ end;
+ if (cinfo^.quantize_colors) then
+ cinfo^.output_components := 1
+ else
+ cinfo^.output_components := cinfo^.out_color_components;
+
+ { See if upsampler will want to emit more than one row at a time }
+ if (use_merged_upsample(cinfo)) then
+ cinfo^.rec_outbuf_height := cinfo^.max_v_samp_factor
+ else
+ cinfo^.rec_outbuf_height := 1;
+end;
+
+
+{ Several decompression processes need to range-limit values to the range
+ 0..MAXJSAMPLE; the input value may fall somewhat outside this range
+ due to noise introduced by quantization, roundoff error, etc. These
+ processes are inner loops and need to be as fast as possible. On most
+ machines, particularly CPUs with pipelines or instruction prefetch,
+ a (subscript-check-less) C table lookup
+ x := sample_range_limit[x];
+ is faster than explicit tests
+ if (x < 0) x := 0;
+ else if (x > MAXJSAMPLE) x := MAXJSAMPLE;
+ These processes all use a common table prepared by the routine below.
+
+ For most steps we can mathematically guarantee that the initial value
+ of x is within MAXJSAMPLE+1 of the legal range, so a table running from
+ -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
+ limiting step (just after the IDCT), a wildly out-of-range value is
+ possible if the input data is corrupt. To avoid any chance of indexing
+ off the end of memory and getting a bad-pointer trap, we perform the
+ post-IDCT limiting thus:
+ x := range_limit[x & MASK];
+ where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
+ samples. Under normal circumstances this is more than enough range and
+ a correct output will be generated; with bogus input data the mask will
+ cause wraparound, and we will safely generate a bogus-but-in-range output.
+ For the post-IDCT step, we want to convert the data from signed to unsigned
+ representation by adding CENTERJSAMPLE at the same time that we limit it.
+ So the post-IDCT limiting table ends up looking like this:
+ CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
+ MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ 0,1,...,CENTERJSAMPLE-1
+ Negative inputs select values from the upper half of the table after
+ masking.
+
+ We can save some space by overlapping the start of the post-IDCT table
+ with the simpler range limiting table. The post-IDCT table begins at
+ sample_range_limit + CENTERJSAMPLE.
+
+ Note that the table is allocated in near data space on PCs; it's small
+ enough and used often enough to justify this. }
+
+{LOCAL}
+procedure prepare_range_limit_table (cinfo : j_decompress_ptr);
+{ Allocate and fill in the sample_range_limit table }
+var
+ table : range_limit_table_ptr;
+ idct_table : JSAMPROW;
+ i : int;
+begin
+ table := range_limit_table_ptr (
+ cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
+ (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)) );
+
+ { First segment of "simple" table: limit[x] := 0 for x < 0 }
+ MEMZERO(table, (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+
+ cinfo^.sample_range_limit := (table);
+ { allow negative subscripts of simple table }
+ { is noop, handled via type definition (Nomssi) }
+ { Main part of "simple" table: limit[x] := x }
+ for i := 0 to MAXJSAMPLE do
+ table^[i] := JSAMPLE (i);
+ idct_table := JSAMPROW(@ table^[CENTERJSAMPLE]);
+ { Point to where post-IDCT table starts }
+ { End of simple table, rest of first half of post-IDCT table }
+ for i := CENTERJSAMPLE to pred(2*(MAXJSAMPLE+1)) do
+ idct_table^[i] := MAXJSAMPLE;
+ { Second half of post-IDCT table }
+ MEMZERO(@(idct_table^[2 * (MAXJSAMPLE+1)]),
+ (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+ MEMCOPY(@(idct_table^[(4 * (MAXJSAMPLE+1) - CENTERJSAMPLE)]),
+ @cinfo^.sample_range_limit^[0], CENTERJSAMPLE * SIZEOF(JSAMPLE));
+
+end;
+
+
+{ Master selection of decompression modules.
+ This is done once at jpeg_start_decompress time. We determine
+ which modules will be used and give them appropriate initialization calls.
+ We also initialize the decompressor input side to begin consuming data.
+
+ Since jpeg_read_header has finished, we know what is in the SOF
+ and (first) SOS markers. We also have all the application parameter
+ settings. }
+
+{LOCAL}
+procedure master_selection (cinfo : j_decompress_ptr);
+var
+ master : my_master_ptr;
+ use_c_buffer : boolean;
+ samplesperrow : long;
+ jd_samplesperrow : JDIMENSION;
+var
+ nscans : int;
+begin
+ master := my_master_ptr (cinfo^.master);
+
+ { Initialize dimensions and other stuff }
+ jpeg_calc_output_dimensions(cinfo);
+ prepare_range_limit_table(cinfo);
+
+ { Width of an output scanline must be representable as JDIMENSION. }
+ samplesperrow := long(cinfo^.output_width) * long (cinfo^.out_color_components);
+ jd_samplesperrow := JDIMENSION (samplesperrow);
+ if (long(jd_samplesperrow) <> samplesperrow) then
+ ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW);
+
+ { Initialize my private state }
+ master^.pass_number := 0;
+ master^.using_merged_upsample := use_merged_upsample(cinfo);
+
+ { Color quantizer selection }
+ master^.quantizer_1pass := NIL;
+ master^.quantizer_2pass := NIL;
+ { No mode changes if not using buffered-image mode. }
+ if (not cinfo^.quantize_colors) or (not cinfo^.buffered_image) then
+ begin
+ cinfo^.enable_1pass_quant := FALSE;
+ cinfo^.enable_external_quant := FALSE;
+ cinfo^.enable_2pass_quant := FALSE;
+ end;
+ if (cinfo^.quantize_colors) then
+ begin
+ if (cinfo^.raw_data_out) then
+ ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL);
+ { 2-pass quantizer only works in 3-component color space. }
+ if (cinfo^.out_color_components <> 3) then
+ begin
+ cinfo^.enable_1pass_quant := TRUE;
+ cinfo^.enable_external_quant := FALSE;
+ cinfo^.enable_2pass_quant := FALSE;
+ cinfo^.colormap := NIL;
+ end
+ else
+ if (cinfo^.colormap <> NIL) then
+ begin
+ cinfo^.enable_external_quant := TRUE;
+ end
+ else
+ if (cinfo^.two_pass_quantize) then
+ begin
+ cinfo^.enable_2pass_quant := TRUE;
+ end
+ else
+ begin
+ cinfo^.enable_1pass_quant := TRUE;
+ end;
+
+ if (cinfo^.enable_1pass_quant) then
+ begin
+{$ifdef QUANT_1PASS_SUPPORTED}
+ jinit_1pass_quantizer(cinfo);
+ master^.quantizer_1pass := cinfo^.cquantize;
+{$else}
+ ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
+{$endif}
+ end;
+
+ { We use the 2-pass code to map to external colormaps. }
+ if (cinfo^.enable_2pass_quant) or (cinfo^.enable_external_quant) then
+ begin
+{$ifdef QUANT_2PASS_SUPPORTED}
+ jinit_2pass_quantizer(cinfo);
+ master^.quantizer_2pass := cinfo^.cquantize;
+{$else}
+ ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
+{$endif}
+ end;
+ { If both quantizers are initialized, the 2-pass one is left active;
+ this is necessary for starting with quantization to an external map. }
+ end;
+
+ { Post-processing: in particular, color conversion first }
+ if (not cinfo^.raw_data_out) then
+ begin
+ if (master^.using_merged_upsample) then
+ begin
+{$ifdef UPSAMPLE_MERGING_SUPPORTED}
+ jinit_merged_upsampler(cinfo); { does color conversion too }
+{$else}
+ ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
+{$endif}
+ end
+ else
+ begin
+ jinit_color_deconverter(cinfo);
+ jinit_upsampler(cinfo);
+ end;
+ jinit_d_post_controller(cinfo, cinfo^.enable_2pass_quant);
+ end;
+ { Inverse DCT }
+ jinit_inverse_dct(cinfo);
+ { Entropy decoding: either Huffman or arithmetic coding. }
+ if (cinfo^.arith_code) then
+ begin
+ ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL);
+ end
+ else
+ begin
+ if (cinfo^.progressive_mode) then
+ begin
+{$ifdef D_PROGRESSIVE_SUPPORTED}
+ jinit_phuff_decoder(cinfo);
+{$else}
+ ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
+{$endif}
+ end
+ else
+ jinit_huff_decoder(cinfo);
+ end;
+
+ { Initialize principal buffer controllers. }
+ use_c_buffer := cinfo^.inputctl^.has_multiple_scans or cinfo^.buffered_image;
+ jinit_d_coef_controller(cinfo, use_c_buffer);
+
+ if (not cinfo^.raw_data_out) then
+ jinit_d_main_controller(cinfo, FALSE { never need full buffer here });
+
+ { We can now tell the memory manager to allocate virtual arrays. }
+ cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo));
+
+ { Initialize input side of decompressor to consume first scan. }
+ cinfo^.inputctl^.start_input_pass (cinfo);
+
+{$ifdef D_MULTISCAN_FILES_SUPPORTED}
+ { If jpeg_start_decompress will read the whole file, initialize
+ progress monitoring appropriately. The input step is counted
+ as one pass. }
+
+ if (cinfo^.progress <> NIL) and (not cinfo^.buffered_image) and
+ (cinfo^.inputctl^.has_multiple_scans) then
+ begin
+
+ { Estimate number of scans to set pass_limit. }
+ if (cinfo^.progressive_mode) then
+ begin
+ { Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. }
+ nscans := 2 + 3 * cinfo^.num_components;
+ end
+ else
+ begin
+ { For a nonprogressive multiscan file, estimate 1 scan per component. }
+ nscans := cinfo^.num_components;
+ end;
+ cinfo^.progress^.pass_counter := Long(0);
+ cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows) * nscans;
+ cinfo^.progress^.completed_passes := 0;
+ if cinfo^.enable_2pass_quant then
+ cinfo^.progress^.total_passes := 3
+ else
+ cinfo^.progress^.total_passes := 2;
+ { Count the input pass as done }
+ Inc(master^.pass_number);
+ end;
+{$endif} { D_MULTISCAN_FILES_SUPPORTED }
+end;
+
+
+{ Per-pass setup.
+ This is called at the beginning of each output pass. We determine which
+ modules will be active during this pass and give them appropriate
+ start_pass calls. We also set is_dummy_pass to indicate whether this
+ is a "real" output pass or a dummy pass for color quantization.
+ (In the latter case, jdapistd.c will crank the pass to completion.) }
+
+{METHODDEF}
+procedure prepare_for_output_pass (cinfo : j_decompress_ptr); far;
+var
+ master : my_master_ptr;
+begin
+ master := my_master_ptr (cinfo^.master);
+
+ if (master^.pub.is_dummy_pass) then
+ begin
+{$ifdef QUANT_2PASS_SUPPORTED}
+ { Final pass of 2-pass quantization }
+ master^.pub.is_dummy_pass := FALSE;
+ cinfo^.cquantize^.start_pass (cinfo, FALSE);
+ cinfo^.post^.start_pass (cinfo, JBUF_CRANK_DEST);
+ cinfo^.main^.start_pass (cinfo, JBUF_CRANK_DEST);
+{$else}
+ ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
+{$endif} { QUANT_2PASS_SUPPORTED }
+ end
+ else
+ begin
+ if (cinfo^.quantize_colors) and (cinfo^.colormap = NIL) then
+ begin
+ { Select new quantization method }
+ if (cinfo^.two_pass_quantize) and (cinfo^.enable_2pass_quant) then
+ begin
+ cinfo^.cquantize := master^.quantizer_2pass;
+ master^.pub.is_dummy_pass := TRUE;
+ end
+ else
+ if (cinfo^.enable_1pass_quant) then
+ begin
+ cinfo^.cquantize := master^.quantizer_1pass;
+ end
+ else
+ begin
+ ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE);
+ end;
+ end;
+ cinfo^.idct^.start_pass (cinfo);
+ cinfo^.coef^.start_output_pass (cinfo);
+ if (not cinfo^.raw_data_out) then
+ begin
+ if (not master^.using_merged_upsample) then
+ cinfo^.cconvert^.start_pass (cinfo);
+ cinfo^.upsample^.start_pass (cinfo);
+ if (cinfo^.quantize_colors) then
+ cinfo^.cquantize^.start_pass (cinfo, master^.pub.is_dummy_pass);
+ if master^.pub.is_dummy_pass then
+ cinfo^.post^.start_pass (cinfo, JBUF_SAVE_AND_PASS)
+ else
+ cinfo^.post^.start_pass (cinfo, JBUF_PASS_THRU);
+ cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU);
+ end;
+ end;
+
+ { Set up progress monitor's pass info if present }
+ if (cinfo^.progress <> NIL) then
+ begin
+ cinfo^.progress^.completed_passes := master^.pass_number;
+ if master^.pub.is_dummy_pass then
+ cinfo^.progress^.total_passes := master^.pass_number + 2
+ else
+ cinfo^.progress^.total_passes := master^.pass_number + 1;
+ { In buffered-image mode, we assume one more output pass if EOI not
+ yet reached, but no more passes if EOI has been reached. }
+
+ if (cinfo^.buffered_image) and (not cinfo^.inputctl^.eoi_reached) then
+ begin
+ if cinfo^.enable_2pass_quant then
+ Inc(cinfo^.progress^.total_passes, 2)
+ else
+ Inc(cinfo^.progress^.total_passes, 1);
+ end;
+ end;
+end;
+
+
+{ Finish up at end of an output pass. }
+
+{METHODDEF}
+procedure finish_output_pass (cinfo : j_decompress_ptr); far;
+var
+ master : my_master_ptr;
+begin
+ master := my_master_ptr (cinfo^.master);
+
+ if (cinfo^.quantize_colors) then
+ cinfo^.cquantize^.finish_pass (cinfo);
+ Inc(master^.pass_number);
+end;
+
+
+{$ifdef D_MULTISCAN_FILES_SUPPORTED}
+
+{ Switch to a new external colormap between output passes. }
+
+{GLOBAL}
+procedure jpeg_new_colormap (cinfo : j_decompress_ptr);
+var
+ master : my_master_ptr;
+begin
+ master := my_master_ptr (cinfo^.master);
+
+ { Prevent application from calling me at wrong times }
+ if (cinfo^.global_state <> DSTATE_BUFIMAGE) then
+ ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
+
+ if (cinfo^.quantize_colors) and (cinfo^.enable_external_quant) and
+ (cinfo^.colormap <> NIL) then
+ begin
+ { Select 2-pass quantizer for external colormap use }
+ cinfo^.cquantize := master^.quantizer_2pass;
+ { Notify quantizer of colormap change }
+ cinfo^.cquantize^.new_color_map (cinfo);
+ master^.pub.is_dummy_pass := FALSE; { just in case }
+ end
+ else
+ ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE);
+end;
+
+{$endif} { D_MULTISCAN_FILES_SUPPORTED }
+
+
+{ Initialize master decompression control and select active modules.
+ This is performed at the start of jpeg_start_decompress. }
+
+{GLOBAL}
+procedure jinit_master_decompress (cinfo : j_decompress_ptr);
+var
+ master : my_master_ptr;
+begin
+ master := my_master_ptr (
+ cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
+ SIZEOF(my_decomp_master)) );
+ cinfo^.master := jpeg_decomp_master_ptr(master);
+ master^.pub.prepare_for_output_pass := prepare_for_output_pass;
+ master^.pub.finish_output_pass := finish_output_pass;
+
+ master^.pub.is_dummy_pass := FALSE;
+
+ master_selection(cinfo);
+end;
+
+end.