263 lines
7.2 KiB
C++
Executable File
263 lines
7.2 KiB
C++
Executable File
#include "All.h"
|
|
#ifdef BACKWARDS_COMPATIBILITY
|
|
|
|
#include "Anti-Predictor.h"
|
|
#ifdef ENABLE_COMPRESSION_MODE_NORMAL
|
|
|
|
void CAntiPredictorNormal0000To3320::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
|
|
{
|
|
// variable declares
|
|
int *ip, *op, *op1, *op2;
|
|
int p, pw;
|
|
int m;
|
|
|
|
// short frame handling
|
|
if (NumberOfElements < 32)
|
|
{
|
|
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
|
|
return;
|
|
}
|
|
|
|
////////////////////////////////////////
|
|
// order 3
|
|
////////////////////////////////////////
|
|
memcpy(pOutputArray, pInputArray, 32);
|
|
|
|
// initialize values
|
|
m = 300;
|
|
op = &pOutputArray[8];
|
|
op1 = &pOutputArray[7];
|
|
op2 = &pOutputArray[6];
|
|
|
|
// make the first prediction
|
|
p = (pOutputArray[7] * 3) - (pOutputArray[6] * 3) + pOutputArray[5];
|
|
pw = (p * m) >> 12;
|
|
|
|
// loop through the array
|
|
for (ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++, op1++, op2++) {
|
|
|
|
// figure the output value
|
|
*op = *ip + pw;
|
|
|
|
// adjust m
|
|
if (*ip > 0)
|
|
m += (p > 0) ? 4 : -4;
|
|
else if (*ip < 0)
|
|
m += (p > 0) ? -4 : 4;
|
|
|
|
// make the next prediction
|
|
p = (*op * 3) - (*op1 * 3) + *op2;
|
|
pw = (p * m) >> 12;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////
|
|
// order 2
|
|
///////////////////////////////////////
|
|
memcpy(pInputArray, pOutputArray, 32);
|
|
m = 3000;
|
|
|
|
op1 = &pInputArray[7];
|
|
p = (*op1 * 2) - pInputArray[6];
|
|
pw = (p * m) >> 12;
|
|
|
|
for (op = &pInputArray[8], ip = &pOutputArray[8]; ip < &pOutputArray[NumberOfElements]; ip++, op++, op1++)
|
|
{
|
|
*op = *ip + pw;
|
|
|
|
// adjust m
|
|
if (*ip > 0)
|
|
m += (p > 0) ? 12 : -12;
|
|
else if (*ip < 0)
|
|
m += (p > 0) ? -12 : 12;
|
|
|
|
p = (*op * 2) - *op1;
|
|
pw = (p * m) >> 12;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// order 1
|
|
///////////////////////////////////////
|
|
pOutputArray[0] = pInputArray[0];
|
|
pOutputArray[1] = pInputArray[1] + pOutputArray[0];
|
|
pOutputArray[2] = pInputArray[2] + pOutputArray[1];
|
|
pOutputArray[3] = pInputArray[3] + pOutputArray[2];
|
|
pOutputArray[4] = pInputArray[4] + pOutputArray[3];
|
|
pOutputArray[5] = pInputArray[5] + pOutputArray[4];
|
|
pOutputArray[6] = pInputArray[6] + pOutputArray[5];
|
|
pOutputArray[7] = pInputArray[7] + pOutputArray[6];
|
|
|
|
m = 3900;
|
|
|
|
p = pOutputArray[7];
|
|
pw = (p * m) >> 12;
|
|
|
|
for (op = &pOutputArray[8], ip = &pInputArray[8]; ip < &pInputArray[NumberOfElements]; ip++, op++) {
|
|
*op = *ip + pw;
|
|
|
|
// adjust m
|
|
if (*ip > 0)
|
|
m += (p > 0) ? 1 : -1;
|
|
else if (*ip < 0)
|
|
m += (p > 0) ? -1 : 1;
|
|
|
|
p = *op;
|
|
pw = (p * m) >> 12;
|
|
}
|
|
|
|
}
|
|
|
|
void CAntiPredictorNormal3320To3800::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
|
|
{
|
|
// variable declares
|
|
int q;
|
|
|
|
// short frame handling
|
|
if (NumberOfElements < 8)
|
|
{
|
|
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
|
|
return;
|
|
}
|
|
|
|
// make the first five samples identical in both arrays
|
|
memcpy(pOutputArray, pInputArray, 20);
|
|
|
|
// initialize values
|
|
int m1 = 0;
|
|
int m2 = 64;
|
|
int m3 = 28;
|
|
int OP0;
|
|
int OP1 = pOutputArray[4];
|
|
|
|
int p3 = (3 * (pOutputArray[4] - pOutputArray[3])) + pOutputArray[2];
|
|
int p2 = pInputArray[4] + ((pInputArray[2] - pInputArray[3]) << 3) - pInputArray[1] + pInputArray[0];
|
|
int p1 = pOutputArray[4];
|
|
|
|
for (q = 5; q < NumberOfElements; q++)
|
|
{
|
|
OP0 = pInputArray[q] + ((p1 * m1) >> 8);
|
|
(pInputArray[q] ^ p1) > 0 ? m1++ : m1--;
|
|
p1 = OP0;
|
|
|
|
pInputArray[q] = OP0 + ((p2 * m2) >> 11);
|
|
(OP0 ^ p2) > 0 ? m2++ : m2--;
|
|
p2 = pInputArray[q] + ((pInputArray[q - 2] - pInputArray[q - 1]) << 3) - pInputArray[q - 3] + pInputArray[q - 4];
|
|
|
|
pOutputArray[q] = pInputArray[q] + ((p3 * m3) >> 9);
|
|
(pInputArray[q] ^ p3) > 0 ? m3++ : m3--;
|
|
p3 = (3 * (pOutputArray[q] - pOutputArray[q - 1])) + pOutputArray[q - 2];
|
|
}
|
|
|
|
int m4 = 370;
|
|
int m5 = 3900;
|
|
|
|
pOutputArray[1] = pInputArray[1] + pOutputArray[0];
|
|
pOutputArray[2] = pInputArray[2] + pOutputArray[1];
|
|
pOutputArray[3] = pInputArray[3] + pOutputArray[2];
|
|
pOutputArray[4] = pInputArray[4] + pOutputArray[3];
|
|
|
|
int p4 = (2 * pInputArray[4]) - pInputArray[3];
|
|
int p5 = pOutputArray[4];
|
|
int IP0, IP1;
|
|
|
|
IP1 = pInputArray[4];
|
|
for (q = 5; q < NumberOfElements; q++)
|
|
{
|
|
IP0 = pOutputArray[q] + ((p4 * m4) >> 9);
|
|
(pOutputArray[q] ^ p4) > 0 ? m4++ : m4--;
|
|
p4 = (2 * IP0) - IP1;
|
|
|
|
pOutputArray[q] = IP0 + ((p5 * m5) >> 12);
|
|
(IP0 ^ p5) > 0 ? m5++ : m5--;
|
|
p5 = pOutputArray[q];
|
|
|
|
IP1 = IP0;
|
|
}
|
|
}
|
|
|
|
void CAntiPredictorNormal3800ToCurrent::AntiPredict(int *pInputArray, int *pOutputArray, int NumberOfElements)
|
|
{
|
|
// the frame to start prediction on
|
|
#define FIRST_ELEMENT 4
|
|
|
|
// short frame handling
|
|
if (NumberOfElements < 8)
|
|
{
|
|
memcpy(pOutputArray, pInputArray, NumberOfElements * 4);
|
|
return;
|
|
}
|
|
|
|
// make the first five samples identical in both arrays
|
|
memcpy(pOutputArray, pInputArray, FIRST_ELEMENT * 4);
|
|
|
|
// variable declares and initializations
|
|
int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0;
|
|
int p4 = pInputArray[FIRST_ELEMENT - 1];
|
|
int p3 = (pInputArray[FIRST_ELEMENT - 1] - pInputArray[FIRST_ELEMENT - 2]) << 1;
|
|
int p2 = pInputArray[FIRST_ELEMENT - 1] + ((pInputArray[FIRST_ELEMENT - 3] - pInputArray[FIRST_ELEMENT - 2]) << 3);// - pInputArray[3] + pInputArray[2];
|
|
int *op = &pOutputArray[FIRST_ELEMENT];
|
|
int *ip = &pInputArray[FIRST_ELEMENT];
|
|
int IPP2 = ip[-2];
|
|
int p7 = 2 * ip[-1] - ip[-2];
|
|
int opp = op[-1];
|
|
|
|
// undo the initial prediction stuff
|
|
for (int q = 1; q < FIRST_ELEMENT; q++) {
|
|
pOutputArray[q] += pOutputArray[q - 1];
|
|
}
|
|
|
|
// pump the primary loop
|
|
for (; op < &pOutputArray[NumberOfElements]; op++, ip++) {
|
|
|
|
register int o = *op, i = *ip;
|
|
|
|
/////////////////////////////////////////////
|
|
o = i + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11);
|
|
|
|
if (i > 0)
|
|
{
|
|
m2 -= ((p2 >> 30) & 2) - 1;
|
|
m3 -= ((p3 >> 28) & 8) - 4;
|
|
m4 -= ((p4 >> 28) & 8) - 4;
|
|
|
|
}
|
|
else if (i < 0)
|
|
{
|
|
m2 += ((p2 >> 30) & 2) - 1;
|
|
m3 += ((p3 >> 28) & 8) - 4;
|
|
m4 += ((p4 >> 28) & 8) - 4;
|
|
}
|
|
|
|
|
|
p2 = o + ((IPP2 - p4) << 3);
|
|
p3 = (o - p4) << 1;
|
|
IPP2 = p4;
|
|
p4 = o;
|
|
|
|
/////////////////////////////////////////////
|
|
o += (((p7 * m5) - (opp * m6)) >> 10);
|
|
|
|
if (p4 > 0)
|
|
{
|
|
m5 -= ((p7 >> 29) & 4) - 2;
|
|
m6 += ((opp >> 30) & 2) - 1;
|
|
}
|
|
else if (p4 < 0)
|
|
{
|
|
m5 += ((p7 >> 29) & 4) - 2;
|
|
m6 -= ((opp >> 30) & 2) - 1;
|
|
}
|
|
|
|
p7 = 2 * o - opp;
|
|
opp = o;
|
|
|
|
/////////////////////////////////////////////
|
|
*op = o + ((op[-1] * 31) >> 5);
|
|
}
|
|
}
|
|
|
|
#endif // #ifdef ENABLE_COMPRESSION_MODE_NORMAL
|
|
|
|
#endif // #ifdef BACKWARDS_COMPATIBILITY
|