private void process_data_context_main(byte[][] output_buf, ref int out_row_ctr, int out_rows_avail)
{
ComponentBuffer[] cb = new ComponentBuffer[m_cinfo.m_num_components];
for (int i = 0; i < m_cinfo.m_num_components; i++)
{
cb[i] = new ComponentBuffer();
cb[i].SetBuffer(m_buffer[i], m_funnyIndices[m_whichFunny][i], m_funnyOffsets[i]);
}
/* Read input data if we haven't filled the main buffer yet */
if (!m_buffer_full)
{
if (m_cinfo.m_coef.decompress_data(cb) == ReadResult.JPEG_SUSPENDED)
{
/* suspension forced, can do nothing more */
return;
}
/* OK, we have an iMCU row to work with */
m_buffer_full = true;
/* count rows received */
m_iMCU_row_ctr++;
}
/* Postprocessor typically will not swallow all the input data it is handed
* in one call (due to filling the output buffer first). Must be prepared
* to exit and restart.
This switch lets us keep track of how far we got.
* Note that each case falls through to the next on successful completion.
*/
if (m_context_state == CTX_POSTPONED_ROW)
{
/* Call postprocessor using previously set pointers for postponed row */
m_cinfo.m_post.post_process_data(cb, ref m_rowgroup_ctr,
m_rowgroups_avail, output_buf, ref out_row_ctr, out_rows_avail);
if (m_rowgroup_ctr < m_rowgroups_avail)
{
/* Need to suspend */
return;
}
m_context_state = CTX_PREPARE_FOR_IMCU;
if (out_row_ctr >= out_rows_avail)
{
/* Postprocessor exactly filled output buf */
return;
}
}
if (m_context_state == CTX_PREPARE_FOR_IMCU)
{
/* Prepare to process first M-1 row groups of this iMCU row */
m_rowgroup_ctr = 0;
m_rowgroups_avail = m_cinfo.min_DCT_v_scaled_size - 1;
/* Check for bottom of image: if so, tweak pointers to "duplicate"
* the last sample row, and adjust rowgroups_avail to ignore padding rows.
*/
if (m_iMCU_row_ctr == m_cinfo.m_total_iMCU_rows)
set_bottom_pointers();
m_context_state = CTX_PROCESS_IMCU;
}
if (m_context_state == CTX_PROCESS_IMCU)
{
/* Call postprocessor using previously set pointers */
m_cinfo.m_post.post_process_data(cb, ref m_rowgroup_ctr,
m_rowgroups_avail, output_buf, ref out_row_ctr, out_rows_avail);
if (m_rowgroup_ctr < m_rowgroups_avail)
{
/* Need to suspend */
return;
}
/* After the first iMCU, change wraparound pointers to normal state */
if (m_iMCU_row_ctr == 1)
set_wraparound_pointers();
/* Prepare to load new iMCU row using other xbuffer list */
m_whichFunny ^= 1; /* 0=>1 or 1=>0 */
m_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 */
m_rowgroup_ctr = m_cinfo.min_DCT_v_scaled_size + 1;
m_rowgroups_avail = m_cinfo.min_DCT_v_scaled_size + 2;
m_context_state = CTX_POSTPONED_ROW;
}
}