private ReadResult decompress_data_ordinary(ComponentBuffer[] output_buf)
{
/* Force some input to be done if we are getting ahead of the input. */
while (m_cinfo.m_input_scan_number < m_cinfo.m_output_scan_number ||
(m_cinfo.m_input_scan_number == m_cinfo.m_output_scan_number &&
m_cinfo.m_input_iMCU_row <= m_cinfo.m_output_iMCU_row))
{
if (m_cinfo.m_inputctl.consume_input() == ReadResult.JPEG_SUSPENDED)
return ReadResult.JPEG_SUSPENDED;
}
int last_iMCU_row = m_cinfo.m_total_iMCU_rows - 1;
/* OK, output from the virtual arrays. */
for (int ci = 0; ci < m_cinfo.m_num_components; ci++)
{
jpeg_component_info componentInfo = m_cinfo.Comp_info[ci];
/* Don't bother to IDCT an uninteresting component. */
if (!componentInfo.component_needed)
continue;
/* Align the virtual buffer for this component. */
JBLOCK[][] buffer = m_whole_image[ci].Access(m_cinfo.m_output_iMCU_row * componentInfo.V_samp_factor,
componentInfo.V_samp_factor);
/* Count non-dummy DCT block rows in this iMCU row. */
int block_rows;
if (m_cinfo.m_output_iMCU_row < last_iMCU_row)
block_rows = componentInfo.V_samp_factor;
else
{
/* NB: can't use last_row_height here; it is input-side-dependent! */
block_rows = componentInfo.height_in_blocks % componentInfo.V_samp_factor;
if (block_rows == 0)
block_rows = componentInfo.V_samp_factor;
}
/* Loop over all DCT blocks to be processed. */
int rowIndex = 0;
for (int block_row = 0; block_row < block_rows; block_row++)
{
int output_col = 0;
for (int block_num = 0; block_num < componentInfo.Width_in_blocks; block_num++)
{
m_cinfo.m_idct.inverse(componentInfo.Component_index,
buffer[block_row][block_num].data, output_buf[ci], rowIndex, output_col);
output_col += componentInfo.DCT_h_scaled_size;
}
rowIndex += componentInfo.DCT_v_scaled_size;
}
}
m_cinfo.m_output_iMCU_row++;
if (m_cinfo.m_output_iMCU_row < m_cinfo.m_total_iMCU_rows)
return ReadResult.JPEG_ROW_COMPLETED;
return ReadResult.JPEG_SCAN_COMPLETED;
}