transencode_coef_controller (j_compress_ptr cinfo,
			     jvirt_barray_ptr * coef_arrays)
{
  j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec;
  c_coef_ptr coef;
  JBLOCKROW buffer;
  int i;

  coef = (c_coef_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(c_coef_controller));
  lossyc->coef_private = (struct jpeg_c_coef_controller *) coef;

  /* Save pointer to virtual arrays */
  coef->whole_image = coef_arrays;

  /* Allocate and pre-zero space for dummy DCT blocks. */
  buffer = (JBLOCKROW)
    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				C_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK));
  jzero_far((void FAR *) buffer, C_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK));
  for (i = 0; i < C_MAX_DATA_UNITS_IN_MCU; i++) {
    coef->dummy_buffer[i] = buffer + i;
  }
}
Exemple #2
0
transencode_coef_controller (j_compress_ptr cinfo,
			     jvirt_barray_ptr * coef_arrays)
{
  my_coef_ptr coef;
  JBLOCKROW buffer;
  int i;

  coef = (my_coef_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(my_coef_controller));
  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
  coef->pub.start_pass = start_pass_coef;
  coef->pub.compress_data = compress_output;

  /* Save pointer to virtual arrays */
  coef->whole_image = coef_arrays;

  /* Allocate and pre-zero space for dummy DCT blocks. */
  buffer = (JBLOCKROW)
    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
    coef->dummy_buffer[i] = buffer + i;
  }
}
Exemple #3
0
start_pass_1_quant (j_decompress_ptr cinfo, wxjpeg_boolean is_pre_scan)
{
  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
  size_t arraysize;
  int i;

  /* Install my colormap. */
  cinfo->colormap = cquantize->sv_colormap;
  cinfo->actual_number_of_colors = cquantize->sv_actual;

  /* Initialize for desired dithering mode. */
  switch (cinfo->dither_mode) {
  case JDITHER_NONE:
    if (cinfo->out_color_components == 3)
      cquantize->pub.color_quantize = color_quantize3;
    else
      cquantize->pub.color_quantize = color_quantize;
    break;
  case JDITHER_ORDERED:
    if (cinfo->out_color_components == 3)
      cquantize->pub.color_quantize = quantize3_ord_dither;
    else
      cquantize->pub.color_quantize = quantize_ord_dither;
    cquantize->row_index = 0;	/* initialize state for ordered dither */
    /* If user changed to ordered dither from another mode,
     * we must recreate the color index table with padding.
     * This will cost extra space, but probably isn't very likely.
     */
    if (! cquantize->is_padded)
      create_colorindex(cinfo);
    /* Create ordered-dither tables if we didn't already. */
    if (cquantize->odither[0] == NULL)
      create_odither_tables(cinfo);
    break;
  case JDITHER_FS:
    cquantize->pub.color_quantize = quantize_fs_dither;
    cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
    /* Allocate Floyd-Steinberg workspace if didn't already. */
    if (cquantize->fserrors[0] == NULL)
      alloc_fs_workspace(cinfo);
    /* Initialize the propagated errors to zero. */
    arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for (i = 0; i < cinfo->out_color_components; i++)
      jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
    break;
  default:
    ERREXIT(cinfo, JERR_NOT_COMPILED);
    break;
  }
}
/*METHODDEF*/static void
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
				 JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */
{
	my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
	register JSAMPROW input_ptr;
	register JSAMPROW output_ptr;
	JSAMPROW colorindex_ci;
	int * dither;			/* points to active row of dither matrix */
	int row_index, col_index;	/* current indexes into dither matrix */
	int nc = cinfo->out_color_components;
	int ci;
	int row;
	JDIMENSION col;
	JDIMENSION width = cinfo->output_width;

	for (row = 0; row < num_rows; row++)
	{
		/* Initialize output values to 0 so can process components separately */
		jzero_far((void FAR *) output_buf[row], (size_t) (width * SIZEOF(JSAMPLE)));
		row_index = cquantize->row_index;
		for (ci = 0; ci < nc; ci++)
		{
			input_ptr		= input_buf[row] + ci;
			output_ptr		= output_buf[row];
			colorindex_ci	= cquantize->colorindex[ci];
			dither			= cquantize->odither[ci][row_index];
			col_index		= 0;

			for (col = width; col > 0; col--)
			{
	/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
	 * select output value, accumulate into output code for this pixel.
	 * Range-limiting need not be done explicitly, as we have extended
	 * the colorindex table to produce the right answers for out-of-range
	 * inputs.	The maximum dither is +- MAXJSAMPLE; this sets the
	 * required amount of padding.
	 */
				*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
				input_ptr	+= nc;
				output_ptr++;
				col_index	= (col_index + 1) & ODITHER_MASK;
			}
		}
		/* Advance row index for next row */
		row_index				= (row_index + 1) & ODITHER_MASK;
		cquantize->row_index	= row_index;
	}
}
METHODDEF void
disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
				JBLOCKIMAGE image_data)
{
  JBLOCKROW MCU_data[1];
  long mcuindex;

  /* this is pretty easy since there is one component and one block per MCU */

  /* Pre-zero the target area to speed up entropy decoder */
  /* (we assume wholesale zeroing is faster than retail) */
  jzero_far((void FAR *) image_data[0][0],
	    (size_t) (cinfo->MCUs_per_row * SIZEOF(JBLOCK)));

  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
    /* Point to the proper spot in the image array for this MCU */
    MCU_data[0] = image_data[0][0] + mcuindex;
    /* Fetch the coefficient data */
    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  }
}
METHODDEF void
disassemble_interleaved_MCU (decompress_info_ptr cinfo,
			     JBLOCKIMAGE image_data)
{
  JBLOCKROW MCU_data[MAX_BLOCKS_IN_MCU];
  long mcuindex;
  short blkn, ci, xpos, ypos;
  jpeg_component_info * compptr;
  JBLOCKROW image_ptr;

  /* Pre-zero the target area to speed up entropy decoder */
  /* (we assume wholesale zeroing is faster than retail) */
  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
      jzero_far((void FAR *) image_data[ci][ypos],
		(size_t) (cinfo->MCUs_per_row * compptr->MCU_width * SIZEOF(JBLOCK)));
    }
  }

  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
    /* Point to the proper spots in the image array for this MCU */
    blkn = 0;
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
      compptr = cinfo->cur_comp_info[ci];
      for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
	image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
	for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
	  MCU_data[blkn] = image_ptr;
	  image_ptr++;
	  blkn++;
	}
      }
    }
    /* Fetch the coefficient data */
    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  }
}
Exemple #7
0
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
__boundcheck_metadata_store((void *)(&coef),(void *)((size_t)(&coef)+sizeof(coef)*8-1));

  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
__boundcheck_metadata_store((void *)(&last_iMCU_row),(void *)((size_t)(&last_iMCU_row)+sizeof(last_iMCU_row)*8-1));

  JDIMENSION blocks_across;
__boundcheck_metadata_store((void *)(&blocks_across),(void *)((size_t)(&blocks_across)+sizeof(blocks_across)*8-1));
JDIMENSION  MCUs_across;
__boundcheck_metadata_store((void *)(&MCUs_across),(void *)((size_t)(&MCUs_across)+sizeof(MCUs_across)*8-1));
JDIMENSION  MCUindex;
__boundcheck_metadata_store((void *)(&MCUindex),(void *)((size_t)(&MCUindex)+sizeof(MCUindex)*8-1));

  int bi;
