private bool decode_mcu_AC_first(JBLOCK[] MCU_data)
{
/* Process restart marker if needed; may have to suspend */
if (m_cinfo.m_restart_interval != 0)
{
if (m_restarts_to_go == 0)
{
if (!process_restart())
return false;
}
}
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (!m_insufficient_data)
{
/* Load up working state.
* We can avoid loading/saving bitread state if in an EOB run.
*/
uint EOBRUN = m_saved.EOBRUN; /* only part of saved state we need */
int[] natural_order = m_cinfo.natural_order;
/* There is always only one block per MCU */
if (EOBRUN != 0)
{
/* if it's a band of zeroes... */
/* ...process it now (we do nothing) */
EOBRUN--;
}
else
{
int get_buffer;
int bits_left;
bitread_working_state br_state = new bitread_working_state();
BITREAD_LOAD_STATE(m_bitstate, out get_buffer, out bits_left, ref br_state);
for (int k = m_cinfo.m_Ss; k <= m_cinfo.m_Se; k++)
{
int s;
if (!HUFF_DECODE(out s, ref br_state, ac_derived_tbl, ref get_buffer, ref bits_left))
return false;
int r = s >> 4;
s &= 15;
if (s != 0)
{
k += r;
if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left))
return false;
r = GET_BITS(s, get_buffer, ref bits_left);
s = HUFF_EXTEND(r, s);
/* Scale and output coefficient in natural (dezigzagged) order */
MCU_data[0][natural_order[k]] = (short)(s << m_cinfo.m_Al);
}
else
{
if (r != 15)
{
/* EOBr, run length is 2^r + appended bits */
if (r != 0)
{
/* EOBr, r > 0 */
EOBRUN = (uint)(1 << r);
if (!CHECK_BIT_BUFFER(ref br_state, r, ref get_buffer, ref bits_left))
return false;
r = GET_BITS(r, get_buffer, ref bits_left);
EOBRUN += (uint)r;
EOBRUN--; /* this band is processed at this moment */
}
break; /* force end-of-band */
}
k += 15; /* ZRL: skip 15 zeroes in band */
}
}
BITREAD_SAVE_STATE(ref m_bitstate, get_buffer, bits_left);
}
/* Completed MCU, so update state */
m_saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
m_restarts_to_go--;
return true;
}