mirror of git://gcc.gnu.org/git/gcc.git
348 lines
9.5 KiB
Java
348 lines
9.5 KiB
Java
/* DCT.java --
|
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Classpath.
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Classpath is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
|
|
Linking this library statically or dynamically with other modules is
|
|
making a combined work based on this library. Thus, the terms and
|
|
conditions of the GNU General Public License cover the whole
|
|
combination.
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent
|
|
modules, and to copy and distribute the resulting executable under
|
|
terms of your choice, provided that you also meet, for each linked
|
|
independent module, the terms and conditions of the license of that
|
|
module. An independent module is a module which is not derived from
|
|
or based on this library. If you modify this library, you may extend
|
|
this exception to your version of the library, but you are not
|
|
obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version. */
|
|
|
|
package gnu.javax.imageio.jpeg;
|
|
|
|
/**
|
|
* Discrete Cosine Transformations.
|
|
*/
|
|
public class DCT
|
|
{
|
|
|
|
/**
|
|
* Cosine matrix
|
|
*/
|
|
public double c[][] = new double[8][8];
|
|
|
|
/**
|
|
* Transformed cosine matrix
|
|
*/
|
|
public double cT[][] = new double[8][8];
|
|
|
|
public DCT()
|
|
{
|
|
initMatrix();
|
|
}
|
|
|
|
/**
|
|
* Figure A.3.3 IDCT, Cu Cv on A-5 of the ISO DIS 10918-1. Requirements and
|
|
* Guidelines.
|
|
*
|
|
* @param u
|
|
* @return
|
|
*/
|
|
public static double C(int u)
|
|
{
|
|
return ((u == 0) ? (double) 1 / (double) Math.sqrt((double) 2)
|
|
: (double) 1);
|
|
}
|
|
|
|
/**
|
|
* Initialize matrix values for the fast_idct function
|
|
*/
|
|
private void initMatrix()
|
|
{
|
|
for (int j = 0; j < 8; j++)
|
|
{
|
|
double nn = (double) (8);
|
|
c[0][j] = 1.0 / Math.sqrt(nn);
|
|
cT[j][0] = c[0][j];
|
|
}
|
|
for (int i = 1; i < 8; i++)
|
|
{
|
|
for (int j = 0; j < 8; j++)
|
|
{
|
|
double jj = (double) j;
|
|
double ii = (double) i;
|
|
c[i][j] =
|
|
Math.sqrt(2.0 / 8.0)
|
|
* Math.cos(((2.0 * jj + 1.0) * ii * Math.PI) / (2.0 * 8.0));
|
|
cT[j][i] = c[i][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* slow_idct - Figure A.3.3 IDCT (informative) on A-5 of the ISO DIS
|
|
* 10918-1. Requirements and Guidelines. This is a slow IDCT, there are
|
|
* better algorithms to use, it's fairly expensive with processor speed.
|
|
*
|
|
* @param matrix
|
|
* @return
|
|
*/
|
|
public static double[][] slow_idct(double[][] matrix)
|
|
{
|
|
double[][] output = new double[matrix.length][matrix.length];
|
|
for (int y = 0; y < 8; y++)
|
|
{
|
|
for (int x = 0; x < 8; x++)
|
|
{
|
|
double val = 0;
|
|
for (double v = 0; v < 8; v++)
|
|
{
|
|
double innerloop = 0;
|
|
for (double u = 0; u < 8; u++)
|
|
innerloop += (DCT.C((int) u) / (double) 2)
|
|
* matrix[(int) v][(int) u]
|
|
* Math.cos((2 * x + 1) * u * Math.PI / (double) 16)
|
|
* Math.cos((2 * y + 1) * v * Math.PI / (double) 16);
|
|
val += (DCT.C((int) v) / (double) 2) * innerloop;
|
|
}
|
|
output[y][x] = (val + 128);
|
|
}
|
|
}
|
|
return (output);
|
|
}
|
|
|
|
public static float[][] slow_fdct(float[][] value)
|
|
{
|
|
float[][] buffer = new float[8][8];
|
|
|
|
for (int u = 0; u < 8; u++)
|
|
{
|
|
for (int v = 0; v < 8; v++)
|
|
{
|
|
buffer[u][v] =
|
|
(float) (1 / 4) * (float) C((int) u) * (float) C((int) v);
|
|
float innerval = 0;
|
|
for (int x = 0; x < 8; x++)
|
|
{
|
|
for (int y = 0; y < 8; y++)
|
|
{
|
|
innerval += value[y][x]
|
|
* Math.cos(((2 * x + 1) * u * Math.PI) / 16)
|
|
* Math.cos(((2 * y + 1) * v * Math.PI) / 16);
|
|
}
|
|
}
|
|
buffer[u][v] *= innerval;
|
|
}
|
|
}
|
|
return (buffer);
|
|
}
|
|
|
|
public float[][] fast_fdct(float[][] input)
|
|
{
|
|
float output[][] = new float[8][8];
|
|
double temp[][] = new double[8][8];
|
|
double temp1;
|
|
int i;
|
|
int j;
|
|
int k;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
temp[i][j] = 0.0;
|
|
for (k = 0; k < 8; k++)
|
|
{
|
|
temp[i][j] += (((int) (input[i][k]) - 128) * cT[k][j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
temp1 = 0.0;
|
|
|
|
for (k = 0; k < 8; k++)
|
|
{
|
|
temp1 += (c[i][k] * temp[k][j]);
|
|
}
|
|
|
|
output[i][j] = (int) Math.round(temp1) * 8;
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* fast_idct - Figure A.3.3 IDCT (informative) on A-5 of the ISO DIS
|
|
* 10918-1. Requires and Guidelines. This is a fast IDCT, it much more
|
|
* effecient and only inaccurate at about 1/1000th of a percent of values
|
|
* analyzed. Cannot be static because initMatrix must run before any
|
|
* fast_idct values can be computed.
|
|
*
|
|
* @param input
|
|
* @return
|
|
*/
|
|
public double[][] fast_idct(double[][] input)
|
|
{
|
|
double output[][] = new double[8][8];
|
|
double temp[][] = new double[8][8];
|
|
double temp1;
|
|
int i, j, k;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
temp[i][j] = 0.0;
|
|
for (k = 0; k < 8; k++)
|
|
{
|
|
temp[i][j] += input[i][k] * c[k][j];
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
temp1 = 0.0;
|
|
for (k = 0; k < 8; k++)
|
|
temp1 += cT[i][k] * temp[k][j];
|
|
temp1 += 128.0;
|
|
if (temp1 < 0)
|
|
output[i][j] = 0;
|
|
else if (temp1 > 255)
|
|
output[i][j] = 255;
|
|
else
|
|
output[i][j] = (int) Math.round(temp1);
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
public double[][] idj_fast_fdct(float input[][])
|
|
{
|
|
double output[][] = new double[8][8];
|
|
double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
|
double tmp10, tmp11, tmp12, tmp13;
|
|
double z1, z2, z3, z4, z5, z11, z13;
|
|
int i;
|
|
int j;
|
|
|
|
// Subtracts 128 from the input values
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
output[i][j] = ((double) input[i][j] - (double) 128.0);
|
|
// input[i][j] -= 128;
|
|
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
tmp0 = output[i][0] + output[i][7];
|
|
tmp7 = output[i][0] - output[i][7];
|
|
tmp1 = output[i][1] + output[i][6];
|
|
tmp6 = output[i][1] - output[i][6];
|
|
tmp2 = output[i][2] + output[i][5];
|
|
tmp5 = output[i][2] - output[i][5];
|
|
tmp3 = output[i][3] + output[i][4];
|
|
tmp4 = output[i][3] - output[i][4];
|
|
|
|
tmp10 = tmp0 + tmp3;
|
|
tmp13 = tmp0 - tmp3;
|
|
tmp11 = tmp1 + tmp2;
|
|
tmp12 = tmp1 - tmp2;
|
|
|
|
output[i][0] = tmp10 + tmp11;
|
|
output[i][4] = tmp10 - tmp11;
|
|
|
|
z1 = (tmp12 + tmp13) * (double) 0.707106781;
|
|
output[i][2] = tmp13 + z1;
|
|
output[i][6] = tmp13 - z1;
|
|
|
|
tmp10 = tmp4 + tmp5;
|
|
tmp11 = tmp5 + tmp6;
|
|
tmp12 = tmp6 + tmp7;
|
|
|
|
z5 = (tmp10 - tmp12) * (double) 0.382683433;
|
|
z2 = ((double) 0.541196100) * tmp10 + z5;
|
|
z4 = ((double) 1.306562965) * tmp12 + z5;
|
|
z3 = tmp11 * ((double) 0.707106781);
|
|
|
|
z11 = tmp7 + z3;
|
|
z13 = tmp7 - z3;
|
|
|
|
output[i][5] = z13 + z2;
|
|
output[i][3] = z13 - z2;
|
|
output[i][1] = z11 + z4;
|
|
output[i][7] = z11 - z4;
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
tmp0 = output[0][i] + output[7][i];
|
|
tmp7 = output[0][i] - output[7][i];
|
|
tmp1 = output[1][i] + output[6][i];
|
|
tmp6 = output[1][i] - output[6][i];
|
|
tmp2 = output[2][i] + output[5][i];
|
|
tmp5 = output[2][i] - output[5][i];
|
|
tmp3 = output[3][i] + output[4][i];
|
|
tmp4 = output[3][i] - output[4][i];
|
|
|
|
tmp10 = tmp0 + tmp3;
|
|
tmp13 = tmp0 - tmp3;
|
|
tmp11 = tmp1 + tmp2;
|
|
tmp12 = tmp1 - tmp2;
|
|
|
|
output[0][i] = tmp10 + tmp11;
|
|
output[4][i] = tmp10 - tmp11;
|
|
|
|
z1 = (tmp12 + tmp13) * (double) 0.707106781;
|
|
output[2][i] = tmp13 + z1;
|
|
output[6][i] = tmp13 - z1;
|
|
|
|
tmp10 = tmp4 + tmp5;
|
|
tmp11 = tmp5 + tmp6;
|
|
tmp12 = tmp6 + tmp7;
|
|
|
|
z5 = (tmp10 - tmp12) * (double) 0.382683433;
|
|
z2 = ((double) 0.541196100) * tmp10 + z5;
|
|
z4 = ((double) 1.306562965) * tmp12 + z5;
|
|
z3 = tmp11 * ((double) 0.707106781);
|
|
|
|
z11 = tmp7 + z3;
|
|
z13 = tmp7 - z3;
|
|
|
|
output[5][i] = z13 + z2;
|
|
output[3][i] = z13 - z2;
|
|
output[1][i] = z11 + z4;
|
|
output[7][i] = z11 - z4;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
}
|