⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdpipe.c

📁 EVM板JPEG实现,Texas Instruments TMS320C54x EVM JPEG
💻 C
📖 第 1 页 / 共 3 页
字号:
  }
}


LOCAL void
expand (decompress_info_ptr cinfo,
	JSAMPIMAGE sampled_data, JSAMPIMAGE fullsize_data,
	long fullsize_width,
	short above, short current, short below, short out)
/* Do upsampling expansion of a single row group (of each component). */
/* above, current, below are indexes of row groups in sampled_data;       */
/* out is the index of the target row group in fullsize_data.             */
/* Special case: above, below can be -1 to indicate top, bottom of image. */
{
  jpeg_component_info *compptr;
  JSAMPARRAY above_ptr, below_ptr;
  JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for downsample expansion at top/bottom */
  short ci, vs, i;

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    vs = compptr->v_samp_factor; /* row group height */

    if (above >= 0)
      above_ptr = sampled_data[ci] + above * vs;
    else {
      /* Top of image: make a dummy above-context with copies of 1st row */
      /* We assume current=0 in this case */
      for (i = 0; i < vs; i++)
	dummy[i] = sampled_data[ci][0];
      above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
    }

    if (below >= 0)
      below_ptr = sampled_data[ci] + below * vs;
    else {
      /* Bot of image: make a dummy below-context with copies of last row */
      for (i = 0; i < vs; i++)
	dummy[i] = sampled_data[ci][(current+1)*vs-1];
      below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
    }

    (*cinfo->methods->upsample[ci])
		(cinfo, (int) ci,
		 compptr->downsampled_width, (int) vs,
		 fullsize_width, (int) cinfo->max_v_samp_factor,
		 above_ptr,
		 sampled_data[ci] + current * vs,
		 below_ptr,
		 fullsize_data[ci] + out * cinfo->max_v_samp_factor);
  }
}


LOCAL void
emit_1pass (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE fullsize_data,
	    JSAMPARRAY dummy)
/* Do color processing and output of num_rows full-size rows. */
/* This is not used when doing 2-pass color quantization. */
/* The dummy argument simply lets this be called via scan_big_image. */
{
  if (cinfo->quantize_colors) {
    (*cinfo->methods->color_quantize) (cinfo, num_rows, fullsize_data,
				       output_workspace[0]);
  } else {
    (*cinfo->methods->color_convert) (cinfo, num_rows, cinfo->image_width,
				      fullsize_data, output_workspace);
  }
    
  (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, output_workspace);
}


/*
 * Support routines for complex controller.
 */

#ifdef NEED_COMPLEX_CONTROLLER

METHODDEF void
scan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
/* Apply quantize_method to entire image stored in fullsize_image[]. */
/* This is the "iterator" routine used by the 2-pass color quantizer. */
/* We also use it directly in some cases. */
{
  long pixel_rows_output;
  short ci;

  for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
       pixel_rows_output += rows_in_mem) {
    (*cinfo->methods->progress_monitor) (cinfo, pixel_rows_output,
					 cinfo->image_height);
    /* Realign the big buffers */
    for (ci = 0; ci < cinfo->num_components; ci++) {
      fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
	(fullsize_image[ci], pixel_rows_output, FALSE);
    }
    /* Let the quantizer have its way with the data.
     * Note that output_workspace is simply workspace for the quantizer;
     * when it's ready to output, it must call put_pixel_rows itself.
     */
    (*quantize_method) (cinfo,
			(int) MIN((long) rows_in_mem,
				  cinfo->image_height - pixel_rows_output),
			fullsize_ptrs, output_workspace[0]);
  }

  cinfo->completed_passes++;
}

#endif /* NEED_COMPLEX_CONTROLLER */


/*
 * Support routines for cross-block smoothing.
 */

#ifdef BLOCK_SMOOTHING_SUPPORTED


LOCAL void
smooth_mcu_row (decompress_info_ptr cinfo,
		JBLOCKIMAGE above, JBLOCKIMAGE input, JBLOCKIMAGE below,
		JBLOCKIMAGE output)
/* Apply cross-block smoothing to one MCU row's worth of coefficient blocks. */
/* above,below are NULL if at top/bottom of image. */
{
  jpeg_component_info *compptr;
  short ci, ri, last;
  JBLOCKROW prev;

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    last = compptr->MCU_height - 1;

    if (above == NULL)
      prev = NULL;
    else
      prev = above[ci][last];

    for (ri = 0; ri < last; ri++) {
      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
				prev, input[ci][ri], input[ci][ri+1],
				output[ci][ri]);
      prev = input[ci][ri];
    }

    if (below == NULL)
      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
				prev, input[ci][last], (JBLOCKROW) NULL,
				output[ci][last]);
    else
      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
				prev, input[ci][last], below[ci][0],
				output[ci][last]);
  }
}


LOCAL void
get_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
		  JBLOCKIMAGE bsmooth[3], int * whichb, long cur_mcu_row)
/* Get an MCU row of coefficients, applying cross-block smoothing. */
/* The output row is placed in coeff_data.  bsmooth and whichb hold */
/* working state, and cur_row is needed to check for image top/bottom. */
/* This routine just takes care of the buffering logic. */
{
  int prev, cur, next;
  
  /* Special case for top of image: need to pre-fetch a row & init whichb */
  if (cur_mcu_row == 0) {
    (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[0]);
    if (cinfo->MCU_rows_in_scan > 1) {
      (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[1]);
      smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], bsmooth[1],
		     coeff_data);
    } else {
      smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], (JBLOCKIMAGE) NULL,
		     coeff_data);
    }
    *whichb = 1;		/* points to next bsmooth[] element to use */
    return;
  }
  
  cur = *whichb;		/* set up references */
  prev = (cur == 0 ? 2 : cur - 1);
  next = (cur == 2 ? 0 : cur + 1);
  *whichb = next;		/* advance whichb for next time */
  
  /* Special case for bottom of image: don't read another row */
  if (cur_mcu_row >= cinfo->MCU_rows_in_scan - 1) {
    smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], (JBLOCKIMAGE) NULL,
		   coeff_data);
    return;
  }
  
  /* Normal case: read ahead a new row, smooth the one I got before */
  (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[next]);
  smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], bsmooth[next],
		 coeff_data);
}


#endif /* BLOCK_SMOOTHING_SUPPORTED */



/*
 * Decompression pipeline controller used for single-scan files
 * without 2-pass color quantization.
 */

