private bool encode_mcu_AC_refine(JBLOCK[][] MCU_data)
{
/* Emit restart marker if needed */
if (m_cinfo.m_restart_interval != 0)
{
if (m_restarts_to_go == 0)
emit_restart_e(m_next_restart_num);
}
/* Encode the MCU data block */
/* It is convenient to make a pre-pass to determine the transformed
* coefficients' absolute values and the EOB position.
*/
int EOB = 0;
int[] natural_order = m_cinfo.natural_order;
int[] absvalues = new int[JpegConstants.DCTSIZE2];
for (int k = m_cinfo.m_Ss; k <= m_cinfo.m_Se; k++)
{
int temp = MCU_data[0][0][natural_order[k]];
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if (temp < 0)
temp = -temp; /* temp is abs value of input */
temp >>= m_cinfo.m_Al; /* apply the point transform */
absvalues[k] = temp; /* save abs value for main pass */
if (temp == 1)
{
/* EOB = index of last newly-nonzero coef */
EOB = k;
}
}
/* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
int r = 0; /* r = run length of zeros */
uint BR = 0; /* BR = count of buffered bits added now */
uint bitBufferOffset = BE; /* Append bits to buffer */
for (int k = m_cinfo.m_Ss; k <= m_cinfo.m_Se; k++)
{
int temp = absvalues[k];
if (temp == 0)
{
r++;
continue;
}
/* Emit any required ZRLs, but not if they can be folded into EOB */
while (r > 15 && k <= EOB)
{
/* emit any pending EOBRUN and the BE correction bits */
emit_eobrun();
/* Emit ZRL */
emit_ac_symbol(ac_tbl_no, 0xF0);
r -= 16;
/* Emit buffered correction bits that must be associated with ZRL */
emit_buffered_bits(bitBufferOffset, BR);
bitBufferOffset = 0;/* BE bits are gone now */
BR = 0;
}
/* If the coef was previously nonzero, it only needs a correction bit.
* NOTE: a straight translation of the spec's figure G.7 would suggest
* that we also need to test r > 15. But if r > 15, we can only get here
* if k > EOB, which implies that this coefficient is not 1.
*/
if (temp > 1)
{
/* The correction bit is the next bit of the absolute value. */
bit_buffer[bitBufferOffset + BR] = (char)(temp & 1);
BR++;
continue;
}
/* Emit any pending EOBRUN and the BE correction bits */
emit_eobrun();
/* Count/emit Huffman symbol for run length / number of bits */
emit_ac_symbol(ac_tbl_no, (r << 4) + 1);
/* Emit output bit for newly-nonzero coef */
temp = (MCU_data[0][0][natural_order[k]] < 0) ? 0 : 1;
emit_bits_e(temp, 1);
/* Emit buffered correction bits that must be associated with this code */
emit_buffered_bits(bitBufferOffset, BR);
bitBufferOffset = 0;/* BE bits are gone now */
BR = 0;
r = 0; /* reset zero run length */
}
if (r > 0 || BR > 0)
{
/* If there are trailing zeroes, */
EOBRUN++; /* count an EOB */
BE += BR; /* concat my correction bits to older ones */
/* We force out the EOB if we risk either:
* 1. overflow of the EOB counter;
* 2. overflow of the correction bit buffer during the next MCU.
*/
if (EOBRUN == 0x7FFF || BE > (MAX_CORR_BITS - JpegConstants.DCTSIZE2 + 1))
emit_eobrun();
}
/* Update restart-interval state too */
if (m_cinfo.m_restart_interval != 0)
{
if (m_restarts_to_go == 0)
{
m_restarts_to_go = m_cinfo.m_restart_interval;
m_next_restart_num++;
m_next_restart_num &= 7;
}
m_restarts_to_go--;
}
return true;
}