mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 15:26:00 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
872
BeefySysLib/img/BFIData.cpp
Normal file
872
BeefySysLib/img/BFIData.cpp
Normal file
|
@ -0,0 +1,872 @@
|
|||
#include "BFIData.h"
|
||||
#include "ImageUtils.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
#define IS_ZERO(v) ((fabs(v) < 0.000000001))
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
#include <valarray>
|
||||
|
||||
const double PI = 3.141592653589793238460;
|
||||
|
||||
typedef std::complex<double> Complex;
|
||||
typedef std::valarray<Complex> CArray;
|
||||
|
||||
// Cooley<65>Tukey FFT (in-place)
|
||||
void fft(CArray& x)
|
||||
{
|
||||
const size_t N = x.size();
|
||||
if (N <= 1) return;
|
||||
|
||||
// divide
|
||||
CArray even = x[std::slice(0, N/2, 2)];
|
||||
CArray odd = x[std::slice(1, N/2, 2)];
|
||||
|
||||
// conquer
|
||||
fft(even);
|
||||
fft(odd);
|
||||
|
||||
// combine
|
||||
for (size_t k = 0; k < N/2; ++k)
|
||||
{
|
||||
Complex t = std::polar(1.0, -2 * PI * k / N) * odd[k];
|
||||
x[k ] = even[k] + t;
|
||||
x[k+N/2] = even[k] - t;
|
||||
}
|
||||
}
|
||||
|
||||
void DFTTest()
|
||||
{
|
||||
const Complex test[] = { 1.0, 2.0, 3.0, 4.0 };
|
||||
CArray data(test, sizeof(test) / sizeof(test[0]));
|
||||
|
||||
fft(data);
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Perform a 2D FFT inplace given a complex 2D array
|
||||
The direction dir, 1 for forward, -1 for reverse
|
||||
The size of the array (nx,ny)
|
||||
Return false if there are memory problems or
|
||||
the dimensions are not powers of 2
|
||||
*/
|
||||
|
||||
class COMPLEX
|
||||
{
|
||||
public:
|
||||
double real;
|
||||
double imag;
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
This computes an in-place complex-to-complex FFT
|
||||
x and y are the real and imaginary arrays of 2^m points.
|
||||
dir = 1 gives forward transform
|
||||
dir = -1 gives reverse transform
|
||||
|
||||
Formula: forward
|
||||
N-1
|
||||
---
|
||||
1 \ - j k 2 pi n / N
|
||||
X(n) = --- > x(k) e = forward transform
|
||||
N / n=0..N-1
|
||||
---
|
||||
k=0
|
||||
|
||||
Formula: reverse
|
||||
N-1
|
||||
---
|
||||
\ j k 2 pi n / N
|
||||
X(n) = > x(k) e = forward transform
|
||||
/ n=0..N-1
|
||||
---
|
||||
k=0
|
||||
*/
|
||||
int FFT(int dir,int m,double *x,double *y)
|
||||
{
|
||||
long nn,i,i1,j,k,i2,l,l1,l2;
|
||||
double c1,c2,tx,ty,t1,t2,u1,u2,z;
|
||||
|
||||
/* Calculate the number of points */
|
||||
nn = 1;
|
||||
for (i=0;i<m;i++)
|
||||
nn *= 2;
|
||||
|
||||
/* Do the bit reversal */
|
||||
i2 = nn >> 1;
|
||||
j = 0;
|
||||
for (i=0;i<nn-1;i++) {
|
||||
if (i < j) {
|
||||
tx = x[i];
|
||||
ty = y[i];
|
||||
x[i] = x[j];
|
||||
y[i] = y[j];
|
||||
x[j] = tx;
|
||||
y[j] = ty;
|
||||
}
|
||||
k = i2;
|
||||
while (k <= j) {
|
||||
j -= k;
|
||||
k >>= 1;
|
||||
}
|
||||
j += k;
|
||||
}
|
||||
|
||||
/* Compute the FFT */
|
||||
c1 = -1.0;
|
||||
c2 = 0.0;
|
||||
l2 = 1;
|
||||
for (l=0;l<m;l++) {
|
||||
l1 = l2;
|
||||
l2 <<= 1;
|
||||
u1 = 1.0;
|
||||
u2 = 0.0;
|
||||
for (j=0;j<l1;j++) {
|
||||
for (i=j;i<nn;i+=l2) {
|
||||
i1 = i + l1;
|
||||
t1 = u1 * x[i1] - u2 * y[i1];
|
||||
t2 = u1 * y[i1] + u2 * x[i1];
|
||||
x[i1] = x[i] - t1;
|
||||
y[i1] = y[i] - t2;
|
||||
x[i] += t1;
|
||||
y[i] += t2;
|
||||
}
|
||||
z = u1 * c1 - u2 * c2;
|
||||
u2 = u1 * c2 + u2 * c1;
|
||||
u1 = z;
|
||||
}
|
||||
c2 = sqrt((1.0 - c1) / 2.0);
|
||||
if (dir == 1)
|
||||
c2 = -c2;
|
||||
c1 = sqrt((1.0 + c1) / 2.0);
|
||||
}
|
||||
|
||||
/* Scaling for forward transform */
|
||||
if (dir == 1) {
|
||||
for (i=0;i<nn;i++) {
|
||||
x[i] /= (double)nn;
|
||||
y[i] /= (double)nn;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class BFComplex
|
||||
{
|
||||
public:
|
||||
double mR;
|
||||
double mI;
|
||||
|
||||
public:
|
||||
BFComplex(double r = 0, double i = 0)
|
||||
{
|
||||
mR = r;
|
||||
mI = i;
|
||||
}
|
||||
|
||||
BFComplex operator +(const BFComplex& complex) const
|
||||
{
|
||||
return BFComplex(mR + complex.mR, mI + complex.mI);
|
||||
}
|
||||
|
||||
BFComplex& operator +=(const BFComplex& complex)
|
||||
{
|
||||
*this = BFComplex(mR + complex.mR, mI + complex.mI);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BFComplex operator *(const BFComplex& complex) const
|
||||
{
|
||||
return BFComplex(mR * complex.mR - mI * complex.mI, mR * complex.mI + mI * complex.mR);
|
||||
}
|
||||
|
||||
BFComplex operator *(double scalar) const
|
||||
{
|
||||
return BFComplex(mR * scalar, mI * scalar);
|
||||
}
|
||||
|
||||
double Magnitude()
|
||||
{
|
||||
return sqrt(mR * mR + mI * mI);
|
||||
}
|
||||
|
||||
double Phase()
|
||||
{
|
||||
return atan2(mI, mR);
|
||||
}
|
||||
|
||||
String ToString()
|
||||
{
|
||||
if (fabs(mI) < 0.00000001)
|
||||
{
|
||||
if (fabs(mR) < 0.00000001)
|
||||
return StrFormat("%f", 0.0);
|
||||
return StrFormat("%f", mR);
|
||||
}
|
||||
if (mI > 0)
|
||||
return StrFormat("%f + %fi", mR, mI);
|
||||
return StrFormat("%f - %fi", mR, -mI);
|
||||
}
|
||||
|
||||
static BFComplex Polar(double scalar, double angle)
|
||||
{
|
||||
return BFComplex(scalar * cos(angle), scalar * sin(angle));
|
||||
}
|
||||
};
|
||||
|
||||
bool Powerof2(int num, int* power, int* twoPM)
|
||||
{
|
||||
*power = 0;
|
||||
*twoPM = 1;
|
||||
while (*twoPM < num)
|
||||
{
|
||||
*twoPM *= 2;
|
||||
(*power)++;
|
||||
}
|
||||
|
||||
return *twoPM == num;
|
||||
}
|
||||
|
||||
int FFT2D(BFComplex **c,int nx,int ny,int dir)
|
||||
{
|
||||
int i,j;
|
||||
int m,twopm;
|
||||
double *real,*imag;
|
||||
|
||||
|
||||
/* Transform the rows */
|
||||
real = (double *)malloc(nx * sizeof(double));
|
||||
imag = (double *)malloc(nx * sizeof(double));
|
||||
if (real == NULL || imag == NULL)
|
||||
return(false);
|
||||
if (!Powerof2(nx,&m,&twopm) || twopm != nx)
|
||||
return(false);
|
||||
for (j=0;j<ny;j++) {
|
||||
for (i=0;i<nx;i++) {
|
||||
real[i] = c[i][j].mR;
|
||||
imag[i] = c[i][j].mI;
|
||||
}
|
||||
FFT(dir,m,real,imag);
|
||||
for (i=0;i<nx;i++) {
|
||||
c[i][j].mR = real[i];
|
||||
c[i][j].mI = imag[i];
|
||||
}
|
||||
}
|
||||
free(real);
|
||||
free(imag);
|
||||
|
||||
/* Transform the columns */
|
||||
real = (double *)malloc(ny * sizeof(double));
|
||||
imag = (double *)malloc(ny * sizeof(double));
|
||||
if (real == NULL || imag == NULL)
|
||||
return(false);
|
||||
if (!Powerof2(ny,&m,&twopm) || twopm != ny)
|
||||
return(false);
|
||||
for (i=0;i<nx;i++) {
|
||||
for (j=0;j<ny;j++) {
|
||||
real[j] = c[i][j].mR;
|
||||
imag[j] = c[i][j].mI;
|
||||
}
|
||||
FFT(dir,m,real,imag);
|
||||
for (j=0;j<ny;j++) {
|
||||
c[i][j].mR = real[j];
|
||||
c[i][j].mI = imag[j];
|
||||
}
|
||||
}
|
||||
free(real);
|
||||
free(imag);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
void DFTTest_2D()
|
||||
{
|
||||
BFComplex** test = new BFComplex*[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
test[i] = new BFComplex[4];
|
||||
for (int j = 0; j < 4; j++)
|
||||
test[i][j].mR = i*4+j+1;
|
||||
}
|
||||
|
||||
/*std::wstring aString;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
aString += L"(";
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (j != 0)
|
||||
aString += L", ";
|
||||
aString += test[i][j].ToString();
|
||||
}
|
||||
aString += L")\n";
|
||||
}
|
||||
OutputDebugStringW(aString.c_str());*/
|
||||
|
||||
/*[][3] =
|
||||
{{1.0, 2.0, 3.0},
|
||||
{4.0, 5.0, 6.0},
|
||||
{7.0, 8.0, 9.0}};*/
|
||||
|
||||
FFT2D(test, 4, 4, -1);
|
||||
|
||||
String aString;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
aString += "(";
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (j != 0)
|
||||
aString += ", ";
|
||||
aString += test[i][j].ToString();
|
||||
}
|
||||
aString += ")\n";
|
||||
}
|
||||
BfpOutput_DebugString(aString.c_str());
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PrintComplex2D(BFComplex* ptr, int cols, int rows)
|
||||
{
|
||||
String aString = "(\n";
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
aString += "\t(";
|
||||
for (int j = 0; j < cols; j++)
|
||||
{
|
||||
if (j != 0)
|
||||
aString += ", ";
|
||||
aString += ptr[i*cols+j].ToString();
|
||||
}
|
||||
aString += ")\n";
|
||||
}
|
||||
aString += ")\n";
|
||||
BfpOutput_DebugString(aString.c_str());
|
||||
}
|
||||
|
||||
|
||||
void FFD_1D(BFComplex* array, int size, int pitch, int aDir)
|
||||
{
|
||||
BFComplex* prev = new BFComplex[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i*pitch];
|
||||
|
||||
for (int idxOut = 0; idxOut < size; idxOut++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int idxIn = 0; idxIn < size; idxIn++)
|
||||
val += prev[idxIn] * BFComplex::Polar(1.0, aDir * 2 * BF_PI_D * idxIn * idxOut / (double) size);
|
||||
if (aDir == 1)
|
||||
val = val * BFComplex(1.0/size);
|
||||
array[idxOut*pitch] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void DFTTest_Mine()
|
||||
{
|
||||
BFComplex test[] =
|
||||
{ 1.0, 2.0, 3.0, 4.0,
|
||||
5.0, 6.0, 7.0, 8.0,
|
||||
9.0, 10.0, 11.0, 12.0,
|
||||
13.0, 14.0, 15.0, 16.0};
|
||||
|
||||
int aCols = 4;
|
||||
int aRows = 4;
|
||||
|
||||
/*std::vector<BFComplex> outR;
|
||||
|
||||
for (int row = 0; row < aRows; row++)
|
||||
{
|
||||
for (int colOut = 0; colOut < aCols; colOut++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int colIn = 0; colIn < aCols; colIn++)
|
||||
val += test[row*aCols+colIn] * BFComplex::Polar(1.0, - 2 * BF_PI_D * colIn * colOut / (double) aCols);
|
||||
outR.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
PrintComplex2D(&outR.front(), aCols, aRows);
|
||||
std::vector<BFComplex> outC;
|
||||
outC.insert(outC.begin(), aCols*aRows, BFComplex());
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
{
|
||||
for (int rowOut = 0; rowOut < aRows; rowOut++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int rowIn = 0; rowIn < aRows; rowIn++)
|
||||
val += outR[rowIn*aCols+col] * BFComplex::Polar(1.0, - 2 * BF_PI_D * rowIn * rowOut / (double) aRows);
|
||||
//outC.push_back(val);
|
||||
outC[rowOut*aCols+col] = val;
|
||||
}
|
||||
}*/
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
FFD_1D(test + col, aRows, aCols, -1);
|
||||
PrintComplex2D(test, aRows, aCols);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
FFD_1D(test + row*aCols, aCols, 1, -1);
|
||||
PrintComplex2D(test, aRows, aCols);
|
||||
|
||||
/*std::vector<BFComplex> outC;
|
||||
outC.insert(outC.begin(), aRows*aCols, BFComplex());
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
{
|
||||
for (int rowOut = 0; rowOut < aRows; rowOut++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int rowIn = 0; rowIn < aRows; rowIn++)
|
||||
val += test[rowIn*aCols+col] * BFComplex::Polar(1.0, - 2 * BF_PI_D * rowIn * rowOut / (double) aRows);
|
||||
outC[rowOut*aCols+col] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PrintComplex2D(&outC.front(), aRows, aCols);
|
||||
std::vector<BFComplex> outR;
|
||||
outR.insert(outR.begin(), aRows*aCols, BFComplex());
|
||||
|
||||
for (int row = 0; row < aRows; row++)
|
||||
{
|
||||
for (int colOut = 0; colOut < aCols; colOut++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int colIn = 0; colIn < aCols; colIn++)
|
||||
val += outC[row*aCols+colIn] * BFComplex::Polar(1.0, - 2 * BF_PI_D * colIn * colOut / (double) aCols);
|
||||
//outC.push_back(val);
|
||||
outR[row*aCols+colOut] = val;
|
||||
}
|
||||
}
|
||||
|
||||
PrintComplex2D(&outR.front(), aRows, aCols);*/
|
||||
|
||||
/*int N = sizeof(test) / sizeof(test[0]);
|
||||
|
||||
std::vector<BFComplex> out;
|
||||
std::vector<BFComplex> invOut;
|
||||
|
||||
BFComplex _a = BFComplex::Polar(1.0, 0.5f) * BFComplex::Polar(1.0, 2.01f);
|
||||
|
||||
for (int k = 0; k < N; k++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int n = 0; n < N; n++)
|
||||
val += test[n] * BFComplex::Polar(1.0, - 2 * BF_PI_D * k * n / (double) N);
|
||||
out.push_back(val);
|
||||
}
|
||||
|
||||
for (int n = 0; n < N; n++)
|
||||
{
|
||||
BFComplex val;
|
||||
for (int k = 0; k < N; k++)
|
||||
val += out[k] * BFComplex::Polar(1.0, 2 * BF_PI_D * k * n / (double) N);
|
||||
invOut.push_back(BFComplex(1.0/N) * val);
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FFTShift1D(BFComplex* array, int size, int pitch, int dir)
|
||||
{
|
||||
BFComplex* prev = new BFComplex[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i * pitch];
|
||||
|
||||
while (dir < 0)
|
||||
dir += size;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i * pitch] = prev[((i + dir) % size)];
|
||||
|
||||
delete prev;
|
||||
}
|
||||
|
||||
static void FFTShift2D(BFComplex* data, int cols, int rows)
|
||||
{
|
||||
for (int col = 0; col < cols; col++)
|
||||
FFTShift1D(data + col, rows, cols, cols / 2);
|
||||
for (int row = 0; row < rows; row++)
|
||||
FFTShift1D(data + row*cols, cols, 1, rows / 2);
|
||||
}
|
||||
|
||||
static void FFTConvert(ImageData* source)
|
||||
{
|
||||
int aCols = source->mWidth;
|
||||
int aRows = source->mHeight;
|
||||
int count = aCols * aRows;
|
||||
BFComplex* nums = new BFComplex[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
PackedColor& color = *((PackedColor*) &source->mBits[i]);
|
||||
nums[i].mR = PackedColorGetGray()(color);
|
||||
}
|
||||
|
||||
//FFT
|
||||
for (int col = 0; col < aCols; col++)
|
||||
FFD_1D(nums + col, aRows, aCols, -1);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
FFD_1D(nums + row*aCols, aCols, 1, -1);
|
||||
|
||||
//INV FFT
|
||||
/*for (int col = 0; col < aCols; col++)
|
||||
FFD_1D(nums + col, aRows, aCols, 1);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
FFD_1D(nums + row*aCols, aCols, 1, 1);*/
|
||||
|
||||
FFTShift2D(nums, aCols, aRows);
|
||||
|
||||
double* fFTLog = new double[count];
|
||||
double maxLog = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
double aLog = log(1 + nums[i].Magnitude());
|
||||
maxLog = std::max(maxLog, aLog);
|
||||
fFTLog[i] = aLog;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//int val = (int) nums[i].Magnitude() / 1;
|
||||
int val = (int) (fFTLog[i] * 255 / maxLog);
|
||||
val = std::min(255, std::max(0, val));
|
||||
|
||||
source->mBits[i] = 0xFF000000 | val | (val << 8) | (val << 16);
|
||||
}
|
||||
|
||||
delete fFTLog;
|
||||
delete [] nums;
|
||||
}
|
||||
|
||||
void DCT_1D(double* array, int size, int pitch)
|
||||
{
|
||||
double* prev = new double[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i*pitch];
|
||||
|
||||
for (int idxOut = 0; idxOut < size; idxOut++)
|
||||
{
|
||||
double val = 0;
|
||||
double scale = (idxOut == 0) ? 1/sqrt(2.0) : 1;
|
||||
|
||||
for (int idxIn = 0; idxIn < size; idxIn++)
|
||||
val += prev[idxIn] * cos(idxOut * BF_PI * (2*idxIn + 1)/(2 * size));
|
||||
array[idxOut*pitch] = 0.5 * scale * val;
|
||||
}
|
||||
|
||||
delete prev;
|
||||
}
|
||||
|
||||
void IDCT_1D(double* array, int size, int pitch)
|
||||
{
|
||||
double* prev = new double[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i*pitch];
|
||||
|
||||
for (int idxOut = 0; idxOut < size; idxOut++)
|
||||
{
|
||||
double val = 0;
|
||||
for (int idxIn = 0; idxIn < size; idxIn++)
|
||||
{
|
||||
double scale = (idxIn == 0) ? 1/sqrt(2.0) : 1;
|
||||
val += scale * prev[idxIn] * cos(idxIn * BF_PI * (2*idxOut + 1)/(2 * size));
|
||||
}
|
||||
array[idxOut*pitch] = 0.5 * val;
|
||||
}
|
||||
|
||||
delete prev;
|
||||
}
|
||||
|
||||
const int DCT_1D_I_TABLE[64] =
|
||||
{
|
||||
4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
|
||||
4017, 3405, 2275, 799, -799, -2275, -3405, -4017,
|
||||
3784, 1567, -1567, -3784, -3784, -1567, 1567, 3784,
|
||||
3405, -799, -4017, -2275, 2275, 4017, 799, -3405,
|
||||
2896, -2896, -2896, 2896, 2896, -2896, -2896, 2896,
|
||||
2275, -4017, 799, 3405, -3405, -799, 4017, -2275,
|
||||
1567, -3784, 3784, -1567, -1567, 3784, -3784, 1567,
|
||||
799, -2275, 3405, -4017, 4017, -3405, 2275, -799
|
||||
};
|
||||
|
||||
void DCT_1D_I(int* array, int size, int pitch)
|
||||
{
|
||||
int* prev = new int[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i*pitch];
|
||||
|
||||
int multIdx = 0;
|
||||
for (int idxOut = 0; idxOut < size; idxOut++)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
for (int idxIn = 0; idxIn < size; idxIn++)
|
||||
val += prev[idxIn] * DCT_1D_I_TABLE[multIdx++];
|
||||
|
||||
if (idxOut == 0)
|
||||
array[idxOut*pitch] = val / 0x2d41;
|
||||
else
|
||||
array[idxOut*pitch] = val / 0x2000;
|
||||
|
||||
}
|
||||
|
||||
delete prev;
|
||||
}
|
||||
|
||||
const int IDCT_1D_I_TABLE[64] =
|
||||
{
|
||||
2896, 4017, 3784, 3405, 2896, 2275, 1567, 799,
|
||||
2896, 3405, 1567, -799, -2896, -4017, -3784, -2275,
|
||||
2896, 2275, -1567, -4017, -2896, 799, 3784, 3405,
|
||||
2896, 799, -3784, -2275, 2896, 3405, -1567, -4017,
|
||||
2896, -799, -3784, 2275, 2896, -3405, -1567, 4017,
|
||||
2896, -2275, -1567, 4017, -2896, -799, 3784, -3405,
|
||||
2896, -3405, 1567, 799, -2896, 4017, -3784, 2275,
|
||||
2896, -4017, 3784, -3405, 2896, -2275, 1567, -799
|
||||
};
|
||||
|
||||
void IDCT_1D_I(int* array, int size, int pitch)
|
||||
{
|
||||
int prev[64];
|
||||
for (int i = 0; i < size; i++)
|
||||
prev[i] = array[i*pitch];
|
||||
|
||||
int multIdx = 0;
|
||||
for (int idxOut = 0; idxOut < size; idxOut++)
|
||||
{
|
||||
int val = 0;
|
||||
for (int idxIn = 0; idxIn < size; idxIn++)
|
||||
val += prev[idxIn] * IDCT_1D_I_TABLE[multIdx++];
|
||||
array[idxOut*pitch] = val / 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
void BFIData::Compress(ImageData* source)
|
||||
{
|
||||
/*DFTTest();
|
||||
DFTTest_2D();
|
||||
DFTTest_Mine();*/
|
||||
|
||||
//FFTConvert(source);
|
||||
|
||||
/*const int rowCount = 3;
|
||||
const int colCount = 4;
|
||||
|
||||
double mat[rowCount][colCount] = {{2, 2, 5, 5}, {4, 4, 10, 11}, {3, 2, 6, 4}};
|
||||
double rightVals[rowCount] = {1, 2, 3};
|
||||
int pivotIdx[colCount] = {-1, -1, -1, -1};
|
||||
|
||||
int moveIdx = 0;
|
||||
|
||||
|
||||
double pivotVals[colCount] = {0};
|
||||
|
||||
for (int pivot = 0; pivot < colCount; pivot++)
|
||||
{
|
||||
bool moved = false;
|
||||
|
||||
for (int eq = moveIdx; eq < rowCount; eq++)
|
||||
{
|
||||
if (!IS_ZERO(mat[eq][pivot]))
|
||||
{
|
||||
pivotVals[pivot] = mat[eq][pivot];
|
||||
for (int swapIdx = 0; swapIdx < colCount; swapIdx++)
|
||||
std::swap(mat[eq][swapIdx], mat[moveIdx][swapIdx]);
|
||||
std::swap(rightVals[eq], rightVals[moveIdx]);
|
||||
pivotIdx[pivot] = moveIdx;
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!moved)
|
||||
continue;
|
||||
|
||||
for (int eq = moveIdx + 1; eq < rowCount; eq++)
|
||||
{
|
||||
double multFactor = -mat[eq][pivot] / mat[moveIdx][pivot];
|
||||
bool nonZero = false;
|
||||
for (int multIdx = pivot; multIdx < colCount; multIdx++)
|
||||
{
|
||||
mat[eq][multIdx] += mat[moveIdx][multIdx]*multFactor;
|
||||
nonZero |= !IS_ZERO(mat[eq][multIdx]);
|
||||
}
|
||||
rightVals[eq] += rightVals[moveIdx]*multFactor;
|
||||
BF_ASSERT(IS_ZERO(rightVals[eq]) || (nonZero));
|
||||
}
|
||||
|
||||
moveIdx++;
|
||||
}
|
||||
|
||||
// Back substitute
|
||||
double result[colCount];
|
||||
for (int col = colCount - 1; col >= 0; col--)
|
||||
{
|
||||
result[col] = 0;
|
||||
if (pivotIdx[col] != -1)
|
||||
{
|
||||
int eq = pivotIdx[col];
|
||||
double left = 0;
|
||||
for (int multCol = col + 1; multCol < colCount; multCol++)
|
||||
left += mat[eq][multCol] * result[multCol];
|
||||
double right = rightVals[eq] - left;
|
||||
right /= mat[eq][col];
|
||||
result[col] = right;
|
||||
}
|
||||
}
|
||||
|
||||
///*/
|
||||
|
||||
|
||||
uint8 rawData[64] = {
|
||||
52, 55, 61, 66, 70, 61, 64, 73,
|
||||
63, 59, 55, 90,109, 85, 69, 72,
|
||||
62, 59, 68,113,144,104, 66, 73,
|
||||
63, 58, 71,122,154,106, 70, 69,
|
||||
67, 61, 68,104,126, 88, 68, 70,
|
||||
79, 65, 60, 70, 77, 68, 58, 75,
|
||||
85, 71, 64, 59, 55, 61, 65, 83,
|
||||
87, 79, 69, 68, 65, 76, 78, 94};
|
||||
|
||||
double dCTIn[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
dCTIn[i] = (int) rawData[i] - 128;
|
||||
|
||||
//double dCTOut[64];
|
||||
|
||||
/*for (int v = 0; v < 8; v++)
|
||||
{
|
||||
for (int u = 0; u < 8; u++)
|
||||
{
|
||||
dCTOut[u+v*8] = 0;
|
||||
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
double au = (u == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
|
||||
double av = (v == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
|
||||
dCTOut[u+v*8] += au*av*dCTIn[x+y*8]*
|
||||
cos(BF_PI_D/8 * (x + 0.5)*u) *
|
||||
cos(BF_PI_D/8 * (y + 0.5)*v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
double dCT[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
dCT[i] = rawData[i] - 128;
|
||||
|
||||
int aCols = 8;
|
||||
int aRows = 8;
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
DCT_1D(dCT + col, aRows, aCols);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
DCT_1D(dCT + row*aCols, aCols, 1);
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
IDCT_1D(dCT + col, aRows, aCols);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
IDCT_1D(dCT + row*aCols, aCols, 1);
|
||||
|
||||
//
|
||||
|
||||
int dCT_I[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
dCT_I[i] = (rawData[i] - 128) * 256;
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
DCT_1D_I(dCT_I + col, aRows, aCols);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
DCT_1D_I(dCT_I + row*aCols, aCols, 1);
|
||||
|
||||
for (int col = 0; col < aCols; col++)
|
||||
IDCT_1D_I(dCT_I + col, aRows, aCols);
|
||||
for (int row = 0; row < aRows; row++)
|
||||
IDCT_1D_I(dCT_I + row*aCols, aCols, 1);
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
int val = dCT_I[i];
|
||||
if (val < 0)
|
||||
dCT_I[i] = (val - 128) / 256;
|
||||
else
|
||||
dCT_I[i] = (val + 128) / 256;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
int quantTable[] = {16, 11, 11, 16, 23, 27, 31, 30, 11, 12, 12, 15, 20, 23, 23, 30,
|
||||
11, 12, 13, 16, 23, 26, 35, 47, 16, 15, 16, 23, 26, 37, 47, 64,
|
||||
23, 20, 23, 26, 39, 51, 64, 64, 27, 23, 26, 37, 51, 64, 64, 64,
|
||||
31, 23, 35, 47, 64, 64, 64, 64, 30, 30, 47, 64, 64, 64, 64, 64};
|
||||
|
||||
int quantDCT[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
quantDCT[i] = (int) BFRound((float) (dCT[i] / quantTable[i]));
|
||||
|
||||
int zigZag[64] = {
|
||||
0, 1, 5, 6, 14, 15, 27, 28,
|
||||
2, 4, 7, 13, 16, 26, 29, 42,
|
||||
3, 8, 12, 17, 25, 30, 41, 43,
|
||||
9, 11, 18, 24, 31, 40, 44, 53,
|
||||
10, 19, 23, 32, 39, 45, 52, 54,
|
||||
20, 22, 33, 38, 46, 51, 55, 60,
|
||||
21, 34, 37, 47, 50, 56, 59, 61,
|
||||
35, 36, 48, 49, 57, 58, 62, 63
|
||||
};
|
||||
|
||||
int zigZagDCT[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
zigZagDCT[i] = quantDCT[zigZag[i]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*double dCTOutH[64];
|
||||
double dCTOutV[64];
|
||||
|
||||
for (int v = 0; v < 8; v++)
|
||||
{
|
||||
for (int u = 0; u < 8; u++)
|
||||
{
|
||||
dCTOutV[u+v*8] = 0;
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
double av = (v == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
|
||||
dCTOutV[u+v*8] += av*dCTIn[u+y*8]*
|
||||
cos(BF_PI_D/8 * (y + 0.5)*v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int v = 0; v < 8; v++)
|
||||
{
|
||||
for (int u = 0; u < 8; u++)
|
||||
{
|
||||
dCTOutH[u+v*8] = 0;
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
double au = (u == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
|
||||
dCTOutH[u+v*8] += au*dCTOutV[x+v*8]*
|
||||
cos(BF_PI_D/8 * (x + 0.5)*u);
|
||||
}
|
||||
|
||||
//dCTOut[u+v*8] = val;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue