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

📄 jdpipe.c

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

  /* Expand the last row group with dummy below-context */
  /* Note whichss points to last buffer side used */
  expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
	 (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
	 (short) (DCTSIZE-1));
  /* and dump the remaining data (may be less than full height) */
  emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
	      fullsize_data, (JSAMPARRAY) NULL);

  /* Clean up after the scan */
  (*cinfo->methods->disassemble_term) (cinfo);
  (*cinfo->methods->upsample_term) (cinfo);
  (*cinfo->methods->entropy_decode_term) (cinfo);
  (*cinfo->methods->read_scan_trailer) (cinfo);
  cinfo->completed_passes++;

  /* Verify that we've seen the whole input file */
  if ((*cinfo->methods->read_scan_header) (cinfo))
/*    WARNMS(cinfo->emethods, "Didn't expect more than one scan"); */
      send_command(ERR5);

  /* Release working memory */
  /* (no work -- we let free_all release what's needful) */
}


/*
 * Decompression pipeline controller used for multiple-scan files
 * and/or 2-pass color quantization.
 *
 * The current implementation places the "big" buffer at the stage of
 * upsampled, non-color-processed data.  This is the only place that
 * makes sense when doing 2-pass quantization.  For processing multiple-scan
 * files without 2-pass quantization, it would be possible to develop another
 * controller that buffers the downsampled data instead, thus reducing the size
 * of the temp files (by about a factor of 2 in typical cases).  However,
 * our present upsampling logic is dependent on the assumption that
 * upsampling occurs during a scan, so it's much easier to do the
 * enlargement as the JPEG file is read.  This also simplifies life for the
 * memory manager, which would otherwise have to deal with overlapping
 * access_big_sarray() requests.
 * At present it appears that most JPEG files will be single-scan,
 * so it doesn't seem worthwhile to worry about this optimization.
 */

#ifdef NEED_COMPLEX_CONTROLLER

METHODDEF void
complex_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];
  int whichss, ri;
  short ci, i;
  boolean single_scan;

  /* 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));

  /* Allocate all working memory that doesn't depend on scan info */
  /* 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);

  /* Get a big image: fullsize_image is sample data after upsampling. */
  fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
			(cinfo->num_components * SIZEOF(big_sarray_ptr));
  for (ci = 0; ci < cinfo->num_components; ci++) {
    fullsize_image[ci] = (*cinfo->emethods->request_big_sarray)
			(fullsize_width,
			 jround_up(cinfo->image_height, (long) rows_in_mem),
			 (long) rows_in_mem);
  }
  /* Also get an area for pointers to currently accessible chunks */
  fullsize_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
				(cinfo->num_components * SIZEOF(JSAMPARRAY));

  /* Tell the memory manager to instantiate big arrays */
  (*cinfo->emethods->alloc_big_arrays)
	 /* extra sarray space is for downsampled-data buffers: */
	((long) (fullsize_width			/* max width in samples */
	 * cinfo->max_v_samp_factor*(DCTSIZE+2)	/* max height */
	 * cinfo->num_components),		/* max components per scan */
	 /* extra barray space is for MCU-row buffers: */
	 (long) ((fullsize_width / DCTSIZE)	/* max width in blocks */
	 * cinfo->max_v_samp_factor		/* max height */
	 * cinfo->num_components		/* max components per scan */
	 * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
	 /* no extra "medium"-object space */
	 (long) 0);
  /* NB: if quantizer needs any "medium" size objects, it must get them */
  /* at color_quant_init time */

  /* If file is single-scan, we can do color quantization prescan on-the-fly
   * during the scan (we must be doing 2-pass quantization, else this method
   * would not have been selected).  If it is multiple scans, we have to make
   * a separate pass after we've collected all the components.  (We could save
   * some I/O by doing CQ prescan during the last scan, but the extra logic
   * doesn't seem worth the trouble.)
   */

  single_scan = (cinfo->comps_in_scan == cinfo->num_components);

  /* Account for passes needed (color quantizer adds its passes separately).
   * If multiscan file, we guess that each component has its own scan,
   * and increment completed_passes by the number of components in the scan.
   */

  if (single_scan)
    cinfo->total_passes++;	/* the single scan */
  else {
    cinfo->total_passes += cinfo->num_components; /* guessed # of scans */
    if (cinfo->two_pass_quantize)
      cinfo->total_passes++;	/* account for separate CQ prescan pass */
  }
  if (! cinfo->two_pass_quantize)
    cinfo->total_passes++;	/* count output pass unless quantizer does it */

  /* Loop over scans in file */

  do {
    
    /* Prepare for this scan */
    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;
    }
    
    /* Allocate scan-local 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);

    /* line up the big buffers for components in this scan */
    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
      fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
	(fullsize_image[cinfo->cur_comp_info[ci]->component_index],
	 (long) 0, TRUE);
    }
    
    /* 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_ptrs, fullsize_width,
	       (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
	       (short) (DCTSIZE-1));
	/* If single scan, can do color quantization prescan on-the-fly */
	if (single_scan)
	  (*cinfo->methods->color_quant_prescan) (cinfo, rows_in_mem,
						  fullsize_ptrs,
						  output_workspace[0]);
	/* Realign the big buffers */
	pixel_rows_output += rows_in_mem;
	for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
	  fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
	    (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
	     pixel_rows_output, TRUE);
	}
	/* Expand first row group of this set */
	expand(cinfo, sampled_data[whichss], fullsize_ptrs, 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_ptrs, 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_ptrs, fullsize_width,
	       (short) (i-1), (short) i, (short) (i+1),
	       (short) i);
      }
    } /* end of loop over scan's data */
    
    /* Expand the last row group with dummy below-context */
    /* Note whichss points to last buffer side used */
    expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
	   (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
	   (short) (DCTSIZE-1));
    /* If single scan, finish on-the-fly color quantization prescan */
    if (single_scan)
      (*cinfo->methods->color_quant_prescan) (cinfo,
			(int) (cinfo->image_height - pixel_rows_output),
			fullsize_ptrs, output_workspace[0]);
    
    /* Clean up after the scan */
    (*cinfo->methods->disassemble_term) (cinfo);
    (*cinfo->methods->upsample_term) (cinfo);
    (*cinfo->methods->entropy_decode_term) (cinfo);
    (*cinfo->methods->read_scan_trailer) (cinfo);
    if (single_scan)
      cinfo->completed_passes++;
    else
      cinfo->completed_passes += cinfo->comps_in_scan;

    /* Release scan-local working memory */
    free_MCU_row(cinfo, coeff_data);
