Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: jdapistd.c

Issue 1258673007: Add jpeg_skip_scanlines() API to libjpeg-turbo (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@master
Patch Set: Updating google.patch Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « google.patch ('k') | jdarith.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * jdapistd.c 2 * jdapistd.c
3 * 3 *
4 * This file was part of the Independent JPEG Group's software: 4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1994-1996, Thomas G. Lane. 5 * Copyright (C) 1994-1996, Thomas G. Lane.
6 * libjpeg-turbo Modifications: 6 * libjpeg-turbo Modifications:
7 * Copyright (C) 2010, D. R. Commander. 7 * Copyright (C) 2010, 2015, D. R. Commander.
8 * Copyright (C) 2015, Google, Inc.
8 * For conditions of distribution and use, see the accompanying README file. 9 * For conditions of distribution and use, see the accompanying README file.
9 * 10 *
10 * This file contains application interface code for the decompression half 11 * This file contains application interface code for the decompression half
11 * of the JPEG library. These are the "standard" API routines that are 12 * of the JPEG library. These are the "standard" API routines that are
12 * used in the normal full-decompression case. They are not used by a 13 * used in the normal full-decompression case. They are not used by a
13 * transcoding-only application. Note that if an application links in 14 * transcoding-only application. Note that if an application links in
14 * jpeg_start_decompress, it will end up linking in the entire decompressor. 15 * jpeg_start_decompress, it will end up linking in the entire decompressor.
15 * We thus must separate this file from jdapimin.c to avoid linking the 16 * We thus must separate this file from jdapimin.c to avoid linking the
16 * whole decompression library into a transcoder. 17 * whole decompression library into a transcoder.
17 */ 18 */
18 19
19 #define JPEG_INTERNALS 20 #include "jdmainct.h"
20 #include "jinclude.h" 21 #include "jdcoefct.h"
21 #include "jpeglib.h" 22 #include "jdsample.h"
22 #include "jpegcomp.h" 23 #include "jmemsys.h"
23 24
24 25
25 /* Forward declarations */ 26 /* Forward declarations */
26 LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); 27 LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
27 28
28 29
29 /* 30 /*
30 * Decompression initialization. 31 * Decompression initialization.
31 * jpeg_read_header must be completed before calling this. 32 * jpeg_read_header must be completed before calling this.
32 * 33 *
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 173 }
173 174
174 /* Process some data */ 175 /* Process some data */
175 row_ctr = 0; 176 row_ctr = 0;
176 (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); 177 (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
177 cinfo->output_scanline += row_ctr; 178 cinfo->output_scanline += row_ctr;
178 return row_ctr; 179 return row_ctr;
179 } 180 }
180 181
181 182
183
184 /* Dummy color convert function used by jpeg_skip_scanlines() */
185 LOCAL(void)
186 noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
187 JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)
188 {
189 }
190
191
192 /*
193 * In some cases, it is best to call jpeg_read_scanlines() and discard the
194 * output, rather than skipping the scanlines, because this allows us to
195 * maintain the internal state of the context-based upsampler. In these cases,
196 * we set up and tear down a dummy color converter in order to avoid valgrind
197 * errors and to achieve the best possible performance.
198 */
199 LOCAL(void)
200 read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
201 {
202 JDIMENSION n;
203 void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
204 JDIMENSION input_row, JSAMPARRAY output_buf,
205 int num_rows);
206
207 color_convert = cinfo->cconvert->color_convert;
208 cinfo->cconvert->color_convert = noop_convert;
209
210 for (n = 0; n < num_lines; n++)
211 jpeg_read_scanlines(cinfo, NULL, 1);
212
213 cinfo->cconvert->color_convert = color_convert;
214 }
215
216 /*
217 * Called by jpeg_skip_scanlines(). This partially skips a decompress block by
218 * incrementing the rowgroup counter.
219 */
220
221 LOCAL(void)
222 increment_simple_rowgroup_ctr (j_decompress_ptr cinfo, JDIMENSION rows)
223 {
224 JDIMENSION rows_left;
225 my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
226
227 /* Increment the counter to the next row group after the skipped rows. */
228 main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor;
229
230 /* Partially skipping a row group would involve modifying the internal state
231 * of the upsampler, so read the remaining rows into a dummy buffer instead.
232 */
233 rows_left = rows % cinfo->max_v_samp_factor;
234 cinfo->output_scanline += rows - rows_left;
235
236 read_and_discard_scanlines(cinfo, rows_left);
237 }
238
239 /*
240 * Skips some scanlines of data from the JPEG decompressor.
241 *
242 * The return value will be the number of lines actually skipped. If skipping
243 * num_lines would move beyond the end of the image, then the actual number of
244 * lines remaining in the image is returned. Otherwise, the return value will
245 * be equal to num_lines.
246 *
247 * Refer to libjpeg.txt for more information.
248 */
249
250 GLOBAL(JDIMENSION)
251 jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
252 {
253 my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
254 my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
255 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
256 JDIMENSION i, x;
257 int y;
258 JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row;
259 JDIMENSION lines_to_skip, lines_to_read;
260
261 if (cinfo->global_state != DSTATE_SCANNING)
262 ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
263
264 /* Do not skip past the bottom of the image. */
265 if (cinfo->output_scanline + num_lines >= cinfo->output_height) {
266 cinfo->output_scanline = cinfo->output_height;
267 return cinfo->output_height - cinfo->output_scanline;
268 }
269
270 if (num_lines == 0)
271 return 0;
272
273 lines_per_iMCU_row = cinfo->_min_DCT_scaled_size * cinfo->max_v_samp_factor;
274 lines_left_in_iMCU_row =
275 (lines_per_iMCU_row - (cinfo->output_scanline % lines_per_iMCU_row)) %
276 lines_per_iMCU_row;
277 lines_after_iMCU_row = num_lines - lines_left_in_iMCU_row;
278
279 /* Skip the lines remaining in the current iMCU row. When upsampling
280 * requires context rows, we need the previous and next rows in order to read
281 * the current row. This adds some complexity.
282 */
283 if (cinfo->upsample->need_context_rows) {
284 /* If the skipped lines would not move us past the current iMCU row, we
285 * read the lines and ignore them. There might be a faster way of doing
286 * this, but we are facing increasing complexity for diminishing returns.
287 * The increasing complexity would be a by-product of meddling with the
288 * state machine used to skip context rows. Near the end of an iMCU row,
289 * the next iMCU row may have already been entropy-decoded. In this unique
290 * case, we will read the next iMCU row if we cannot skip past it as well.
291 */
292 if ((num_lines < lines_left_in_iMCU_row + 1) ||
293 (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full &&
294 lines_after_iMCU_row < lines_per_iMCU_row + 1)) {
295 read_and_discard_scanlines(cinfo, num_lines);
296 return num_lines;
297 }
298
299 /* If the next iMCU row has already been entropy-decoded, make sure that
300 * we do not skip too far.
301 */
302 if (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full) {
303 cinfo->output_scanline += lines_left_in_iMCU_row + lines_per_iMCU_row;
304 lines_after_iMCU_row -= lines_per_iMCU_row;
305 } else {
306 cinfo->output_scanline += lines_left_in_iMCU_row;
307 }
308
309 /* If we have just completed the first block, adjust the buffer pointers */
310 if (main_ptr->iMCU_row_ctr == 0 ||
311 (main_ptr->iMCU_row_ctr == 1 && lines_left_in_iMCU_row > 2))
312 set_wraparound_pointers(cinfo);
313 main_ptr->buffer_full = FALSE;
314 main_ptr->rowgroup_ctr = 0;
315 main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
316 upsample->next_row_out = cinfo->max_v_samp_factor;
317 upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
318 }
319
320 /* Skipping is much simpler when context rows are not required. */
321 else {
322 if (num_lines < lines_left_in_iMCU_row) {
323 increment_simple_rowgroup_ctr(cinfo, num_lines);
324 return num_lines;
325 } else {
326 cinfo->output_scanline += lines_left_in_iMCU_row;
327 main_ptr->buffer_full = FALSE;
328 main_ptr->rowgroup_ctr = 0;
329 upsample->next_row_out = cinfo->max_v_samp_factor;
330 upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
331 }
332 }
333
334 /* Calculate how many full iMCU rows we can skip. */
335 if (cinfo->upsample->need_context_rows)
336 lines_to_skip = ((lines_after_iMCU_row - 1) / lines_per_iMCU_row) *
337 lines_per_iMCU_row;
338 else
339 lines_to_skip = (lines_after_iMCU_row / lines_per_iMCU_row) *
340 lines_per_iMCU_row;
341 /* Calculate the number of lines that remain to be skipped after skipping all
342 * of the full iMCU rows that we can. We will not read these lines unless we
343 * have to.
344 */
345 lines_to_read = lines_after_iMCU_row - lines_to_skip;
346
347 /* For images requiring multiple scans (progressive, non-interleaved, etc.),
348 * all of the entropy decoding occurs in jpeg_start_decompress(), assuming
349 * that the input data source is non-suspending. This makes skipping easy.
350 */
351 if (cinfo->inputctl->has_multiple_scans) {
352 if (cinfo->upsample->need_context_rows) {
353 cinfo->output_scanline += lines_to_skip;
354 cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
355 main_ptr->iMCU_row_ctr += lines_after_iMCU_row / lines_per_iMCU_row;
356 /* It is complex to properly move to the middle of a context block, so
357 * read the remaining lines instead of skipping them.
358 */
359 read_and_discard_scanlines(cinfo, lines_to_read);
360 } else {
361 cinfo->output_scanline += lines_to_skip;
362 cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
363 increment_simple_rowgroup_ctr(cinfo, lines_to_read);
364 }
365 upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
366 return num_lines;
367 }
368
369 /* Skip the iMCU rows that we can safely skip. */
370 for (i = 0; i < lines_to_skip; i += lines_per_iMCU_row) {
371 for (y = 0; y < coef->MCU_rows_per_iMCU_row; y++) {
372 for (x = 0; x < cinfo->MCUs_per_row; x++) {
373 /* Calling decode_mcu() with a NULL pointer causes it to discard the
374 * decoded coefficients. This is ~5% faster for large subsets, but
375 * it's tough to tell a difference for smaller images.
376 */
377 (*cinfo->entropy->decode_mcu) (cinfo, NULL);
378 }
379 }
380 cinfo->input_iMCU_row++;
381 cinfo->output_iMCU_row++;
382 if (cinfo->input_iMCU_row < cinfo->total_iMCU_rows)
383 start_iMCU_row(cinfo);
384 else
385 (*cinfo->inputctl->finish_input_pass) (cinfo);
386 }
387 cinfo->output_scanline += lines_to_skip;
388
389 if (cinfo->upsample->need_context_rows) {
390 /* Context-based upsampling keeps track of iMCU rows. */
391 main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row;
392
393 /* It is complex to properly move to the middle of a context block, so
394 * read the remaining lines instead of skipping them.
395 */
396 read_and_discard_scanlines(cinfo, lines_to_read);
397 } else {
398 increment_simple_rowgroup_ctr(cinfo, lines_to_read);
399 }
400
401 /* Since skipping lines involves skipping the upsampling step, the value of
402 * "rows_to_go" will become invalid unless we set it here. NOTE: This is a
403 * bit odd, since "rows_to_go" seems to be redundantly keeping track of
404 * output_scanline.
405 */
406 upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
407
408 /* Always skip the requested number of lines. */
409 return num_lines;
410 }
411
182 /* 412 /*
183 * Alternate entry point to read raw data. 413 * Alternate entry point to read raw data.
184 * Processes exactly one iMCU row per call, unless suspended. 414 * Processes exactly one iMCU row per call, unless suspended.
185 */ 415 */
186 416
187 GLOBAL(JDIMENSION) 417 GLOBAL(JDIMENSION)
188 jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, 418 jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
189 JDIMENSION max_lines) 419 JDIMENSION max_lines)
190 { 420 {
191 JDIMENSION lines_per_iMCU_row; 421 JDIMENSION lines_per_iMCU_row;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 while (cinfo->input_scan_number <= cinfo->output_scan_number && 499 while (cinfo->input_scan_number <= cinfo->output_scan_number &&
270 ! cinfo->inputctl->eoi_reached) { 500 ! cinfo->inputctl->eoi_reached) {
271 if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) 501 if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
272 return FALSE; /* Suspend, come back later */ 502 return FALSE; /* Suspend, come back later */
273 } 503 }
274 cinfo->global_state = DSTATE_BUFIMAGE; 504 cinfo->global_state = DSTATE_BUFIMAGE;
275 return TRUE; 505 return TRUE;
276 } 506 }
277 507
278 #endif /* D_MULTISCAN_FILES_SUPPORTED */ 508 #endif /* D_MULTISCAN_FILES_SUPPORTED */
OLDNEW
« no previous file with comments | « google.patch ('k') | jdarith.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698