__boundcheck_metadata_store((void *)(&bi),(void *)((size_t)(&bi)+sizeof(bi)*8-1));
int  ci;
__boundcheck_metadata_store((void *)(&ci),(void *)((size_t)(&ci)+sizeof(ci)*8-1));
int  h_samp_factor;
__boundcheck_metadata_store((void *)(&h_samp_factor),(void *)((size_t)(&h_samp_factor)+sizeof(h_samp_factor)*8-1));
int  block_row;
__boundcheck_metadata_store((void *)(&block_row),(void *)((size_t)(&block_row)+sizeof(block_row)*8-1));
int  block_rows;
__boundcheck_metadata_store((void *)(&block_rows),(void *)((size_t)(&block_rows)+sizeof(block_rows)*8-1));
int  ndummy;
__boundcheck_metadata_store((void *)(&ndummy),(void *)((size_t)(&ndummy)+sizeof(ndummy)*8-1));

  JCOEF lastDC;
__boundcheck_metadata_store((void *)(&lastDC),(void *)((size_t)(&lastDC)+sizeof(lastDC)*8-1));

  jpeg_component_info *compptr;
__boundcheck_metadata_store((void *)(&compptr),(void *)((size_t)(&compptr)+sizeof(compptr)*8-1));

  JBLOCKARRAY buffer;
__boundcheck_metadata_store((void *)(&buffer),(void *)((size_t)(&buffer)+sizeof(buffer)*8-1));

  JBLOCKROW thisblockrow;
__boundcheck_metadata_store((void *)(&thisblockrow),(void *)((size_t)(&thisblockrow)+sizeof(thisblockrow)*8-1));
JBLOCKROW  lastblockrow;
__boundcheck_metadata_store((void *)(&lastblockrow),(void *)((size_t)(&lastblockrow)+sizeof(lastblockrow)*8-1));


  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    /* Align the virtual buffer for this component. */
    buffer = (*(JBLOCKARRAY (*)(j_common_ptr, jvirt_barray_ptr, JDIMENSION, JDIMENSION, boolean))(__boundcheck_ptr_reference(258,28,"compress_first_pass",(void *)(cinfo->mem->access_virt_barray),(void *)cinfo->mem->access_virt_barray)))
      ((j_common_ptr) cinfo, coef->whole_image[_RV_insert_check(0,10,259,30,"compress_first_pass",ci)],
       coef->iMCU_row_num * compptr->v_samp_factor,
       (JDIMENSION) compptr->v_samp_factor, TRUE);
    /* Count non-dummy DCT block rows in this iMCU row. */
    if (coef->iMCU_row_num < last_iMCU_row)
      block_rows = compptr->v_samp_factor;
    else {
      /* NB: can't use last_row_height here, since may not be set! */
      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    }
    blocks_across = compptr->width_in_blocks;
    h_samp_factor = compptr->h_samp_factor;
    /* Count number of dummy blocks to be added at the right margin. */
    ndummy = (int) (blocks_across % h_samp_factor);
    if (ndummy > 0)
      ndummy = h_samp_factor - ndummy;
    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
     * on forward_DCT processes a complete horizontal row of DCT blocks.
     */
    for (block_row = 0; block_row < block_rows; block_row++) {
      thisblockrow = (*(JBLOCKROW *)(__boundcheck_ptr_reference(280,22,"compress_first_pass",(void *)(&buffer[0]),(void *)(&buffer[block_row]))));
      (*(void (*)(j_compress_ptr, jpeg_component_info *, JSAMPARRAY, JBLOCKROW, JDIMENSION, JDIMENSION, JDIMENSION))(__boundcheck_ptr_reference(281,22,"compress_first_pass",(void *)(cinfo->fdct->forward_DCT),(void *)cinfo->fdct->forward_DCT))) (cinfo, compptr,
				   (*(JSAMPARRAY *)(__boundcheck_ptr_reference(282,8,"compress_first_pass",(void *)(&input_buf[0]),(void *)(&input_buf[ci])))), thisblockrow,
				   (JDIMENSION) (block_row * DCTSIZE),
				   (JDIMENSION) 0, blocks_across);
      if (ndummy > 0) {
	/* Create dummy blocks at the right edge of the image. */
	thisblockrow += blocks_across; /* => first dummy block */
	jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
	lastDC = (*(JCOEF *)(__boundcheck_ptr_reference(289,11,"compress_first_pass",(void *)(&thisblockrow[-1][0]),(void *)(&thisblockrow[-1][0]))));
	for (bi = 0; bi < ndummy; bi++) {
	  (*(JCOEF *)(__boundcheck_ptr_reference(291,4,"compress_first_pass",(void *)(&thisblockrow[bi][0]),(void *)(&thisblockrow[bi][0])))) = lastDC;
	}
      }
    }
    /* If at end of image, create dummy block rows as needed.
     * The tricky part here is that within each MCU, we want the DC values
     * of the dummy blocks to match the last real block's DC value.
     * This squeezes a few more bytes out of the resulting file...
     */
    if (coef->iMCU_row_num == last_iMCU_row) {
      blocks_across += ndummy;	/* include lower right corner */
      MCUs_across = blocks_across / h_samp_factor;
      for (block_row = block_rows; block_row < compptr->v_samp_factor;
	   block_row++) {
	thisblockrow = (*(JBLOCKROW *)(__boundcheck_ptr_reference(305,17,"compress_first_pass",(void *)(&buffer[0]),(void *)(&buffer[block_row]))));
	lastblockrow = (*(JBLOCKROW *)(__boundcheck_ptr_reference(306,17,"compress_first_pass",(void *)(&buffer[0]),(void *)(&buffer[block_row - 1]))));
	jzero_far((void FAR *) thisblockrow,
		  (size_t) (blocks_across * SIZEOF(JBLOCK)));
	for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
	  lastDC = (*(JCOEF *)(__boundcheck_ptr_reference(310,13,"compress_first_pass",(void *)(&lastblockrow[h_samp_factor - 1][0]),(void *)(&lastblockrow[h_samp_factor - 1][0]))));
	  for (bi = 0; bi < h_samp_factor; bi++) {
	    (*(JCOEF *)(__boundcheck_ptr_reference(312,6,"compress_first_pass",(void *)(&thisblockrow[bi][0]),(void *)(&thisblockrow[bi][0])))) = lastDC;
	  }
	  thisblockrow += h_samp_factor; /* advance to next MCU in row */
	  lastblockrow += h_samp_factor;
	}
      }
    }
  }
  /* NB: compress_output will increment iMCU_row_num if successful.
   * A suspension return will result in redoing all the work above next time.
   */

  /* Emit data to the entropy encoder, sharing code with subsequent passes */
  return compress_output(cinfo, input_buf);
}
Exemple #8
0
quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
       JSAMPARRAY output_buf, int num_rows)
