1 : /*
2 : * jdapistd.c
3 : *
4 : * Copyright (C) 1994-1996, Thomas G. Lane.
5 : * Copyright (C) 2010, D. R. Commander.
6 : * This file is part of the Independent JPEG Group's software.
7 : * For conditions of distribution and use, see the accompanying README file.
8 : *
9 : * This file contains application interface code for the decompression half
10 : * of the JPEG library. These are the "standard" API routines that are
11 : * used in the normal full-decompression case. They are not used by a
12 : * transcoding-only application. Note that if an application links in
13 : * jpeg_start_decompress, it will end up linking in the entire decompressor.
14 : * We thus must separate this file from jdapimin.c to avoid linking the
15 : * whole decompression library into a transcoder.
16 : */
17 :
18 : #define JPEG_INTERNALS
19 : #include "jinclude.h"
20 : #include "jpeglib.h"
21 : #include "jpegcomp.h"
22 :
23 :
24 : /* Forward declarations */
25 : LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
26 :
27 :
28 : /*
29 : * Decompression initialization.
30 : * jpeg_read_header must be completed before calling this.
31 : *
32 : * If a multipass operating mode was selected, this will do all but the
33 : * last pass, and thus may take a great deal of time.
34 : *
35 : * Returns FALSE if suspended. The return value need be inspected only if
36 : * a suspending data source is used.
37 : */
38 :
39 : GLOBAL(boolean)
40 5 : jpeg_start_decompress (j_decompress_ptr cinfo)
41 : {
42 5 : if (cinfo->global_state == DSTATE_READY) {
43 : /* First call: initialize master control, select active modules */
44 5 : jinit_master_decompress(cinfo);
45 5 : if (cinfo->buffered_image) {
46 : /* No more work here; expecting jpeg_start_output next */
47 0 : cinfo->global_state = DSTATE_BUFIMAGE;
48 0 : return TRUE;
49 : }
50 5 : cinfo->global_state = DSTATE_PRELOAD;
51 : }
52 5 : if (cinfo->global_state == DSTATE_PRELOAD) {
53 : /* If file has multiple scans, absorb them all into the coef buffer */
54 5 : if (cinfo->inputctl->has_multiple_scans) {
55 : #ifdef D_MULTISCAN_FILES_SUPPORTED
56 : for (;;) {
57 : int retcode;
58 : /* Call progress monitor hook if present */
59 0 : if (cinfo->progress != NULL)
60 0 : (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
61 : /* Absorb some more input */
62 0 : retcode = (*cinfo->inputctl->consume_input) (cinfo);
63 0 : if (retcode == JPEG_SUSPENDED)
64 0 : return FALSE;
65 0 : if (retcode == JPEG_REACHED_EOI)
66 0 : break;
67 : /* Advance progress counter if appropriate */
68 0 : if (cinfo->progress != NULL &&
69 0 : (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
70 0 : if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
71 : /* jdmaster underestimated number of scans; ratchet up one scan */
72 0 : cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
73 : }
74 : }
75 0 : }
76 : #else
77 : ERREXIT(cinfo, JERR_NOT_COMPILED);
78 : #endif /* D_MULTISCAN_FILES_SUPPORTED */
79 : }
80 5 : cinfo->output_scan_number = cinfo->input_scan_number;
81 0 : } else if (cinfo->global_state != DSTATE_PRESCAN)
82 0 : ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
83 : /* Perform any dummy output passes, and set up for the final pass */
84 5 : return output_pass_setup(cinfo);
85 : }
86 :
87 :
88 : /*
89 : * Set up for an output pass, and perform any dummy pass(es) needed.
90 : * Common subroutine for jpeg_start_decompress and jpeg_start_output.
91 : * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
92 : * Exit: If done, returns TRUE and sets global_state for proper output mode.
93 : * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
94 : */
95 :
96 : LOCAL(boolean)
97 5 : output_pass_setup (j_decompress_ptr cinfo)
98 : {
99 5 : if (cinfo->global_state != DSTATE_PRESCAN) {
100 : /* First call: do pass setup */
101 5 : (*cinfo->master->prepare_for_output_pass) (cinfo);
102 5 : cinfo->output_scanline = 0;
103 5 : cinfo->global_state = DSTATE_PRESCAN;
104 : }
105 : /* Loop over any required dummy passes */
106 10 : while (cinfo->master->is_dummy_pass) {
107 : #ifdef QUANT_2PASS_SUPPORTED
108 : /* Crank through the dummy pass */
109 0 : while (cinfo->output_scanline < cinfo->output_height) {
110 : JDIMENSION last_scanline;
111 : /* Call progress monitor hook if present */
112 0 : if (cinfo->progress != NULL) {
113 0 : cinfo->progress->pass_counter = (long) cinfo->output_scanline;
114 0 : cinfo->progress->pass_limit = (long) cinfo->output_height;
115 0 : (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
116 : }
117 : /* Process some data */
118 0 : last_scanline = cinfo->output_scanline;
119 0 : (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
120 : &cinfo->output_scanline, (JDIMENSION) 0);
121 0 : if (cinfo->output_scanline == last_scanline)
122 0 : return FALSE; /* No progress made, must suspend */
123 : }
124 : /* Finish up dummy pass, and set up for another one */
125 0 : (*cinfo->master->finish_output_pass) (cinfo);
126 0 : (*cinfo->master->prepare_for_output_pass) (cinfo);
127 0 : cinfo->output_scanline = 0;
128 : #else
129 : ERREXIT(cinfo, JERR_NOT_COMPILED);
130 : #endif /* QUANT_2PASS_SUPPORTED */
131 : }
132 : /* Ready for application to drive output pass through
133 : * jpeg_read_scanlines or jpeg_read_raw_data.
134 : */
135 5 : cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
136 5 : return TRUE;
137 : }
138 :
139 :
140 : /*
141 : * Read some scanlines of data from the JPEG decompressor.
142 : *
143 : * The return value will be the number of lines actually read.
144 : * This may be less than the number requested in several cases,
145 : * including bottom of image, data source suspension, and operating
146 : * modes that emit multiple scanlines at a time.
147 : *
148 : * Note: we warn about excess calls to jpeg_read_scanlines() since
149 : * this likely signals an application programmer error. However,
150 : * an oversize buffer (max_lines > scanlines remaining) is not an error.
151 : */
152 :
153 : GLOBAL(JDIMENSION)
154 233 : jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
155 : JDIMENSION max_lines)
156 : {
157 : JDIMENSION row_ctr;
158 :
159 233 : if (cinfo->global_state != DSTATE_SCANNING)
160 0 : ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
161 233 : if (cinfo->output_scanline >= cinfo->output_height) {
162 0 : WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
163 0 : return 0;
164 : }
165 :
166 : /* Call progress monitor hook if present */
167 233 : if (cinfo->progress != NULL) {
168 0 : cinfo->progress->pass_counter = (long) cinfo->output_scanline;
169 0 : cinfo->progress->pass_limit = (long) cinfo->output_height;
170 0 : (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
171 : }
172 :
173 : /* Process some data */
174 233 : row_ctr = 0;
175 233 : (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
176 233 : cinfo->output_scanline += row_ctr;
177 233 : return row_ctr;
178 : }
179 :
180 :
181 : /*
182 : * Alternate entry point to read raw data.
183 : * Processes exactly one iMCU row per call, unless suspended.
184 : */
185 :
186 : GLOBAL(JDIMENSION)
187 0 : jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
188 : JDIMENSION max_lines)
189 : {
190 : JDIMENSION lines_per_iMCU_row;
191 :
192 0 : if (cinfo->global_state != DSTATE_RAW_OK)
193 0 : ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
194 0 : if (cinfo->output_scanline >= cinfo->output_height) {
195 0 : WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
196 0 : return 0;
197 : }
198 :
199 : /* Call progress monitor hook if present */
200 0 : if (cinfo->progress != NULL) {
201 0 : cinfo->progress->pass_counter = (long) cinfo->output_scanline;
202 0 : cinfo->progress->pass_limit = (long) cinfo->output_height;
203 0 : (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
204 : }
205 :
206 : /* Verify that at least one iMCU row can be returned. */
207 0 : lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size;
208 0 : if (max_lines < lines_per_iMCU_row)
209 0 : ERREXIT(cinfo, JERR_BUFFER_SIZE);
210 :
211 : /* Decompress directly into user's buffer. */
212 0 : if (! (*cinfo->coef->decompress_data) (cinfo, data))
213 0 : return 0; /* suspension forced, can do nothing more */
214 :
215 : /* OK, we processed one iMCU row. */
216 0 : cinfo->output_scanline += lines_per_iMCU_row;
217 0 : return lines_per_iMCU_row;
218 : }
219 :
220 :
221 : /* Additional entry points for buffered-image mode. */
222 :
223 : #ifdef D_MULTISCAN_FILES_SUPPORTED
224 :
225 : /*
226 : * Initialize for an output pass in buffered-image mode.
227 : */
228 :
229 : GLOBAL(boolean)
230 0 : jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
231 : {
232 0 : if (cinfo->global_state != DSTATE_BUFIMAGE &&
233 0 : cinfo->global_state != DSTATE_PRESCAN)
234 0 : ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
235 : /* Limit scan number to valid range */
236 0 : if (scan_number <= 0)
237 0 : scan_number = 1;
238 0 : if (cinfo->inputctl->eoi_reached &&
239 0 : scan_number > cinfo->input_scan_number)
240 0 : scan_number = cinfo->input_scan_number;
241 0 : cinfo->output_scan_number = scan_number;
242 : /* Perform any dummy output passes, and set up for the real pass */
243 0 : return output_pass_setup(cinfo);
244 : }
245 :
246 :
247 : /*
248 : * Finish up after an output pass in buffered-image mode.
249 : *
250 : * Returns FALSE if suspended. The return value need be inspected only if
251 : * a suspending data source is used.
252 : */
253 :
254 : GLOBAL(boolean)
255 0 : jpeg_finish_output (j_decompress_ptr cinfo)
256 : {
257 0 : if ((cinfo->global_state == DSTATE_SCANNING ||
258 0 : cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
259 : /* Terminate this pass. */
260 : /* We do not require the whole pass to have been completed. */
261 0 : (*cinfo->master->finish_output_pass) (cinfo);
262 0 : cinfo->global_state = DSTATE_BUFPOST;
263 0 : } else if (cinfo->global_state != DSTATE_BUFPOST) {
264 : /* BUFPOST = repeat call after a suspension, anything else is error */
265 0 : ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
266 : }
267 : /* Read markers looking for SOS or EOI */
268 0 : while (cinfo->input_scan_number <= cinfo->output_scan_number &&
269 0 : ! cinfo->inputctl->eoi_reached) {
270 0 : if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
271 0 : return FALSE; /* Suspend, come back later */
272 : }
273 0 : cinfo->global_state = DSTATE_BUFIMAGE;
274 0 : return TRUE;
275 : }
276 :
277 : #endif /* D_MULTISCAN_FILES_SUPPORTED */
|