#ifdef BLOCK_SMOOTHING_SUPPORTED
    if (cinfo->do_block_smoothing) {
      free_MCU_row(cinfo, bsmooth[0]);
      free_MCU_row(cinfo, bsmooth[1]);
      free_MCU_row(cinfo, bsmooth[2]);
    }
#endif
    free_sampling_buffer(cinfo, sampled_data);
    
    /* Repeat if there is another scan */
  } while ((!single_scan) && (*cinfo->methods->read_scan_header) (cinfo));

  if (single_scan) {
    /* If we expected just one scan, make SURE there's just one */
    if ((*cinfo->methods->read_scan_header) (cinfo))
/*      WARNMS(cinfo->emethods, "Didn't expect more than one scan"); */
      send_command(ERR5);
    /* We did the CQ prescan on-the-fly, so we are all set. */
  } else {
    /* For multiple-scan file, do the CQ prescan as a separate pass. */
    /* The main reason why prescan is passed the output_workspace is */
    /* so that we can use scan_big_image to call it... */
    if (cinfo->two_pass_quantize)
      scan_big_image(cinfo, cinfo->methods->color_quant_prescan);
  }

  /* Now that we've collected the data, do color processing and output */
  if (cinfo->two_pass_quantize)
    (*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
  else
    scan_big_image(cinfo, emit_1pass);

  /* Release working memory */
  /* (no work -- we let free_all release what's needful) */
}

#endif /* NEED_COMPLEX_CONTROLLER */


/*
 * The method selection routine for decompression pipeline controllers.
 * Note that at this point we've already read the JPEG header and first SOS,
 * so we can tell whether the input is one scan or not.
 */

GLOBAL void
jseldpipeline (decompress_info_ptr cinfo)
{
  /* simplify subsequent tests on color quantization */
  if (! cinfo->quantize_colors)
    cinfo->two_pass_quantize = FALSE;
  
  if (cinfo->comps_in_scan == cinfo->num_components) {
    /* It's a single-scan file */
    if (cinfo->two_pass_quantize) {
#ifdef NEED_COMPLEX_CONTROLLER
      cinfo->methods->d_pipeline_controller = complex_dcontroller;
#else
/*      ERREXIT(cinfo->emethods, "2-pass quantization support was not compiled"); */
      send_command(ERR7);
      receive_command();
      exit();
#endif
    } else
      cinfo->methods->d_pipeline_controller = simple_dcontroller;
  } else {
    /* It's a multiple-scan file */
#ifdef NEED_COMPLEX_CONTROLLER
    cinfo->methods->d_pipeline_controller = complex_dcontroller;
#else
/*    ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled"); */
      send_command(ERR7);
      receive_command();
      exit();
#endif
  }
}

⌨️ 快捷键说明

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