1bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 2bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * jdapistd.c 3bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 4a73e870ad02de20c2b34cb3a5382c2846c2afbe3DRC * This file was part of the Independent JPEG Group's software: 5489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane * Copyright (C) 1994-1996, Thomas G. Lane. 6a6ef282a49f2d7d1b4d19cc89f63e81fd66b35b7DRC * libjpeg-turbo Modifications: 7ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Copyright (C) 2010, 2015, D. R. Commander. 8ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Copyright (C) 2015, Google, Inc. 9bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * For conditions of distribution and use, see the accompanying README file. 10bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 11bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * This file contains application interface code for the decompression half 12bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * of the JPEG library. These are the "standard" API routines that are 13bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * used in the normal full-decompression case. They are not used by a 14bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * transcoding-only application. Note that if an application links in 15bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * jpeg_start_decompress, it will end up linking in the entire decompressor. 16bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * We thus must separate this file from jdapimin.c to avoid linking the 17bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * whole decompression library into a transcoder. 18bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 19bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 20ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC#include "jdmainct.h" 21ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC#include "jdcoefct.h" 22ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC#include "jdsample.h" 23ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC#include "jmemsys.h" 24bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 25bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* Forward declarations */ 26bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRCLOCAL(boolean) output_pass_setup (j_decompress_ptr cinfo); 27bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 28bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 29bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 30bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Decompression initialization. 31bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * jpeg_read_header must be completed before calling this. 32bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 33bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * If a multipass operating mode was selected, this will do all but the 34bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * last pass, and thus may take a great deal of time. 35bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 36bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Returns FALSE if suspended. The return value need be inspected only if 37bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * a suspending data source is used. 38bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 39bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 40489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(boolean) 41bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_start_decompress (j_decompress_ptr cinfo) 42bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 43bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state == DSTATE_READY) { 44bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* First call: initialize master control, select active modules */ 45bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane jinit_master_decompress(cinfo); 46bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->buffered_image) { 47bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* No more work here; expecting jpeg_start_output next */ 48bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = DSTATE_BUFIMAGE; 49bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return TRUE; 50bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 51bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = DSTATE_PRELOAD; 52bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 53bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state == DSTATE_PRELOAD) { 54bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* If file has multiple scans, absorb them all into the coef buffer */ 55bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->inputctl->has_multiple_scans) { 56bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#ifdef D_MULTISCAN_FILES_SUPPORTED 57bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane for (;;) { 58e5eaf37440b8e337ab150c017df7c03faf846c51DRC int retcode; 59e5eaf37440b8e337ab150c017df7c03faf846c51DRC /* Call progress monitor hook if present */ 60e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (cinfo->progress != NULL) 61e5eaf37440b8e337ab150c017df7c03faf846c51DRC (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 62e5eaf37440b8e337ab150c017df7c03faf846c51DRC /* Absorb some more input */ 63e5eaf37440b8e337ab150c017df7c03faf846c51DRC retcode = (*cinfo->inputctl->consume_input) (cinfo); 64e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (retcode == JPEG_SUSPENDED) 65e5eaf37440b8e337ab150c017df7c03faf846c51DRC return FALSE; 66e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (retcode == JPEG_REACHED_EOI) 67e5eaf37440b8e337ab150c017df7c03faf846c51DRC break; 68e5eaf37440b8e337ab150c017df7c03faf846c51DRC /* Advance progress counter if appropriate */ 69e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (cinfo->progress != NULL && 70e5eaf37440b8e337ab150c017df7c03faf846c51DRC (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { 71e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { 72e5eaf37440b8e337ab150c017df7c03faf846c51DRC /* jdmaster underestimated number of scans; ratchet up one scan */ 73e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; 74e5eaf37440b8e337ab150c017df7c03faf846c51DRC } 75e5eaf37440b8e337ab150c017df7c03faf846c51DRC } 76bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 77bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#else 78bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT(cinfo, JERR_NOT_COMPILED); 79bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#endif /* D_MULTISCAN_FILES_SUPPORTED */ 80bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 81bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scan_number = cinfo->input_scan_number; 82bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } else if (cinfo->global_state != DSTATE_PRESCAN) 83bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 84bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Perform any dummy output passes, and set up for the final pass */ 85bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return output_pass_setup(cinfo); 86bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 87bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 88bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 89bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 90bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Set up for an output pass, and perform any dummy pass(es) needed. 91bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Common subroutine for jpeg_start_decompress and jpeg_start_output. 92bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Entry: global_state = DSTATE_PRESCAN only if previously suspended. 93bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Exit: If done, returns TRUE and sets global_state for proper output mode. 94bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. 95bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 96bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 97489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean) 98bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Laneoutput_pass_setup (j_decompress_ptr cinfo) 99bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 100bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state != DSTATE_PRESCAN) { 101bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* First call: do pass setup */ 102bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->master->prepare_for_output_pass) (cinfo); 103bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scanline = 0; 104bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = DSTATE_PRESCAN; 105bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 106bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Loop over any required dummy passes */ 107bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane while (cinfo->master->is_dummy_pass) { 108bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 109bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Crank through the dummy pass */ 110bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane while (cinfo->output_scanline < cinfo->output_height) { 111bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane JDIMENSION last_scanline; 112bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Call progress monitor hook if present */ 113bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->progress != NULL) { 114e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->progress->pass_counter = (long) cinfo->output_scanline; 115e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->progress->pass_limit = (long) cinfo->output_height; 116e5eaf37440b8e337ab150c017df7c03faf846c51DRC (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 117bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 118bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Process some data */ 119bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane last_scanline = cinfo->output_scanline; 120bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, 121e5eaf37440b8e337ab150c017df7c03faf846c51DRC &cinfo->output_scanline, (JDIMENSION) 0); 122bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->output_scanline == last_scanline) 123e5eaf37440b8e337ab150c017df7c03faf846c51DRC return FALSE; /* No progress made, must suspend */ 124bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 125bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Finish up dummy pass, and set up for another one */ 126bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->master->finish_output_pass) (cinfo); 127bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->master->prepare_for_output_pass) (cinfo); 128bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scanline = 0; 129bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#else 130bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT(cinfo, JERR_NOT_COMPILED); 131bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#endif /* QUANT_2PASS_SUPPORTED */ 132bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 133bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Ready for application to drive output pass through 134bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * jpeg_read_scanlines or jpeg_read_raw_data. 135bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 136bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; 137bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return TRUE; 138bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 139bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 140bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 141bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 1420ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * Enable partial scanline decompression 1430ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * 1440ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * Must be called after jpeg_start_decompress() and before any calls to 1450ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * jpeg_read_scanlines() or jpeg_skip_scanlines(). 1460ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * 1470ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * Refer to libjpeg.txt for more information. 1480ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 1490ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1500ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCGLOBAL(void) 1510ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCjpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset, 1520ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC JDIMENSION *width) 1530ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC{ 1540ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC int ci, align, orig_downsampled_width; 1550ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC JDIMENSION input_xoffset; 1560ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC boolean reinit_upsampler = FALSE; 1570ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jpeg_component_info *compptr; 1580ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1590ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (cinfo->global_state != DSTATE_SCANNING || cinfo->output_scanline != 0) 1600ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 1610ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1620ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (!xoffset || !width) 1630ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC ERREXIT(cinfo, JERR_BAD_CROP_SPEC); 1640ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1650ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* xoffset and width must fall within the output image dimensions. */ 1660ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (*width == 0 || *xoffset + *width > cinfo->output_width) 1670ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); 1680ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1690ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* No need to do anything if the caller wants the entire width. */ 1700ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (*width == cinfo->output_width) 1710ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC return; 1720ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1730ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Ensuring the proper alignment of xoffset is tricky. At minimum, it 1740ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * must align with an MCU boundary, because: 1750ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * 1760ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * (1) The IDCT is performed in blocks, and it is not feasible to modify 1770ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * the algorithm so that it can transform partial blocks. 1780ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * (2) Because of the SIMD extensions, any input buffer passed to the 1790ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * upsampling and color conversion routines must be aligned to the 1800ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * SIMD word size (for instance, 128-bit in the case of SSE2.) The 1810ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * easiest way to accomplish this without copying data is to ensure 1820ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * that upsampling and color conversion begin at the start of the 1830ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * first MCU column that will be inverse transformed. 1840ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * 1850ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * In practice, we actually impose a stricter alignment requirement. We 1860ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * require that xoffset be a multiple of the maximum MCU column width of all 1870ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * of the components (the "iMCU column width.") This is to simplify the 1880ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * single-pass decompression case, allowing us to use the same MCU column 1890ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * width for all of the components. 1900ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 1910ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC align = cinfo->min_DCT_scaled_size * cinfo->max_h_samp_factor; 1920ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1930ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Adjust xoffset to the nearest iMCU boundary <= the requested value */ 1940ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC input_xoffset = *xoffset; 1950ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC *xoffset = (input_xoffset / align) * align; 1960ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 1970ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Adjust the width so that the right edge of the output image is as 1980ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * requested (only the left edge is altered.) It is important that calling 1990ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * programs check this value after this function returns, so that they can 2000ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * allocate an output buffer with the appropriate size. 2010ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 2020ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC *width = *width + input_xoffset - *xoffset; 2030ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->output_width = *width; 2040ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2050ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Set the first and last iMCU columns that we must decompress. These values 2060ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * will be used in single-scan decompressions. 2070ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 2080ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->first_iMCU_col = 2090ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (JDIMENSION) (long) (*xoffset) / (long) align; 2100ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->last_iMCU_col = 2110ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (JDIMENSION) jdiv_round_up((long) (*xoffset + cinfo->output_width), 2120ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (long) align) - 1; 2130ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2140ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 2150ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC ci++, compptr++) { 2160ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Set downsampled_width to the new output width. */ 2170ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC orig_downsampled_width = compptr->downsampled_width; 2180ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC compptr->downsampled_width = 2190ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (JDIMENSION) jdiv_round_up((long) (cinfo->output_width * 2200ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC compptr->h_samp_factor), 2210ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (long) cinfo->max_h_samp_factor); 2220ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (compptr->downsampled_width < 2 && orig_downsampled_width >= 2) 2230ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC reinit_upsampler = TRUE; 2240ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2250ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Set the first and last iMCU columns that we must decompress. These 2260ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * values will be used in multi-scan decompressions. 2270ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 2280ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->first_MCU_col[ci] = 2290ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (JDIMENSION) (long) (*xoffset * compptr->h_samp_factor) / 2300ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (long) align; 2310ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->last_MCU_col[ci] = 2320ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (JDIMENSION) jdiv_round_up((long) ((*xoffset + cinfo->output_width) * 2330ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC compptr->h_samp_factor), 2340ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (long) align) - 1; 2350ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } 2360ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2370ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (reinit_upsampler) { 2380ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->jinit_upsampler_no_alloc = TRUE; 2390ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jinit_upsampler(cinfo); 2400ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo->master->jinit_upsampler_no_alloc = FALSE; 2410ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } 2420ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC} 2430ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2440ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 2450ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC/* 246bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Read some scanlines of data from the JPEG decompressor. 247bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 248bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * The return value will be the number of lines actually read. 249bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * This may be less than the number requested in several cases, 250bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * including bottom of image, data source suspension, and operating 251bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * modes that emit multiple scanlines at a time. 252bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 253bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Note: we warn about excess calls to jpeg_read_scanlines() since 254bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * this likely signals an application programmer error. However, 255bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * an oversize buffer (max_lines > scanlines remaining) is not an error. 256bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 257bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 258489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(JDIMENSION) 259bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, 260e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION max_lines) 261bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 262bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane JDIMENSION row_ctr; 263bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 264bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state != DSTATE_SCANNING) 265bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 266bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->output_scanline >= cinfo->output_height) { 267bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 268bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return 0; 269bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 270bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 271bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Call progress monitor hook if present */ 272bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->progress != NULL) { 273bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->progress->pass_counter = (long) cinfo->output_scanline; 274bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->progress->pass_limit = (long) cinfo->output_height; 275bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 276bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 277bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 278bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Process some data */ 279bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane row_ctr = 0; 280bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); 281bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scanline += row_ctr; 282bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return row_ctr; 283bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 284bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 285bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 28690c92ed5bf98bda381fcc369f0da46837dbb8894DRC/* Dummy color convert function used by jpeg_skip_scanlines() */ 28790c92ed5bf98bda381fcc369f0da46837dbb8894DRCLOCAL(void) 28890c92ed5bf98bda381fcc369f0da46837dbb8894DRCnoop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 28990c92ed5bf98bda381fcc369f0da46837dbb8894DRC JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) 29090c92ed5bf98bda381fcc369f0da46837dbb8894DRC{ 29190c92ed5bf98bda381fcc369f0da46837dbb8894DRC} 29290c92ed5bf98bda381fcc369f0da46837dbb8894DRC 29390c92ed5bf98bda381fcc369f0da46837dbb8894DRC 29490c92ed5bf98bda381fcc369f0da46837dbb8894DRC/* 29590c92ed5bf98bda381fcc369f0da46837dbb8894DRC * In some cases, it is best to call jpeg_read_scanlines() and discard the 29690c92ed5bf98bda381fcc369f0da46837dbb8894DRC * output, rather than skipping the scanlines, because this allows us to 29790c92ed5bf98bda381fcc369f0da46837dbb8894DRC * maintain the internal state of the context-based upsampler. In these cases, 29890c92ed5bf98bda381fcc369f0da46837dbb8894DRC * we set up and tear down a dummy color converter in order to avoid valgrind 29990c92ed5bf98bda381fcc369f0da46837dbb8894DRC * errors and to achieve the best possible performance. 30090c92ed5bf98bda381fcc369f0da46837dbb8894DRC */ 301ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 302ac30a1bf12751bd82e56158eb9456a28d9c086f3DRCLOCAL(void) 30390c92ed5bf98bda381fcc369f0da46837dbb8894DRCread_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines) 304ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC{ 30590c92ed5bf98bda381fcc369f0da46837dbb8894DRC JDIMENSION n; 30690c92ed5bf98bda381fcc369f0da46837dbb8894DRC void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 30790c92ed5bf98bda381fcc369f0da46837dbb8894DRC JDIMENSION input_row, JSAMPARRAY output_buf, 30890c92ed5bf98bda381fcc369f0da46837dbb8894DRC int num_rows); 30990c92ed5bf98bda381fcc369f0da46837dbb8894DRC 31090c92ed5bf98bda381fcc369f0da46837dbb8894DRC color_convert = cinfo->cconvert->color_convert; 31190c92ed5bf98bda381fcc369f0da46837dbb8894DRC cinfo->cconvert->color_convert = noop_convert; 312ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 31390c92ed5bf98bda381fcc369f0da46837dbb8894DRC for (n = 0; n < num_lines; n++) 31490c92ed5bf98bda381fcc369f0da46837dbb8894DRC jpeg_read_scanlines(cinfo, NULL, 1); 315ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 31690c92ed5bf98bda381fcc369f0da46837dbb8894DRC cinfo->cconvert->color_convert = color_convert; 317ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC} 318ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 319ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 320ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC/* 321ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Called by jpeg_skip_scanlines(). This partially skips a decompress block by 322ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * incrementing the rowgroup counter. 323ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 324ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 325ac30a1bf12751bd82e56158eb9456a28d9c086f3DRCLOCAL(void) 326ac30a1bf12751bd82e56158eb9456a28d9c086f3DRCincrement_simple_rowgroup_ctr (j_decompress_ptr cinfo, JDIMENSION rows) 327ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC{ 32890c92ed5bf98bda381fcc369f0da46837dbb8894DRC JDIMENSION rows_left; 329ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC my_main_ptr main_ptr = (my_main_ptr) cinfo->main; 330ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 331ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Increment the counter to the next row group after the skipped rows. */ 332ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor; 333ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 334ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Partially skipping a row group would involve modifying the internal state 335ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * of the upsampler, so read the remaining rows into a dummy buffer instead. 336ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 337ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC rows_left = rows % cinfo->max_v_samp_factor; 338ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += rows - rows_left; 339ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 34090c92ed5bf98bda381fcc369f0da46837dbb8894DRC read_and_discard_scanlines(cinfo, rows_left); 341ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC} 342ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 343ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC/* 344ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Skips some scanlines of data from the JPEG decompressor. 345ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * 346ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * The return value will be the number of lines actually skipped. If skipping 347ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * num_lines would move beyond the end of the image, then the actual number of 348ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * lines remaining in the image is returned. Otherwise, the return value will 349ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * be equal to num_lines. 350ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * 351ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Refer to libjpeg.txt for more information. 352ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 353ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 354ac30a1bf12751bd82e56158eb9456a28d9c086f3DRCGLOBAL(JDIMENSION) 355ac30a1bf12751bd82e56158eb9456a28d9c086f3DRCjpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines) 356ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC{ 357ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC my_main_ptr main_ptr = (my_main_ptr) cinfo->main; 358ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC my_coef_ptr coef = (my_coef_ptr) cinfo->coef; 359ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 3603fb56e969c890e6aa7b044eea7e24751ab6f4e97DRC JDIMENSION i, x; 3613fb56e969c890e6aa7b044eea7e24751ab6f4e97DRC int y; 362ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row; 363ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC JDIMENSION lines_to_skip, lines_to_read; 364ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 365ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->global_state != DSTATE_SCANNING) 366ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 367ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 368ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Do not skip past the bottom of the image. */ 369ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->output_scanline + num_lines >= cinfo->output_height) { 370ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline = cinfo->output_height; 371ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return cinfo->output_height - cinfo->output_scanline; 372ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 373ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 374ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (num_lines == 0) 375ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return 0; 376ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 377ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_per_iMCU_row = cinfo->_min_DCT_scaled_size * cinfo->max_v_samp_factor; 378ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_left_in_iMCU_row = 379ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (lines_per_iMCU_row - (cinfo->output_scanline % lines_per_iMCU_row)) % 380ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_per_iMCU_row; 381ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_after_iMCU_row = num_lines - lines_left_in_iMCU_row; 382ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 383ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Skip the lines remaining in the current iMCU row. When upsampling 384ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * requires context rows, we need the previous and next rows in order to read 385ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * the current row. This adds some complexity. 386ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 387ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->upsample->need_context_rows) { 388ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* If the skipped lines would not move us past the current iMCU row, we 389ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * read the lines and ignore them. There might be a faster way of doing 390ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * this, but we are facing increasing complexity for diminishing returns. 391ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * The increasing complexity would be a by-product of meddling with the 392ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * state machine used to skip context rows. Near the end of an iMCU row, 393ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * the next iMCU row may have already been entropy-decoded. In this unique 394ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * case, we will read the next iMCU row if we cannot skip past it as well. 395ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 396ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if ((num_lines < lines_left_in_iMCU_row + 1) || 397ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full && 398ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_after_iMCU_row < lines_per_iMCU_row + 1)) { 39990c92ed5bf98bda381fcc369f0da46837dbb8894DRC read_and_discard_scanlines(cinfo, num_lines); 400ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return num_lines; 401ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 402ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 403ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* If the next iMCU row has already been entropy-decoded, make sure that 404ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * we do not skip too far. 405ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 406ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full) { 407ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_left_in_iMCU_row + lines_per_iMCU_row; 408ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_after_iMCU_row -= lines_per_iMCU_row; 409ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else { 410ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_left_in_iMCU_row; 411ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 412f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC 413f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC /* If we have just completed the first block, adjust the buffer pointers */ 414f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC if (main_ptr->iMCU_row_ctr == 0 || 415f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC (main_ptr->iMCU_row_ctr == 1 && lines_left_in_iMCU_row > 2)) 416f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC set_wraparound_pointers(cinfo); 417ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->buffer_full = FALSE; 418ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->rowgroup_ctr = 0; 419ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->context_state = CTX_PREPARE_FOR_IMCU; 420ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->next_row_out = cinfo->max_v_samp_factor; 421ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; 422ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 423ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 424ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Skipping is much simpler when context rows are not required. */ 425ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC else { 426ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (num_lines < lines_left_in_iMCU_row) { 427ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC increment_simple_rowgroup_ctr(cinfo, num_lines); 428ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return num_lines; 429ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else { 430ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_left_in_iMCU_row; 431ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->buffer_full = FALSE; 432ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC main_ptr->rowgroup_ctr = 0; 433ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->next_row_out = cinfo->max_v_samp_factor; 434ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; 435ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 436ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 437ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 438ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Calculate how many full iMCU rows we can skip. */ 439ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->upsample->need_context_rows) 440ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_to_skip = ((lines_after_iMCU_row - 1) / lines_per_iMCU_row) * 441ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_per_iMCU_row; 442ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC else 443ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_to_skip = (lines_after_iMCU_row / lines_per_iMCU_row) * 444ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_per_iMCU_row; 445ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Calculate the number of lines that remain to be skipped after skipping all 446ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * of the full iMCU rows that we can. We will not read these lines unless we 447ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * have to. 448ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 449ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC lines_to_read = lines_after_iMCU_row - lines_to_skip; 450ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 451ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* For images requiring multiple scans (progressive, non-interleaved, etc.), 452ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * all of the entropy decoding occurs in jpeg_start_decompress(), assuming 453ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * that the input data source is non-suspending. This makes skipping easy. 454ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 455ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->inputctl->has_multiple_scans) { 456ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->upsample->need_context_rows) { 457ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_to_skip; 458ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row; 459f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC main_ptr->iMCU_row_ctr += lines_after_iMCU_row / lines_per_iMCU_row; 460ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* It is complex to properly move to the middle of a context block, so 461ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * read the remaining lines instead of skipping them. 462ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 46390c92ed5bf98bda381fcc369f0da46837dbb8894DRC read_and_discard_scanlines(cinfo, lines_to_read); 464ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else { 465ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_to_skip; 466ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row; 467ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC increment_simple_rowgroup_ctr(cinfo, lines_to_read); 468ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 469ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; 470ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return num_lines; 471ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 472ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 473ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Skip the iMCU rows that we can safely skip. */ 474ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC for (i = 0; i < lines_to_skip; i += lines_per_iMCU_row) { 475ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC for (y = 0; y < coef->MCU_rows_per_iMCU_row; y++) { 476ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC for (x = 0; x < cinfo->MCUs_per_row; x++) { 477ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Calling decode_mcu() with a NULL pointer causes it to discard the 478ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * decoded coefficients. This is ~5% faster for large subsets, but 479f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC * it's tough to tell a difference for smaller images. 480ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 481ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (*cinfo->entropy->decode_mcu) (cinfo, NULL); 482ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 483ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 484ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->input_iMCU_row++; 485ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_iMCU_row++; 486ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->input_iMCU_row < cinfo->total_iMCU_rows) 487ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC start_iMCU_row(cinfo); 488ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC else 489ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (*cinfo->inputctl->finish_input_pass) (cinfo); 490ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 491ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo->output_scanline += lines_to_skip; 492ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 493ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (cinfo->upsample->need_context_rows) { 494ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Context-based upsampling keeps track of iMCU rows. */ 495f8a1775eab51fb0a83e82343d2eae8cf52b16124DRC main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row; 496ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 497ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* It is complex to properly move to the middle of a context block, so 498ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * read the remaining lines instead of skipping them. 499ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 50090c92ed5bf98bda381fcc369f0da46837dbb8894DRC read_and_discard_scanlines(cinfo, lines_to_read); 501ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else { 502ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC increment_simple_rowgroup_ctr(cinfo, lines_to_read); 503ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 504ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 505ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Since skipping lines involves skipping the upsampling step, the value of 506ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * "rows_to_go" will become invalid unless we set it here. NOTE: This is a 507ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * bit odd, since "rows_to_go" seems to be redundantly keeping track of 508ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * output_scanline. 509ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 510ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; 511ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 512ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Always skip the requested number of lines. */ 513ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC return num_lines; 514ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC} 515ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 516bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 517bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Alternate entry point to read raw data. 518bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Processes exactly one iMCU row per call, unless suspended. 519bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 520bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 521489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(JDIMENSION) 522bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, 523e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION max_lines) 524bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 525bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane JDIMENSION lines_per_iMCU_row; 526bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 527bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state != DSTATE_RAW_OK) 528bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 529bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->output_scanline >= cinfo->output_height) { 530bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane WARNMS(cinfo, JWRN_TOO_MUCH_DATA); 531bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return 0; 532bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 533bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 534bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Call progress monitor hook if present */ 535bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->progress != NULL) { 536bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->progress->pass_counter = (long) cinfo->output_scanline; 537bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->progress->pass_limit = (long) cinfo->output_height; 538bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); 539bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 540bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 541bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Verify that at least one iMCU row can be returned. */ 54249967cdb30edd0479a1719eedc1dace5ba078d3fDRC lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size; 543bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (max_lines < lines_per_iMCU_row) 544bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT(cinfo, JERR_BUFFER_SIZE); 545bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 546bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Decompress directly into user's buffer. */ 547bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (! (*cinfo->coef->decompress_data) (cinfo, data)) 548e5eaf37440b8e337ab150c017df7c03faf846c51DRC return 0; /* suspension forced, can do nothing more */ 549bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 550bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* OK, we processed one iMCU row. */ 551bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scanline += lines_per_iMCU_row; 552bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return lines_per_iMCU_row; 553bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 554bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 555bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 556bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* Additional entry points for buffered-image mode. */ 557bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 558bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#ifdef D_MULTISCAN_FILES_SUPPORTED 559bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 560bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 561bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Initialize for an output pass in buffered-image mode. 562bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 563bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 564489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(boolean) 565bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_start_output (j_decompress_ptr cinfo, int scan_number) 566bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 567bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->global_state != DSTATE_BUFIMAGE && 568bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state != DSTATE_PRESCAN) 569bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 570bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Limit scan number to valid range */ 571bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (scan_number <= 0) 572bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane scan_number = 1; 573bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (cinfo->inputctl->eoi_reached && 574bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane scan_number > cinfo->input_scan_number) 575bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane scan_number = cinfo->input_scan_number; 576bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->output_scan_number = scan_number; 577bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Perform any dummy output passes, and set up for the real pass */ 578bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return output_pass_setup(cinfo); 579bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 580bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 581bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 582bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane/* 583bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Finish up after an output pass in buffered-image mode. 584bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * 585bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Returns FALSE if suspended. The return value need be inspected only if 586bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * a suspending data source is used. 587bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 588bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 589489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(boolean) 590bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_finish_output (j_decompress_ptr cinfo) 591bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane{ 592bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if ((cinfo->global_state == DSTATE_SCANNING || 593bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { 594bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Terminate this pass. */ 595bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* We do not require the whole pass to have been completed. */ 596bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (*cinfo->master->finish_output_pass) (cinfo); 597bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = DSTATE_BUFPOST; 598bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } else if (cinfo->global_state != DSTATE_BUFPOST) { 599bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* BUFPOST = repeat call after a suspension, anything else is error */ 600bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 601bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 602bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* Read markers looking for SOS or EOI */ 603bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane while (cinfo->input_scan_number <= cinfo->output_scan_number && 604e5eaf37440b8e337ab150c017df7c03faf846c51DRC ! cinfo->inputctl->eoi_reached) { 605bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) 606e5eaf37440b8e337ab150c017df7c03faf846c51DRC return FALSE; /* Suspend, come back later */ 607bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 608bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane cinfo->global_state = DSTATE_BUFIMAGE; 609bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane return TRUE; 610bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane} 611bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane 612bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane#endif /* D_MULTISCAN_FILES_SUPPORTED */ 613