1/*
2 * jdapistd.c
3 *
4 * 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.
7 *
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.
15 */
16
17#define JPEG_INTERNALS
18#include "jinclude.h"
19#include "jpeglib.h"
20
21
22/* Forward declarations */
23LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
24
25
26/*
27 * Decompression initialization.
28 * jpeg_read_header must be completed before calling this.
29 *
30 * If a multipass operating mode was selected, this will do all but the
31 * last pass, and thus may take a great deal of time.
32 *
33 * Returns FALSE if suspended.  The return value need be inspected only if
34 * a suspending data source is used.
35 */
36
37GLOBAL(boolean)
38jpeg_start_decompress (j_decompress_ptr cinfo)
39{
40  if (cinfo->global_state == DSTATE_READY) {
41    /* First call: initialize master control, select active modules */
42    jinit_master_decompress(cinfo);
43    if (cinfo->buffered_image) {
44      /* No more work here; expecting jpeg_start_output next */
45      cinfo->global_state = DSTATE_BUFIMAGE;
46      return TRUE;
47    }
48    cinfo->global_state = DSTATE_PRELOAD;
49  }
50  if (cinfo->global_state == DSTATE_PRELOAD) {
51    /* If file has multiple scans, absorb them all into the coef buffer */
52    if (cinfo->inputctl->has_multiple_scans) {
53#ifdef D_MULTISCAN_FILES_SUPPORTED
54      for (;;) {
55	int retcode;
56	/* Call progress monitor hook if present */
57	if (cinfo->progress != NULL)
58	  (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
59	/* Absorb some more input */
60	retcode = (*cinfo->inputctl->consume_input) (cinfo);
61	if (retcode == JPEG_SUSPENDED)
62	  return FALSE;
63	if (retcode == JPEG_REACHED_EOI)
64	  break;
65	/* Advance progress counter if appropriate */
66	if (cinfo->progress != NULL &&
67	    (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
68	  if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
69	    /* jdmaster underestimated number of scans; ratchet up one scan */
70	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
71	  }
72	}
73      }
74#else
75      ERREXIT(cinfo, JERR_NOT_COMPILED);
76#endif /* D_MULTISCAN_FILES_SUPPORTED */
77    }
78    cinfo->output_scan_number = cinfo->input_scan_number;
79  } else if (cinfo->global_state != DSTATE_PRESCAN)
80    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
81  /* Perform any dummy output passes, and set up for the final pass */
82  return output_pass_setup(cinfo);
83}
84
85/*
86 * Tile decompression initialization.
87 * jpeg_read_header must be completed before calling this.
88 */
89
90GLOBAL(boolean)
91jpeg_start_tile_decompress (j_decompress_ptr cinfo)
92{
93  if (cinfo->global_state == DSTATE_READY) {
94    /* First call: initialize master control, select active modules */
95    cinfo->tile_decode = TRUE;
96    jinit_master_decompress(cinfo);
97    if (cinfo->buffered_image) {
98      cinfo->global_state = DSTATE_BUFIMAGE;
99      return TRUE;
100    }
101    cinfo->global_state = DSTATE_PRELOAD;
102  }
103  if (cinfo->global_state == DSTATE_PRELOAD) {
104    cinfo->output_scan_number = cinfo->input_scan_number;
105  } else if (cinfo->global_state != DSTATE_PRESCAN)
106    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
107  /* Perform any dummy output passes, and set up for the final pass */
108  return output_pass_setup(cinfo);
109}
110
111
112/*
113 * Set up for an output pass, and perform any dummy pass(es) needed.
114 * Common subroutine for jpeg_start_decompress and jpeg_start_output.
115 * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
116 * Exit: If done, returns TRUE and sets global_state for proper output mode.
117 *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
118 */
119
120LOCAL(boolean)
121output_pass_setup (j_decompress_ptr cinfo)
122{
123  if (cinfo->global_state != DSTATE_PRESCAN) {
124    /* First call: do pass setup */
125    (*cinfo->master->prepare_for_output_pass) (cinfo);
126    cinfo->output_scanline = 0;
127    cinfo->global_state = DSTATE_PRESCAN;
128  }
129  /* Loop over any required dummy passes */
130  while (cinfo->master->is_dummy_pass) {
131#ifdef QUANT_2PASS_SUPPORTED
132    /* Crank through the dummy pass */
133    while (cinfo->output_scanline < cinfo->output_height) {
134      JDIMENSION last_scanline;
135      /* Call progress monitor hook if present */
136      if (cinfo->progress != NULL) {
137	cinfo->progress->pass_counter = (long) cinfo->output_scanline;
138	cinfo->progress->pass_limit = (long) cinfo->output_height;
139	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
140      }
141      /* Process some data */
142      last_scanline = cinfo->output_scanline;
143      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
144				    &cinfo->output_scanline, (JDIMENSION) 0);
145      if (cinfo->output_scanline == last_scanline)
146	return FALSE;		/* No progress made, must suspend */
147    }
148    /* Finish up dummy pass, and set up for another one */
149    (*cinfo->master->finish_output_pass) (cinfo);
150    (*cinfo->master->prepare_for_output_pass) (cinfo);
151    cinfo->output_scanline = 0;
152#else
153    ERREXIT(cinfo, JERR_NOT_COMPILED);
154#endif /* QUANT_2PASS_SUPPORTED */
155  }
156  /* Ready for application to drive output pass through
157   * jpeg_read_scanlines or jpeg_read_raw_data.
158   */
159  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
160  return TRUE;
161}
162
163
164/*
165 * Read some scanlines of data from the JPEG decompressor.
166 *
167 * The return value will be the number of lines actually read.
168 * This may be less than the number requested in several cases,
169 * including bottom of image, data source suspension, and operating
170 * modes that emit multiple scanlines at a time.
171 *
172 * Note: we warn about excess calls to jpeg_read_scanlines() since
173 * this likely signals an application programmer error.  However,
174 * an oversize buffer (max_lines > scanlines remaining) is not an error.
175 */
176
177GLOBAL(JDIMENSION)
178jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
179		     JDIMENSION max_lines)
180{
181  JDIMENSION row_ctr;
182
183  if (cinfo->global_state != DSTATE_SCANNING)
184    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
185  if (cinfo->output_scanline >= cinfo->output_height) {
186    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
187    return 0;
188  }
189
190  /* Call progress monitor hook if present */
191  if (cinfo->progress != NULL) {
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  }
196
197  /* Process some data */
198  row_ctr = 0;
199  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
200  cinfo->output_scanline += row_ctr;
201  return row_ctr;
202}
203/*
204 * Initialize the jpeg decoder to decompressing a rectangle with size of (width, height)
205 * and its upper-left corner located at (start_x, start_y).
206 * Align start_x and start_y to multiplies of iMCU width and height, respectively.
207 * Also, the new reader position and sampled image size will be returned in
208 * (start_x, start_y) and (width, height), respectively.
209 */
210
211GLOBAL(void)
212jpeg_init_read_tile_scanline(j_decompress_ptr cinfo, huffman_index *index,
213		     int *start_x, int *start_y, int *width, int *height)
214{
215  // Calculates the boundary of iMCU
216  int lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
217  int lines_per_iMCU_col = cinfo->max_h_samp_factor * DCTSIZE;
218  int row_offset = *start_y / lines_per_iMCU_row;
219  int col_left_boundary = ((*start_x / lines_per_iMCU_col)
220            / index->MCU_sample_size) * index->MCU_sample_size;
221  int col_right_boundary =
222                  jdiv_round_up(*start_x + *width, lines_per_iMCU_col);
223
224  cinfo->coef->MCU_columns_to_skip =
225      *start_x / lines_per_iMCU_col - col_left_boundary;
226
227  *height = (*start_y - row_offset * lines_per_iMCU_row) + *height;
228  *start_x = col_left_boundary * lines_per_iMCU_col;
229  *start_y = row_offset * lines_per_iMCU_row;
230  cinfo->image_width = jmin(cinfo->original_image_width,
231          col_right_boundary * lines_per_iMCU_col) -
232          col_left_boundary * lines_per_iMCU_col;
233  cinfo->input_iMCU_row = row_offset;
234  cinfo->output_iMCU_row = row_offset;
235
236  // Updates JPEG decoder parameter
237  jinit_color_deconverter(cinfo);
238  jpeg_calc_output_dimensions(cinfo);
239  jinit_upsampler(cinfo);
240  (*cinfo->master->prepare_for_output_pass) (cinfo);
241  if (cinfo->progressive_mode)
242    (*cinfo->entropy->start_pass) (cinfo);
243  else
244    jpeg_decompress_per_scan_setup(cinfo);
245
246  int sample_size = DCTSIZE / cinfo->min_DCT_scaled_size;
247
248  *height = jdiv_round_up(*height, sample_size);
249  *width = cinfo->output_width;
250  cinfo->output_scanline = lines_per_iMCU_row * row_offset / sample_size;
251  cinfo->inputctl->consume_input = cinfo->coef->consume_data;
252  cinfo->inputctl->consume_input_build_huffman_index =
253      cinfo->coef->consume_data_build_huffman_index;
254  cinfo->entropy->index = index;
255  cinfo->input_iMCU_row = row_offset;
256  cinfo->output_iMCU_row = row_offset;
257  cinfo->coef->MCU_column_left_boundary = col_left_boundary;
258  cinfo->coef->MCU_column_right_boundary = col_right_boundary;
259  cinfo->coef->column_left_boundary =
260      col_left_boundary / index->MCU_sample_size;
261  cinfo->coef->column_right_boundary =
262      jdiv_round_up(col_right_boundary, index->MCU_sample_size);
263}
264
265/*
266 * Read a scanline from the current position.
267 *
268 * Return the number of lines actually read.
269 */
270
271GLOBAL(JDIMENSION)
272jpeg_read_tile_scanline (j_decompress_ptr cinfo, huffman_index *index,
273        JSAMPARRAY scanlines)
274{
275  // Calculates the boundary of iMCU
276  int lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
277  int lines_per_iMCU_col = cinfo->max_h_samp_factor * DCTSIZE;
278  int sample_size = DCTSIZE / cinfo->min_DCT_scaled_size;
279  JDIMENSION row_ctr = 0;
280
281  if (cinfo->progressive_mode) {
282    (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, 1);
283  } else {
284    if (cinfo->output_scanline % (lines_per_iMCU_row / sample_size) == 0) {
285      // Set the read head to the next iMCU row
286      int iMCU_row_offset = cinfo->output_scanline /
287            (lines_per_iMCU_row / sample_size);
288      int offset_data_col_position = cinfo->coef->MCU_column_left_boundary /
289            index->MCU_sample_size;
290      huffman_offset_data offset_data =
291          index->scan[0].offset[iMCU_row_offset][offset_data_col_position];
292      (*cinfo->entropy->configure_huffman_decoder) (cinfo, offset_data);
293    }
294    (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, 1);
295  }
296
297  cinfo->output_scanline += row_ctr;
298  return row_ctr;
299}
300
301/*
302 * Alternate entry point to read raw data.
303 * Processes exactly one iMCU row per call, unless suspended.
304 */
305
306GLOBAL(JDIMENSION)
307jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
308		    JDIMENSION max_lines)
309{
310  JDIMENSION lines_per_iMCU_row;
311
312  if (cinfo->global_state != DSTATE_RAW_OK)
313    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
314  if (cinfo->output_scanline >= cinfo->output_height) {
315    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
316    return 0;
317  }
318
319  /* Call progress monitor hook if present */
320  if (cinfo->progress != NULL) {
321    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
322    cinfo->progress->pass_limit = (long) cinfo->output_height;
323    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
324  }
325
326  /* Verify that at least one iMCU row can be returned. */
327  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
328  if (max_lines < lines_per_iMCU_row)
329    ERREXIT(cinfo, JERR_BUFFER_SIZE);
330
331  /* Decompress directly into user's buffer. */
332  if (! (*cinfo->coef->decompress_data) (cinfo, data))
333    return 0;			/* suspension forced, can do nothing more */
334
335  /* OK, we processed one iMCU row. */
336  cinfo->output_scanline += lines_per_iMCU_row;
337  return lines_per_iMCU_row;
338}
339
340
341/* Additional entry points for buffered-image mode. */
342
343#ifdef D_MULTISCAN_FILES_SUPPORTED
344
345/*
346 * Initialize for an output pass in buffered-image mode.
347 */
348
349GLOBAL(boolean)
350jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
351{
352  if (cinfo->global_state != DSTATE_BUFIMAGE &&
353      cinfo->global_state != DSTATE_PRESCAN)
354    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
355  /* Limit scan number to valid range */
356  if (scan_number <= 0)
357    scan_number = 1;
358  if (cinfo->inputctl->eoi_reached &&
359      scan_number > cinfo->input_scan_number)
360    scan_number = cinfo->input_scan_number;
361  cinfo->output_scan_number = scan_number;
362  /* Perform any dummy output passes, and set up for the real pass */
363  return output_pass_setup(cinfo);
364}
365
366
367/*
368 * Finish up after an output pass in buffered-image mode.
369 *
370 * Returns FALSE if suspended.  The return value need be inspected only if
371 * a suspending data source is used.
372 */
373
374GLOBAL(boolean)
375jpeg_finish_output (j_decompress_ptr cinfo)
376{
377  if ((cinfo->global_state == DSTATE_SCANNING ||
378       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
379    /* Terminate this pass. */
380    /* We do not require the whole pass to have been completed. */
381    (*cinfo->master->finish_output_pass) (cinfo);
382    cinfo->global_state = DSTATE_BUFPOST;
383  } else if (cinfo->global_state != DSTATE_BUFPOST) {
384    /* BUFPOST = repeat call after a suspension, anything else is error */
385    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
386  }
387  /* Read markers looking for SOS or EOI */
388  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
389	 ! cinfo->inputctl->eoi_reached) {
390    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
391      return FALSE;		/* Suspend, come back later */
392  }
393  cinfo->global_state = DSTATE_BUFIMAGE;
394  return TRUE;
395}
396
397#endif /* D_MULTISCAN_FILES_SUPPORTED */
398