private void jpeg_idct_2x2(int component_index, short[] coef_block, int output_row, int output_col)
{
/* buffers data between passes */
int[] workspace = new int[JpegConstants.DCTSIZE * 2];
/* Pass 1: process columns from input, store into work array. */
int coefBlockIndex = 0;
int workspaceIndex = 0;
int[] quantTable = m_dctTables[component_index].int_array;
int quantTableIndex = 0;
for (int ctr = JpegConstants.DCTSIZE; ctr > 0; coefBlockIndex++, quantTableIndex++, workspaceIndex++, ctr--)
{
/* Don't bother to process columns 2,4,6 */
if (ctr == JpegConstants.DCTSIZE - 2 || ctr == JpegConstants.DCTSIZE - 4 || ctr == JpegConstants.DCTSIZE - 6)
continue;
if (coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 1] == 0 &&
coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 3] == 0 &&
coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 5] == 0 &&
coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 7] == 0)
{
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
int dcval = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 0],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 0]) << REDUCED_PASS1_BITS;
workspace[workspaceIndex + JpegConstants.DCTSIZE * 0] = dcval;
workspace[workspaceIndex + JpegConstants.DCTSIZE * 1] = dcval;
continue;
}
/* Even part */
int z1 = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 0],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 0]);
int tmp10 = z1 << (REDUCED_CONST_BITS + 2);
/* Odd part */
z1 = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 7],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 7]);
int tmp0 = z1 * -REDUCED_FIX_0_720959822; /* sqrt(2) * (c7-c5+c3-c1) */
z1 = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 5],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 5]);
tmp0 += z1 * REDUCED_FIX_0_850430095; /* sqrt(2) * (-c1+c3+c5+c7) */
z1 = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 3],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 3]);
tmp0 += z1 * (-REDUCED_FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
z1 = REDUCED_DEQUANTIZE(coef_block[coefBlockIndex + JpegConstants.DCTSIZE * 1],
quantTable[quantTableIndex + JpegConstants.DCTSIZE * 1]);
tmp0 += z1 * REDUCED_FIX_3_624509785; /* sqrt(2) * (c1+c3+c5+c7) */
/* Final output stage */
workspace[workspaceIndex + JpegConstants.DCTSIZE * 0] = JpegUtils.DESCALE(tmp10 + tmp0, REDUCED_CONST_BITS - REDUCED_PASS1_BITS + 2);
workspace[workspaceIndex + JpegConstants.DCTSIZE * 1] = JpegUtils.DESCALE(tmp10 - tmp0, REDUCED_CONST_BITS - REDUCED_PASS1_BITS + 2);
}
/* Pass 2: process 2 rows from work array, store into output array. */
workspaceIndex = 0;
byte[] limit = m_cinfo.m_sample_range_limit;
int limitOffset = m_cinfo.m_sampleRangeLimitOffset - RANGE_SUBSET;
for (int ctr = 0; ctr < 2; ctr++)
{
int currentOutRow = output_row + ctr;
/* It's not clear whether a zero row test is worthwhile here ... */
if (workspace[workspaceIndex + 1] == 0 &&
workspace[workspaceIndex + 3] == 0 &&
workspace[workspaceIndex + 5] == 0 &&
workspace[workspaceIndex + 7] == 0)
{
/* AC terms all zero */
byte dcval = limit[limitOffset + JpegUtils.DESCALE(workspace[workspaceIndex + 0], REDUCED_PASS1_BITS + 3) & RANGE_MASK];
m_componentBuffer[currentOutRow][output_col + 0] = dcval;
m_componentBuffer[currentOutRow][output_col + 1] = dcval;
workspaceIndex += JpegConstants.DCTSIZE; /* advance pointer to next row */
continue;
}
/* Even part */
int tmp10 = (workspace[workspaceIndex + 0]) << (REDUCED_CONST_BITS + 2);
/* Odd part */
int tmp0 = workspace[workspaceIndex + 7] * (-REDUCED_FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ +
workspace[workspaceIndex + 5] * REDUCED_FIX_0_850430095 /* sqrt(2) * (-c1+c3+c5+c7) */ +
workspace[workspaceIndex + 3] * (-REDUCED_FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ +
workspace[workspaceIndex + 1] * REDUCED_FIX_3_624509785; /* sqrt(2) * (c1+c3+c5+c7) */
/* Final output stage */
m_componentBuffer[currentOutRow][output_col + 0] = limit[limitOffset + JpegUtils.DESCALE(tmp10 + tmp0, REDUCED_CONST_BITS + REDUCED_PASS1_BITS + 3 + 2) & RANGE_MASK];
m_componentBuffer[currentOutRow][output_col + 1] = limit[limitOffset + JpegUtils.DESCALE(tmp10 - tmp0, REDUCED_CONST_BITS + REDUCED_PASS1_BITS + 3 + 2) & RANGE_MASK];
workspaceIndex += JpegConstants.DCTSIZE; /* advance pointer to next row */
}
}