/* General case, with Floyd-Steinberg dithering */
{
  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
  register LOCFSERROR cur; /* current error or pixel value */
  LOCFSERROR belowerr;   /* error for pixel below cur */
  LOCFSERROR bpreverr;   /* error for below/prev col */
  LOCFSERROR bnexterr;   /* error for below/next col */
  LOCFSERROR delta;
  register FSERRPTR errorptr;  /* => fserrors[] at column before current */
  register JSAMPROW input_ptr;
  register JSAMPROW output_ptr;
  JSAMPROW colorindex_ci;
  JSAMPROW colormap_ci;
  int pixcode;
  int nc = cinfo->out_color_components;
  int dir;     /* 1 for left-to-right, -1 for right-to-left */
  int dirnc;     /* dir * nc */
  int ci;
  int row;
  JDIMENSION col;
  JDIMENSION width = cinfo->output_width;
  JSAMPLE *range_limit = cinfo->sample_range_limit;
  SHIFT_TEMPS

  for (row = 0; row < num_rows; row++) {
    /* Initialize output values to 0 so can process components separately */
    jzero_far((void FAR *) output_buf[row],
       (size_t) (width * SIZEOF(JSAMPLE)));
    for (ci = 0; ci < nc; ci++) {
      input_ptr = input_buf[row] + ci;
      output_ptr = output_buf[row];
      if (cquantize->on_odd_row) {
 /* work right to left in this row */
 input_ptr += (width-1) * nc; /* so point to rightmost pixel */
 output_ptr += width-1;
 dir = -1;
 dirnc = -nc;
 errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
      } else {
 /* work left to right in this row */
 dir = 1;
 dirnc = nc;
 errorptr = cquantize->fserrors[ci]; /* => entry before first column */
      }
      colorindex_ci = cquantize->colorindex[ci];
      colormap_ci = cquantize->sv_colormap[ci];
      /* Preset error values: no error propagated to first pixel from left */
      cur = 0;
      /* and no error propagated to row below yet */
      belowerr = bpreverr = 0;

      for (col = width; col > 0; col--) {
 /* cur holds the error propagated from the previous pixel on the
  * current line.  Add the error propagated from the previous line
  * to form the complete error correction term for this pixel, and
  * round the error term (which is expressed * 16) to an integer.
  * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
  * for either sign of the error value.
  * Note: errorptr points to *previous* column's array entry.
  */
 cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
 /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
  * The maximum error is +- MAXJSAMPLE; this sets the required size
  * of the range_limit array.
  */
 cur += GETJSAMPLE(*input_ptr);
 cur = GETJSAMPLE(range_limit[cur]);
 /* Select output value, accumulate into output code for this pixel */
 pixcode = GETJSAMPLE(colorindex_ci[cur]);
 *output_ptr += (JSAMPLE) pixcode;
 /* Compute actual representation error at this pixel */
 /* Note: we can do this even though we don't have the final */
 /* pixel code, because the colormap is orthogonal. */
 cur -= GETJSAMPLE(colormap_ci[pixcode]);
 /* Compute error fractions to be propagated to adjacent pixels.
  * Add these into the running sums, and simultaneously shift the
  * next-line error sums left by 1 column.
  */
 bnexterr = cur;
 delta = cur * 2;
 cur += delta;   /* form error * 3 */
 errorptr[0] = (FSERROR) (bpreverr + cur);
 cur += delta;   /* form error * 5 */
 bpreverr = belowerr + cur;
 belowerr = bnexterr;
 cur += delta;   /* form error * 7 */
 /* At this point cur contains the 7/16 error value to be propagated
  * to the next pixel on the current line, and all the errors for the
  * next line have been shifted over. We are therefore ready to move on.
  */
 input_ptr += dirnc; /* advance input ptr to next column */
 output_ptr += dir;  /* advance output ptr to next column */
 errorptr += dir;  /* advance errorptr to current column */
      }
      /* Post-loop cleanup: we must unload the final error value into the
       * final fserrors[] entry.  Note we need not unload belowerr because
       * it is for the dummy column before or after the actual array.
       */
      errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
    }
    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
  }
}
Exemple #9
0
METHODDEF int
decompress_onepass( j_decompress_ptr cinfo, JSAMPIMAGE output_buf ) {
    my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    JDIMENSION MCU_col_num; /* index of current MCU within row */
    JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
    JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    int blkn, ci, xindex, yindex, yoffset, useful_width;
    JSAMPARRAY output_ptr;
    JDIMENSION start_col, output_col;
    jpeg_component_info * compptr;
    inverse_DCT_method_ptr inverse_DCT;

    /* Loop to process as much as one whole iMCU row */
    for ( yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
          yoffset++ ) {
        for ( MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
              MCU_col_num++ ) {
            /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
            jzero_far( (void FAR *) coef->MCU_buffer[0],
                      (size_t) ( cinfo->blocks_in_MCU * SIZEOF( JBLOCK ) ) );
            if ( !( *cinfo->entropy->decode_mcu )( cinfo, coef->MCU_buffer ) ) {
                /* Suspension forced; update state counters and exit */
                coef->MCU_vert_offset = yoffset;
                coef->MCU_ctr = MCU_col_num;
                return JPEG_SUSPENDED;
            }
            /* Determine where data should go in output_buf and do the IDCT thing.
             * We skip dummy blocks at the right and bottom edges (but blkn gets
             * incremented past them!).  Note the inner loop relies on having
             * allocated the MCU_buffer[] blocks sequentially.
             */
            blkn = 0;   /* index of current DCT block within MCU */
            for ( ci = 0; ci < cinfo->comps_in_scan; ci++ ) {
                compptr = cinfo->cur_comp_info[ci];
                /* Don't bother to IDCT an uninteresting component. */
                if ( !compptr->component_needed ) {
                    blkn += compptr->MCU_blocks;
                    continue;
                }
                inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
                useful_width = ( MCU_col_num < last_MCU_col ) ? compptr->MCU_width
                               : compptr->last_col_width;
                output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size;
                start_col = MCU_col_num * compptr->MCU_sample_width;
                for ( yindex = 0; yindex < compptr->MCU_height; yindex++ ) {
                    if ( ( cinfo->input_iMCU_row < last_iMCU_row ) ||
                        ( yoffset + yindex < compptr->last_row_height ) ) {
                        output_col = start_col;
                        for ( xindex = 0; xindex < useful_width; xindex++ ) {
                            ( *inverse_DCT )( cinfo, compptr,
                                              (JCOEFPTR) coef->MCU_buffer[blkn + xindex],
                                              output_ptr, output_col );
                            output_col += compptr->DCT_scaled_size;
                        }
                    }
                    blkn += compptr->MCU_width;
                    output_ptr += compptr->DCT_scaled_size;
                }
            }
        }
        /* Completed an MCU row, but perhaps not an iMCU row */
        coef->MCU_ctr = 0;
    }
    /* Completed the iMCU row, advance counters for next one */
    cinfo->output_iMCU_row++;
    if ( ++ ( cinfo->input_iMCU_row ) < cinfo->total_iMCU_rows ) {
        start_iMCU_row( cinfo );
        return JPEG_ROW_COMPLETED;
    }
    /* Completed the scan */
    ( *cinfo->inputctl->finish_input_pass )( cinfo );
    return JPEG_SCAN_COMPLETED;
}
Exemple #10
0
JBLOCKARRAY my_memory_mgr::access_virt_barray(jvirt_barray_ptr ptr,
        JDIMENSION start_row, JDIMENSION num_rows,
        boolean writable)
/* Access the part of a virtual block array starting at start_row */
/* and extending for num_rows rows.  writable is true if  */
/* caller intends to modify the accessed area. */
{
    JDIMENSION end_row = start_row + num_rows;
    JDIMENSION undef_row;

    /* debugging check */
    if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
            ptr->mem_buffer == NULL)
        cinfo->ERREXIT(JERR_BAD_VIRTUAL_ACCESS);

    /* Make the desired part of the virtual array accessible */
    if (start_row < ptr->cur_start_row ||
            end_row > ptr->cur_start_row+ptr->rows_in_mem) {
        if (! ptr->b_s_open)
            cinfo->ERREXIT(JERR_VIRTUAL_BUG);
        /* Flush old buffer contents if necessary */
        if (ptr->dirty) {
            do_barray_io(cinfo, ptr, TRUE);
            ptr->dirty = FALSE;
        }
        /* Decide what part of virtual array to access.
         * Algorithm: if target address > current window, assume forward scan,
         * load starting at target address.  If target address < current window,
         * assume backward scan, load so that target area is top of window.
         * Note that when switching from forward write to forward read, will have
         * start_row = 0, so the limiting case applies and we load from 0 anyway.
         */
        if (start_row > ptr->cur_start_row) {
            ptr->cur_start_row = start_row;
        } else {
            /* use long arithmetic here to avoid overflow & unsigned problems */
            long ltemp;

            ltemp = (long) end_row - (long) ptr->rows_in_mem;
            if (ltemp < 0)
                ltemp = 0;		/* don't fall off front end of file */
            ptr->cur_start_row = (JDIMENSION) ltemp;
        }
        /* Read in the selected part of the array.
         * During the initial write pass, we will do no actual read
         * because the selected part is all undefined.
         */
        do_barray_io(cinfo, ptr, FALSE);
    }
    /* Ensure the accessed part of the array is defined; prezero if needed.
     * To improve locality of access, we only prezero the part of the array
     * that the caller is about to access, not the entire in-memory array.
     */
    if (ptr->first_undef_row < end_row) {
        if (ptr->first_undef_row < start_row) {
            if (writable)		/* writer skipped over a section of array */
                cinfo->ERREXIT(JERR_BAD_VIRTUAL_ACCESS);
            undef_row = start_row;	/* but reader is allowed to read ahead */
        } else {
            undef_row = ptr->first_undef_row;
        }
        if (writable)
            ptr->first_undef_row = end_row;
        if (ptr->pre_zero) {
            size_t bytesperrow = (size_t) ptr->blocksperrow * sizeof(JBLOCK);
            undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
            end_row -= ptr->cur_start_row;
            while (undef_row < end_row) {
                jzero_far((void *) ptr->mem_buffer[undef_row], bytesperrow);
                undef_row++;
            }
        } else {
            if (! writable)		/* reader looking at undefined data */
                cinfo->ERREXIT(JERR_BAD_VIRTUAL_ACCESS);
        }
    }
    /* Flag the buffer dirty if caller will write in it */
    if (writable)
        ptr->dirty = TRUE;
    /* Return address of proper part of the buffer */
    return ptr->mem_buffer + (start_row - ptr->cur_start_row);
}
Exemple #11
0
METHODDEF boolean
decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
  // sm: this is a downcast from a pointer to jpeg_d_coef_controller
  // to a pointer to my_coef_controller_d, whose first field isa
  // jpeg_d_coef_controller structure; but there is no tag field..
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;

  JDIMENSION MCU_col_num;	/* index of current MCU within row */
  int blkn, ci, xindex, yindex, yoffset, num_MCU_rows;
  JDIMENSION total_width, remaining_rows, start_col;
  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
  JBLOCKROW buffer_ptr;
  jpeg_component_info *compptr;

  /* Align the virtual buffers for the components used in this scan. */
  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    buffer[ci] = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
       coef->MCU_row_num * compptr->v_samp_factor, TRUE);
    /* Entropy decoder expects buffer to be zeroed. */
    total_width = (JDIMENSION) jround_up((long) compptr->width_in_blocks,
					 (long) compptr->h_samp_factor);
    for (yindex = 0; yindex < compptr->v_samp_factor; yindex++) {
      jzero_far((void FAR *) buffer[ci][yindex], 
		(size_t) (total_width * SIZEOF(JBLOCK)));
    }
  }

  /* In an interleaved scan, we process exactly one MCU row.
   * In a noninterleaved scan, we need to process v_samp_factor MCU rows,
   * each of which contains a single block row.
   */
  if (cinfo->comps_in_scan == 1) {
    compptr = cinfo->cur_comp_info[0];
    num_MCU_rows = compptr->v_samp_factor;
    /* but watch out for the bottom of the image */
    remaining_rows = cinfo->MCU_rows_in_scan -
		     coef->MCU_row_num * compptr->v_samp_factor;
    if (remaining_rows < (JDIMENSION) num_MCU_rows)
      num_MCU_rows = (int) remaining_rows;
  } else {
    num_MCU_rows = 1;
  }

  /* Loop to process one whole iMCU row */
  for (yoffset = 0; yoffset < num_MCU_rows; yoffset++) {
    for (MCU_col_num = 0; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) {
      /* Construct list of pointers to DCT blocks belonging to this MCU */
      blkn = 0;			/* index of current DCT block within MCU */
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[ci];
	start_col = MCU_col_num * compptr->MCU_width;
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
	    coef->MCU_buffer[blkn++] = buffer_ptr++;
	  }
	}
      }
      /* Try to fetch the MCU. */
      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
	ERREXIT(cinfo, JERR_CANT_SUSPEND); /* not supported */
      }
    }
  }

  coef->MCU_row_num++;
  return TRUE;
}
Exemple #12
0
METHODDEF boolean
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	/* index of current MCU within row */
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  JDIMENSION last_MCU_row = cinfo->MCU_rows_in_scan - 1;
  int blkn, ci, xindex, yindex, useful_width;
  JSAMPARRAY output_ptr;
  JDIMENSION start_col, output_col;
  jpeg_component_info *compptr;
  inverse_DCT_method_ptr inverse_DCT;

  /* Loop to process as much as one whole MCU row */

  for (MCU_col_num = coef->MCU_col_num; MCU_col_num <= last_MCU_col;
       MCU_col_num++) {

    /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
    jzero_far((void FAR *) coef->MCU_buffer[0],
	      (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
    if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
      /* Suspension forced; return with row unfinished */
      coef->MCU_col_num = MCU_col_num; /* update my state */
      return FALSE;
    }

    /* Determine where data should go in output_buf and do the IDCT thing.
     * We skip dummy blocks at the right and bottom edges (but blkn gets
     * incremented past them!).  Note the inner loop relies on having
     * allocated the MCU_buffer[] blocks sequentially.
     */
    blkn = 0;			/* index of current DCT block within MCU */
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
      compptr = cinfo->cur_comp_info[ci];
      /* Don't bother to IDCT an uninteresting component. */
      if (! compptr->component_needed) {
	blkn += compptr->MCU_blocks;
	continue;
      }
      inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
      useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						  : compptr->last_col_width;
      output_ptr = output_buf[ci];
      start_col = MCU_col_num * compptr->MCU_sample_width;
      for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	if (coef->MCU_row_num < last_MCU_row ||
	    yindex < compptr->last_row_height) {
	  output_col = start_col;
	  for (xindex = 0; xindex < useful_width; xindex++) {
	    (*inverse_DCT) (cinfo, compptr,
			    (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
			    output_ptr, output_col);
	    output_col += compptr->DCT_scaled_size;
	  }
	}
	blkn += compptr->MCU_width;
	output_ptr += compptr->DCT_scaled_size;
      }
    }
  }

  /* We finished the row successfully */
  coef->MCU_col_num = 0;	/* prepare for next row */
  coef->MCU_row_num++;
  return TRUE;
}
consume_data_build_huffman_index_progressive(j_decompress_ptr cinfo,
                                             huffman_index *index, int current_scan) {
    my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    JDIMENSION MCU_col_num;    /* index of current MCU within row */
    int blkn, ci, xindex, yindex, yoffset;
    JDIMENSION start_col;
    JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    JBLOCKROW buffer_ptr;
    jpeg_component_info *compptr;

    int factor = 4; // maximum factor is 4.
    for (ci = 0; ci < cinfo->comps_in_scan; ci++)
        factor = jmin(factor, cinfo->cur_comp_info[ci]->h_samp_factor);

    int sample_size = index->MCU_sample_size * factor;
    huffman_scan_header *scan_header = index->scan + current_scan;
    scan_header->MCU_rows_per_iMCU_row = coef->MCU_rows_per_iMCU_row;
    scan_header->MCUs_per_row = jdiv_round_up(cinfo->MCUs_per_row, sample_size);
    scan_header->comps_in_scan = cinfo->comps_in_scan;

    size_t allocate_size = coef->MCU_rows_per_iMCU_row
                           * scan_header->MCUs_per_row * sizeof(huffman_offset_data);
    scan_header->offset[cinfo->input_iMCU_row] =
            (huffman_offset_data *) malloc(allocate_size);
    index->mem_used += allocate_size;

    huffman_offset_data *offset_data = scan_header->offset[cinfo->input_iMCU_row];

    /* Align the virtual buffers for the components used in this scan. */
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
        compptr = cinfo->cur_comp_info[ci];
        buffer[ci] = (*cinfo->mem->access_virt_barray)
                ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
                 0, // Only need one row buffer
                 (JDIMENSION) compptr->v_samp_factor, TRUE);
    }
    /* Loop to process one whole iMCU row */
    for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
         yoffset++) {
        for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
             MCU_col_num++) {
            /* For each MCU, we loop through different color components.
             * Then, for each color component we will get a list of pointers to DCT
             * blocks in the virtual buffer.
             */
            blkn = 0; /* index of current DCT block within MCU */
            for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
                compptr = cinfo->cur_comp_info[ci];
                start_col = MCU_col_num * compptr->MCU_width;
                /* Get the list of pointers to DCT blocks in
                 * the virtual buffer in a color component of the MCU.
                 */
                for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
                    buffer_ptr = buffer[ci][yindex + yoffset] + start_col;
                    for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
                        coef->MCU_buffer[blkn++] = buffer_ptr++;
                        if (cinfo->input_scan_number == 0) {
                            // need to do pre-zero by ourself.
                            jzero_far((void FAR *) coef->MCU_buffer[blkn - 1],
                                      (size_t)(SIZEOF(JBLOCK)));
                        }
                    }
                }
            }
            // Record huffman bit offset
            if (MCU_col_num % sample_size == 0) {
                (*cinfo->entropy->get_huffman_decoder_configuration)
                        (cinfo, offset_data);
                ++offset_data;
            }
            /* Try to fetch the MCU. */
            if (!(*cinfo->entropy->decode_mcu)(cinfo, coef->MCU_buffer)) {
                /* Suspension forced; update state counters and exit */
                coef->MCU_vert_offset = yoffset;
                coef->MCU_ctr = MCU_col_num;
                return JPEG_SUSPENDED;
            }
        }
        /* Completed an MCU row, but perhaps not an iMCU row */
        coef->MCU_ctr = 0;
    }
    (*cinfo->entropy->get_huffman_decoder_configuration)
            (cinfo, &scan_header->prev_MCU_offset);
    /* Completed the iMCU row, advance counters for next one */
    if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
        start_iMCU_row(cinfo);
        return JPEG_ROW_COMPLETED;
    }
    /* Completed the scan */
    (*cinfo->inputctl->finish_input_pass)(cinfo);
    return JPEG_SCAN_COMPLETED;
}
consume_data(j_decompress_ptr cinfo) {
    my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    JDIMENSION MCU_col_num;    /* index of current MCU within row */
    int blkn, ci, xindex, yindex, yoffset;
    JDIMENSION start_col;
    JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    JBLOCKROW buffer_ptr;
    jpeg_component_info *compptr;

    /* Align the virtual buffers for the components used in this scan. */
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
        compptr = cinfo->cur_comp_info[ci];
        buffer[ci] = (*cinfo->mem->access_virt_barray)
                ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
                 cinfo->tile_decode ? 0 : cinfo->input_iMCU_row * compptr->v_samp_factor,
                 (JDIMENSION) compptr->v_samp_factor, TRUE);
        /* Note: entropy decoder expects buffer to be zeroed,
         * but this is handled automatically by the memory manager
         * because we requested a pre-zeroed array.
         */
    }
    unsigned int MCUs_per_row = cinfo->MCUs_per_row;
#ifdef ANDROID_TILE_BASED_DECODE
    if (cinfo->tile_decode) {
      int iMCU_width_To_MCU_width;
      if (cinfo->comps_in_scan > 1) {
        // Interleaved
        iMCU_width_To_MCU_width = 1;
      } else {
        // Non-intervleaved
        iMCU_width_To_MCU_width = cinfo->cur_comp_info[0]->h_samp_factor;
      }
      MCUs_per_row = jmin(MCUs_per_row,
          (cinfo->coef->column_right_boundary - cinfo->coef->column_left_boundary)
          * cinfo->entropy->index->MCU_sample_size * iMCU_width_To_MCU_width);
    }
#endif

    /* Loop to process one whole iMCU row */
    for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
         yoffset++) {
        // configure huffman decoder
#ifdef ANDROID_TILE_BASED_DECODE
        if (cinfo->tile_decode) {
          huffman_scan_header scan_header =
                cinfo->entropy->index->scan[cinfo->input_scan_number];
          int col_offset = cinfo->coef->column_left_boundary;
          (*cinfo->entropy->configure_huffman_decoder) (cinfo,
                  scan_header.offset[cinfo->input_iMCU_row]
                  [col_offset + yoffset * scan_header.MCUs_per_row]);
        }
#endif

        // zero all blocks
        for (MCU_col_num = coef->MCU_ctr; MCU_col_num < MCUs_per_row;
             MCU_col_num++) {
            /* Construct list of pointers to DCT blocks belonging to this MCU */
            blkn = 0;            /* index of current DCT block within MCU */
            for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
                compptr = cinfo->cur_comp_info[ci];
                start_col = MCU_col_num * compptr->MCU_width;
                for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
                    buffer_ptr = buffer[ci][yindex + yoffset] + start_col;
                    for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
                        coef->MCU_buffer[blkn++] = buffer_ptr++;
#ifdef ANDROID_TILE_BASED_DECODE
                        if (cinfo->tile_decode && cinfo->input_scan_number == 0) {
                          // need to do pre-zero ourselves.
                          jzero_far((void FAR *) coef->MCU_buffer[blkn-1],
                                    (size_t) (SIZEOF(JBLOCK)));
                        }
#endif
                    }
                }
            }


            /* Try to fetch the MCU. */
            if (!(*cinfo->entropy->decode_mcu)(cinfo, coef->MCU_buffer)) {
                /* Suspension forced; update state counters and exit */
                coef->MCU_vert_offset = yoffset;
                coef->MCU_ctr = MCU_col_num;
                return JPEG_SUSPENDED;
            }
        }
        /* Completed an MCU row, but perhaps not an iMCU row */
        coef->MCU_ctr = 0;
    }
    /* Completed the iMCU row, advance counters for next one */
    if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
        start_iMCU_row(cinfo);
        return JPEG_ROW_COMPLETED;
    }
    /* Completed the scan */
    (*cinfo->inputctl->finish_input_pass)(cinfo);
    return JPEG_SCAN_COMPLETED;
}
Exemple #15
0
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	/* index of current MCU within row */
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  int blkn, bi, ci, yindex, yoffset, blockcnt;
  JDIMENSION ypos, xpos;
  jpeg_component_info *compptr;

  /* Loop to write as much as one whole iMCU row */
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
       yoffset++) {
    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
	 MCU_col_num++) {
      /* Determine where data comes from in input_buf and do the DCT thing.
       * Each call on forward_DCT processes a horizontal row of DCT blocks
       * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
       * sequentially.  Dummy blocks at the right or bottom edge are filled in
       * specially.  The data in them does not matter for image reconstruction,
       * so we fill them with values that will encode to the smallest amount of
       * data, viz: all zeroes in the AC entries, DC entries equal to previous
       * block's DC value.  (Thanks to Thomas Kinsman for this idea.)
       */
      blkn = 0;
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[ci];
	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						: compptr->last_col_width;
	xpos = MCU_col_num * compptr->MCU_sample_width;
	ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  if (coef->iMCU_row_num < last_iMCU_row ||
	      yoffset+yindex < compptr->last_row_height) {
	    (*cinfo->fdct->forward_DCT) (cinfo, compptr,
					 input_buf[compptr->component_index],
					 coef->MCU_buffer[blkn],
					 ypos, xpos, (JDIMENSION) blockcnt);
	    if (blockcnt < compptr->MCU_width) {
	      /* Create some dummy blocks at the right edge of the image. */
	      jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
			(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
	      for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
		coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
	      }
	    }
	  } else {
	    /* Create a row of dummy blocks at the bottom of the image. */
	    jzero_far((void FAR *) coef->MCU_buffer[blkn],
		      compptr->MCU_width * SIZEOF(JBLOCK));
	    for (bi = 0; bi < compptr->MCU_width; bi++) {
	      coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
	    }
	  }
	  blkn += compptr->MCU_width;
	  ypos += DCTSIZE;
	}
      }
      /* Try to write the MCU.  In event of a suspension failure, we will
       * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
       */
      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
	/* Suspension forced; update state counters and exit */
	coef->MCU_vert_offset = yoffset;
	coef->mcu_ctr = MCU_col_num;
	return FALSE;
      }
    }
    /* Completed an MCU row, but perhaps not an iMCU row */
    coef->mcu_ctr = 0;
  }
  /* Completed the iMCU row, advance counters for next one */
  coef->iMCU_row_num++;
  start_iMCU_row(cinfo);
  return TRUE;
}
Exemple #16
0
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
__boundcheck_metadata_store((void *)(&coef),(void *)((size_t)(&coef)+sizeof(coef)*8-1));

  JDIMENSION MCU_col_num;
