]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/jpeg6/jdapistd.cpp
...
[xonotic/netradiant.git] / libs / jpeg6 / jdapistd.cpp
1 /*
2
3  * jdapistd.c
4
5  *
6
7  * Copyright (C) 1994-1995, Thomas G. Lane.
8
9  * This file is part of the Independent JPEG Group's software.
10
11  * For conditions of distribution and use, see the accompanying README file.
12
13  *
14
15  * This file contains application interface code for the decompression half
16
17  * of the JPEG library.  These are the "standard" API routines that are
18
19  * used in the normal full-decompression case.  They are not used by a
20
21  * transcoding-only application.  Note that if an application links in
22
23  * jpeg_start_decompress, it will end up linking in the entire decompressor.
24
25  * We thus must separate this file from jdapimin.c to avoid linking the
26
27  * whole decompression library into a transcoder.
28
29  */
30
31
32
33 #define JPEG_INTERNALS
34
35 #include "jinclude.h"
36
37 #include "radiant_jpeglib.h"
38
39
40
41
42
43 /* Forward declarations */
44
45 LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo));
46
47
48
49
50
51 /*
52
53  * Decompression initialization.
54
55  * jpeg_read_header must be completed before calling this.
56
57  *
58
59  * If a multipass operating mode was selected, this will do all but the
60
61  * last pass, and thus may take a great deal of time.
62
63  *
64
65  * Returns FALSE if suspended.  The return value need be inspected only if
66
67  * a suspending data source is used.
68
69  */
70
71
72
73 GLOBAL boolean
74
75 jpeg_start_decompress (j_decompress_ptr cinfo)
76
77 {
78
79   if (cinfo->global_state == DSTATE_READY) {
80
81     /* First call: initialize master control, select active modules */
82
83     jinit_master_decompress(cinfo);
84
85     if (cinfo->buffered_image) {
86
87       /* No more work here; expecting jpeg_start_output next */
88
89       cinfo->global_state = DSTATE_BUFIMAGE;
90
91       return TRUE;
92
93     }
94
95     cinfo->global_state = DSTATE_PRELOAD;
96
97   }
98
99   if (cinfo->global_state == DSTATE_PRELOAD) {
100
101     /* If file has multiple scans, absorb them all into the coef buffer */
102
103     if (cinfo->inputctl->has_multiple_scans) {
104
105 #ifdef D_MULTISCAN_FILES_SUPPORTED
106
107       for (;;) {
108
109         int retcode;
110
111         /* Call progress monitor hook if present */
112
113         if (cinfo->progress != NULL)
114
115           (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
116
117         /* Absorb some more input */
118
119         retcode = (*cinfo->inputctl->consume_input) (cinfo);
120
121         if (retcode == JPEG_SUSPENDED)
122
123           return FALSE;
124
125         if (retcode == JPEG_REACHED_EOI)
126
127           break;
128
129         /* Advance progress counter if appropriate */
130
131         if (cinfo->progress != NULL &&
132
133             (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
134
135           if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
136
137             /* jdmaster underestimated number of scans; ratchet up one scan */
138
139             cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
140
141           }
142
143         }
144
145       }
146
147 #else
148
149       ERREXIT(cinfo, JERR_NOT_COMPILED);
150
151 #endif /* D_MULTISCAN_FILES_SUPPORTED */
152
153     }
154
155     cinfo->output_scan_number = cinfo->input_scan_number;
156
157   } else if (cinfo->global_state != DSTATE_PRESCAN)
158
159     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
160
161   /* Perform any dummy output passes, and set up for the final pass */
162
163   return output_pass_setup(cinfo);
164
165 }
166
167
168
169
170
171 /*
172
173  * Set up for an output pass, and perform any dummy pass(es) needed.
174
175  * Common subroutine for jpeg_start_decompress and jpeg_start_output.
176
177  * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
178
179  * Exit: If done, returns TRUE and sets global_state for proper output mode.
180
181  *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
182
183  */
184
185
186
187 LOCAL boolean
188
189 output_pass_setup (j_decompress_ptr cinfo)
190
191 {
192
193   if (cinfo->global_state != DSTATE_PRESCAN) {
194
195     /* First call: do pass setup */
196
197     (*cinfo->master->prepare_for_output_pass) (cinfo);
198
199     cinfo->output_scanline = 0;
200
201     cinfo->global_state = DSTATE_PRESCAN;
202
203   }
204
205   /* Loop over any required dummy passes */
206
207   while (cinfo->master->is_dummy_pass) {
208
209 #ifdef QUANT_2PASS_SUPPORTED
210
211     /* Crank through the dummy pass */
212
213     while (cinfo->output_scanline < cinfo->output_height) {
214
215       JDIMENSION last_scanline;
216
217       /* Call progress monitor hook if present */
218
219       if (cinfo->progress != NULL) {
220
221         cinfo->progress->pass_counter = (long) cinfo->output_scanline;
222
223         cinfo->progress->pass_limit = (long) cinfo->output_height;
224
225         (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
226
227       }
228
229       /* Process some data */
230
231       last_scanline = cinfo->output_scanline;
232
233       (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
234
235                                     &cinfo->output_scanline, (JDIMENSION) 0);
236
237       if (cinfo->output_scanline == last_scanline)
238
239         return FALSE;           /* No progress made, must suspend */
240
241     }
242
243     /* Finish up dummy pass, and set up for another one */
244
245     (*cinfo->master->finish_output_pass) (cinfo);
246
247     (*cinfo->master->prepare_for_output_pass) (cinfo);
248
249     cinfo->output_scanline = 0;
250
251 #else
252
253     ERREXIT(cinfo, JERR_NOT_COMPILED);
254
255 #endif /* QUANT_2PASS_SUPPORTED */
256
257   }
258
259   /* Ready for application to drive output pass through
260
261    * jpeg_read_scanlines or jpeg_read_raw_data.
262
263    */
264
265   cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
266
267   return TRUE;
268
269 }
270
271
272
273
274
275 /*
276
277  * Read some scanlines of data from the JPEG decompressor.
278
279  *
280
281  * The return value will be the number of lines actually read.
282
283  * This may be less than the number requested in several cases,
284
285  * including bottom of image, data source suspension, and operating
286
287  * modes that emit multiple scanlines at a time.
288
289  *
290
291  * Note: we warn about excess calls to jpeg_read_scanlines() since
292
293  * this likely signals an application programmer error.  However,
294
295  * an oversize buffer (max_lines > scanlines remaining) is not an error.
296
297  */
298
299
300
301 GLOBAL JDIMENSION
302
303 jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
304
305                      JDIMENSION max_lines)
306
307 {
308
309   JDIMENSION row_ctr;
310
311
312
313   if (cinfo->global_state != DSTATE_SCANNING)
314
315     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
316
317   if (cinfo->output_scanline >= cinfo->output_height) {
318
319     WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
320
321     return 0;
322
323   }
324
325
326
327   /* Call progress monitor hook if present */
328
329   if (cinfo->progress != NULL) {
330
331     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
332
333     cinfo->progress->pass_limit = (long) cinfo->output_height;
334
335     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
336
337   }
338
339
340
341   /* Process some data */
342
343   row_ctr = 0;
344
345   (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
346
347   cinfo->output_scanline += row_ctr;
348
349   return row_ctr;
350
351 }
352
353
354
355
356
357 /*
358
359  * Alternate entry point to read raw data.
360
361  * Processes exactly one iMCU row per call, unless suspended.
362
363  */
364
365
366
367 GLOBAL JDIMENSION
368
369 jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
370
371                     JDIMENSION max_lines)
372
373 {
374
375   JDIMENSION lines_per_iMCU_row;
376
377
378
379   if (cinfo->global_state != DSTATE_RAW_OK)
380
381     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
382
383   if (cinfo->output_scanline >= cinfo->output_height) {
384
385     WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
386
387     return 0;
388
389   }
390
391
392
393   /* Call progress monitor hook if present */
394
395   if (cinfo->progress != NULL) {
396
397     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
398
399     cinfo->progress->pass_limit = (long) cinfo->output_height;
400
401     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
402
403   }
404
405
406
407   /* Verify that at least one iMCU row can be returned. */
408
409   lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
410
411   if (max_lines < lines_per_iMCU_row)
412
413     ERREXIT(cinfo, JERR_BUFFER_SIZE);
414
415
416
417   /* Decompress directly into user's buffer. */
418
419   if (! (*cinfo->coef->decompress_data) (cinfo, data))
420
421     return 0;                   /* suspension forced, can do nothing more */
422
423
424
425   /* OK, we processed one iMCU row. */
426
427   cinfo->output_scanline += lines_per_iMCU_row;
428
429   return lines_per_iMCU_row;
430
431 }
432
433
434
435
436
437 /* Additional entry points for buffered-image mode. */
438
439
440
441 #ifdef D_MULTISCAN_FILES_SUPPORTED
442
443
444
445 /*
446
447  * Initialize for an output pass in buffered-image mode.
448
449  */
450
451
452
453 GLOBAL boolean
454
455 jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
456
457 {
458
459   if (cinfo->global_state != DSTATE_BUFIMAGE &&
460
461       cinfo->global_state != DSTATE_PRESCAN)
462
463     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
464
465   /* Limit scan number to valid range */
466
467   if (scan_number <= 0)
468
469     scan_number = 1;
470
471   if (cinfo->inputctl->eoi_reached &&
472
473       scan_number > cinfo->input_scan_number)
474
475     scan_number = cinfo->input_scan_number;
476
477   cinfo->output_scan_number = scan_number;
478
479   /* Perform any dummy output passes, and set up for the real pass */
480
481   return output_pass_setup(cinfo);
482
483 }
484
485
486
487
488
489 /*
490
491  * Finish up after an output pass in buffered-image mode.
492
493  *
494
495  * Returns FALSE if suspended.  The return value need be inspected only if
496
497  * a suspending data source is used.
498
499  */
500
501
502
503 GLOBAL boolean
504
505 jpeg_finish_output (j_decompress_ptr cinfo)
506
507 {
508
509   if ((cinfo->global_state == DSTATE_SCANNING ||
510
511        cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
512
513     /* Terminate this pass. */
514
515     /* We do not require the whole pass to have been completed. */
516
517     (*cinfo->master->finish_output_pass) (cinfo);
518
519     cinfo->global_state = DSTATE_BUFPOST;
520
521   } else if (cinfo->global_state != DSTATE_BUFPOST) {
522
523     /* BUFPOST = repeat call after a suspension, anything else is error */
524
525     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
526
527   }
528
529   /* Read markers looking for SOS or EOI */
530
531   while (cinfo->input_scan_number <= cinfo->output_scan_number &&
532
533          ! cinfo->inputctl->eoi_reached) {
534
535     if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
536
537       return FALSE;             /* Suspend, come back later */
538
539   }
540
541   cinfo->global_state = DSTATE_BUFIMAGE;
542
543   return TRUE;
544
545 }
546
547
548
549 #endif /* D_MULTISCAN_FILES_SUPPORTED */
550