mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-30 17:05:37 +08:00
added broken implementation of ERI lossy images.
also reorganized Entis-related classes and enums. static math methods moved to separate static class.
This commit is contained in:
parent
8d8dae710d
commit
6a89368023
@ -66,6 +66,7 @@
|
|||||||
<Compile Include="Abel\ImageGPS.cs" />
|
<Compile Include="Abel\ImageGPS.cs" />
|
||||||
<Compile Include="Actgs\ArcDAT.cs" />
|
<Compile Include="Actgs\ArcDAT.cs" />
|
||||||
<Compile Include="ArcCG.cs" />
|
<Compile Include="ArcCG.cs" />
|
||||||
|
<Compile Include="Entis\ErisaMatrix.cs" />
|
||||||
<Compile Include="ImageLZ.cs" />
|
<Compile Include="ImageLZ.cs" />
|
||||||
<Compile Include="NitroPlus\ArcNPK.cs" />
|
<Compile Include="NitroPlus\ArcNPK.cs" />
|
||||||
<Compile Include="SimpleEncryption.cs" />
|
<Compile Include="SimpleEncryption.cs" />
|
||||||
|
@ -115,7 +115,7 @@ namespace GameRes.Formats.Entis
|
|||||||
var earc = (EriMultiImage)arc;
|
var earc = (EriMultiImage)arc;
|
||||||
var eent = (EriEntry)entry;
|
var eent = (EriEntry)entry;
|
||||||
var pixels = earc.GetFrame (eent.FrameIndex);
|
var pixels = earc.GetFrame (eent.FrameIndex);
|
||||||
if (32 == earc.Info.BPP && 0 == (earc.Info.FormatType & (int)EriImage.WithAlpha))
|
if (32 == earc.Info.BPP && 0 == (earc.Info.FormatType & EriType.WithAlpha))
|
||||||
{
|
{
|
||||||
for (int p = 3; p < pixels.Length; p += 4)
|
for (int p = 3; p < pixels.Length; p += 4)
|
||||||
pixels[p] = 0xFF;
|
pixels[p] = 0xFF;
|
||||||
|
File diff suppressed because it is too large
Load Diff
488
ArcFormats/Entis/ErisaMatrix.cs
Normal file
488
ArcFormats/Entis/ErisaMatrix.cs
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
//! \file ErisaMatrix.cs
|
||||||
|
//! \date Fri Feb 26 01:12:26 2016
|
||||||
|
//! \brief Erisa Library math methods.
|
||||||
|
//
|
||||||
|
// *****************************************************************************
|
||||||
|
// E R I S A - L i b r a r y
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2000-2004 Leshade Entis. All rights reserved.
|
||||||
|
// *****************************************************************************/
|
||||||
|
//
|
||||||
|
// C# port by morkt
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using GameRes.Utility;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.Entis
|
||||||
|
{
|
||||||
|
internal static class Erisa
|
||||||
|
{
|
||||||
|
public const int MIN_DCT_DEGREE = 2;
|
||||||
|
public const int MAX_DCT_DEGREE = 12;
|
||||||
|
|
||||||
|
static readonly float ERI_rCosPI4 = (float)Math.Cos (Math.PI / 4);
|
||||||
|
static readonly float ERI_r2CosPI4 = 2 * ERI_rCosPI4;
|
||||||
|
static readonly float[] ERI_DCTofK2 = new float[2];
|
||||||
|
|
||||||
|
static readonly float[][] ERI_pMatrixDCTofK = new float[MAX_DCT_DEGREE][]
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
ERI_DCTofK2, // = cos( (2*i+1) / 8 )
|
||||||
|
new float[4], // = cos( (2*i+1) / 16 )
|
||||||
|
new float[8], // = cos( (2*i+1) / 32 )
|
||||||
|
new float[16], // = cos( (2*i+1) / 64 )
|
||||||
|
new float[32], // = cos( (2*i+1) / 128 )
|
||||||
|
new float[64], // = cos( (2*i+1) / 256 )
|
||||||
|
new float[128], // = cos( (2*i+1) / 512 )
|
||||||
|
new float[256], // = cos( (2*i+1) / 1024 )
|
||||||
|
new float[512], // = cos( (2*i+1) / 2048 )
|
||||||
|
new float[1024], // = cos( (2*i+1) / 4096 )
|
||||||
|
new float[2048], // = cos( (2*i+1) / 8192 )
|
||||||
|
};
|
||||||
|
|
||||||
|
static Erisa ()
|
||||||
|
{
|
||||||
|
InitializeMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeMatrix ()
|
||||||
|
{
|
||||||
|
for (int i = 1; i < MAX_DCT_DEGREE; i++)
|
||||||
|
{
|
||||||
|
int n = (1 << i);
|
||||||
|
float[] pDCTofK = ERI_pMatrixDCTofK[i];
|
||||||
|
double nr = Math.PI / (4.0 * n);
|
||||||
|
double dr = nr + nr;
|
||||||
|
double ir = nr;
|
||||||
|
for (int j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
pDCTofK[j] = (float)Math.Cos (ir);
|
||||||
|
ir += dr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RoundR32ToWordArray (byte[] ptrDst, int dst, int nStep, float[] ptrSrc, int nCount)
|
||||||
|
{
|
||||||
|
nStep *= 2;
|
||||||
|
for (int i = 0; i < nCount; i++)
|
||||||
|
{
|
||||||
|
int nValue = RoundR32ToInt (ptrSrc[i]);
|
||||||
|
if (nValue <= -0x8000)
|
||||||
|
{
|
||||||
|
LittleEndian.Pack ((short)-0x8000, ptrDst, dst);
|
||||||
|
}
|
||||||
|
else if (nValue >= 0x7FFF)
|
||||||
|
{
|
||||||
|
LittleEndian.Pack ((short)0x7FFF, ptrDst, dst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LittleEndian.Pack ((short)nValue, ptrDst, dst);
|
||||||
|
}
|
||||||
|
dst += nStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int RoundR32ToInt (float r)
|
||||||
|
{
|
||||||
|
if (r >= 0.0)
|
||||||
|
return (int)Math.Floor (r + 0.5);
|
||||||
|
else
|
||||||
|
return (int)Math.Ceiling (r - 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EriSinCos[] CreateRevolveParameter (int nDegreeDCT)
|
||||||
|
{
|
||||||
|
int nDegreeNum = 1 << nDegreeDCT;
|
||||||
|
int lc = 1;
|
||||||
|
for (int n = nDegreeNum / 2; n >= 8; n /= 8)
|
||||||
|
{
|
||||||
|
++lc;
|
||||||
|
}
|
||||||
|
EriSinCos[] ptrRevolve = new EriSinCos[lc*8];
|
||||||
|
|
||||||
|
double k = Math.PI / (nDegreeNum * 2);
|
||||||
|
int ptrNextRev = 0;
|
||||||
|
int nStep = 2;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
double ws = 1.0;
|
||||||
|
double a = 0.0;
|
||||||
|
for (int j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
a += nStep;
|
||||||
|
ws = ws * ptrRevolve[ptrNextRev+j].rSin + ptrRevolve[ptrNextRev+j].rCos * Math.Cos (a * k);
|
||||||
|
}
|
||||||
|
double r = Math.Atan2 (ws, Math.Cos ((a + nStep) * k));
|
||||||
|
ptrRevolve[ptrNextRev+i].rSin = (float)Math.Sin (r);
|
||||||
|
ptrRevolve[ptrNextRev+i].rCos = (float)Math.Cos (r);
|
||||||
|
}
|
||||||
|
ptrNextRev += 7;
|
||||||
|
nStep *= 8;
|
||||||
|
}
|
||||||
|
while (nStep < nDegreeNum);
|
||||||
|
return ptrRevolve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OddGivensInverseMatrix (float[] ptrSrc, int src, EriSinCos[] ptrRevolve, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
int nDegreeNum = 1 << nDegreeDCT;
|
||||||
|
int index = 1;
|
||||||
|
int nStep = 2;
|
||||||
|
int lc = (nDegreeNum / 2) / 8;
|
||||||
|
int resolve_idx = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
resolve_idx += 7;
|
||||||
|
index += nStep * 7;
|
||||||
|
nStep *= 8;
|
||||||
|
if (lc <= 8)
|
||||||
|
break;
|
||||||
|
lc /= 8;
|
||||||
|
}
|
||||||
|
int k = index + nStep * (lc - 2);
|
||||||
|
int j;
|
||||||
|
float r1, r2;
|
||||||
|
for (j = lc - 2; j >= 0; j--)
|
||||||
|
{
|
||||||
|
r1 = ptrSrc[src + k];
|
||||||
|
r2 = ptrSrc[src + k + nStep];
|
||||||
|
ptrSrc[src + k] = r1 * ptrRevolve[resolve_idx+j].rCos + r2 * ptrRevolve[resolve_idx+j].rSin;
|
||||||
|
ptrSrc[src + k + nStep] = r2 * ptrRevolve[resolve_idx+j].rCos - r1 * ptrRevolve[resolve_idx+j].rSin;
|
||||||
|
k -= nStep;
|
||||||
|
}
|
||||||
|
for (; lc <= (nDegreeNum / 2) / 8; lc *= 8)
|
||||||
|
{
|
||||||
|
resolve_idx -= 7;
|
||||||
|
nStep /= 8;
|
||||||
|
index -= nStep * 7;
|
||||||
|
for (int i = 0; i < lc; i++)
|
||||||
|
{
|
||||||
|
k = i * (nStep * 8) + index + nStep * 6;
|
||||||
|
for ( j = 6; j >= 0; j -- )
|
||||||
|
{
|
||||||
|
r1 = ptrSrc[src + k];
|
||||||
|
r2 = ptrSrc[src + k + nStep];
|
||||||
|
ptrSrc[src + k] =
|
||||||
|
r1 * ptrRevolve[resolve_idx+j].rCos + r2 * ptrRevolve[resolve_idx+j].rSin;
|
||||||
|
ptrSrc[src + k + nStep] =
|
||||||
|
r2 * ptrRevolve[resolve_idx+j].rCos - r1 * ptrRevolve[resolve_idx+j].rSin;
|
||||||
|
k -= nStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastIPLOT (float[] ptrSrc, int src, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
int nDegreeNum = 1 << nDegreeDCT;
|
||||||
|
for (int i = 0; i < nDegreeNum; i += 2)
|
||||||
|
{
|
||||||
|
float r1 = ptrSrc[src + i];
|
||||||
|
float r2 = ptrSrc[src + i + 1];
|
||||||
|
ptrSrc[src + i] = 0.5f * (r1 + r2);
|
||||||
|
ptrSrc[src + i + 1] = 0.5f * (r1 - r2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastILOT (float[] ptrDst, float[] ptrSrc1, int src1, float[] ptrSrc2, int src2, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
int nDegreeNum = 1 << nDegreeDCT;
|
||||||
|
for (int i = 0; i < nDegreeNum; i += 2)
|
||||||
|
{
|
||||||
|
float r1 = ptrSrc1[src1 + i];
|
||||||
|
float r2 = ptrSrc2[src2 + i + 1];
|
||||||
|
ptrDst[i] = r1 + r2;
|
||||||
|
ptrDst[i + 1] = r1 - r2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastDCT (float[] ptrDst, int dst, int nDstInterval, float[] ptrSrc, int src, float[] ptrWorkBuf, int work, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
Debug.Assert ((nDegreeDCT >= MIN_DCT_DEGREE) && (nDegreeDCT <= MAX_DCT_DEGREE));
|
||||||
|
|
||||||
|
if (nDegreeDCT == MIN_DCT_DEGREE)
|
||||||
|
{
|
||||||
|
float[] r32Buf = new float[4];
|
||||||
|
r32Buf[0] = ptrSrc[src] + ptrSrc[src+3];
|
||||||
|
r32Buf[2] = ptrSrc[src] - ptrSrc[src+3];
|
||||||
|
r32Buf[1] = ptrSrc[src+1] + ptrSrc[src+2];
|
||||||
|
r32Buf[3] = ptrSrc[src+1] - ptrSrc[src+2];
|
||||||
|
|
||||||
|
ptrDst[dst] = 0.5f * (r32Buf[0] + r32Buf[1]);
|
||||||
|
ptrDst[dst+nDstInterval * 2] = ERI_rCosPI4 * (r32Buf[0] - r32Buf[1]);
|
||||||
|
|
||||||
|
r32Buf[2] = ERI_DCTofK2[0] * r32Buf[2];
|
||||||
|
r32Buf[3] = ERI_DCTofK2[1] * r32Buf[3];
|
||||||
|
|
||||||
|
r32Buf[0] = r32Buf[2] + r32Buf[3];
|
||||||
|
r32Buf[1] = ERI_r2CosPI4 * (r32Buf[2] - r32Buf[3]);
|
||||||
|
|
||||||
|
r32Buf[1] -= r32Buf[0];
|
||||||
|
|
||||||
|
ptrDst[dst+nDstInterval] = r32Buf[0];
|
||||||
|
ptrDst[dst+nDstInterval * 3] = r32Buf[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
uint nDegreeNum = 1u << nDegreeDCT;
|
||||||
|
uint nHalfDegree = nDegreeNum >> 1;
|
||||||
|
for (i = 0; i < nHalfDegree; i++)
|
||||||
|
{
|
||||||
|
ptrWorkBuf[work+i] = ptrSrc[src+i] + ptrSrc[src + nDegreeNum - i - 1];
|
||||||
|
ptrWorkBuf[work+i + nHalfDegree] = ptrSrc[src+i] - ptrSrc[src + nDegreeNum - i - 1];
|
||||||
|
}
|
||||||
|
int nDstStep = nDstInterval << 1;
|
||||||
|
FastDCT (ptrDst, dst, nDstStep, ptrWorkBuf, work, ptrSrc, src, nDegreeDCT - 1);
|
||||||
|
|
||||||
|
float[] pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
||||||
|
src = (int)(work+nHalfDegree); // ptrSrc = ptrWorkBuf + nHalfDegree;
|
||||||
|
dst += nDstInterval; // ptrDst += nDstInterval;
|
||||||
|
|
||||||
|
for (i = 0; i < nHalfDegree; i++)
|
||||||
|
{
|
||||||
|
ptrWorkBuf[src + i] *= pDCTofK[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
FastDCT (ptrDst, dst, nDstStep, ptrWorkBuf, src, ptrWorkBuf, work, nDegreeDCT - 1);
|
||||||
|
|
||||||
|
int ptrNext = dst; // within ptrDst;
|
||||||
|
for (i = 0; i < nHalfDegree; i++)
|
||||||
|
{
|
||||||
|
ptrDst[ptrNext] += ptrDst[ptrNext]; // *ptrNext += *ptrNext;
|
||||||
|
ptrNext += nDstStep;
|
||||||
|
}
|
||||||
|
ptrNext = dst;
|
||||||
|
for (i = 1; i < nHalfDegree; i ++)
|
||||||
|
{
|
||||||
|
ptrDst[ptrNext + nDstStep] -= ptrDst[ptrNext];
|
||||||
|
ptrNext += nDstStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastIDCT (float[] ptrDst, float[] srcBuf, int ptrSrc, int nSrcInterval, float[] ptrWorkBuf, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
FastIDCT (ptrDst, 0, srcBuf, ptrSrc, nSrcInterval, ptrWorkBuf, nDegreeDCT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastIDCT (float[] dstBuf, int ptrDst, float[] srcBuf, int ptrSrc, int nSrcInterval, float[] ptrWorkBuf, int nDegreeDCT)
|
||||||
|
{
|
||||||
|
Debug.Assert ((nDegreeDCT >= MIN_DCT_DEGREE) && (nDegreeDCT <= MAX_DCT_DEGREE));
|
||||||
|
|
||||||
|
if (nDegreeDCT == MIN_DCT_DEGREE)
|
||||||
|
{
|
||||||
|
float[] r32Buf1 = new float[2];
|
||||||
|
float[] r32Buf2 = new float[4];
|
||||||
|
|
||||||
|
r32Buf1[0] = srcBuf[ptrSrc];
|
||||||
|
r32Buf1[1] = ERI_rCosPI4 * srcBuf[ptrSrc + nSrcInterval * 2];
|
||||||
|
|
||||||
|
r32Buf2[0] = r32Buf1[0] + r32Buf1[1];
|
||||||
|
r32Buf2[1] = r32Buf1[0] - r32Buf1[1];
|
||||||
|
|
||||||
|
r32Buf1[0] = ERI_DCTofK2[0] * srcBuf[ptrSrc + nSrcInterval];
|
||||||
|
r32Buf1[1] = ERI_DCTofK2[1] * srcBuf[ptrSrc + nSrcInterval * 3];
|
||||||
|
|
||||||
|
r32Buf2[2] = r32Buf1[0] + r32Buf1[1];
|
||||||
|
r32Buf2[3] = ERI_r2CosPI4 * (r32Buf1[0] - r32Buf1[1]);
|
||||||
|
|
||||||
|
r32Buf2[3] -= r32Buf2[2];
|
||||||
|
|
||||||
|
dstBuf[ptrDst] = r32Buf2[0] + r32Buf2[2];
|
||||||
|
dstBuf[ptrDst+3] = r32Buf2[0] - r32Buf2[2];
|
||||||
|
dstBuf[ptrDst+1] = r32Buf2[1] + r32Buf2[3];
|
||||||
|
dstBuf[ptrDst+2] = r32Buf2[1] - r32Buf2[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint nDegreeNum = 1u << nDegreeDCT;
|
||||||
|
uint nHalfDegree = nDegreeNum >> 1;
|
||||||
|
int nSrcStep = nSrcInterval << 1;
|
||||||
|
FastIDCT (dstBuf, ptrDst, srcBuf, ptrSrc, nSrcStep, ptrWorkBuf, nDegreeDCT - 1);
|
||||||
|
|
||||||
|
float[] pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
||||||
|
int pOddDst = ptrDst + (int)nHalfDegree; // within dstBuf
|
||||||
|
int ptrNext = ptrSrc + nSrcInterval; // within srcBuf
|
||||||
|
|
||||||
|
uint i;
|
||||||
|
for (i = 0; i < nHalfDegree; i++)
|
||||||
|
{
|
||||||
|
ptrWorkBuf[i] = srcBuf[ptrNext] * pDCTofK[i];
|
||||||
|
ptrNext += nSrcStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
FastDCT (dstBuf, pOddDst, 1, ptrWorkBuf, 0, ptrWorkBuf, (int)nHalfDegree, nDegreeDCT - 1);
|
||||||
|
|
||||||
|
for (i = 0; i < nHalfDegree; i ++)
|
||||||
|
{
|
||||||
|
dstBuf[pOddDst + i] += dstBuf[pOddDst + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < nHalfDegree; i++)
|
||||||
|
{
|
||||||
|
dstBuf[pOddDst + i] -= dstBuf[pOddDst + i - 1];
|
||||||
|
}
|
||||||
|
float[] r32Buf = new float[4];
|
||||||
|
uint nQuadDegree = nHalfDegree >> 1;
|
||||||
|
for (i = 0; i < nQuadDegree; i++)
|
||||||
|
{
|
||||||
|
r32Buf[0] = dstBuf[ptrDst+i] + dstBuf[nHalfDegree + i];
|
||||||
|
r32Buf[3] = dstBuf[ptrDst+i] - dstBuf[nHalfDegree + i];
|
||||||
|
r32Buf[1] = dstBuf[nHalfDegree - 1 - i] + dstBuf[ptrDst + nDegreeNum - 1 - i];
|
||||||
|
r32Buf[2] = dstBuf[nHalfDegree - 1 - i] - dstBuf[ptrDst + nDegreeNum - 1 - i];
|
||||||
|
|
||||||
|
dstBuf[ptrDst+i] = r32Buf[0];
|
||||||
|
dstBuf[nHalfDegree - 1 - i] = r32Buf[1];
|
||||||
|
dstBuf[nHalfDegree + i] = r32Buf[2];
|
||||||
|
dstBuf[ptrDst+nDegreeNum - 1 - i] = r32Buf[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Revolve2x2 (float[] buf1, int ptrBuf1, float[] buf2, int ptrBuf2, float rSin, float rCos, int nStep, int nCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nCount; i++)
|
||||||
|
{
|
||||||
|
float r1 = buf1[ptrBuf1];
|
||||||
|
float r2 = buf2[ptrBuf2];
|
||||||
|
|
||||||
|
buf1[ptrBuf1] = r1 * rCos - r2 * rSin;
|
||||||
|
buf2[ptrBuf2] = r1 * rSin + r2 * rCos;
|
||||||
|
|
||||||
|
ptrBuf1 += nStep;
|
||||||
|
ptrBuf2 += nStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConvertArraySByteToFloat (float[] ptrDst, sbyte[] ptrSrc, int src, int nCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nCount; ++i)
|
||||||
|
{
|
||||||
|
ptrDst[i] = ptrSrc[src+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void VectorMultiply (float[] ptrDst, float[] ptrSrc, int src, int nCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nCount; ++i)
|
||||||
|
{
|
||||||
|
ptrDst[i] *= ptrSrc[src+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FastIDCT8x8 (float[] ptrDst)
|
||||||
|
{
|
||||||
|
var rWork = new float[8];
|
||||||
|
var rTemp = new float[64];
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
FastIDCT (rTemp, i * 8, ptrDst, i, 8, rWork, 3);
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
FastIDCT (ptrDst, i * 8, rTemp, i, 8, rWork, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly EriSinCos[] escRev = new EriSinCos[3]
|
||||||
|
{
|
||||||
|
new EriSinCos { rSin = 0.734510f, rCos = 0.678598f },
|
||||||
|
new EriSinCos { rSin = 0.887443f, rCos = 0.460917f },
|
||||||
|
new EriSinCos { rSin = 0.970269f, rCos = 0.242030f }
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void FastILOT8x8 (float[] ptrDst, float[] horz, int ptrHorzCur, float[] vert, int ptrVertCur)
|
||||||
|
{
|
||||||
|
var rWork = new float[8];
|
||||||
|
var rTemp = new float[64];
|
||||||
|
float s1, s2, r1, r2, r3;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
for (j = 2, k = i + 40; j >= 0; j--, k -= 16)
|
||||||
|
{
|
||||||
|
r1 = ptrDst[k];
|
||||||
|
r2 = ptrDst[k + 16];
|
||||||
|
ptrDst[k] = r1 * escRev[j].rCos + r2 * escRev[j].rSin;
|
||||||
|
ptrDst[k + 16] = r2 * escRev[j].rCos - r1 * escRev[j].rSin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 64; i += 16)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
k = i + j;
|
||||||
|
s1 = ptrDst[k];
|
||||||
|
s2 = ptrDst[k + 8];
|
||||||
|
r1 = 0.5f * (s1 + s2);
|
||||||
|
r2 = 0.5f * (s1 - s2);
|
||||||
|
|
||||||
|
r3 = vert[ptrVertCur+k];
|
||||||
|
vert[ptrVertCur+k] = r1;
|
||||||
|
vert[ptrVertCur+k + 8] = r2;
|
||||||
|
ptrDst[k] = r3 + r2;
|
||||||
|
ptrDst[k + 8] = r3 - r2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 64; i += 8)
|
||||||
|
{
|
||||||
|
for (j = 2, k = i + 5; j >= 0; j--, k -= 2)
|
||||||
|
{
|
||||||
|
r1 = ptrDst[k];
|
||||||
|
r2 = ptrDst[k + 2];
|
||||||
|
ptrDst[k] = r1 * escRev[j].rCos + r2 * escRev[j].rSin;
|
||||||
|
ptrDst[k + 2] = r2 * escRev[j].rCos - r1 * escRev[j].rSin;
|
||||||
|
}
|
||||||
|
for ( j = 0; j < 8; j += 2 )
|
||||||
|
{
|
||||||
|
k = i + j;
|
||||||
|
s1 = ptrDst[k];
|
||||||
|
s2 = ptrDst[k + 1];
|
||||||
|
r1 = 0.5f * (s1 + s2);
|
||||||
|
r2 = 0.5f * (s1 - s2);
|
||||||
|
r3 = horz[ptrHorzCur+k];
|
||||||
|
horz[ptrHorzCur+k] = r1;
|
||||||
|
horz[ptrHorzCur+k + 1] = r2;
|
||||||
|
ptrDst[k] = r3 + r2;
|
||||||
|
ptrDst[k + 1] = r3 - r2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
FastIDCT (rTemp, i * 8, ptrDst, i, 8, rWork, 3);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
FastIDCT (ptrDst, i * 8, rTemp, i, 8, rWork, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConvertArrayFloatToByte (sbyte[] ptrDst, float[] ptrSrc, int nCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nCount; i++)
|
||||||
|
{
|
||||||
|
int n = RoundR32ToInt (ptrSrc[i]);
|
||||||
|
if ((uint)n > 0xFF)
|
||||||
|
{
|
||||||
|
n = (~n >> 31) & 0xFF;
|
||||||
|
}
|
||||||
|
ptrDst[i] = (sbyte)n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConvertArrayFloatToSByte (sbyte[] ptrDst, float[] ptrSrc, int nCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nCount; i++)
|
||||||
|
{
|
||||||
|
int n = RoundR32ToInt (ptrSrc[i]);
|
||||||
|
if (n < -0x80)
|
||||||
|
n = -0x80;
|
||||||
|
else if (n > 0x7F)
|
||||||
|
n = 0x7F;
|
||||||
|
ptrDst[i] = (sbyte)n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,10 +40,10 @@ namespace GameRes.Formats.Entis
|
|||||||
public int Version;
|
public int Version;
|
||||||
public CvType Transformation;
|
public CvType Transformation;
|
||||||
public EriCode Architecture;
|
public EriCode Architecture;
|
||||||
public int FormatType;
|
public EriType FormatType;
|
||||||
public bool VerticalFlip;
|
public bool VerticalFlip;
|
||||||
public int ClippedPixel;
|
public int ClippedPixel;
|
||||||
public int SamplingFlags;
|
public EriSampling SamplingFlags;
|
||||||
public ulong QuantumizedBits;
|
public ulong QuantumizedBits;
|
||||||
public ulong AllottedBits;
|
public ulong AllottedBits;
|
||||||
public int BlockingDegree;
|
public int BlockingDegree;
|
||||||
@ -79,7 +79,8 @@ namespace GameRes.Formats.Entis
|
|||||||
Nemesis = -16,
|
Nemesis = -16,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EriImage
|
[Flags]
|
||||||
|
public enum EriType
|
||||||
{
|
{
|
||||||
RGB = 0x00000001,
|
RGB = 0x00000001,
|
||||||
Gray = 0x00000002,
|
Gray = 0x00000002,
|
||||||
@ -88,13 +89,20 @@ namespace GameRes.Formats.Entis
|
|||||||
HSB = 0x00000006,
|
HSB = 0x00000006,
|
||||||
RGBA = 0x04000001,
|
RGBA = 0x04000001,
|
||||||
BGRA = 0x04000003,
|
BGRA = 0x04000003,
|
||||||
TypeMask = 0x0000FFFF,
|
Mask = 0x0000FFFF,
|
||||||
WithPalette = 0x01000000,
|
WithPalette = 0x01000000,
|
||||||
UseClipping = 0x02000000,
|
UseClipping = 0x02000000,
|
||||||
WithAlpha = 0x04000000,
|
WithAlpha = 0x04000000,
|
||||||
SideBySide = 0x10000000,
|
SideBySide = 0x10000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum EriSampling
|
||||||
|
{
|
||||||
|
YUV_4_4_4 = 0x00040404,
|
||||||
|
YUV_4_2_2 = 0x00040202,
|
||||||
|
YUV_4_1_1 = 0x00040101,
|
||||||
|
}
|
||||||
|
|
||||||
internal class EriFile : BinaryReader
|
internal class EriFile : BinaryReader
|
||||||
{
|
{
|
||||||
internal struct Section
|
internal struct Section
|
||||||
@ -185,7 +193,7 @@ namespace GameRes.Formats.Entis
|
|||||||
info = new EriMetaData { StreamPos = stream_pos, Version = version };
|
info = new EriMetaData { StreamPos = stream_pos, Version = version };
|
||||||
info.Transformation = (CvType)reader.ReadInt32();
|
info.Transformation = (CvType)reader.ReadInt32();
|
||||||
info.Architecture = (EriCode)reader.ReadInt32();
|
info.Architecture = (EriCode)reader.ReadInt32();
|
||||||
info.FormatType = reader.ReadInt32();
|
info.FormatType = (EriType)reader.ReadInt32();
|
||||||
int w = reader.ReadInt32();
|
int w = reader.ReadInt32();
|
||||||
int h = reader.ReadInt32();
|
int h = reader.ReadInt32();
|
||||||
info.Width = (uint)Math.Abs (w);
|
info.Width = (uint)Math.Abs (w);
|
||||||
@ -193,7 +201,7 @@ namespace GameRes.Formats.Entis
|
|||||||
info.VerticalFlip = h < 0;
|
info.VerticalFlip = h < 0;
|
||||||
info.BPP = reader.ReadInt32();
|
info.BPP = reader.ReadInt32();
|
||||||
info.ClippedPixel = reader.ReadInt32();
|
info.ClippedPixel = reader.ReadInt32();
|
||||||
info.SamplingFlags = reader.ReadInt32();
|
info.SamplingFlags = (EriSampling)reader.ReadInt32();
|
||||||
info.QuantumizedBits = reader.ReadUInt64();
|
info.QuantumizedBits = reader.ReadUInt64();
|
||||||
info.AllottedBits = reader.ReadUInt64();
|
info.AllottedBits = reader.ReadUInt64();
|
||||||
info.BlockingDegree = reader.ReadInt32();
|
info.BlockingDegree = reader.ReadInt32();
|
||||||
|
@ -71,14 +71,6 @@ namespace GameRes.Formats.Entis
|
|||||||
EriSinCos[] m_pRevolveParam;
|
EriSinCos[] m_pRevolveParam;
|
||||||
readonly int[] m_nFrequencyPoint = new int[7];
|
readonly int[] m_nFrequencyPoint = new int[7];
|
||||||
|
|
||||||
const int MIN_DCT_DEGREE = 2;
|
|
||||||
const int MAX_DCT_DEGREE = 12;
|
|
||||||
|
|
||||||
static MioDecoder ()
|
|
||||||
{
|
|
||||||
eriInitializeMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MioDecoder (MioInfoHeader info)
|
public MioDecoder (MioInfoHeader info)
|
||||||
{
|
{
|
||||||
m_nBufLength = 0;
|
m_nBufLength = 0;
|
||||||
@ -119,7 +111,7 @@ namespace GameRes.Formats.Entis
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((m_mioih.SubbandDegree < 8) || (m_mioih.SubbandDegree > MAX_DCT_DEGREE))
|
if ((m_mioih.SubbandDegree < 8) || (m_mioih.SubbandDegree > Erisa.MAX_DCT_DEGREE))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -284,7 +276,7 @@ namespace GameRes.Formats.Entis
|
|||||||
|
|
||||||
void InitializeWithDegree (int nSubbandDegree)
|
void InitializeWithDegree (int nSubbandDegree)
|
||||||
{
|
{
|
||||||
m_pRevolveParam = eriCreateRevolveParameter (nSubbandDegree);
|
m_pRevolveParam = Erisa.CreateRevolveParameter (nSubbandDegree);
|
||||||
for (int i = 0, j = 0; i < 7; i ++)
|
for (int i = 0, j = 0; i < 7; i ++)
|
||||||
{
|
{
|
||||||
int nFrequencyWidth = 1 << (nSubbandDegree + FreqWidth[i]);
|
int nFrequencyWidth = 1 << (nSubbandDegree + FreqWidth[i]);
|
||||||
@ -525,17 +517,17 @@ namespace GameRes.Formats.Entis
|
|||||||
IQuantumize (m_ptrMatrixBuf, 0, m_ptrBuffer2, m_ptrNextSource, m_nDegreeNum, nWeightCode, nCoefficient);
|
IQuantumize (m_ptrMatrixBuf, 0, m_ptrBuffer2, m_ptrNextSource, m_nDegreeNum, nWeightCode, nCoefficient);
|
||||||
m_ptrNextSource += (int)m_nDegreeNum;
|
m_ptrNextSource += (int)m_nDegreeNum;
|
||||||
|
|
||||||
eriOddGivensInverseMatrix (m_ptrMatrixBuf, 0, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrMatrixBuf, 0, m_pRevolveParam, m_nSubbandDegree);
|
||||||
eriFastIPLOT (m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
||||||
eriFastILOT (m_ptrWorkBuf, m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
Erisa.FastILOT (m_ptrWorkBuf, m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
||||||
|
|
||||||
Array.Copy (m_ptrMatrixBuf, 0, m_ptrLastDCT, m_ptrLastDCTBuf, m_nDegreeNum);
|
Array.Copy (m_ptrMatrixBuf, 0, m_ptrLastDCT, m_ptrLastDCTBuf, m_nDegreeNum);
|
||||||
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, 0, m_nDegreeNum);
|
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, 0, m_nDegreeNum);
|
||||||
|
|
||||||
eriFastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, 0, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
Erisa.FastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, 0, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
||||||
if (nSamples != 0)
|
if (nSamples != 0)
|
||||||
{
|
{
|
||||||
eriRoundR32ToWordArray (ptrDst, iDst, m_mioih.ChannelCount, m_ptrInternalBuf, (int)nSamples);
|
Erisa.RoundR32ToWordArray (ptrDst, iDst, m_mioih.ChannelCount, m_ptrInternalBuf, (int)nSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,12 +543,12 @@ namespace GameRes.Formats.Entis
|
|||||||
m_ptrBuffer1[i * 2 + 1] = m_ptrBuffer2[m_ptrNextSource++];
|
m_ptrBuffer1[i * 2 + 1] = m_ptrBuffer2[m_ptrNextSource++];
|
||||||
}
|
}
|
||||||
IQuantumize (m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrBuffer1, 0, m_nDegreeNum, nWeightCode, nCoefficient);
|
IQuantumize (m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrBuffer1, 0, m_nDegreeNum, nWeightCode, nCoefficient);
|
||||||
eriOddGivensInverseMatrix (m_ptrLastDCT, m_ptrLastDCTBuf, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrLastDCT, m_ptrLastDCTBuf, m_pRevolveParam, m_nSubbandDegree);
|
||||||
for (i = 0; i < m_nDegreeNum; i += 2)
|
for (i = 0; i < m_nDegreeNum; i += 2)
|
||||||
{
|
{
|
||||||
m_ptrLastDCT[m_ptrLastDCTBuf + i] = m_ptrLastDCT[m_ptrLastDCTBuf + i + 1];
|
m_ptrLastDCT[m_ptrLastDCTBuf + i] = m_ptrLastDCT[m_ptrLastDCTBuf + i + 1];
|
||||||
}
|
}
|
||||||
eriFastIPLOT (m_ptrLastDCT, m_ptrLastDCTBuf, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrLastDCT, m_ptrLastDCTBuf, m_nSubbandDegree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodePostBlock (byte[] ptrDst, int iDst, uint nSamples)
|
void DecodePostBlock (byte[] ptrDst, int iDst, uint nSamples)
|
||||||
@ -571,22 +563,22 @@ namespace GameRes.Formats.Entis
|
|||||||
m_ptrBuffer1[i * 2 + 1] = m_ptrBuffer2[m_ptrNextSource++];
|
m_ptrBuffer1[i * 2 + 1] = m_ptrBuffer2[m_ptrNextSource++];
|
||||||
}
|
}
|
||||||
IQuantumize (m_ptrMatrixBuf, 0, m_ptrBuffer1, 0, m_nDegreeNum, nWeightCode, nCoefficient);
|
IQuantumize (m_ptrMatrixBuf, 0, m_ptrBuffer1, 0, m_nDegreeNum, nWeightCode, nCoefficient);
|
||||||
eriOddGivensInverseMatrix (m_ptrMatrixBuf, 0, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrMatrixBuf, 0, m_pRevolveParam, m_nSubbandDegree);
|
||||||
|
|
||||||
for (i = 0; i < m_nDegreeNum; i += 2)
|
for (i = 0; i < m_nDegreeNum; i += 2)
|
||||||
{
|
{
|
||||||
m_ptrMatrixBuf[i] = - m_ptrMatrixBuf[i + 1];
|
m_ptrMatrixBuf[i] = - m_ptrMatrixBuf[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
eriFastIPLOT (m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
||||||
eriFastILOT (m_ptrWorkBuf, m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
Erisa.FastILOT (m_ptrWorkBuf, m_ptrLastDCT, m_ptrLastDCTBuf, m_ptrMatrixBuf, 0, m_nSubbandDegree);
|
||||||
|
|
||||||
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, 0, m_nDegreeNum);
|
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, 0, m_nDegreeNum);
|
||||||
|
|
||||||
eriFastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, 0, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
Erisa.FastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, 0, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
||||||
if (nSamples != 0)
|
if (nSamples != 0)
|
||||||
{
|
{
|
||||||
eriRoundR32ToWordArray (ptrDst, iDst, m_mioih.ChannelCount, m_ptrInternalBuf, (int)nSamples);
|
Erisa.RoundR32ToWordArray (ptrDst, iDst, m_mioih.ChannelCount, m_ptrInternalBuf, (int)nSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,18 +799,18 @@ namespace GameRes.Formats.Entis
|
|||||||
|
|
||||||
float rSin = (float)Math.Sin (nRevCode * Math.PI / 8);
|
float rSin = (float)Math.Sin (nRevCode * Math.PI / 8);
|
||||||
float rCos = (float)Math.Cos (nRevCode * Math.PI / 8);
|
float rCos = (float)Math.Cos (nRevCode * Math.PI / 8);
|
||||||
eriRevolve2x2 (m_ptrLastDCT, ptrLapBuf1, m_ptrLastDCT, ptrLapBuf2, rSin, rCos, 1, m_nDegreeNum);
|
Erisa.Revolve2x2 (m_ptrLastDCT, ptrLapBuf1, m_ptrLastDCT, ptrLapBuf2, rSin, rCos, 1, m_nDegreeNum);
|
||||||
|
|
||||||
ptrLapBuf = 0; //m_ptrLastDCT;
|
ptrLapBuf = 0; //m_ptrLastDCT;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
eriOddGivensInverseMatrix (m_ptrLastDCT, ptrLapBuf, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrLastDCT, ptrLapBuf, m_pRevolveParam, m_nSubbandDegree);
|
||||||
|
|
||||||
for (j = 0; j < m_nDegreeNum; j += 2)
|
for (j = 0; j < m_nDegreeNum; j += 2)
|
||||||
{
|
{
|
||||||
m_ptrLastDCT[ptrLapBuf + j] = m_ptrLastDCT[ptrLapBuf + j + 1];
|
m_ptrLastDCT[ptrLapBuf + j] = m_ptrLastDCT[ptrLapBuf + j + 1];
|
||||||
}
|
}
|
||||||
eriFastIPLOT (m_ptrLastDCT, ptrLapBuf, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrLastDCT, ptrLapBuf, m_nSubbandDegree);
|
||||||
ptrLapBuf += (int)m_nDegreeNum;
|
ptrLapBuf += (int)m_nDegreeNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -846,27 +838,27 @@ namespace GameRes.Formats.Entis
|
|||||||
|
|
||||||
float rSin = (float) Math.Sin (nRevCode1 * Math.PI / 8);
|
float rSin = (float) Math.Sin (nRevCode1 * Math.PI / 8);
|
||||||
float rCos = (float) Math.Cos (nRevCode1 * Math.PI / 8);
|
float rCos = (float) Math.Cos (nRevCode1 * Math.PI / 8);
|
||||||
eriRevolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1, m_ptrMatrixBuf, ptrSrcBuf2, rSin, rCos, 2, m_nDegreeNum / 2);
|
Erisa.Revolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1, m_ptrMatrixBuf, ptrSrcBuf2, rSin, rCos, 2, m_nDegreeNum / 2);
|
||||||
|
|
||||||
rSin = (float) Math.Sin (nRevCode2 * Math.PI / 8);
|
rSin = (float) Math.Sin (nRevCode2 * Math.PI / 8);
|
||||||
rCos = (float) Math.Cos (nRevCode2 * Math.PI / 8);
|
rCos = (float) Math.Cos (nRevCode2 * Math.PI / 8);
|
||||||
eriRevolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1 + 1, m_ptrMatrixBuf, ptrSrcBuf2 + 1, rSin, rCos, 2, m_nDegreeNum / 2);
|
Erisa.Revolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1 + 1, m_ptrMatrixBuf, ptrSrcBuf2 + 1, rSin, rCos, 2, m_nDegreeNum / 2);
|
||||||
|
|
||||||
ptrSrcBuf = 0; // m_ptrMatrixBuf;
|
ptrSrcBuf = 0; // m_ptrMatrixBuf;
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
eriOddGivensInverseMatrix (m_ptrMatrixBuf, ptrSrcBuf, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrMatrixBuf, ptrSrcBuf, m_pRevolveParam, m_nSubbandDegree);
|
||||||
eriFastIPLOT (m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
||||||
eriFastILOT (m_ptrWorkBuf, m_ptrLastDCT, ptrLapBuf, m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
Erisa.FastILOT (m_ptrWorkBuf, m_ptrLastDCT, ptrLapBuf, m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
||||||
|
|
||||||
Array.Copy (m_ptrMatrixBuf, ptrSrcBuf, m_ptrLastDCT, ptrLapBuf, m_nDegreeNum);
|
Array.Copy (m_ptrMatrixBuf, ptrSrcBuf, m_ptrLastDCT, ptrLapBuf, m_nDegreeNum);
|
||||||
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, ptrSrcBuf, m_nDegreeNum);
|
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, ptrSrcBuf, m_nDegreeNum);
|
||||||
|
|
||||||
eriFastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, ptrSrcBuf, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
Erisa.FastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, ptrSrcBuf, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
||||||
if (nSamples != 0)
|
if (nSamples != 0)
|
||||||
{
|
{
|
||||||
eriRoundR32ToWordArray (ptrDst, iDst + (int)i*2, 2, m_ptrInternalBuf, (int)nSamples);
|
Erisa.RoundR32ToWordArray (ptrDst, iDst + (int)i*2, 2, m_ptrInternalBuf, (int)nSamples);
|
||||||
}
|
}
|
||||||
ptrSrcBuf += m_nDegreeNum;
|
ptrSrcBuf += m_nDegreeNum;
|
||||||
ptrLapBuf += m_nDegreeNum;
|
ptrLapBuf += m_nDegreeNum;
|
||||||
@ -901,27 +893,27 @@ namespace GameRes.Formats.Entis
|
|||||||
|
|
||||||
rSin = (float) Math.Sin (nRevCode * Math.PI / 8);
|
rSin = (float) Math.Sin (nRevCode * Math.PI / 8);
|
||||||
rCos = (float) Math.Cos (nRevCode * Math.PI / 8);
|
rCos = (float) Math.Cos (nRevCode * Math.PI / 8);
|
||||||
eriRevolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1, m_ptrMatrixBuf, ptrSrcBuf2, rSin, rCos, 1, m_nDegreeNum);
|
Erisa.Revolve2x2 (m_ptrMatrixBuf, ptrSrcBuf1, m_ptrMatrixBuf, ptrSrcBuf2, rSin, rCos, 1, m_nDegreeNum);
|
||||||
|
|
||||||
ptrSrcBuf = 0; // m_ptrMatrixBuf;
|
ptrSrcBuf = 0; // m_ptrMatrixBuf;
|
||||||
|
|
||||||
for (i = 0; i < 2; i ++)
|
for (i = 0; i < 2; i ++)
|
||||||
{
|
{
|
||||||
eriOddGivensInverseMatrix (m_ptrMatrixBuf, ptrSrcBuf, m_pRevolveParam, m_nSubbandDegree);
|
Erisa.OddGivensInverseMatrix (m_ptrMatrixBuf, ptrSrcBuf, m_pRevolveParam, m_nSubbandDegree);
|
||||||
|
|
||||||
for (j = 0; j < m_nDegreeNum; j += 2)
|
for (j = 0; j < m_nDegreeNum; j += 2)
|
||||||
{
|
{
|
||||||
m_ptrMatrixBuf[ptrSrcBuf + j] = -m_ptrMatrixBuf[ptrSrcBuf + j + 1];
|
m_ptrMatrixBuf[ptrSrcBuf + j] = -m_ptrMatrixBuf[ptrSrcBuf + j + 1];
|
||||||
}
|
}
|
||||||
eriFastIPLOT (m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
Erisa.FastIPLOT (m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
||||||
eriFastILOT (m_ptrWorkBuf, m_ptrLastDCT, ptrLapBuf, m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
Erisa.FastILOT (m_ptrWorkBuf, m_ptrLastDCT, ptrLapBuf, m_ptrMatrixBuf, ptrSrcBuf, m_nSubbandDegree);
|
||||||
|
|
||||||
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, ptrSrcBuf, m_nDegreeNum);
|
Array.Copy (m_ptrWorkBuf, 0, m_ptrMatrixBuf, ptrSrcBuf, m_nDegreeNum);
|
||||||
|
|
||||||
eriFastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, ptrSrcBuf, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
Erisa.FastIDCT (m_ptrInternalBuf, m_ptrMatrixBuf, ptrSrcBuf, 1, m_ptrWorkBuf, m_nSubbandDegree);
|
||||||
if (nSamples != 0)
|
if (nSamples != 0)
|
||||||
{
|
{
|
||||||
eriRoundR32ToWordArray (ptrDst, iDst + (int)i*2, 2, m_ptrInternalBuf, (int)nSamples);
|
Erisa.RoundR32ToWordArray (ptrDst, iDst + (int)i*2, 2, m_ptrInternalBuf, (int)nSamples);
|
||||||
}
|
}
|
||||||
ptrLapBuf += m_nDegreeNum;
|
ptrLapBuf += m_nDegreeNum;
|
||||||
ptrSrcBuf += m_nDegreeNum;
|
ptrSrcBuf += m_nDegreeNum;
|
||||||
@ -972,346 +964,5 @@ namespace GameRes.Formats.Entis
|
|||||||
ptrDestination[dst + i] = (float) (rCoefficient * m_ptrWeightTable[i] * ptrQuantumized[qsrc+i]);
|
ptrDestination[dst + i] = (float) (rCoefficient * m_ptrWeightTable[i] * ptrQuantumized[qsrc+i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly float ERI_rCosPI4 = (float)Math.Cos (Math.PI / 4);
|
|
||||||
static readonly float ERI_r2CosPI4 = 2 * ERI_rCosPI4;
|
|
||||||
static readonly float[] ERI_DCTofK2 = new float[2]; // = cos( (2*i+1) / 8 )
|
|
||||||
static readonly float[] ERI_DCTofK4 = new float[4]; // = cos( (2*i+1) / 16 )
|
|
||||||
static readonly float[] ERI_DCTofK8 = new float[8]; // = cos( (2*i+1) / 32 )
|
|
||||||
static readonly float[] ERI_DCTofK16 = new float[16]; // = cos( (2*i+1) / 64 )
|
|
||||||
static readonly float[] ERI_DCTofK32 = new float[32]; // = cos( (2*i+1) / 128 )
|
|
||||||
static readonly float[] ERI_DCTofK64 = new float[64]; // = cos( (2*i+1) / 256 )
|
|
||||||
static readonly float[] ERI_DCTofK128 = new float[128]; // = cos( (2*i+1) / 512 )
|
|
||||||
static readonly float[] ERI_DCTofK256 = new float[256]; // = cos( (2*i+1) / 1024 )
|
|
||||||
static readonly float[] ERI_DCTofK512 = new float[512]; // = cos( (2*i+1) / 2048 )
|
|
||||||
static readonly float[] ERI_DCTofK1024 = new float[1024]; // = cos( (2*i+1) / 4096 )
|
|
||||||
static readonly float[] ERI_DCTofK2048 = new float[2048]; // = cos( (2*i+1) / 8192 )
|
|
||||||
|
|
||||||
static readonly float[][] ERI_pMatrixDCTofK = new float[MAX_DCT_DEGREE][]
|
|
||||||
{
|
|
||||||
null,
|
|
||||||
ERI_DCTofK2,
|
|
||||||
ERI_DCTofK4,
|
|
||||||
ERI_DCTofK8,
|
|
||||||
ERI_DCTofK16,
|
|
||||||
ERI_DCTofK32,
|
|
||||||
ERI_DCTofK64,
|
|
||||||
ERI_DCTofK128,
|
|
||||||
ERI_DCTofK256,
|
|
||||||
ERI_DCTofK512,
|
|
||||||
ERI_DCTofK1024,
|
|
||||||
ERI_DCTofK2048
|
|
||||||
};
|
|
||||||
|
|
||||||
static void eriInitializeMatrix ()
|
|
||||||
{
|
|
||||||
for (int i = 1; i < MAX_DCT_DEGREE; i++)
|
|
||||||
{
|
|
||||||
int n = (1 << i);
|
|
||||||
float[] pDCTofK = ERI_pMatrixDCTofK[i];
|
|
||||||
double nr = Math.PI / (4.0 * n);
|
|
||||||
double dr = nr + nr;
|
|
||||||
double ir = nr;
|
|
||||||
for (int j = 0; j < n; j++)
|
|
||||||
{
|
|
||||||
pDCTofK[j] = (float)Math.Cos (ir);
|
|
||||||
ir += dr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriRoundR32ToWordArray (byte[] ptrDst, int dst, int nStep, float[] ptrSrc, int nCount)
|
|
||||||
{
|
|
||||||
nStep *= 2;
|
|
||||||
for (int i = 0; i < nCount; i++)
|
|
||||||
{
|
|
||||||
int nValue = eriRoundR32ToInt (ptrSrc[i]);
|
|
||||||
if (nValue <= -0x8000)
|
|
||||||
{
|
|
||||||
LittleEndian.Pack ((short)-0x8000, ptrDst, dst);
|
|
||||||
}
|
|
||||||
else if (nValue >= 0x7FFF)
|
|
||||||
{
|
|
||||||
LittleEndian.Pack ((short)0x7FFF, ptrDst, dst);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LittleEndian.Pack ((short)nValue, ptrDst, dst);
|
|
||||||
}
|
|
||||||
dst += nStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eriRoundR32ToInt (float r)
|
|
||||||
{
|
|
||||||
if (r >= 0.0)
|
|
||||||
return (int)Math.Floor (r + 0.5);
|
|
||||||
else
|
|
||||||
return (int)Math.Ceiling (r - 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EriSinCos[] eriCreateRevolveParameter (int nDegreeDCT)
|
|
||||||
{
|
|
||||||
int nDegreeNum = 1 << nDegreeDCT;
|
|
||||||
int lc = 1;
|
|
||||||
for (int n = nDegreeNum / 2; n >= 8; n /= 8)
|
|
||||||
{
|
|
||||||
++lc;
|
|
||||||
}
|
|
||||||
EriSinCos[] ptrRevolve = new EriSinCos[lc*8];
|
|
||||||
|
|
||||||
double k = Math.PI / (nDegreeNum * 2);
|
|
||||||
int ptrNextRev = 0;
|
|
||||||
int nStep = 2;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
double ws = 1.0;
|
|
||||||
double a = 0.0;
|
|
||||||
for (int j = 0; j < i; j++)
|
|
||||||
{
|
|
||||||
a += nStep;
|
|
||||||
ws = ws * ptrRevolve[ptrNextRev+j].rSin + ptrRevolve[ptrNextRev+j].rCos * Math.Cos (a * k);
|
|
||||||
}
|
|
||||||
double r = Math.Atan2 (ws, Math.Cos ((a + nStep) * k));
|
|
||||||
ptrRevolve[ptrNextRev+i].rSin = (float)Math.Sin (r);
|
|
||||||
ptrRevolve[ptrNextRev+i].rCos = (float)Math.Cos (r);
|
|
||||||
}
|
|
||||||
ptrNextRev += 7;
|
|
||||||
nStep *= 8;
|
|
||||||
}
|
|
||||||
while (nStep < nDegreeNum);
|
|
||||||
return ptrRevolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriOddGivensInverseMatrix (float[] ptrSrc, int src, EriSinCos[] ptrRevolve, int nDegreeDCT)
|
|
||||||
{
|
|
||||||
int nDegreeNum = 1 << nDegreeDCT;
|
|
||||||
int index = 1;
|
|
||||||
int nStep = 2;
|
|
||||||
int lc = (nDegreeNum / 2) / 8;
|
|
||||||
int resolve_idx = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
resolve_idx += 7;
|
|
||||||
index += nStep * 7;
|
|
||||||
nStep *= 8;
|
|
||||||
if (lc <= 8)
|
|
||||||
break;
|
|
||||||
lc /= 8;
|
|
||||||
}
|
|
||||||
int k = index + nStep * (lc - 2);
|
|
||||||
int j;
|
|
||||||
float r1, r2;
|
|
||||||
for (j = lc - 2; j >= 0; j--)
|
|
||||||
{
|
|
||||||
r1 = ptrSrc[src + k];
|
|
||||||
r2 = ptrSrc[src + k + nStep];
|
|
||||||
ptrSrc[src + k] = r1 * ptrRevolve[resolve_idx+j].rCos + r2 * ptrRevolve[resolve_idx+j].rSin;
|
|
||||||
ptrSrc[src + k + nStep] = r2 * ptrRevolve[resolve_idx+j].rCos - r1 * ptrRevolve[resolve_idx+j].rSin;
|
|
||||||
k -= nStep;
|
|
||||||
}
|
|
||||||
for (; lc <= (nDegreeNum / 2) / 8; lc *= 8)
|
|
||||||
{
|
|
||||||
resolve_idx -= 7;
|
|
||||||
nStep /= 8;
|
|
||||||
index -= nStep * 7;
|
|
||||||
for (int i = 0; i < lc; i++)
|
|
||||||
{
|
|
||||||
k = i * (nStep * 8) + index + nStep * 6;
|
|
||||||
for ( j = 6; j >= 0; j -- )
|
|
||||||
{
|
|
||||||
r1 = ptrSrc[src + k];
|
|
||||||
r2 = ptrSrc[src + k + nStep];
|
|
||||||
ptrSrc[src + k] =
|
|
||||||
r1 * ptrRevolve[resolve_idx+j].rCos + r2 * ptrRevolve[resolve_idx+j].rSin;
|
|
||||||
ptrSrc[src + k + nStep] =
|
|
||||||
r2 * ptrRevolve[resolve_idx+j].rCos - r1 * ptrRevolve[resolve_idx+j].rSin;
|
|
||||||
k -= nStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriFastIPLOT (float[] ptrSrc, int src, int nDegreeDCT)
|
|
||||||
{
|
|
||||||
int nDegreeNum = 1 << nDegreeDCT;
|
|
||||||
for (int i = 0; i < nDegreeNum; i += 2)
|
|
||||||
{
|
|
||||||
float r1 = ptrSrc[src + i];
|
|
||||||
float r2 = ptrSrc[src + i + 1];
|
|
||||||
ptrSrc[src + i] = 0.5f * (r1 + r2);
|
|
||||||
ptrSrc[src + i + 1] = 0.5f * (r1 - r2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriFastILOT (float[] ptrDst, float[] ptrSrc1, int src1, float[] ptrSrc2, int src2, int nDegreeDCT)
|
|
||||||
{
|
|
||||||
int nDegreeNum = 1 << nDegreeDCT;
|
|
||||||
for (int i = 0; i < nDegreeNum; i += 2)
|
|
||||||
{
|
|
||||||
float r1 = ptrSrc1[src1 + i];
|
|
||||||
float r2 = ptrSrc2[src2 + i + 1];
|
|
||||||
ptrDst[i] = r1 + r2;
|
|
||||||
ptrDst[i + 1] = r1 - r2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriFastDCT (float[] ptrDst, int dst, int nDstInterval, float[] ptrSrc, int src, float[] ptrWorkBuf, int work, int nDegreeDCT)
|
|
||||||
{
|
|
||||||
Debug.Assert ((nDegreeDCT >= MIN_DCT_DEGREE) && (nDegreeDCT <= MAX_DCT_DEGREE));
|
|
||||||
|
|
||||||
if (nDegreeDCT == MIN_DCT_DEGREE)
|
|
||||||
{
|
|
||||||
float[] r32Buf = new float[4];
|
|
||||||
r32Buf[0] = ptrSrc[src] + ptrSrc[src+3];
|
|
||||||
r32Buf[2] = ptrSrc[src] - ptrSrc[src+3];
|
|
||||||
r32Buf[1] = ptrSrc[src+1] + ptrSrc[src+2];
|
|
||||||
r32Buf[3] = ptrSrc[src+1] - ptrSrc[src+2];
|
|
||||||
|
|
||||||
ptrDst[dst] = 0.5f * (r32Buf[0] + r32Buf[1]);
|
|
||||||
ptrDst[dst+nDstInterval * 2] = ERI_rCosPI4 * (r32Buf[0] - r32Buf[1]);
|
|
||||||
|
|
||||||
r32Buf[2] = ERI_DCTofK2[0] * r32Buf[2];
|
|
||||||
r32Buf[3] = ERI_DCTofK2[1] * r32Buf[3];
|
|
||||||
|
|
||||||
r32Buf[0] = r32Buf[2] + r32Buf[3];
|
|
||||||
r32Buf[1] = ERI_r2CosPI4 * (r32Buf[2] - r32Buf[3]);
|
|
||||||
|
|
||||||
r32Buf[1] -= r32Buf[0];
|
|
||||||
|
|
||||||
ptrDst[dst+nDstInterval] = r32Buf[0];
|
|
||||||
ptrDst[dst+nDstInterval * 3] = r32Buf[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint i;
|
|
||||||
uint nDegreeNum = 1u << nDegreeDCT;
|
|
||||||
uint nHalfDegree = nDegreeNum >> 1;
|
|
||||||
for (i = 0; i < nHalfDegree; i++)
|
|
||||||
{
|
|
||||||
ptrWorkBuf[work+i] = ptrSrc[src+i] + ptrSrc[src + nDegreeNum - i - 1];
|
|
||||||
ptrWorkBuf[work+i + nHalfDegree] = ptrSrc[src+i] - ptrSrc[src + nDegreeNum - i - 1];
|
|
||||||
}
|
|
||||||
int nDstStep = nDstInterval << 1;
|
|
||||||
eriFastDCT (ptrDst, dst, nDstStep, ptrWorkBuf, work, ptrSrc, src, nDegreeDCT - 1);
|
|
||||||
|
|
||||||
float[] pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
|
||||||
src = (int)(work+nHalfDegree); // ptrSrc = ptrWorkBuf + nHalfDegree;
|
|
||||||
dst += nDstInterval; // ptrDst += nDstInterval;
|
|
||||||
|
|
||||||
for (i = 0; i < nHalfDegree; i++)
|
|
||||||
{
|
|
||||||
ptrWorkBuf[src + i] *= pDCTofK[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
eriFastDCT (ptrDst, dst, nDstStep, ptrWorkBuf, src, ptrWorkBuf, work, nDegreeDCT - 1);
|
|
||||||
// eriFastDCT (ptrDst, nDstStep, ptrSrc, ptrWorkBuf, nDegreeDCT - 1);
|
|
||||||
|
|
||||||
int ptrNext = dst; // within ptrDst;
|
|
||||||
for (i = 0; i < nHalfDegree; i++)
|
|
||||||
{
|
|
||||||
ptrDst[ptrNext] += ptrDst[ptrNext]; // *ptrNext += *ptrNext;
|
|
||||||
ptrNext += nDstStep;
|
|
||||||
}
|
|
||||||
ptrNext = dst;
|
|
||||||
for (i = 1; i < nHalfDegree; i ++)
|
|
||||||
{
|
|
||||||
ptrDst[ptrNext + nDstStep] -= ptrDst[ptrNext];
|
|
||||||
ptrNext += nDstStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eriFastIDCT (float[] ptrDst, float[] srcBuf, int ptrSrc, int nSrcInterval, float[] ptrWorkBuf, int nDegreeDCT)
|
|
||||||
{
|
|
||||||
Debug.Assert ((nDegreeDCT >= MIN_DCT_DEGREE) && (nDegreeDCT <= MAX_DCT_DEGREE));
|
|
||||||
|
|
||||||
if (nDegreeDCT == MIN_DCT_DEGREE)
|
|
||||||
{
|
|
||||||
float[] r32Buf1 = new float[2];
|
|
||||||
float[] r32Buf2 = new float[4];
|
|
||||||
|
|
||||||
r32Buf1[0] = srcBuf[ptrSrc];
|
|
||||||
r32Buf1[1] = ERI_rCosPI4 * srcBuf[ptrSrc + nSrcInterval * 2];
|
|
||||||
|
|
||||||
r32Buf2[0] = r32Buf1[0] + r32Buf1[1];
|
|
||||||
r32Buf2[1] = r32Buf1[0] - r32Buf1[1];
|
|
||||||
|
|
||||||
r32Buf1[0] = ERI_DCTofK2[0] * srcBuf[ptrSrc + nSrcInterval];
|
|
||||||
r32Buf1[1] = ERI_DCTofK2[1] * srcBuf[ptrSrc + nSrcInterval * 3];
|
|
||||||
|
|
||||||
r32Buf2[2] = r32Buf1[0] + r32Buf1[1];
|
|
||||||
r32Buf2[3] = ERI_r2CosPI4 * (r32Buf1[0] - r32Buf1[1]);
|
|
||||||
|
|
||||||
r32Buf2[3] -= r32Buf2[2];
|
|
||||||
|
|
||||||
ptrDst[0] = r32Buf2[0] + r32Buf2[2];
|
|
||||||
ptrDst[3] = r32Buf2[0] - r32Buf2[2];
|
|
||||||
ptrDst[1] = r32Buf2[1] + r32Buf2[3];
|
|
||||||
ptrDst[2] = r32Buf2[1] - r32Buf2[3];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint nDegreeNum = 1u << nDegreeDCT;
|
|
||||||
uint nHalfDegree = nDegreeNum >> 1;
|
|
||||||
int nSrcStep = nSrcInterval << 1;
|
|
||||||
eriFastIDCT (ptrDst, srcBuf, ptrSrc, nSrcStep, ptrWorkBuf, nDegreeDCT - 1);
|
|
||||||
|
|
||||||
float[] pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
|
||||||
int pOddDst = (int)nHalfDegree; // within ptrDst
|
|
||||||
int ptrNext = ptrSrc + nSrcInterval; // within srcBuf
|
|
||||||
|
|
||||||
uint i;
|
|
||||||
for (i = 0; i < nHalfDegree; i++)
|
|
||||||
{
|
|
||||||
ptrWorkBuf[i] = srcBuf[ptrNext] * pDCTofK[i];
|
|
||||||
ptrNext += nSrcStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
eriFastDCT (ptrDst, pOddDst, 1, ptrWorkBuf, 0, ptrWorkBuf, (int)nHalfDegree, nDegreeDCT - 1);
|
|
||||||
// eriFastDCT(pOddDst, 1, ptrWorkBuf, (ptrWorkBuf + nHalfDegree), nDegreeDCT - 1);
|
|
||||||
|
|
||||||
for (i = 0; i < nHalfDegree; i ++)
|
|
||||||
{
|
|
||||||
ptrDst[pOddDst + i] += ptrDst[pOddDst + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < nHalfDegree; i++)
|
|
||||||
{
|
|
||||||
ptrDst[pOddDst + i] -= ptrDst[pOddDst + i - 1];
|
|
||||||
}
|
|
||||||
float[] r32Buf = new float[4];
|
|
||||||
uint nQuadDegree = nHalfDegree >> 1;
|
|
||||||
for (i = 0; i < nQuadDegree; i++)
|
|
||||||
{
|
|
||||||
r32Buf[0] = ptrDst[i] + ptrDst[nHalfDegree + i];
|
|
||||||
r32Buf[3] = ptrDst[i] - ptrDst[nHalfDegree + i];
|
|
||||||
r32Buf[1] = ptrDst[nHalfDegree - 1 - i] + ptrDst[nDegreeNum - 1 - i];
|
|
||||||
r32Buf[2] = ptrDst[nHalfDegree - 1 - i] - ptrDst[nDegreeNum - 1 - i];
|
|
||||||
|
|
||||||
ptrDst[i] = r32Buf[0];
|
|
||||||
ptrDst[nHalfDegree - 1 - i] = r32Buf[1];
|
|
||||||
ptrDst[nHalfDegree + i] = r32Buf[2];
|
|
||||||
ptrDst[nDegreeNum - 1 - i] = r32Buf[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eriRevolve2x2 (float[] buf1, int ptrBuf1, float[] buf2, int ptrBuf2, float rSin, float rCos, int nStep, int nCount)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < nCount; i++)
|
|
||||||
{
|
|
||||||
float r1 = buf1[ptrBuf1];
|
|
||||||
float r2 = buf2[ptrBuf2];
|
|
||||||
|
|
||||||
buf1[ptrBuf1] = r1 * rCos - r2 * rSin;
|
|
||||||
buf2[ptrBuf2] = r1 * rSin + r2 * rCos;
|
|
||||||
|
|
||||||
ptrBuf1 += nStep;
|
|
||||||
ptrBuf2 += nStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user