__boundcheck_metadata_store((void *)(&MCU_col_num),(void *)((size_t)(&MCU_col_num)+sizeof(MCU_col_num)*8-1));
	/* index of current MCU within row */
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
__boundcheck_metadata_store((void *)(&last_MCU_col),(void *)((size_t)(&last_MCU_col)+sizeof(last_MCU_col)*8-1));

  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
__boundcheck_metadata_store((void *)(&last_iMCU_row),(void *)((size_t)(&last_iMCU_row)+sizeof(last_iMCU_row)*8-1));

  int blkn;
__boundcheck_metadata_store((void *)(&blkn),(void *)((size_t)(&blkn)+sizeof(blkn)*8-1));
int  bi;
__boundcheck_metadata_store((void *)(&bi),(void *)((size_t)(&bi)+sizeof(bi)*8-1));
int  ci;
__boundcheck_metadata_store((void *)(&ci),(void *)((size_t)(&ci)+sizeof(ci)*8-1));
int  yindex;
__boundcheck_metadata_store((void *)(&yindex),(void *)((size_t)(&yindex)+sizeof(yindex)*8-1));
int  yoffset;
__boundcheck_metadata_store((void *)(&yoffset),(void *)((size_t)(&yoffset)+sizeof(yoffset)*8-1));
int  blockcnt;
__boundcheck_metadata_store((void *)(&blockcnt),(void *)((size_t)(&blockcnt)+sizeof(blockcnt)*8-1));

  JDIMENSION ypos;
__boundcheck_metadata_store((void *)(&ypos),(void *)((size_t)(&ypos)+sizeof(ypos)*8-1));
JDIMENSION  xpos;
__boundcheck_metadata_store((void *)(&xpos),(void *)((size_t)(&xpos)+sizeof(xpos)*8-1));

  jpeg_component_info *compptr;
__boundcheck_metadata_store((void *)(&compptr),(void *)((size_t)(&compptr)+sizeof(compptr)*8-1));


  /* Loop to write as much as one whole iMCU row */
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
       yoffset++) {
    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
	 MCU_col_num++) {
      /* Determine where data comes from in input_buf and do the DCT thing.
       * Each call on forward_DCT processes a horizontal row of DCT blocks
       * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
       * sequentially.  Dummy blocks at the right or bottom edge are filled in
       * specially.  The data in them does not matter for image reconstruction,
       * so we fill them with values that will encode to the smallest amount of
       * data, viz: all zeroes in the AC entries, DC entries equal to previous
       * block's DC value.  (Thanks to Thomas Kinsman for this idea.)
       */
      blkn = 0;
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[_RV_insert_check(0,4,169,12,"compress_data",ci)];
	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						: compptr->last_col_width;
	xpos = MCU_col_num * compptr->MCU_sample_width;
	ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  if (coef->iMCU_row_num < last_iMCU_row ||
	      yoffset+yindex < compptr->last_row_height) {
	    (*(void (*)(j_compress_ptr, jpeg_component_info *, JSAMPARRAY, JBLOCKROW, JDIMENSION, JDIMENSION, JDIMENSION))(__boundcheck_ptr_reference(177,21,"compress_data",(void *)(cinfo->fdct->forward_DCT),(void *)cinfo->fdct->forward_DCT))) (cinfo, compptr,
					 (*(JSAMPARRAY *)(__boundcheck_ptr_reference(178,7,"compress_data",(void *)(&input_buf[0]),(void *)(&input_buf[ci])))), coef->MCU_buffer[_RV_insert_check(0,10,178,22,"compress_data",blkn)],
					 ypos, xpos, (JDIMENSION) blockcnt);
	    if (blockcnt < compptr->MCU_width) {
	      /* Create some dummy blocks at the right edge of the image. */
	      jzero_far((void FAR *) coef->MCU_buffer[_RV_insert_check(0,10,182,31,"compress_data",blkn + blockcnt)],
			(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
	      for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
		coef->MCU_buffer[_RV_insert_check(0,10,185,3,"compress_data",blkn+bi)][_RV_insert_check(0,10,185,3,"compress_data",0)][_RV_insert_check(0,10,185,3,"compress_data",0)] = coef->MCU_buffer[_RV_insert_check(0,10,185,37,"compress_data",blkn+bi-1)][_RV_insert_check(0,10,185,37,"compress_data",0)][_RV_insert_check(0,10,185,37,"compress_data",0)];
	      }
	    }
	  } else {
	    /* Create a row of dummy blocks at the bottom of the image. */
	    jzero_far((void FAR *) coef->MCU_buffer[_RV_insert_check(0,10,190,29,"compress_data",blkn)],
		      compptr->MCU_width * SIZEOF(JBLOCK));
	    for (bi = 0; bi < compptr->MCU_width; bi++) {
	      coef->MCU_buffer[_RV_insert_check(0,10,193,8,"compress_data",blkn+bi)][_RV_insert_check(0,10,193,8,"compress_data",0)][_RV_insert_check(0,10,193,8,"compress_data",0)] = coef->MCU_buffer[_RV_insert_check(0,10,193,42,"compress_data",blkn-1)][_RV_insert_check(0,10,193,42,"compress_data",0)][_RV_insert_check(0,10,193,42,"compress_data",0)];
	    }
	  }
	  blkn += compptr->MCU_width;
	  ypos += DCTSIZE;
	}
      }
      /* Try to write the MCU.  In event of a suspension failure, we will
       * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
       */
      if (! (*(boolean (*)(j_compress_ptr, JBLOCKROW *))(__boundcheck_ptr_reference(203,31,"compress_data",(void *)(cinfo->entropy->encode_mcu),(void *)cinfo->entropy->encode_mcu))) (cinfo, coef->MCU_buffer)) {
	/* Suspension forced; update state counters and exit */
	coef->MCU_vert_offset = yoffset;
	coef->mcu_ctr = MCU_col_num;
	return FALSE;
      }
    }
    /* Completed an MCU row, but perhaps not an iMCU row */
    coef->mcu_ctr = 0;
  }
  /* Completed the iMCU row, advance counters for next one */
  coef->iMCU_row_num++;
  start_iMCU_row(cinfo);
  return TRUE;
}
Exemple #17
0
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  JDIMENSION blocks_across, MCUs_across, MCUindex;
  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
  JCOEF lastDC;
  jpeg_component_info *compptr;
  JBLOCKARRAY buffer;
  JBLOCKROW thisblockrow, lastblockrow;

  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    
    buffer = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr) cinfo, coef->whole_image[ci],
       coef->iMCU_row_num * compptr->v_samp_factor,
       (JDIMENSION) compptr->v_samp_factor, TRUE);
    
    if (coef->iMCU_row_num < last_iMCU_row)
      block_rows = compptr->v_samp_factor;
    else {
      
      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    }
    blocks_across = compptr->width_in_blocks;
    h_samp_factor = compptr->h_samp_factor;
    
    ndummy = (int) (blocks_across % h_samp_factor);
    if (ndummy > 0)
      ndummy = h_samp_factor - ndummy;
    for (block_row = 0; block_row < block_rows; block_row++) {
      thisblockrow = buffer[block_row];
      (*cinfo->fdct->forward_DCT) (cinfo, compptr,
				   input_buf[ci], thisblockrow,
				   (JDIMENSION) (block_row * DCTSIZE),
				   (JDIMENSION) 0, blocks_across);
      if (ndummy > 0) {
	
	thisblockrow += blocks_across; 
	jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
	lastDC = thisblockrow[-1][0];
	for (bi = 0; bi < ndummy; bi++) {
	  thisblockrow[bi][0] = lastDC;
	}
      }
    }
    if (coef->iMCU_row_num == last_iMCU_row) {
      blocks_across += ndummy;	
      MCUs_across = blocks_across / h_samp_factor;
      for (block_row = block_rows; block_row < compptr->v_samp_factor;
	   block_row++) {
	thisblockrow = buffer[block_row];
	lastblockrow = buffer[block_row-1];
	jzero_far((void FAR *) thisblockrow,
		  (size_t) (blocks_across * SIZEOF(JBLOCK)));
	for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
	  lastDC = lastblockrow[h_samp_factor-1][0];
	  for (bi = 0; bi < h_samp_factor; bi++) {
	    thisblockrow[bi][0] = lastDC;
	  }
	  thisblockrow += h_samp_factor; 
	  lastblockrow += h_samp_factor;
	}
      }
    }
  }

  
  return compress_output(cinfo, input_buf);
}
Exemple #18
0
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  int blkn, bi, ci, yindex, yoffset, blockcnt;
  JDIMENSION ypos, xpos;
  jpeg_component_info *compptr;

  
  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
       yoffset++) {
    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
	 MCU_col_num++) {
      blkn = 0;
      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	compptr = cinfo->cur_comp_info[ci];
	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						: compptr->last_col_width;
	xpos = MCU_col_num * compptr->MCU_sample_width;
	ypos = yoffset * DCTSIZE; 
	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
	  if (coef->iMCU_row_num < last_iMCU_row ||
	      yoffset+yindex < compptr->last_row_height) {
	    (*cinfo->fdct->forward_DCT) (cinfo, compptr,
					 input_buf[compptr->component_index],
					 coef->MCU_buffer[blkn],
					 ypos, xpos, (JDIMENSION) blockcnt);
	    if (blockcnt < compptr->MCU_width) {
	      
	      jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
			(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
	      for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
		coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
	      }
	    }
	  } else {
	    
	    jzero_far((void FAR *) coef->MCU_buffer[blkn],
		      compptr->MCU_width * SIZEOF(JBLOCK));
	    for (bi = 0; bi < compptr->MCU_width; bi++) {
	      coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
	    }
	  }
	  blkn += compptr->MCU_width;
	  ypos += DCTSIZE;
	}
      }
      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
	
	coef->MCU_vert_offset = yoffset;
	coef->mcu_ctr = MCU_col_num;
	return FALSE;
      }
    }
    
    coef->mcu_ctr = 0;
  }
  
  coef->iMCU_row_num++;
  start_iMCU_row(cinfo);
  return TRUE;
}
Exemple #19
0
compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  JDIMENSION blocks_across, MCUs_across, MCUindex;
  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
  JCOEF lastDC;
  jpeg_component_info *compptr;
  JBLOCKARRAY buffer;
  JBLOCKROW thisblockrow, lastblockrow;
  JBLOCKARRAY buffer_dst;

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    c_derived_tbl dctbl_data;
    c_derived_tbl *dctbl = &dctbl_data;
    c_derived_tbl actbl_data;
    c_derived_tbl *actbl = &actbl_data;
    
#ifdef C_ARITH_CODING_SUPPORTED
    arith_rates arith_r_data;
    arith_rates *arith_r = &arith_r_data;
#endif
    
    compptr = cinfo->cur_comp_info[ci];

#ifdef C_ARITH_CODING_SUPPORTED
    if (cinfo->arith_code)
      jget_arith_rates(cinfo, compptr->dc_tbl_no, compptr->ac_tbl_no, arith_r);
    else
#endif
    {
      jpeg_make_c_derived_tbl(cinfo, TRUE, compptr->dc_tbl_no, &dctbl);
      jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl);
    }

    /* Align the virtual buffer for this component. */
    buffer = (*cinfo->mem->access_virt_barray)
    ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
     coef->iMCU_row_num * compptr->v_samp_factor,
     (JDIMENSION) compptr->v_samp_factor, TRUE);
    
    buffer_dst = (*cinfo->mem->access_virt_barray)
    ((j_common_ptr) cinfo, coef->whole_image_uq[compptr->component_index],
     coef->iMCU_row_num * compptr->v_samp_factor,
     (JDIMENSION) compptr->v_samp_factor, TRUE);
    
    /* Count non-dummy DCT block rows in this iMCU row. */
    if (coef->iMCU_row_num < last_iMCU_row)
      block_rows = compptr->v_samp_factor;
    else {
      /* NB: can't use last_row_height here, since may not be set! */
      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    }
    blocks_across = compptr->width_in_blocks;
    h_samp_factor = compptr->h_samp_factor;
    /* Count number of dummy blocks to be added at the right margin. */
    ndummy = (int) (blocks_across % h_samp_factor);
    if (ndummy > 0)
      ndummy = h_samp_factor - ndummy;
    
    lastDC = 0;
    
    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
     * on forward_DCT processes a complete horizontal row of DCT blocks.
     */
    for (block_row = 0; block_row < block_rows; block_row++) {
      thisblockrow = buffer[block_row];
      lastblockrow = (block_row > 0) ? buffer[block_row-1] : NULL;
#ifdef C_ARITH_CODING_SUPPORTED
      if (cinfo->arith_code)
        quantize_trellis_arith(cinfo, arith_r, thisblockrow,
                               buffer_dst[block_row], blocks_across,
                               cinfo->quant_tbl_ptrs[compptr->quant_tbl_no],
                               cinfo->master->norm_src[compptr->quant_tbl_no],
                               cinfo->master->norm_coef[compptr->quant_tbl_no],
                               &lastDC, lastblockrow, buffer_dst[block_row-1]);
      else
#endif
        quantize_trellis(cinfo, dctbl, actbl, thisblockrow,
                         buffer_dst[block_row], blocks_across,
                         cinfo->quant_tbl_ptrs[compptr->quant_tbl_no],
                         cinfo->master->norm_src[compptr->quant_tbl_no],
                         cinfo->master->norm_coef[compptr->quant_tbl_no],
                         &lastDC, lastblockrow, buffer_dst[block_row-1]);
      
      if (ndummy > 0) {
        /* Create dummy blocks at the right edge of the image. */
        thisblockrow += blocks_across; /* => first dummy block */
        jzero_far((void *) thisblockrow, ndummy * sizeof(JBLOCK));
        lastDC = thisblockrow[-1][0];
        for (bi = 0; bi < ndummy; bi++) {
          thisblockrow[bi][0] = lastDC;
        }
      }
    }
    /* If at end of image, create dummy block rows as needed.
     * The tricky part here is that within each MCU, we want the DC values
     * of the dummy blocks to match the last real block's DC value.
     * This squeezes a few more bytes out of the resulting file...
     */
    if (coef->iMCU_row_num == last_iMCU_row) {
      blocks_across += ndummy;  /* include lower right corner */
      MCUs_across = blocks_across / h_samp_factor;
      for (block_row = block_rows; block_row < compptr->v_samp_factor;
           block_row++) {
        thisblockrow = buffer[block_row];
        lastblockrow = buffer[block_row-1];
        jzero_far((void *) thisblockrow,
                  (size_t) (blocks_across * sizeof(JBLOCK)));
        for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
          lastDC = lastblockrow[h_samp_factor-1][0];
          for (bi = 0; bi < h_samp_factor; bi++) {
            thisblockrow[bi][0] = lastDC;
          }
          thisblockrow += h_samp_factor; /* advance to next MCU in row */
          lastblockrow += h_samp_factor;
        }
      }
    }
  }

  /* NB: compress_output will increment iMCU_row_num if successful.
   * A suspension return will result in redoing all the work above next time.
   */
  
  /* Emit data to the entropy encoder, sharing code with subsequent passes */
  return compress_output(cinfo, input_buf);
}
Exemple #20
0
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  JDIMENSION blocks_across, MCUs_across, MCUindex;
  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
  JCOEF lastDC;
  jpeg_component_info *compptr;
  JBLOCKARRAY buffer;
  JBLOCKROW thisblockrow, lastblockrow;

  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    /* Align the virtual buffer for this component. */
    buffer = (*cinfo->mem->access_virt_barray)
      ((j_common_ptr) cinfo, coef->whole_image[ci],
       coef->iMCU_row_num * compptr->v_samp_factor,
       (JDIMENSION) compptr->v_samp_factor, TRUE);
    /* Count non-dummy DCT block rows in this iMCU row. */
    if (coef->iMCU_row_num < last_iMCU_row)
      block_rows = compptr->v_samp_factor;
    else {
      /* NB: can't use last_row_height here, since may not be set! */
      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    }
    blocks_across = compptr->width_in_blocks;
    h_samp_factor = compptr->h_samp_factor;
    /* Count number of dummy blocks to be added at the right margin. */
    ndummy = (int) (blocks_across % h_samp_factor);
    if (ndummy > 0)
      ndummy = h_samp_factor - ndummy;
    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
     * on forward_DCT processes a complete horizontal row of DCT blocks.
     */
    for (block_row = 0; block_row < block_rows; block_row++) {
      thisblockrow = buffer[block_row];
      (*cinfo->fdct->forward_DCT) (cinfo, compptr,
				   input_buf[ci], thisblockrow,
				   (JDIMENSION) (block_row * DCTSIZE),
				   (JDIMENSION) 0, blocks_across);
      if (ndummy > 0) {
	/* Create dummy blocks at the right edge of the image. */
	thisblockrow += blocks_across; /* => first dummy block */
	jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
	lastDC = thisblockrow[-1][0];
	for (bi = 0; bi < ndummy; bi++) {
	  thisblockrow[bi][0] = lastDC;
	}
      }
    }
    /* If at end of image, create dummy block rows as needed.
     * The tricky part here is that within each MCU, we want the DC values
     * of the dummy blocks to match the last real block's DC value.
     * This squeezes a few more bytes out of the resulting file...
     */
    if (coef->iMCU_row_num == last_iMCU_row) {
      blocks_across += ndummy;	/* include lower right corner */
      MCUs_across = blocks_across / h_samp_factor;
      for (block_row = block_rows; block_row < compptr->v_samp_factor;
	   block_row++) {
	thisblockrow = buffer[block_row];
	lastblockrow = buffer[block_row-1];
	jzero_far((void FAR *) thisblockrow,
		  (size_t) (blocks_across * SIZEOF(JBLOCK)));
	for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
	  lastDC = lastblockrow[h_samp_factor-1][0];
	  for (bi = 0; bi < h_samp_factor; bi++) {
	    thisblockrow[bi][0] = lastDC;
	  }
	  thisblockrow += h_samp_factor; /* advance to next MCU in row */
	  lastblockrow += h_samp_factor;
	}
      }
    }
  }
  /* NB: compress_output will increment iMCU_row_num if successful.
   * A suspension return will result in redoing all the work above next time.
   */

  /* Emit data to the entropy encoder, sharing code with subsequent passes */
  return compress_output(cinfo, input_buf);
}
Exemple #21
0
decode_mcus (j_decompress_ptr cinfo, JDIFFIMAGE diff_buf,
         JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, JDIMENSION nMCU)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsd->entropy_private;
  unsigned int mcu_num;
  int sampn, ci, yoffset, MCU_width, ptrn;
  BITREAD_STATE_VARS;

  /* Set output pointer locations based on MCU_col_num */
  for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) {
    ci = entropy->output_ptr_info[ptrn].ci;
    yoffset = entropy->output_ptr_info[ptrn].yoffset;
    MCU_width = entropy->output_ptr_info[ptrn].MCU_width;
    entropy->output_ptr[ptrn] =
      diff_buf[ci][MCU_row_num + (JDIMENSION)yoffset] + MCU_col_num * (JDIMENSION)MCU_width;
  }

  /*
   * If we've run out of data, zero out the buffers and return.
   * By resetting the undifferencer, the output samples will be CENTERJSAMPLE.
   *
   * NB: We should find a way to do this without interacting with the
   * undifferencer module directly.
   */
  if (entropy->insufficient_data) {
    for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++)
      jzero_far((void FAR *) entropy->output_ptr[ptrn],
        nMCU * (size_t)entropy->output_ptr_info[ptrn].MCU_width * SIZEOF(JDIFF));

    (*losslsd->predict_process_restart) (cinfo);
  }

  else {

    /* Load up working state */
    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);

    /* Outer loop handles the number of MCU requested */

    for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {

      /* Inner loop handles the samples in the MCU */
      for (sampn = 0; sampn < cinfo->data_units_in_MCU; sampn++) {
    d_derived_tbl * dctbl = entropy->cur_tbls[sampn];
    register int s, r;

    /* Section H.2.2: decode the sample difference */
    HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1);
    if (s) {
      if (s == 16)  /* special case: always output 32768 */
        s = 32768;
      else {    /* normal case: fetch subsequent bits */
        CHECK_BIT_BUFFER(br_state, s, return mcu_num);
        r = GET_BITS(s);
        s = HUFF_EXTEND(r, s);
      }
    }

    /* Output the sample difference */
    *entropy->output_ptr[entropy->output_ptr_index[sampn]]++ = (JDIFF) s;
      }

      /* Completed MCU, so update state */
      BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    }
  }

 return nMCU;
}