private bool encode_one_block(savable_state state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl)
{
/* Encode the DC coefficient difference per section F.1.2.1 */
int temp = block[0] - last_dc_val;
int temp2 = temp;
if (temp < 0)
{
temp = -temp; /* temp is abs value of input */
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */
int nbits = 0;
while (temp != 0)
{
nbits++;
temp >>= 1;
}
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > MAX_COEF_BITS + 1)
m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
/* Emit the Huffman-coded symbol for the number of bits */
if (!emit_bits_s(state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits]))
return false;
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits != 0)
{
/* emit_bits rejects calls with size 0 */
if (!emit_bits_s(state, temp2, nbits))
return false;
}
/* Encode the AC coefficients per section F.1.2.2 */
int r = 0; /* r = run length of zeros */
int[] natural_order = m_cinfo.natural_order;
int Se = m_cinfo.lim_Se;
for (int k = 1; k <= Se; k++)
{
temp2 = block[natural_order[k]];
if (temp2 == 0)
{
r++;
}
else
{
/* if run length > 15, must emit special run-length-16 codes (0xF0) */
while (r > 15)
{
if (!emit_bits_s(state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0]))
return false;
r -= 16;
}
temp = temp2;
if (temp < 0)
{
temp = -temp; /* temp is abs value of input */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1) != 0)
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > MAX_COEF_BITS)
m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF);
/* Emit Huffman symbol for run length / number of bits */
temp = (r << 4) + nbits;
if (!emit_bits_s(state, actbl.ehufco[temp], actbl.ehufsi[temp]))
return false;
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (!emit_bits_s(state, temp2, nbits))
return false;
r = 0;
}
}
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0)
{
if (!emit_bits_s(state, actbl.ehufco[0], actbl.ehufsi[0]))
return false;
}
return true;
}