METHODDEF void
simple_dcontroller (decompress_info_ptr cinfo)
{
  long fullsize_width;		/* # of samples per row in full-size buffers */
  long cur_mcu_row;		/* counts # of MCU rows processed */
  long pixel_rows_output;	/* # of pixel rows actually emitted */
  int mcu_rows_per_loop;	/* # of MCU rows processed per outer loop */
  /* Work buffer for dequantized coefficients (IDCT input) */
  JBLOCKIMAGE coeff_data;
  /* Work buffer for cross-block smoothing input */
#ifdef BLOCK_SMOOTHING_SUPPORTED
  JBLOCKIMAGE bsmooth[3];	/* this is optional */
  int whichb;
#endif
  /* Work buffer for downsampled image data (see comments at head of file) */
  JSAMPIMAGE sampled_data[2];
  /* Work buffer for upsampled data */
  JSAMPIMAGE fullsize_data;
  int whichss, ri;
  short i;

  /* Compute dimensions of full-size pixel buffers */
  /* Note these are the same whether interleaved or not. */
  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
  fullsize_width = jround_up(cinfo->image_width,
			     (long) (cinfo->max_h_samp_factor * DCTSIZE));

  /* Prepare for single scan containing all components */
  if (cinfo->comps_in_scan == 1) {
    noninterleaved_scan_setup(cinfo);
    /* Need to read Vk MCU rows to obtain Vk block rows */
    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
  } else {
    interleaved_scan_setup(cinfo);
    /* in an interleaved scan, one MCU row provides Vk block rows */
    mcu_rows_per_loop = 1;
  }
  cinfo->total_passes++;

  /* Allocate working memory: */
  /* coeff_data holds a single MCU row of coefficient blocks */
  coeff_data = alloc_MCU_row(cinfo);
  /* if doing cross-block smoothing, need extra space for its input */
#ifdef BLOCK_SMOOTHING_SUPPORTED
  if (cinfo->do_block_smoothing) {
    bsmooth[0] = alloc_MCU_row(cinfo);
    bsmooth[1] = alloc_MCU_row(cinfo);
    bsmooth[2] = alloc_MCU_row(cinfo);
  }
#endif
  /* sampled_data is sample data before upsampling */
  alloc_sampling_buffer(cinfo, sampled_data);
  /* fullsize_data is sample data after upsampling */
  fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
				  (long) rows_in_mem, fullsize_width);
  /* output_workspace is the color-processed data */
  output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
				     (long) rows_in_mem, fullsize_width);
  prepare_range_limit_table(cinfo);

  /* Tell the memory manager to instantiate big arrays.
   * We don't need any big arrays in this controller,
   * but some other module (like the output file writer) may need one.
   */
  (*cinfo->emethods->alloc_big_arrays)
	((long) 0,				/* no more small sarrays */
	 (long) 0,				/* no more small barrays */
	 (long) 0);				/* no more "medium" objects */
  /* NB: if quantizer needs any "medium" size objects, it must get them */
  /* at color_quant_init time */

  /* Initialize to read scan data */

  (*cinfo->methods->entropy_decode_init) (cinfo);
  (*cinfo->methods->upsample_init) (cinfo);
  (*cinfo->methods->disassemble_init) (cinfo);

  /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */

  pixel_rows_output = 0;
  whichss = 1;			/* arrange to start with sampled_data[0] */

  for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
       cur_mcu_row += mcu_rows_per_loop) {
    (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
					 cinfo->MCU_rows_in_scan);

    whichss ^= 1;		/* switch to other downsampled-data buffer */

    /* Obtain v_samp_factor block rows of each component in the scan. */
    /* This is a single MCU row if interleaved, multiple MCU rows if not. */
    /* In the noninterleaved case there might be fewer than v_samp_factor */
    /* block rows remaining; if so, pad with copies of the last pixel row */
    /* so that upsampling doesn't have to treat it as a special case. */

    for (ri = 0; ri < mcu_rows_per_loop; ri++) {
      if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
	/* OK to actually read an MCU row. */
#ifdef BLOCK_SMOOTHING_SUPPORTED
	if (cinfo->do_block_smoothing)
	  get_smoothed_row(cinfo, coeff_data,
			   bsmooth, &whichb, cur_mcu_row + ri);
	else
#endif
	  (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
      
	(*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
					sampled_data[whichss],
					ri * DCTSIZE);
      } else {
	/* Need to pad out with copies of the last downsampled row. */
	/* This can only happen if there is just one component. */
	duplicate_row(sampled_data[whichss][0],
		      cinfo->cur_comp_info[0]->downsampled_width,
		      ri * DCTSIZE - 1, DCTSIZE);
      }
    }

    /* Upsample the data */
    /* First time through is a special case */

    if (cur_mcu_row) {
      /* Expand last row group of previous set */
      expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
	     (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
	     (short) (DCTSIZE-1));
      /* and dump the previous set's expanded data */
      emit_1pass (cinfo, rows_in_mem, fullsize_data, (JSAMPARRAY) NULL);
      pixel_rows_output += rows_in_mem;
      /* Expand first row group of this set */
      expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
	     (short) (DCTSIZE+1), (short) 0, (short) 1,
	     (short) 0);
    } else {
      /* Expand first row group with dummy above-context */
      expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
	     (short) (-1), (short) 0, (short) 1,
	     (short) 0);
    }
    /* Expand second through next-to-last row groups of this set */
    for (i = 1; i <= DCTSIZE-2; i++) {
      expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
	     (short) (i-1), (short) i, (short) (i+1),
	     (short) i);
    }
  } /* end of outer loop */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -