vrshoot
diff libs/libjpeg/jdapistd.c @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/libjpeg/jdapistd.c Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,275 @@ 1.4 +/* 1.5 + * jdapistd.c 1.6 + * 1.7 + * Copyright (C) 1994-1996, Thomas G. Lane. 1.8 + * This file is part of the Independent JPEG Group's software. 1.9 + * For conditions of distribution and use, see the accompanying README file. 1.10 + * 1.11 + * This file contains application interface code for the decompression half 1.12 + * of the JPEG library. These are the "standard" API routines that are 1.13 + * used in the normal full-decompression case. They are not used by a 1.14 + * transcoding-only application. Note that if an application links in 1.15 + * jpeg_start_decompress, it will end up linking in the entire decompressor. 1.16 + * We thus must separate this file from jdapimin.c to avoid linking the 1.17 + * whole decompression library into a transcoder. 1.18 + */ 1.19 + 1.20 +#define JPEG_INTERNALS 1.21 +#include "jinclude.h" 1.22 +#include "jpeglib.h" 1.23 + 1.24 + 1.25 +/* Forward declarations */ 1.26 +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); 1.27 + 1.28 + 1.29 +/* 1.30 + * Decompression initialization. 1.31 + * jpeg_read_header must be completed before calling this. 1.32 + * 1.33 + * If a multipass operating mode was selected, this will do all but the 1.34 + * last pass, and thus may take a great deal of time. 1.35 + * 1.36 + * Returns FALSE if suspended. The return value need be inspected only if 1.37 + * a suspending data source is used. 1.38 + */ 1.39 + 1.40 +GLOBAL(boolean) 1.41 +jpeg_start_decompress (j_decompress_ptr cinfo) 1.42 +{ 1.43 + if (cinfo->global_state == DSTATE_READY) { 1.44 + /* First call: initialize master control, select active modules */ 1.45 + jinit_master_decompress(cinfo); 1.46 + if (cinfo->buffered_image) { 1.47 + /* No more work here; expecting jpeg_start_output next */ 1.48 + cinfo->global_state = DSTATE_BUFIMAGE; 1.49 + return TRUE; 1.50 + } 1.51 + cinfo->global_state = DSTATE_PRELOAD; 1.52 + } 1.53 + if (cinfo->global_state == DSTATE_PRELOAD) { 1.54 + /* If file has multiple scans, absorb them all into the coef buffer */ 1.55 + if (cinfo->inputctl->has_multiple_scans) { 1.56 +#ifdef D_MULTISCAN_FILES_SUPPORTED 1.57 + for (;;) { 1.58 + int retcode; 1.59 + /* Call progress monitor hook if present */ 1.60 + if (cinfo->progress != NULL) 1.61 + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 1.62 + /* Absorb some more input */ 1.63 + retcode = (*cinfo->inputctl->consume_input) (cinfo); 1.64 + if (retcode == JPEG_SUSPENDED) 1.65 + return FALSE; 1.66 + if (retcode == JPEG_REACHED_EOI) 1.67 + break; 1.68 + /* Advance progress counter if appropriate */ 1.69 + if (cinfo->progress != NULL && 1.70 + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { 1.71 + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { 1.72 + /* jdmaster underestimated number of scans; ratchet up one scan */ 1.73 + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; 1.74 + } 1.75 + } 1.76 + } 1.77 +#else 1.78 + ERREXIT(cinfo, JERR_NOT_COMPILED); 1.79 +#endif /* D_MULTISCAN_FILES_SUPPORTED */ 1.80 + } 1.81 + cinfo->output_scan_number = cinfo->input_scan_number; 1.82 + } else if (cinfo->global_state != DSTATE_PRESCAN) 1.83 + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1.84 + /* Perform any dummy output passes, and set up for the final pass */ 1.85 + return output_pass_setup(cinfo); 1.86 +} 1.87 + 1.88 + 1.89 +/* 1.90 + * Set up for an output pass, and perform any dummy pass(es) needed. 1.91 + * Common subroutine for jpeg_start_decompress and jpeg_start_output. 1.92 + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. 1.93 + * Exit: If done, returns TRUE and sets global_state for proper output mode. 1.94 + * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. 1.95 + */ 1.96 + 1.97 +LOCAL(boolean) 1.98 +output_pass_setup (j_decompress_ptr cinfo) 1.99 +{ 1.100 + if (cinfo->global_state != DSTATE_PRESCAN) { 1.101 + /* First call: do pass setup */ 1.102 + (*cinfo->master->prepare_for_output_pass) (cinfo); 1.103 + cinfo->output_scanline = 0; 1.104 + cinfo->global_state = DSTATE_PRESCAN; 1.105 + } 1.106 + /* Loop over any required dummy passes */ 1.107 + while (cinfo->master->is_dummy_pass) { 1.108 +#ifdef QUANT_2PASS_SUPPORTED 1.109 + /* Crank through the dummy pass */ 1.110 + while (cinfo->output_scanline < cinfo->output_height) { 1.111 + JDIMENSION last_scanline; 1.112 + /* Call progress monitor hook if present */ 1.113 + if (cinfo->progress != NULL) { 1.114 + cinfo->progress->pass_counter = (long) cinfo->output_scanline; 1.115 + cinfo->progress->pass_limit = (long) cinfo->output_height; 1.116 + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 1.117 + } 1.118 + /* Process some data */ 1.119 + last_scanline = cinfo->output_scanline; 1.120 + (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, 1.121 + &cinfo->output_scanline, (JDIMENSION) 0); 1.122 + if (cinfo->output_scanline == last_scanline) 1.123 + return FALSE; /* No progress made, must suspend */ 1.124 + } 1.125 + /* Finish up dummy pass, and set up for another one */ 1.126 + (*cinfo->master->finish_output_pass) (cinfo); 1.127 + (*cinfo->master->prepare_for_output_pass) (cinfo); 1.128 + cinfo->output_scanline = 0; 1.129 +#else 1.130 + ERREXIT(cinfo, JERR_NOT_COMPILED); 1.131 +#endif /* QUANT_2PASS_SUPPORTED */ 1.132 + } 1.133 + /* Ready for application to drive output pass through 1.134 + * jpeg_read_scanlines or jpeg_read_raw_data. 1.135 + */ 1.136 + cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; 1.137 + return TRUE; 1.138 +} 1.139 + 1.140 + 1.141 +/* 1.142 + * Read some scanlines of data from the JPEG decompressor. 1.143 + * 1.144 + * The return value will be the number of lines actually read. 1.145 + * This may be less than the number requested in several cases, 1.146 + * including bottom of image, data source suspension, and operating 1.147 + * modes that emit multiple scanlines at a time. 1.148 + * 1.149 + * Note: we warn about excess calls to jpeg_read_scanlines() since 1.150 + * this likely signals an application programmer error. However, 1.151 + * an oversize buffer (max_lines > scanlines remaining) is not an error. 1.152 + */ 1.153 + 1.154 +GLOBAL(JDIMENSION) 1.155 +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, 1.156 + JDIMENSION max_lines) 1.157 +{ 1.158 + JDIMENSION row_ctr; 1.159 + 1.160 + if (cinfo->global_state != DSTATE_SCANNING) 1.161 + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1.162 + if (cinfo->output_scanline >= cinfo->output_height) { 1.163 + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 1.164 + return 0; 1.165 + } 1.166 + 1.167 + /* Call progress monitor hook if present */ 1.168 + if (cinfo->progress != NULL) { 1.169 + cinfo->progress->pass_counter = (long) cinfo->output_scanline; 1.170 + cinfo->progress->pass_limit = (long) cinfo->output_height; 1.171 + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 1.172 + } 1.173 + 1.174 + /* Process some data */ 1.175 + row_ctr = 0; 1.176 + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); 1.177 + cinfo->output_scanline += row_ctr; 1.178 + return row_ctr; 1.179 +} 1.180 + 1.181 + 1.182 +/* 1.183 + * Alternate entry point to read raw data. 1.184 + * Processes exactly one iMCU row per call, unless suspended. 1.185 + */ 1.186 + 1.187 +GLOBAL(JDIMENSION) 1.188 +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, 1.189 + JDIMENSION max_lines) 1.190 +{ 1.191 + JDIMENSION lines_per_iMCU_row; 1.192 + 1.193 + if (cinfo->global_state != DSTATE_RAW_OK) 1.194 + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1.195 + if (cinfo->output_scanline >= cinfo->output_height) { 1.196 + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 1.197 + return 0; 1.198 + } 1.199 + 1.200 + /* Call progress monitor hook if present */ 1.201 + if (cinfo->progress != NULL) { 1.202 + cinfo->progress->pass_counter = (long) cinfo->output_scanline; 1.203 + cinfo->progress->pass_limit = (long) cinfo->output_height; 1.204 + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 1.205 + } 1.206 + 1.207 + /* Verify that at least one iMCU row can be returned. */ 1.208 + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; 1.209 + if (max_lines < lines_per_iMCU_row) 1.210 + ERREXIT(cinfo, JERR_BUFFER_SIZE); 1.211 + 1.212 + /* Decompress directly into user's buffer. */ 1.213 + if (! (*cinfo->coef->decompress_data) (cinfo, data)) 1.214 + return 0; /* suspension forced, can do nothing more */ 1.215 + 1.216 + /* OK, we processed one iMCU row. */ 1.217 + cinfo->output_scanline += lines_per_iMCU_row; 1.218 + return lines_per_iMCU_row; 1.219 +} 1.220 + 1.221 + 1.222 +/* Additional entry points for buffered-image mode. */ 1.223 + 1.224 +#ifdef D_MULTISCAN_FILES_SUPPORTED 1.225 + 1.226 +/* 1.227 + * Initialize for an output pass in buffered-image mode. 1.228 + */ 1.229 + 1.230 +GLOBAL(boolean) 1.231 +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) 1.232 +{ 1.233 + if (cinfo->global_state != DSTATE_BUFIMAGE && 1.234 + cinfo->global_state != DSTATE_PRESCAN) 1.235 + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1.236 + /* Limit scan number to valid range */ 1.237 + if (scan_number <= 0) 1.238 + scan_number = 1; 1.239 + if (cinfo->inputctl->eoi_reached && 1.240 + scan_number > cinfo->input_scan_number) 1.241 + scan_number = cinfo->input_scan_number; 1.242 + cinfo->output_scan_number = scan_number; 1.243 + /* Perform any dummy output passes, and set up for the real pass */ 1.244 + return output_pass_setup(cinfo); 1.245 +} 1.246 + 1.247 + 1.248 +/* 1.249 + * Finish up after an output pass in buffered-image mode. 1.250 + * 1.251 + * Returns FALSE if suspended. The return value need be inspected only if 1.252 + * a suspending data source is used. 1.253 + */ 1.254 + 1.255 +GLOBAL(boolean) 1.256 +jpeg_finish_output (j_decompress_ptr cinfo) 1.257 +{ 1.258 + if ((cinfo->global_state == DSTATE_SCANNING || 1.259 + cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { 1.260 + /* Terminate this pass. */ 1.261 + /* We do not require the whole pass to have been completed. */ 1.262 + (*cinfo->master->finish_output_pass) (cinfo); 1.263 + cinfo->global_state = DSTATE_BUFPOST; 1.264 + } else if (cinfo->global_state != DSTATE_BUFPOST) { 1.265 + /* BUFPOST = repeat call after a suspension, anything else is error */ 1.266 + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1.267 + } 1.268 + /* Read markers looking for SOS or EOI */ 1.269 + while (cinfo->input_scan_number <= cinfo->output_scan_number && 1.270 + ! cinfo->inputctl->eoi_reached) { 1.271 + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) 1.272 + return FALSE; /* Suspend, come back later */ 1.273 + } 1.274 + cinfo->global_state = DSTATE_BUFIMAGE; 1.275 + return TRUE; 1.276 +} 1.277 + 1.278 +#endif /* D_MULTISCAN_FILES_SUPPORTED */