private void jpeg_fdct_16x16(int[] data1, byte[][] sample_data, int start_row, int start_col)
{
/* Pass 1: process rows.
* Note results are scaled up by sqrt(8) compared to a true DCT;
* furthermore, we scale the results by 2**PASS1_BITS.
* cK represents sqrt(2) * cos(K*pi/32).
*/
int[] workspace = new int[JpegConstants.DCTSIZE2];
int dataIndex = 0;
int[] data = data1;
int ctr = 0;
for (;;)
{
byte[] elem = sample_data[start_row + ctr];
int elemIndex = start_col;
/* Even part */
int tmp0 = elem[elemIndex + 0] + elem[elemIndex + 15];
int tmp1 = elem[elemIndex + 1] + elem[elemIndex + 14];
int tmp2 = elem[elemIndex + 2] + elem[elemIndex + 13];
int tmp3 = elem[elemIndex + 3] + elem[elemIndex + 12];
int tmp4 = elem[elemIndex + 4] + elem[elemIndex + 11];
int tmp5 = elem[elemIndex + 5] + elem[elemIndex + 10];
int tmp6 = elem[elemIndex + 6] + elem[elemIndex + 9];
int tmp7 = elem[elemIndex + 7] + elem[elemIndex + 8];
int tmp10 = tmp0 + tmp7;
int tmp14 = tmp0 - tmp7;
int tmp11 = tmp1 + tmp6;
int tmp15 = tmp1 - tmp6;
int tmp12 = tmp2 + tmp5;
int tmp16 = tmp2 - tmp5;
int tmp13 = tmp3 + tmp4;
int tmp17 = tmp3 - tmp4;
tmp0 = elem[elemIndex + 0] - elem[elemIndex + 15];
tmp1 = elem[elemIndex + 1] - elem[elemIndex + 14];
tmp2 = elem[elemIndex + 2] - elem[elemIndex + 13];
tmp3 = elem[elemIndex + 3] - elem[elemIndex + 12];
tmp4 = elem[elemIndex + 4] - elem[elemIndex + 11];
tmp5 = elem[elemIndex + 5] - elem[elemIndex + 10];
tmp6 = elem[elemIndex + 6] - elem[elemIndex + 9];
tmp7 = elem[elemIndex + 7] - elem[elemIndex + 8];
/* Apply unsigned->signed conversion. */
data[dataIndex + 0] =
((tmp10 + tmp11 + tmp12 + tmp13 - 16 * JpegConstants.CENTERJSAMPLE) << SLOW_INTEGER_PASS1_BITS);
data[dataIndex + 4] =
JpegUtils.DESCALE(
(tmp10 - tmp13) * SLOW_INTEGER_FIX(1.306562965) + /* c4[16] = c2[8] */
(tmp11 - tmp12) * SLOW_INTEGER_FIX_0_541196100, /* c12[16] = c6[8] */
SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
tmp10 = (tmp17 - tmp15) * SLOW_INTEGER_FIX(0.275899379) + /* c14[16] = c7[8] */
(tmp14 - tmp16) * SLOW_INTEGER_FIX(1.387039845); /* c2[16] = c1[8] */
data[dataIndex + 2] = JpegUtils.DESCALE(
tmp10 + tmp15 * SLOW_INTEGER_FIX(1.451774982) /* c6+c14 */
+ tmp16 * SLOW_INTEGER_FIX(2.172734804), /* c2+c10 */
SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
data[dataIndex + 6] = JpegUtils.DESCALE(
tmp10 - tmp14 * SLOW_INTEGER_FIX(0.211164243) /* c2-c6 */
- tmp17 * SLOW_INTEGER_FIX(1.061594338), /* c10+c14 */
SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
/* Odd part */
tmp11 = (tmp0 + tmp1) * SLOW_INTEGER_FIX(1.353318001) + /* c3 */
(tmp6 - tmp7) * SLOW_INTEGER_FIX(0.410524528); /* c13 */
tmp12 = (tmp0 + tmp2) * SLOW_INTEGER_FIX(1.247225013) + /* c5 */
(tmp5 + tmp7) * SLOW_INTEGER_FIX(0.666655658); /* c11 */
tmp13 = (tmp0 + tmp3) * SLOW_INTEGER_FIX(1.093201867) + /* c7 */
(tmp4 - tmp7) * SLOW_INTEGER_FIX(0.897167586); /* c9 */
tmp14 = (tmp1 + tmp2) * SLOW_INTEGER_FIX(0.138617169) + /* c15 */
(tmp6 - tmp5) * SLOW_INTEGER_FIX(1.407403738); /* c1 */
tmp15 = (tmp1 + tmp3) * (-SLOW_INTEGER_FIX(0.666655658)) + /* -c11 */
(tmp4 + tmp6) * (-SLOW_INTEGER_FIX(1.247225013)); /* -c5 */
tmp16 = (tmp2 + tmp3) * (-SLOW_INTEGER_FIX(1.353318001)) + /* -c3 */
(tmp5 - tmp4) * SLOW_INTEGER_FIX(0.410524528); /* c13 */
tmp10 = tmp11 + tmp12 + tmp13 -
tmp0 * SLOW_INTEGER_FIX(2.286341144) + /* c7+c5+c3-c1 */
tmp7 * SLOW_INTEGER_FIX(0.779653625); /* c15+c13-c11+c9 */
tmp11 += tmp14 + tmp15 + tmp1 * SLOW_INTEGER_FIX(0.071888074) /* c9-c3-c15+c11 */
- tmp6 * SLOW_INTEGER_FIX(1.663905119); /* c7+c13+c1-c5 */
tmp12 += tmp14 + tmp16 - tmp2 * SLOW_INTEGER_FIX(1.125726048) /* c7+c5+c15-c3 */
+ tmp5 * SLOW_INTEGER_FIX(1.227391138); /* c9-c11+c1-c13 */
tmp13 += tmp15 + tmp16 + tmp3 * SLOW_INTEGER_FIX(1.065388962) /* c15+c3+c11-c7 */
+ tmp4 * SLOW_INTEGER_FIX(2.167985692); /* c1+c13+c5-c9 */
data[dataIndex + 1] = JpegUtils.DESCALE(tmp10, SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
data[dataIndex + 3] = JpegUtils.DESCALE(tmp11, SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
data[dataIndex + 5] = JpegUtils.DESCALE(tmp12, SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
data[dataIndex + 7] = JpegUtils.DESCALE(tmp13, SLOW_INTEGER_CONST_BITS - SLOW_INTEGER_PASS1_BITS);
ctr++;
if (ctr != JpegConstants.DCTSIZE)
{
if (ctr == JpegConstants.DCTSIZE * 2)
{
/* Done. */
break;
}
/* advance pointer to next row */
dataIndex += JpegConstants.DCTSIZE;
}
else
{
/* switch pointer to extended workspace */
data = workspace;
dataIndex = 0;
}
}
/* Pass 2: process columns.
* We remove the PASS1_BITS scaling, but leave the results scaled up
* by an overall factor of 8.
* We must also scale the output by (8/16)**2 = 1/2**2.
* cK represents sqrt(2) * cos(K*pi/32).
*/
data = data1;
dataIndex = 0;
int workspaceIndex = 0;
for (ctr = JpegConstants.DCTSIZE - 1; ctr >= 0; ctr--)
{
/* Even part */
int tmp0 = data[dataIndex + JpegConstants.DCTSIZE * 0] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 7];
int tmp1 = data[dataIndex + JpegConstants.DCTSIZE * 1] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 6];
int tmp2 = data[dataIndex + JpegConstants.DCTSIZE * 2] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 5];
int tmp3 = data[dataIndex + JpegConstants.DCTSIZE * 3] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 4];
int tmp4 = data[dataIndex + JpegConstants.DCTSIZE * 4] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 3];
int tmp5 = data[dataIndex + JpegConstants.DCTSIZE * 5] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 2];
int tmp6 = data[dataIndex + JpegConstants.DCTSIZE * 6] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 1];
int tmp7 = data[dataIndex + JpegConstants.DCTSIZE * 7] + workspace[workspaceIndex + JpegConstants.DCTSIZE * 0];
int tmp10 = tmp0 + tmp7;
int tmp14 = tmp0 - tmp7;
int tmp11 = tmp1 + tmp6;
int tmp15 = tmp1 - tmp6;
int tmp12 = tmp2 + tmp5;
int tmp16 = tmp2 - tmp5;
int tmp13 = tmp3 + tmp4;
int tmp17 = tmp3 - tmp4;
tmp0 = data[dataIndex + JpegConstants.DCTSIZE * 0] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 7];
tmp1 = data[dataIndex + JpegConstants.DCTSIZE * 1] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 6];
tmp2 = data[dataIndex + JpegConstants.DCTSIZE * 2] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 5];
tmp3 = data[dataIndex + JpegConstants.DCTSIZE * 3] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 4];
tmp4 = data[dataIndex + JpegConstants.DCTSIZE * 4] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 3];
tmp5 = data[dataIndex + JpegConstants.DCTSIZE * 5] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 2];
tmp6 = data[dataIndex + JpegConstants.DCTSIZE * 6] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 1];
tmp7 = data[dataIndex + JpegConstants.DCTSIZE * 7] - workspace[workspaceIndex + JpegConstants.DCTSIZE * 0];
data[dataIndex + JpegConstants.DCTSIZE * 0] =
JpegUtils.DESCALE(tmp10 + tmp11 + tmp12 + tmp13, SLOW_INTEGER_PASS1_BITS + 2);
data[dataIndex + JpegConstants.DCTSIZE * 4] =
JpegUtils.DESCALE((tmp10 - tmp13) * SLOW_INTEGER_FIX(1.306562965) + /* c4[16] = c2[8] */
(tmp11 - tmp12) * SLOW_INTEGER_FIX_0_541196100, /* c12[16] = c6[8] */
SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
tmp10 = (tmp17 - tmp15) * SLOW_INTEGER_FIX(0.275899379) + /* c14[16] = c7[8] */
(tmp14 - tmp16) * SLOW_INTEGER_FIX(1.387039845); /* c2[16] = c1[8] */
data[dataIndex + JpegConstants.DCTSIZE * 2] =
JpegUtils.DESCALE(tmp10 + tmp15 * SLOW_INTEGER_FIX(1.451774982) /* c6+c14 */
+ tmp16 * SLOW_INTEGER_FIX(2.172734804), /* c2+10 */
SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
data[dataIndex + JpegConstants.DCTSIZE * 6] =
JpegUtils.DESCALE(tmp10 - tmp14 * SLOW_INTEGER_FIX(0.211164243) /* c2-c6 */
- tmp17 * SLOW_INTEGER_FIX(1.061594338), /* c10+c14 */
SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
/* Odd part */
tmp11 = (tmp0 + tmp1) * SLOW_INTEGER_FIX(1.353318001) + /* c3 */
(tmp6 - tmp7) * SLOW_INTEGER_FIX(0.410524528); /* c13 */
tmp12 = (tmp0 + tmp2) * SLOW_INTEGER_FIX(1.247225013) + /* c5 */
(tmp5 + tmp7) * SLOW_INTEGER_FIX(0.666655658); /* c11 */
tmp13 = (tmp0 + tmp3) * SLOW_INTEGER_FIX(1.093201867) + /* c7 */
(tmp4 - tmp7) * SLOW_INTEGER_FIX(0.897167586); /* c9 */
tmp14 = (tmp1 + tmp2) * SLOW_INTEGER_FIX(0.138617169) + /* c15 */
(tmp6 - tmp5) * SLOW_INTEGER_FIX(1.407403738); /* c1 */
tmp15 = (tmp1 + tmp3) * (-SLOW_INTEGER_FIX(0.666655658)) + /* -c11 */
(tmp4 + tmp6) * (-SLOW_INTEGER_FIX(1.247225013)); /* -c5 */
tmp16 = (tmp2 + tmp3) * (-SLOW_INTEGER_FIX(1.353318001)) + /* -c3 */
(tmp5 - tmp4) * SLOW_INTEGER_FIX(0.410524528); /* c13 */
tmp10 = tmp11 + tmp12 + tmp13 -
tmp0 * SLOW_INTEGER_FIX(2.286341144) + /* c7+c5+c3-c1 */
tmp7 * SLOW_INTEGER_FIX(0.779653625); /* c15+c13-c11+c9 */
tmp11 += tmp14 + tmp15 + tmp1 * SLOW_INTEGER_FIX(0.071888074) /* c9-c3-c15+c11 */
- tmp6 * SLOW_INTEGER_FIX(1.663905119); /* c7+c13+c1-c5 */
tmp12 += tmp14 + tmp16 - tmp2 * SLOW_INTEGER_FIX(1.125726048) /* c7+c5+c15-c3 */
+ tmp5 * SLOW_INTEGER_FIX(1.227391138); /* c9-c11+c1-c13 */
tmp13 += tmp15 + tmp16 + tmp3 * SLOW_INTEGER_FIX(1.065388962) /* c15+c3+c11-c7 */
+ tmp4 * SLOW_INTEGER_FIX(2.167985692); /* c1+c13+c5-c9 */
data[dataIndex + JpegConstants.DCTSIZE * 1] = JpegUtils.DESCALE(tmp10, SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
data[dataIndex + JpegConstants.DCTSIZE * 3] = JpegUtils.DESCALE(tmp11, SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
data[dataIndex + JpegConstants.DCTSIZE * 5] = JpegUtils.DESCALE(tmp12, SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
data[dataIndex + JpegConstants.DCTSIZE * 7] = JpegUtils.DESCALE(tmp13, SLOW_INTEGER_CONST_BITS + SLOW_INTEGER_PASS1_BITS + 2);
dataIndex++; /* advance pointer to next column */
workspaceIndex++; /* advance pointer to next column */
}
}