DEADSOFTWARE

hopefully no more windows
[d2df-editor.git] / src / lib / vampimg / JpegLib / imjdapistd.pas
1 unit imjdapistd;
3 { Original : jdapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. }
5 { This file is part of the Independent JPEG Group's software.
6 For conditions of distribution and use, see the accompanying README file.
8 This file contains application interface code for the decompression half
9 of the JPEG library. These are the "standard" API routines that are
10 used in the normal full-decompression case. They are not used by a
11 transcoding-only application. Note that if an application links in
12 jpeg_start_decompress, it will end up linking in the entire decompressor.
13 We thus must separate this file from jdapimin.c to avoid linking the
14 whole decompression library into a transcoder. }
16 interface
18 {$I imjconfig.inc}
20 uses
21 imjmorecfg,
22 imjinclude,
23 imjdeferr,
24 imjerror,
25 imjpeglib,
26 imjdmaster;
28 { Read some scanlines of data from the JPEG decompressor.
30 The return value will be the number of lines actually read.
31 This may be less than the number requested in several cases,
32 including bottom of image, data source suspension, and operating
33 modes that emit multiple scanlines at a time.
35 Note: we warn about excess calls to jpeg_read_scanlines() since
36 this likely signals an application programmer error. However,
37 an oversize buffer (max_lines > scanlines remaining) is not an error. }
39 {GLOBAL}
40 function jpeg_read_scanlines (cinfo : j_decompress_ptr;
41 scanlines : JSAMPARRAY;
42 max_lines : JDIMENSION) : JDIMENSION;
45 { Alternate entry point to read raw data.
46 Processes exactly one iMCU row per call, unless suspended. }
48 {GLOBAL}
49 function jpeg_read_raw_data (cinfo : j_decompress_ptr;
50 data : JSAMPIMAGE;
51 max_lines : JDIMENSION) : JDIMENSION;
53 {$ifdef D_MULTISCAN_FILES_SUPPORTED}
55 { Initialize for an output pass in buffered-image mode. }
57 {GLOBAL}
58 function jpeg_start_output (cinfo : j_decompress_ptr;
59 scan_number : int) : boolean;
61 { Finish up after an output pass in buffered-image mode.
63 Returns FALSE if suspended. The return value need be inspected only if
64 a suspending data source is used. }
66 {GLOBAL}
67 function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean;
69 {$endif} { D_MULTISCAN_FILES_SUPPORTED }
71 { Decompression initialization.
72 jpeg_read_header must be completed before calling this.
74 If a multipass operating mode was selected, this will do all but the
75 last pass, and thus may take a great deal of time.
77 Returns FALSE if suspended. The return value need be inspected only if
78 a suspending data source is used. }
80 {GLOBAL}
81 function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean;
84 implementation
86 { Forward declarations }
87 {LOCAL}
88 function output_pass_setup (cinfo : j_decompress_ptr) : boolean; forward;
90 { Decompression initialization.
91 jpeg_read_header must be completed before calling this.
93 If a multipass operating mode was selected, this will do all but the
94 last pass, and thus may take a great deal of time.
96 Returns FALSE if suspended. The return value need be inspected only if
97 a suspending data source is used. }
99 {GLOBAL}
100 function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean;
101 var
102 retcode : int;
103 begin
104 if (cinfo^.global_state = DSTATE_READY) then
105 begin
106 { First call: initialize master control, select active modules }
107 jinit_master_decompress(cinfo);
108 if (cinfo^.buffered_image) then
109 begin
110 { No more work here; expecting jpeg_start_output next }
111 cinfo^.global_state := DSTATE_BUFIMAGE;
112 jpeg_start_decompress := TRUE;
113 exit;
114 end;
115 cinfo^.global_state := DSTATE_PRELOAD;
116 end;
117 if (cinfo^.global_state = DSTATE_PRELOAD) then
118 begin
119 { If file has multiple scans, absorb them all into the coef buffer }
120 if (cinfo^.inputctl^.has_multiple_scans) then
121 begin
122 {$ifdef D_MULTISCAN_FILES_SUPPORTED}
123 while TRUE do
124 begin
126 { Call progress monitor hook if present }
127 if (cinfo^.progress <> NIL) then
128 cinfo^.progress^.progress_monitor (j_common_ptr(cinfo));
129 { Absorb some more input }
130 retcode := cinfo^.inputctl^.consume_input (cinfo);
131 if (retcode = JPEG_SUSPENDED) then
132 begin
133 jpeg_start_decompress := FALSE;
134 exit;
135 end;
136 if (retcode = JPEG_REACHED_EOI) then
137 break;
138 { Advance progress counter if appropriate }
139 if (cinfo^.progress <> NIL) and
140 ((retcode = JPEG_ROW_COMPLETED) or (retcode = JPEG_REACHED_SOS)) then
141 begin
142 Inc(cinfo^.progress^.pass_counter);
143 if (cinfo^.progress^.pass_counter >= cinfo^.progress^.pass_limit) then
144 begin
145 { jdmaster underestimated number of scans; ratchet up one scan }
146 Inc(cinfo^.progress^.pass_limit, long(cinfo^.total_iMCU_rows));
147 end;
148 end;
149 end;
150 {$else}
151 ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
152 {$endif} { D_MULTISCAN_FILES_SUPPORTED }
153 end;
154 cinfo^.output_scan_number := cinfo^.input_scan_number;
155 end
156 else
157 if (cinfo^.global_state <> DSTATE_PRESCAN) then
158 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
159 { Perform any dummy output passes, and set up for the final pass }
160 jpeg_start_decompress := output_pass_setup(cinfo);
161 end;
164 { Set up for an output pass, and perform any dummy pass(es) needed.
165 Common subroutine for jpeg_start_decompress and jpeg_start_output.
166 Entry: global_state := DSTATE_PRESCAN only if previously suspended.
167 Exit: If done, returns TRUE and sets global_state for proper output mode.
168 If suspended, returns FALSE and sets global_state := DSTATE_PRESCAN. }
170 {LOCAL}
171 function output_pass_setup (cinfo : j_decompress_ptr) : boolean;
172 var
173 last_scanline : JDIMENSION;
174 begin
175 if (cinfo^.global_state <> DSTATE_PRESCAN) then
176 begin
177 { First call: do pass setup }
178 cinfo^.master^.prepare_for_output_pass (cinfo);
179 cinfo^.output_scanline := 0;
180 cinfo^.global_state := DSTATE_PRESCAN;
181 end;
182 { Loop over any required dummy passes }
183 while (cinfo^.master^.is_dummy_pass) do
184 begin
185 {$ifdef QUANT_2PASS_SUPPORTED}
186 { Crank through the dummy pass }
187 while (cinfo^.output_scanline < cinfo^.output_height) do
188 begin
189 { Call progress monitor hook if present }
190 if (cinfo^.progress <> NIL) then
191 begin
192 cinfo^.progress^.pass_counter := long (cinfo^.output_scanline);
193 cinfo^.progress^.pass_limit := long (cinfo^.output_height);
194 cinfo^.progress^.progress_monitor (j_common_ptr(cinfo));
195 end;
196 { Process some data }
197 last_scanline := cinfo^.output_scanline;
198 cinfo^.main^.process_data (cinfo, JSAMPARRAY(NIL),
199 cinfo^.output_scanline, {var}
200 JDIMENSION(0));
201 if (cinfo^.output_scanline = last_scanline) then
202 begin
203 output_pass_setup := FALSE; { No progress made, must suspend }
204 exit;
205 end;
206 end;
207 { Finish up dummy pass, and set up for another one }
208 cinfo^.master^.finish_output_pass (cinfo);
209 cinfo^.master^.prepare_for_output_pass (cinfo);
210 cinfo^.output_scanline := 0;
211 {$else}
212 ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
213 {$endif} { QUANT_2PASS_SUPPORTED }
214 end;
215 { Ready for application to drive output pass through
216 jpeg_read_scanlines or jpeg_read_raw_data. }
217 if cinfo^.raw_data_out then
218 cinfo^.global_state := DSTATE_RAW_OK
219 else
220 cinfo^.global_state := DSTATE_SCANNING;
221 output_pass_setup := TRUE;
222 end;
225 { Read some scanlines of data from the JPEG decompressor.
227 The return value will be the number of lines actually read.
228 This may be less than the number requested in several cases,
229 including bottom of image, data source suspension, and operating
230 modes that emit multiple scanlines at a time.
232 Note: we warn about excess calls to jpeg_read_scanlines() since
233 this likely signals an application programmer error. However,
234 an oversize buffer (max_lines > scanlines remaining) is not an error. }
236 {GLOBAL}
237 function jpeg_read_scanlines (cinfo : j_decompress_ptr;
238 scanlines : JSAMPARRAY;
239 max_lines : JDIMENSION) : JDIMENSION;
240 var
241 row_ctr : JDIMENSION;
242 begin
243 if (cinfo^.global_state <> DSTATE_SCANNING) then
244 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
245 if (cinfo^.output_scanline >= cinfo^.output_height) then
246 begin
247 WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA);
248 jpeg_read_scanlines := 0;
249 exit;
250 end;
252 { Call progress monitor hook if present }
253 if (cinfo^.progress <> NIL) then
254 begin
255 cinfo^.progress^.pass_counter := long (cinfo^.output_scanline);
256 cinfo^.progress^.pass_limit := long (cinfo^.output_height);
257 cinfo^.progress^.progress_monitor (j_common_ptr(cinfo));
258 end;
260 { Process some data }
261 row_ctr := 0;
262 cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, max_lines);
263 Inc(cinfo^.output_scanline, row_ctr);
264 jpeg_read_scanlines := row_ctr;
265 end;
268 { Alternate entry point to read raw data.
269 Processes exactly one iMCU row per call, unless suspended. }
271 {GLOBAL}
272 function jpeg_read_raw_data (cinfo : j_decompress_ptr;
273 data : JSAMPIMAGE;
274 max_lines : JDIMENSION) : JDIMENSION;
275 var
276 lines_per_iMCU_row : JDIMENSION;
277 begin
278 if (cinfo^.global_state <> DSTATE_RAW_OK) then
279 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
280 if (cinfo^.output_scanline >= cinfo^.output_height) then
281 begin
282 WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA);
283 jpeg_read_raw_data := 0;
284 exit;
285 end;
287 { Call progress monitor hook if present }
288 if (cinfo^.progress <> NIL) then
289 begin
290 cinfo^.progress^.pass_counter := long (cinfo^.output_scanline);
291 cinfo^.progress^.pass_limit := long (cinfo^.output_height);
292 cinfo^.progress^.progress_monitor (j_common_ptr(cinfo));
293 end;
295 { Verify that at least one iMCU row can be returned. }
296 lines_per_iMCU_row := cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size;
297 if (max_lines < lines_per_iMCU_row) then
298 ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE);
300 { Decompress directly into user's buffer. }
301 if (cinfo^.coef^.decompress_data (cinfo, data) = 0) then
302 begin
303 jpeg_read_raw_data := 0; { suspension forced, can do nothing more }
304 exit;
305 end;
307 { OK, we processed one iMCU row. }
308 Inc(cinfo^.output_scanline, lines_per_iMCU_row);
309 jpeg_read_raw_data := lines_per_iMCU_row;
310 end;
313 { Additional entry points for buffered-image mode. }
315 {$ifdef D_MULTISCAN_FILES_SUPPORTED}
317 { Initialize for an output pass in buffered-image mode. }
319 {GLOBAL}
320 function jpeg_start_output (cinfo : j_decompress_ptr;
321 scan_number : int) : boolean;
322 begin
323 if (cinfo^.global_state <> DSTATE_BUFIMAGE) and
324 (cinfo^.global_state <> DSTATE_PRESCAN) then
325 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
326 { Limit scan number to valid range }
327 if (scan_number <= 0) then
328 scan_number := 1;
329 if (cinfo^.inputctl^.eoi_reached) and
330 (scan_number > cinfo^.input_scan_number) then
331 scan_number := cinfo^.input_scan_number;
332 cinfo^.output_scan_number := scan_number;
333 { Perform any dummy output passes, and set up for the real pass }
334 jpeg_start_output := output_pass_setup(cinfo);
335 end;
338 { Finish up after an output pass in buffered-image mode.
340 Returns FALSE if suspended. The return value need be inspected only if
341 a suspending data source is used. }
343 {GLOBAL}
344 function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean;
345 begin
346 if ((cinfo^.global_state = DSTATE_SCANNING) or
347 (cinfo^.global_state = DSTATE_RAW_OK) and cinfo^.buffered_image) then
348 begin
349 { Terminate this pass. }
350 { We do not require the whole pass to have been completed. }
351 cinfo^.master^.finish_output_pass (cinfo);
352 cinfo^.global_state := DSTATE_BUFPOST;
353 end
354 else
355 if (cinfo^.global_state <> DSTATE_BUFPOST) then
356 begin
357 { BUFPOST := repeat call after a suspension, anything else is error }
358 ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
359 end;
360 { Read markers looking for SOS or EOI }
361 while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and
362 (not cinfo^.inputctl^.eoi_reached) do
363 begin
364 if (cinfo^.inputctl^.consume_input (cinfo) = JPEG_SUSPENDED) then
365 begin
366 jpeg_finish_output := FALSE; { Suspend, come back later }
367 exit;
368 end;
369 end;
370 cinfo^.global_state := DSTATE_BUFIMAGE;
371 jpeg_finish_output := TRUE;
372 end;
374 {$endif} { D_MULTISCAN_FILES_SUPPORTED }
376 end.