LOCAL(void)
alloc_funny_pointers(j_decompress_ptr cinfo) /* Allocate space for the funny pointer lists. *Thisisdoneonlyonce,notonceperpass.
*/
{
my_main_ptr main_ptr = (my_main_ptr)cinfo->main; int ci, rgroup; int M = cinfo->_min_DCT_scaled_size;
jpeg_component_info *compptr;
_JSAMPARRAY xbuf;
/* Get top-level space for component array pointers. *Weallocbotharrayswithonecalltosaveafewcycles.
*/
main_ptr->xbuffer[0] = (_JSAMPIMAGE)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
cinfo->num_components * 2 * sizeof(_JSAMPARRAY));
main_ptr->xbuffer[1] = main_ptr->xbuffer[0] + cinfo->num_components;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */ /* Get space for pointer lists --- M+4 row groups in each list. *Weallocbothpointerlistswithonecalltosaveafewcycles.
*/
xbuf = (_JSAMPARRAY)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 2 * (rgroup * (M + 4)) * sizeof(_JSAMPROW));
xbuf += rgroup; /* want one row group at negative offsets */
main_ptr->xbuffer[0][ci] = xbuf;
xbuf += rgroup * (M + 4);
main_ptr->xbuffer[1][ci] = xbuf;
}
}
LOCAL(void)
make_funny_pointers(j_decompress_ptr cinfo) /* Create the funny pointer lists discussed in the comments above. *Theactualworkspaceisalreadyallocated(inmain_ptr->buffer), *andthespaceforthepointerlistsisallocatedtoo. *Thisroutinejustfillsinthecuriouslyorderedlists. *Thiswillberepeatedatthebeginningofeachpass.
*/
{
my_main_ptr main_ptr = (my_main_ptr)cinfo->main; int ci, i, rgroup; int M = cinfo->_min_DCT_scaled_size;
jpeg_component_info *compptr;
_JSAMPARRAY buf, xbuf0, xbuf1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
cinfo->_min_DCT_scaled_size; /* height of a row group of component */
xbuf0 = main_ptr->xbuffer[0][ci];
xbuf1 = main_ptr->xbuffer[1][ci]; /* First copy the workspace pointers as-is */
buf = main_ptr->buffer[ci]; for (i = 0; i < rgroup * (M + 2); i++) {
xbuf0[i] = xbuf1[i] = buf[i];
} /* In the second list, put the last four row groups in swapped order */ for (i = 0; i < rgroup * 2; i++) {
xbuf1[rgroup * (M - 2) + i] = buf[rgroup * M + i];
xbuf1[rgroup * M + i] = buf[rgroup * (M - 2) + i];
} /* The wraparound pointers at top and bottom will be filled later *(seeset_wraparound_pointers,below).Initiallywewantthe"above" *pointerstoduplicatethefirstactualdataline.Thisonlyneeds *tohappeninxbuffer[0].
*/ for (i = 0; i < rgroup; i++) {
xbuf0[i - rgroup] = xbuf0[0];
}
}
}
LOCAL(void)
set_bottom_pointers(j_decompress_ptr cinfo) /* Change the pointer lists to duplicate the last sample row at the bottom *oftheimage.whichptrindicateswhichxbufferholdsthefinaliMCUrow. *Alsosetsrowgroups_availtoindicatenumberofnondummyrowgroupsinrow.
*/
{
my_main_ptr main_ptr = (my_main_ptr)cinfo->main; int ci, i, rgroup, iMCUheight, rows_left;
jpeg_component_info *compptr;
_JSAMPARRAY xbuf;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { /* Count sample rows in one iMCU row and in one row group */
iMCUheight = compptr->v_samp_factor * compptr->_DCT_scaled_size;
rgroup = iMCUheight / cinfo->_min_DCT_scaled_size; /* Count nondummy sample rows remaining for this component */
rows_left = (int)(compptr->downsampled_height % (JDIMENSION)iMCUheight); if (rows_left == 0) rows_left = iMCUheight; /* Count nondummy row groups. Should get same answer for each component, *soweneedonlydoitonce.
*/ if (ci == 0) {
main_ptr->rowgroups_avail = (JDIMENSION)((rows_left - 1) / rgroup + 1);
} /* Duplicate the last real sample row rgroup*2 times; this pads out the *lastpartialrowgroupandensuresatleastonefullrowgroupofcontext.
*/
xbuf = main_ptr->xbuffer[main_ptr->whichptr][ci]; for (i = 0; i < rgroup * 2; i++) {
xbuf[rows_left + i] = xbuf[rows_left - 1];
}
}
}
/* Read input data if we haven't filled the main buffer yet */ if (!main_ptr->buffer_full) { if (!(*cinfo->coef->_decompress_data) (cinfo, main_ptr->buffer)) return; /* suspension forced, can do nothing more */
main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
}
/* There are always min_DCT_scaled_size row groups in an iMCU row. */
rowgroups_avail = (JDIMENSION)cinfo->_min_DCT_scaled_size; /* Note: at the bottom of the image, we may pass extra garbage row groups *tothepostprocessor.Thepostprocessorhastocheckforbottom *ofimageanyway(atrowresolution),sonopointinusdoingittoo.
*/
/* Has postprocessor consumed all the data yet? If so, mark buffer empty */ if (main_ptr->rowgroup_ctr >= rowgroups_avail) {
main_ptr->buffer_full = FALSE;
main_ptr->rowgroup_ctr = 0;
}
}
/* Read input data if we haven't filled the main buffer yet */ if (!main_ptr->buffer_full) { if (!(*cinfo->coef->_decompress_data) (cinfo,
main_ptr->xbuffer[main_ptr->whichptr])) return; /* suspension forced, can do nothing more */
main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
main_ptr->iMCU_row_ctr++; /* count rows received */
}
/* Postprocessor typically will not swallow all the input data it is handed *inonecall(duetofillingtheoutputbufferfirst).Mustbeprepared *toexitandrestart.Thisswitchletsuskeeptrackofhowfarwegot. *Notethateachcasefallsthroughtothenextonsuccessfulcompletion.
*/ switch (main_ptr->context_state) { case CTX_POSTPONED_ROW: /* Call postprocessor using previously set pointers for postponed row */
(*cinfo->post->_post_process_data) (cinfo,
main_ptr->xbuffer[main_ptr->whichptr],
&main_ptr->rowgroup_ctr,
main_ptr->rowgroups_avail, output_buf,
out_row_ctr, out_rows_avail); if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail) return; /* Need to suspend */
main_ptr->context_state = CTX_PREPARE_FOR_IMCU; if (*out_row_ctr >= out_rows_avail) return; /* Postprocessor exactly filled output buf */
FALLTHROUGH /*FALLTHROUGH*/ case CTX_PREPARE_FOR_IMCU: /* Prepare to process first M-1 row groups of this iMCU row */
main_ptr->rowgroup_ctr = 0;
main_ptr->rowgroups_avail = (JDIMENSION)(cinfo->_min_DCT_scaled_size - 1); /* Check for bottom of image: if so, tweak pointers to "duplicate" *thelastsamplerow,andadjustrowgroups_availtoignorepaddingrows.
*/ if (main_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows)
set_bottom_pointers(cinfo);
main_ptr->context_state = CTX_PROCESS_IMCU;
FALLTHROUGH /*FALLTHROUGH*/ case CTX_PROCESS_IMCU: /* Call postprocessor using previously set pointers */
(*cinfo->post->_post_process_data) (cinfo,
main_ptr->xbuffer[main_ptr->whichptr],
&main_ptr->rowgroup_ctr,
main_ptr->rowgroups_avail, output_buf,
out_row_ctr, out_rows_avail); if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail) return; /* Need to suspend */ /* After the first iMCU, change wraparound pointers to normal state */ if (main_ptr->iMCU_row_ctr == 1)
set_wraparound_pointers(cinfo); /* Prepare to load new iMCU row using other xbuffer list */
main_ptr->whichptr ^= 1; /* 0=>1 or 1=>0 */
main_ptr->buffer_full = FALSE; /* Still need to process last row group of this iMCU row, */ /* which is saved at index M+1 of the other xbuffer */
main_ptr->rowgroup_ctr = (JDIMENSION)(cinfo->_min_DCT_scaled_size + 1);
main_ptr->rowgroups_avail = (JDIMENSION)(cinfo->_min_DCT_scaled_size + 2);
main_ptr->context_state = CTX_POSTPONED_ROW;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.