public virtual bool compress_data(byte[][][] input_buf)
{
/* Align the virtual buffers for the components used in this scan. */
JBLOCK[][][] buffer = new JBLOCK[JpegConstants.MAX_COMPS_IN_SCAN][][];
for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
{
jpeg_component_info componentInfo = m_cinfo.Component_info[m_cinfo.m_cur_comp_info[ci]];
buffer[ci] = m_whole_image[componentInfo.Component_index].Access(
m_iMCU_row_num * componentInfo.V_samp_factor, componentInfo.V_samp_factor);
}
/* Loop to process one whole iMCU row */
int last_MCU_col = m_cinfo.m_MCUs_per_row - 1;
int last_iMCU_row = m_cinfo.m_total_iMCU_rows - 1;
JBLOCK[][] MCU_buffer = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU][];
for (int yoffset = m_MCU_vert_offset; yoffset < m_MCU_rows_per_iMCU_row; yoffset++)
{
for (int MCU_col_num = m_mcu_ctr; MCU_col_num < m_cinfo.m_MCUs_per_row; MCU_col_num++)
{
/* Construct list of pointers to DCT blocks belonging to this MCU */
int blkn = 0; /* index of current DCT block within MCU */
for (int ci = 0; ci < m_cinfo.m_comps_in_scan; ci++)
{
jpeg_component_info componentInfo = m_cinfo.Component_info[m_cinfo.m_cur_comp_info[ci]];
int start_col = MCU_col_num * componentInfo.MCU_width;
int blockcnt = (MCU_col_num < last_MCU_col) ? componentInfo.MCU_width : componentInfo.last_col_width;
for (int yindex = 0; yindex < componentInfo.MCU_height; yindex++)
{
int xindex = 0;
if (m_iMCU_row_num < last_iMCU_row || yindex + yoffset < componentInfo.last_row_height)
{
/* Fill in pointers to real blocks in this row */
for (xindex = 0; xindex < blockcnt; xindex++)
{
int bufLength = buffer[ci][yindex + yoffset].Length;
int start = start_col + xindex;
MCU_buffer[blkn] = new JBLOCK[bufLength - start];
for (int j = start; j < bufLength; j++)
MCU_buffer[blkn][j - start] = buffer[ci][yindex + yoffset][j];
blkn++;
}
}
else
{
/* At bottom of image, need a whole row of dummy blocks */
xindex = 0;
}
/* Fill in any dummy blocks needed in this row.
* Dummy blocks are filled in the same way as in jccoefct.c:
* all zeroes in the AC entries, DC entries equal to previous
* block's DC value. The init routine has already zeroed the
* AC entries, so we need only set the DC entries correctly.
*/
for (; xindex < componentInfo.MCU_width; xindex++)
{
MCU_buffer[blkn] = m_dummy_buffer[blkn];
MCU_buffer[blkn][0][0] = MCU_buffer[blkn - 1][0][0];
blkn++;
}
}
}
/* Try to write the MCU. */
if (!m_cinfo.m_entropy.encode_mcu(MCU_buffer))
{
/* Suspension forced; update state counters and exit */
m_MCU_vert_offset = yoffset;
m_mcu_ctr = MCU_col_num;
return false;
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
m_mcu_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
m_iMCU_row_num++;
start_iMCU_row();
return true;
}