📄 jcpipe.c
字号:
static JBLOCKARRAY rowptr;
if (next_MCU_index >= MCUs_in_big_row) {
rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
next_whole_row, TRUE);
next_whole_row++;
next_MCU_index = 0;
}
/*
* note that on 80x86, the cast applied to MCU_data implies
* near to far pointer conversion.
*/
jcopy_block_row((JBLOCKROW) MCU_data,
rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
(long) cinfo->blocks_in_MCU);
next_MCU_index++;
}
METHODDEF void
dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
/* The method may be either the entropy encoder or some routine supplied */
/* by the entropy optimizer. */
{
/* On an 80x86 machine, the entropy encoder expects the passed data block
* to be in NEAR memory (for performance reasons), so we have to copy it
* back from the big array to a local array. On less brain-damaged CPUs
* we needn't do that.
*/
#ifdef NEED_FAR_POINTERS
JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
#endif
long mcurow, mcuindex, next_row;
int next_index;
JBLOCKARRAY rowptr = NULL; /* init only to suppress compiler complaint */
next_row = 0;
next_index = MCUs_in_big_row;
for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
(*cinfo->methods->progress_monitor) (cinfo, mcurow,
cinfo->MCU_rows_in_scan);
for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
if (next_index >= MCUs_in_big_row) {
rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
next_row, FALSE);
next_row++;
next_index = 0;
}
#ifdef NEED_FAR_POINTERS
jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
(JBLOCKROW) MCU_data, /* casts near to far pointer! */
(long) cinfo->blocks_in_MCU);
(*output_method) (cinfo, MCU_data);
#else
(*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
#endif
next_index++;
}
}
cinfo->completed_passes++;
}
/*
* Compression pipeline controller used for single-scan files
* with no optimization of entropy parameters.
*/
METHODDEF void
single_ccontroller (compress_info_ptr cinfo)
{
int rows_in_mem; /* # of sample rows in full-size buffers */
long fullsize_width; /* # of samples per row in full-size buffers */
long cur_pixel_row; /* counts # of pixel rows processed */
long mcu_rows_output; /* # of MCU rows actually emitted */
int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
/* Work buffer for pre-downsampling data (see comments at head of file) */
JSAMPIMAGE fullsize_data[2];
/* Work buffer for downsampled data */
JSAMPIMAGE sampled_data;
int rows_this_time;
short ci, whichss, i;
/* Prepare for single scan containing all components */
/***************************DID NOT SUPPORT THIS ERROR***********************
if (cinfo->num_components > MAX_COMPS_IN_SCAN)
ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
****************************************************************************/
cinfo->comps_in_scan = cinfo->num_components;
for (ci = 0; ci < cinfo->num_components; ci++) {
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
}
/*********************WE USE INTERLEAVED SCAN*******************************
if (cinfo->comps_in_scan == 1) {
noninterleaved_scan_setup(cinfo);
Vk block rows constitute the same number of MCU 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 contains Vk block rows */
mcu_rows_per_loop = 1;
/* } */
cinfo->total_passes++;
/* 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 working memory: */
/* fullsize_data is sample data before downsampling */
alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
/* sampled_data is sample data after downsampling */
sampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
(cinfo->num_components * SIZEOF(JSAMPARRAY));
for (ci = 0; ci < cinfo->num_components; ci++) {
sampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
(cinfo->comp_info[ci].downsampled_width,
(long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
}
/* Tell the memory manager to instantiate big arrays.
* We don't need any big arrays in this controller,
* but some other module (like the input file reader) 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 */
/* Initialize output file & do per-scan object init */
(*cinfo->methods->write_scan_header) (cinfo);
cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
(*cinfo->methods->entropy_encode_init) (cinfo);
(*cinfo->methods->downsample_init) (cinfo);
(*cinfo->methods->extract_init) (cinfo);
/* Loop over input image: rows_in_mem pixel rows are processed per loop */
mcu_rows_output = 0;
whichss = 1; /* arrange to start with fullsize_data[0] */
for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
cur_pixel_row += rows_in_mem) {
(*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
cinfo->image_height);
whichss ^= 1; /* switch to other fullsize_data buffer */
/* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
/* Then we have exactly DCTSIZE row groups for downsampling. */
rows_this_time = (int) MIN((long) rows_in_mem,
cinfo->image_height - cur_pixel_row);
(*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
fullsize_data[whichss]);
(*cinfo->methods->edge_expand) (cinfo,
cinfo->image_width, rows_this_time,
fullsize_width, rows_in_mem,
fullsize_data[whichss]);
/* Downsample the data (all components) */
/* First time through is a special case */
if (cur_pixel_row) {
/* Downsample last row group of previous set */
downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
(short) (DCTSIZE-1));
/* and dump the previous set's downsampled data */
(*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
mcu_rows_per_loop,
cinfo->methods->entropy_encode);
mcu_rows_output += mcu_rows_per_loop;
/* Downsample first row group of this set */
downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
(short) (DCTSIZE+1), (short) 0, (short) 1,
(short) 0);
} else {
/* Downsample first row group with dummy above-context */
downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
(short) (-1), (short) 0, (short) 1,
(short) 0);
}
/* Downsample second through next-to-last row groups of this set */
for (i = 1; i <= DCTSIZE-2; i++) {
downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
(short) (i-1), (short) i, (short) (i+1),
(short) i);
}
} /* end of outer loop */
/* Downsample the last row group with dummy below-context */
/* Note whichss points to last buffer side used */
downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
(short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
(short) (DCTSIZE-1));
/* Dump the remaining data (may be less than full height if uninterleaved) */
(*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
(int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
cinfo->methods->entropy_encode);
/* Finish output file */
(*cinfo->methods->extract_term) (cinfo);
(*cinfo->methods->downsample_term) (cinfo);
(*cinfo->methods->entropy_encode_term) (cinfo);
(*cinfo->methods->write_scan_trailer) (cinfo);
cinfo->completed_passes++;
/* Release working memory */
/* (no work -- we let free_all release what's needful) */
}
/*
* The method selection routine for compression pipeline controllers.
*/
GLOBAL void
jselcpipeline (compress_info_ptr cinfo)
{
cinfo->methods->c_pipeline_controller = single_ccontroller;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -