| Index: jdapistd.c
 | 
| diff --git a/jdapistd.c b/jdapistd.c
 | 
| index 056fa1d07bc9979ec93ca412dbee7baecbed91d4..37afc8448b93ea0cad5e744b0ef899a0b7c316ec 100644
 | 
| --- a/jdapistd.c
 | 
| +++ b/jdapistd.c
 | 
| @@ -4,9 +4,10 @@
 | 
|   * This file was part of the Independent JPEG Group's software:
 | 
|   * Copyright (C) 1994-1996, Thomas G. Lane.
 | 
|   * libjpeg-turbo Modifications:
 | 
| - * Copyright (C) 2010, 2015, D. R. Commander.
 | 
| + * Copyright (C) 2010, 2015-2016, D. R. Commander.
 | 
|   * Copyright (C) 2015, Google, Inc.
 | 
| - * For conditions of distribution and use, see the accompanying README file.
 | 
| + * For conditions of distribution and use, see the accompanying README.ijg
 | 
| + * file.
 | 
|   *
 | 
|   * This file contains application interface code for the decompression half
 | 
|   * of the JPEG library.  These are the "standard" API routines that are
 | 
| @@ -17,14 +18,14 @@
 | 
|   * whole decompression library into a transcoder.
 | 
|   */
 | 
|  
 | 
| +#include "jinclude.h"
 | 
|  #include "jdmainct.h"
 | 
|  #include "jdcoefct.h"
 | 
|  #include "jdsample.h"
 | 
|  #include "jmemsys.h"
 | 
|  
 | 
| -
 | 
|  /* Forward declarations */
 | 
| -LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
 | 
| +LOCAL(boolean) output_pass_setup (j_decompress_ptr cinfo);
 | 
|  
 | 
|  
 | 
|  /*
 | 
| @@ -56,24 +57,24 @@ jpeg_start_decompress (j_decompress_ptr cinfo)
 | 
|      if (cinfo->inputctl->has_multiple_scans) {
 | 
|  #ifdef D_MULTISCAN_FILES_SUPPORTED
 | 
|        for (;;) {
 | 
| -	int retcode;
 | 
| -	/* Call progress monitor hook if present */
 | 
| -	if (cinfo->progress != NULL)
 | 
| -	  (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 | 
| -	/* Absorb some more input */
 | 
| -	retcode = (*cinfo->inputctl->consume_input) (cinfo);
 | 
| -	if (retcode == JPEG_SUSPENDED)
 | 
| -	  return FALSE;
 | 
| -	if (retcode == JPEG_REACHED_EOI)
 | 
| -	  break;
 | 
| -	/* Advance progress counter if appropriate */
 | 
| -	if (cinfo->progress != NULL &&
 | 
| -	    (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
 | 
| -	  if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
 | 
| -	    /* jdmaster underestimated number of scans; ratchet up one scan */
 | 
| -	    cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
 | 
| -	  }
 | 
| -	}
 | 
| +        int retcode;
 | 
| +        /* Call progress monitor hook if present */
 | 
| +        if (cinfo->progress != NULL)
 | 
| +          (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 | 
| +        /* Absorb some more input */
 | 
| +        retcode = (*cinfo->inputctl->consume_input) (cinfo);
 | 
| +        if (retcode == JPEG_SUSPENDED)
 | 
| +          return FALSE;
 | 
| +        if (retcode == JPEG_REACHED_EOI)
 | 
| +          break;
 | 
| +        /* Advance progress counter if appropriate */
 | 
| +        if (cinfo->progress != NULL &&
 | 
| +            (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
 | 
| +          if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
 | 
| +            /* jdmaster underestimated number of scans; ratchet up one scan */
 | 
| +            cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
 | 
| +          }
 | 
| +        }
 | 
|        }
 | 
|  #else
 | 
|        ERREXIT(cinfo, JERR_NOT_COMPILED);
 | 
| @@ -112,16 +113,16 @@ output_pass_setup (j_decompress_ptr cinfo)
 | 
|        JDIMENSION last_scanline;
 | 
|        /* Call progress monitor hook if present */
 | 
|        if (cinfo->progress != NULL) {
 | 
| -	cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 | 
| -	cinfo->progress->pass_limit = (long) cinfo->output_height;
 | 
| -	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 | 
| +        cinfo->progress->pass_counter = (long) cinfo->output_scanline;
 | 
| +        cinfo->progress->pass_limit = (long) cinfo->output_height;
 | 
| +        (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
 | 
|        }
 | 
|        /* Process some data */
 | 
|        last_scanline = cinfo->output_scanline;
 | 
|        (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
 | 
| -				    &cinfo->output_scanline, (JDIMENSION) 0);
 | 
| +                                    &cinfo->output_scanline, (JDIMENSION) 0);
 | 
|        if (cinfo->output_scanline == last_scanline)
 | 
| -	return FALSE;		/* No progress made, must suspend */
 | 
| +        return FALSE;           /* No progress made, must suspend */
 | 
|      }
 | 
|      /* Finish up dummy pass, and set up for another one */
 | 
|      (*cinfo->master->finish_output_pass) (cinfo);
 | 
| @@ -140,6 +141,110 @@ output_pass_setup (j_decompress_ptr cinfo)
 | 
|  
 | 
|  
 | 
|  /*
 | 
| + * Enable partial scanline decompression
 | 
| + *
 | 
| + * Must be called after jpeg_start_decompress() and before any calls to
 | 
| + * jpeg_read_scanlines() or jpeg_skip_scanlines().
 | 
| + *
 | 
| + * Refer to libjpeg.txt for more information.
 | 
| + */
 | 
| +
 | 
| +GLOBAL(void)
 | 
| +jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
 | 
| +                    JDIMENSION *width)
 | 
| +{
 | 
| +  int ci, align, orig_downsampled_width;
 | 
| +  JDIMENSION input_xoffset;
 | 
| +  boolean reinit_upsampler = FALSE;
 | 
| +  jpeg_component_info *compptr;
 | 
| +
 | 
| +  if (cinfo->global_state != DSTATE_SCANNING || cinfo->output_scanline != 0)
 | 
| +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 | 
| +
 | 
| +  if (!xoffset || !width)
 | 
| +    ERREXIT(cinfo, JERR_BAD_CROP_SPEC);
 | 
| +
 | 
| +  /* xoffset and width must fall within the output image dimensions. */
 | 
| +  if (*width == 0 || *xoffset + *width > cinfo->output_width)
 | 
| +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
 | 
| +
 | 
| +  /* No need to do anything if the caller wants the entire width. */
 | 
| +  if (*width == cinfo->output_width)
 | 
| +    return;
 | 
| +
 | 
| +  /* Ensuring the proper alignment of xoffset is tricky.  At minimum, it
 | 
| +   * must align with an MCU boundary, because:
 | 
| +   *
 | 
| +   *   (1) The IDCT is performed in blocks, and it is not feasible to modify
 | 
| +   *       the algorithm so that it can transform partial blocks.
 | 
| +   *   (2) Because of the SIMD extensions, any input buffer passed to the
 | 
| +   *       upsampling and color conversion routines must be aligned to the
 | 
| +   *       SIMD word size (for instance, 128-bit in the case of SSE2.)  The
 | 
| +   *       easiest way to accomplish this without copying data is to ensure
 | 
| +   *       that upsampling and color conversion begin at the start of the
 | 
| +   *       first MCU column that will be inverse transformed.
 | 
| +   *
 | 
| +   * In practice, we actually impose a stricter alignment requirement.  We
 | 
| +   * require that xoffset be a multiple of the maximum MCU column width of all
 | 
| +   * of the components (the "iMCU column width.")  This is to simplify the
 | 
| +   * single-pass decompression case, allowing us to use the same MCU column
 | 
| +   * width for all of the components.
 | 
| +   */
 | 
| +  align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor;
 | 
| +
 | 
| +  /* Adjust xoffset to the nearest iMCU boundary <= the requested value */
 | 
| +  input_xoffset = *xoffset;
 | 
| +  *xoffset = (input_xoffset / align) * align;
 | 
| +
 | 
| +  /* Adjust the width so that the right edge of the output image is as
 | 
| +   * requested (only the left edge is altered.)  It is important that calling
 | 
| +   * programs check this value after this function returns, so that they can
 | 
| +   * allocate an output buffer with the appropriate size.
 | 
| +   */
 | 
| +  *width = *width + input_xoffset - *xoffset;
 | 
| +  cinfo->output_width = *width;
 | 
| +
 | 
| +  /* Set the first and last iMCU columns that we must decompress.  These values
 | 
| +   * will be used in single-scan decompressions.
 | 
| +   */
 | 
| +  cinfo->master->first_iMCU_col =
 | 
| +    (JDIMENSION) (long) (*xoffset) / (long) align;
 | 
| +  cinfo->master->last_iMCU_col =
 | 
| +    (JDIMENSION) jdiv_round_up((long) (*xoffset + cinfo->output_width),
 | 
| +                               (long) align) - 1;
 | 
| +
 | 
| +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
 | 
| +       ci++, compptr++) {
 | 
| +    /* Set downsampled_width to the new output width. */
 | 
| +    orig_downsampled_width = compptr->downsampled_width;
 | 
| +    compptr->downsampled_width =
 | 
| +      (JDIMENSION) jdiv_round_up((long) (cinfo->output_width *
 | 
| +                                         compptr->h_samp_factor),
 | 
| +                                 (long) cinfo->max_h_samp_factor);
 | 
| +    if (compptr->downsampled_width < 2 && orig_downsampled_width >= 2)
 | 
| +      reinit_upsampler = TRUE;
 | 
| +
 | 
| +    /* Set the first and last iMCU columns that we must decompress.  These
 | 
| +     * values will be used in multi-scan decompressions.
 | 
| +     */
 | 
| +    cinfo->master->first_MCU_col[ci] =
 | 
| +      (JDIMENSION) (long) (*xoffset * compptr->h_samp_factor) /
 | 
| +                   (long) align;
 | 
| +    cinfo->master->last_MCU_col[ci] =
 | 
| +      (JDIMENSION) jdiv_round_up((long) ((*xoffset + cinfo->output_width) *
 | 
| +                                         compptr->h_samp_factor),
 | 
| +                                 (long) align) - 1;
 | 
| +  }
 | 
| +
 | 
| +  if (reinit_upsampler) {
 | 
| +    cinfo->master->jinit_upsampler_no_alloc = TRUE;
 | 
| +    jinit_upsampler(cinfo);
 | 
| +    cinfo->master->jinit_upsampler_no_alloc = FALSE;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +/*
 | 
|   * Read some scanlines of data from the JPEG decompressor.
 | 
|   *
 | 
|   * The return value will be the number of lines actually read.
 | 
| @@ -154,7 +259,7 @@ output_pass_setup (j_decompress_ptr cinfo)
 | 
|  
 | 
|  GLOBAL(JDIMENSION)
 | 
|  jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
 | 
| -		     JDIMENSION max_lines)
 | 
| +                     JDIMENSION max_lines)
 | 
|  {
 | 
|    JDIMENSION row_ctr;
 | 
|  
 | 
| @@ -180,7 +285,6 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -
 | 
|  /* Dummy color convert function used by jpeg_skip_scanlines() */
 | 
|  LOCAL(void)
 | 
|  noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
 | 
| @@ -196,6 +300,7 @@ noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
 | 
|   * we set up and tear down a dummy color converter in order to avoid valgrind
 | 
|   * errors and to achieve the best possible performance.
 | 
|   */
 | 
| +
 | 
|  LOCAL(void)
 | 
|  read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
 | 
|  {
 | 
| @@ -213,6 +318,7 @@ read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
 | 
|    cinfo->cconvert->color_convert = color_convert;
 | 
|  }
 | 
|  
 | 
| +
 | 
|  /*
 | 
|   * Called by jpeg_skip_scanlines().  This partially skips a decompress block by
 | 
|   * incrementing the rowgroup counter.
 | 
| @@ -416,7 +522,7 @@ jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
 | 
|  
 | 
|  GLOBAL(JDIMENSION)
 | 
|  jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
 | 
| -		    JDIMENSION max_lines)
 | 
| +                    JDIMENSION max_lines)
 | 
|  {
 | 
|    JDIMENSION lines_per_iMCU_row;
 | 
|  
 | 
| @@ -441,7 +547,7 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
 | 
|  
 | 
|    /* Decompress directly into user's buffer. */
 | 
|    if (! (*cinfo->coef->decompress_data) (cinfo, data))
 | 
| -    return 0;			/* suspension forced, can do nothing more */
 | 
| +    return 0;                   /* suspension forced, can do nothing more */
 | 
|  
 | 
|    /* OK, we processed one iMCU row. */
 | 
|    cinfo->output_scanline += lines_per_iMCU_row;
 | 
| @@ -497,9 +603,9 @@ jpeg_finish_output (j_decompress_ptr cinfo)
 | 
|    }
 | 
|    /* Read markers looking for SOS or EOI */
 | 
|    while (cinfo->input_scan_number <= cinfo->output_scan_number &&
 | 
| -	 ! cinfo->inputctl->eoi_reached) {
 | 
| +         ! cinfo->inputctl->eoi_reached) {
 | 
|      if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
 | 
| -      return FALSE;		/* Suspend, come back later */
 | 
| +      return FALSE;             /* Suspend, come back later */
 | 
|    }
 | 
|    cinfo->global_state = DSTATE_BUFIMAGE;
 | 
|    return TRUE;
 | 
| 
 |