Beispiel #1
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 = &coef->pub;
  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));
  FMEMZERO((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;
  }
}
Beispiel #2
0
GLOBAL void

jzero_far (void FAR * target, size_t bytestozero)

/* Zero out a chunk of FAR memory. */

/* This might be sample-array data, block-array data, or alloc_large data. */

{

#ifdef FMEMZERO

  FMEMZERO(target, bytestozero);

#else

  register char FAR * ptr = (char FAR *) target;

  register size_t count;



  for (count = bytestozero; count > 0; count--) {

    *ptr++ = 0;

  }

#endif

}
Beispiel #3
0
start_pass_1_quant( j_decompress_ptr cinfo, 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 ) );
		for( i = 0; i < cinfo->out_color_components; i++ ) {
			FMEMZERO( ( void FAR * ) cquantize->fserrors[i], arraysize );
		}
		break;
	default:
		ERREXIT( cinfo, JERR_NOT_COMPILED );
		break;
	}
}
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 */
        FMEMZERO((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;
    }
}
Beispiel #5
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 */
		FMEMZERO( ( 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 );
	}
}
Beispiel #6
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;
  forward_DCT_ptr forward_DCT;

  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;
    forward_DCT = cinfo->fdct->forward_DCT[ci];
    /* 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];
      (*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
		      (JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
		      (JDIMENSION) 0, blocks_across);
      if (ndummy > 0) {
	/* Create dummy blocks at the right edge of the image. */
	thisblockrow += blocks_across; /* => first dummy block */
	FMEMZERO((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];
	FMEMZERO((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);
}
Beispiel #7
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;
  forward_DCT_ptr forward_DCT;

  /* 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];
	forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
	blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
						: compptr->last_col_width;
	xpos = MCU_col_num * compptr->MCU_sample_width;
	ypos = yoffset * compptr->DCT_v_scaled_size;
	/* 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) {
	    (*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. */
	      FMEMZERO((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. */
	    FMEMZERO((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 += compptr->DCT_v_scaled_size;
	}
      }
      /* 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;
}
jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
{
    my_coef_ptr coef;

    coef = (my_coef_ptr)
           (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE,
                                      SIZEOF(my_coef_controller));
    cinfo->coef = (struct jpeg_d_coef_controller*) coef;
    coef->pub.start_input_pass = start_input_pass;
    coef->pub.start_output_pass = start_output_pass;
#ifdef BLOCK_SMOOTHING_SUPPORTED
    coef->coef_bits_latch = NULL;
#endif

    /* Create the coefficient buffer. */
    if (need_full_buffer)
    {
#ifdef D_MULTISCAN_FILES_SUPPORTED
        /* Allocate a full-image virtual array for each component, */
        /* padded to a multiple of samp_factor DCT blocks in each direction. */
        /* Note we ask for a pre-zeroed array. */
        int ci, access_rows;
        jpeg_component_info* compptr;

        for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
                ci++, compptr++)
        {
            access_rows = compptr->v_samp_factor;
#ifdef BLOCK_SMOOTHING_SUPPORTED

            /* If block smoothing could be used, need a bigger window */
            if (cinfo->progressive_mode)
            {
                access_rows *= 3;
            }

#endif
            coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
                                    ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
                                     (JDIMENSION) jround_up((long) compptr->width_in_blocks,
                                                            (long) compptr->h_samp_factor),
                                     (JDIMENSION) jround_up((long) compptr->height_in_blocks,
                                                            (long) compptr->v_samp_factor),
                                     (JDIMENSION) access_rows);
        }

        coef->pub.consume_data = consume_data;
        coef->pub.decompress_data = decompress_data;
        coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
#else
        ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
    }
    else
    {
        /* We only need a single-MCU buffer. */
        JBLOCKROW buffer;
        int i;

        buffer = (JBLOCKROW)
                 (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE,
                                            D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));

        for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++)
        {
            coef->MCU_buffer[i] = buffer + i;
        }

        if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */
            FMEMZERO((void FAR*) buffer,
                     (size_t)(D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)));

        coef->pub.consume_data = dummy_consume_data;
        coef->pub.decompress_data = decompress_onepass;
        coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
    }
}