1#include "All.h"
2#include "APECompress.h"
3#include "NewPredictor.h"
4
5/*****************************************************************************************
6CPredictorCompressNormal
7*****************************************************************************************/
8CPredictorCompressNormal::CPredictorCompressNormal(int nCompressionLevel)
9    : IPredictorCompress(nCompressionLevel)
10{
11    if (nCompressionLevel == COMPRESSION_LEVEL_FAST)
12    {
13        m_pNNFilter = NULL;
14        m_pNNFilter1 = NULL;
15        m_pNNFilter2 = NULL;
16    }
17    else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL)
18    {
19        m_pNNFilter = new CNNFilter(16, 11, MAC_VERSION_NUMBER);
20        m_pNNFilter1 = NULL;
21        m_pNNFilter2 = NULL;
22    }
23    else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH)
24    {
25        m_pNNFilter = new CNNFilter(64, 11, MAC_VERSION_NUMBER);
26        m_pNNFilter1 = NULL;
27        m_pNNFilter2 = NULL;
28    }
29    else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH)
30    {
31        m_pNNFilter = new CNNFilter(256, 13, MAC_VERSION_NUMBER);
32        m_pNNFilter1 = new CNNFilter(32, 10, MAC_VERSION_NUMBER);
33        m_pNNFilter2 = NULL;
34    }
35    else if (nCompressionLevel == COMPRESSION_LEVEL_INSANE)
36    {
37        m_pNNFilter = new CNNFilter(1024 + 256, 15, MAC_VERSION_NUMBER);
38        m_pNNFilter1 = new CNNFilter(256, 13, MAC_VERSION_NUMBER);
39        m_pNNFilter2 = new CNNFilter(16, 11, MAC_VERSION_NUMBER);
40
41    }
42    else
43    {
44        throw(1);
45    }
46}
47CPredictorCompressNormal::~CPredictorCompressNormal()
48{
49    SAFE_DELETE(m_pNNFilter)
50    SAFE_DELETE(m_pNNFilter1)
51    SAFE_DELETE(m_pNNFilter2)
52}
53
54int CPredictorCompressNormal::Flush()
55{
56    if (m_pNNFilter) m_pNNFilter->Flush();
57    if (m_pNNFilter1) m_pNNFilter1->Flush();
58    if (m_pNNFilter2) m_pNNFilter2->Flush();
59
60    m_rbPrediction.Flush();
61    m_rbAdapt.Flush();
62    m_Stage1FilterA.Flush(); m_Stage1FilterB.Flush();
63
64    memset(m_aryM, 0, sizeof(m_aryM));
65
66    int * paryM = &m_aryM[8];
67    paryM[0] = 360;
68    paryM[-1] = 317;
69    paryM[-2] = -109;
70    paryM[-3] = 98;
71
72    m_nCurrentIndex = 0;
73
74    return ERROR_SUCCESS;
75}
76
77int CPredictorCompressNormal::CompressValue(int nA, int nB)
78{
79    // roll the buffers if necessary
80    if (m_nCurrentIndex == WINDOW_BLOCKS)
81    {
82        m_rbPrediction.Roll(); m_rbAdapt.Roll();
83        m_nCurrentIndex = 0;
84    }
85
86    // stage 1: simple, non-adaptive order 1 prediction
87    nA = m_Stage1FilterA.Compress(nA);
88    nB = m_Stage1FilterB.Compress(nB);
89
90    // stage 2: adaptive offset filter(s)
91    m_rbPrediction[0] = nA;
92    m_rbPrediction[-2] = m_rbPrediction[-1] - m_rbPrediction[-2];
93
94    m_rbPrediction[-5] = nB;
95    m_rbPrediction[-6] = m_rbPrediction[-5] - m_rbPrediction[-6];
96
97    int * paryM = &m_aryM[8];
98
99    int nPredictionA = (m_rbPrediction[-1] * paryM[0]) + (m_rbPrediction[-2] * paryM[-1]) + (m_rbPrediction[-3] * paryM[-2]) + (m_rbPrediction[-4] * paryM[-3]);
100    int nPredictionB = (m_rbPrediction[-5] * paryM[-4]) + (m_rbPrediction[-6] * paryM[-5]) + (m_rbPrediction[-7] * paryM[-6]) + (m_rbPrediction[-8] * paryM[-7]) + (m_rbPrediction[-9] * paryM[-8]);
101
102    int nOutput = nA - ((nPredictionA + (nPredictionB >> 1)) >> 10);
103
104    // adapt
105    m_rbAdapt[0] = (m_rbPrediction[-1]) ? ((m_rbPrediction[-1] >> 30) & 2) - 1 : 0;
106    m_rbAdapt[-1] = (m_rbPrediction[-2]) ? ((m_rbPrediction[-2] >> 30) & 2) - 1 : 0;
107    m_rbAdapt[-4] = (m_rbPrediction[-5]) ? ((m_rbPrediction[-5] >> 30) & 2) - 1 : 0;
108    m_rbAdapt[-5] = (m_rbPrediction[-6]) ? ((m_rbPrediction[-6] >> 30) & 2) - 1 : 0;
109
110    if (nOutput > 0)
111    {
112        int * pM = &paryM[-8]; int * pAdapt = &m_rbAdapt[-8];
113        EXPAND_9_TIMES(*pM++ -= *pAdapt++;)
114    }
115    else if (nOutput < 0)
116    {
117        int * pM = &paryM[-8]; int * pAdapt = &m_rbAdapt[-8];
118        EXPAND_9_TIMES(*pM++ += *pAdapt++;)
119    }
120
121    // stage 3: NNFilters
122    if (m_pNNFilter)
123    {
124        nOutput = m_pNNFilter->Compress(nOutput);
125
126        if (m_pNNFilter1)
127        {
128            nOutput = m_pNNFilter1->Compress(nOutput);
129
130            if (m_pNNFilter2)
131                nOutput = m_pNNFilter2->Compress(nOutput);
132        }
133    }
134
135    m_rbPrediction.IncrementFast();    m_rbAdapt.IncrementFast();
136    m_nCurrentIndex++;
137
138    return nOutput;
139}
140
141/*****************************************************************************************
142CPredictorDecompressNormal3930to3950
143*****************************************************************************************/
144CPredictorDecompressNormal3930to3950::CPredictorDecompressNormal3930to3950(int nCompressionLevel, int nVersion)
145    : IPredictorDecompress(nCompressionLevel, nVersion)
146{
147    m_pBuffer[0] = new int [HISTORY_ELEMENTS + WINDOW_BLOCKS];
148
149    if (nCompressionLevel == COMPRESSION_LEVEL_FAST)
150    {
151        m_pNNFilter = NULL;
152        m_pNNFilter1 = NULL;
153    }
154    else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL)
155    {
156        m_pNNFilter = new CNNFilter(16, 11, nVersion);
157        m_pNNFilter1 = NULL;
158    }
159    else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH)
160    {
161        m_pNNFilter = new CNNFilter(64, 11, nVersion);
162        m_pNNFilter1 = NULL;
163    }
164    else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH)
165    {
166        m_pNNFilter = new CNNFilter(256, 13, nVersion);
167        m_pNNFilter1 = new CNNFilter(32, 10, nVersion);
168    }
169    else
170    {
171        throw(1);
172    }
173}
174
175CPredictorDecompressNormal3930to3950::~CPredictorDecompressNormal3930to3950()
176{
177    SAFE_DELETE(m_pNNFilter)
178    SAFE_DELETE(m_pNNFilter1)
179    SAFE_ARRAY_DELETE(m_pBuffer[0])
180}
181
182int CPredictorDecompressNormal3930to3950::Flush()
183{
184    if (m_pNNFilter) m_pNNFilter->Flush();
185    if (m_pNNFilter1) m_pNNFilter1->Flush();
186
187    ZeroMemory(m_pBuffer[0], (HISTORY_ELEMENTS + 1) * sizeof(int));
188    ZeroMemory(&m_aryM[0], M_COUNT * sizeof(int));
189
190    m_aryM[0] = 360;
191    m_aryM[1] = 317;
192    m_aryM[2] = -109;
193    m_aryM[3] = 98;
194
195    m_pInputBuffer = &m_pBuffer[0][HISTORY_ELEMENTS];
196
197    m_nLastValue = 0;
198    m_nCurrentIndex = 0;
199
200    return ERROR_SUCCESS;
201}
202
203int CPredictorDecompressNormal3930to3950::DecompressValue(int nInput, int)
204{
205    if (m_nCurrentIndex == WINDOW_BLOCKS)
206    {
207        // copy forward and adjust pointers
208        memcpy(&m_pBuffer[0][0], &m_pBuffer[0][WINDOW_BLOCKS], HISTORY_ELEMENTS * sizeof(int));
209        m_pInputBuffer = &m_pBuffer[0][HISTORY_ELEMENTS];
210
211        m_nCurrentIndex = 0;
212    }
213
214    // stage 2: NNFilter
215    if (m_pNNFilter1)
216        nInput = m_pNNFilter1->Decompress(nInput);
217    if (m_pNNFilter)
218        nInput = m_pNNFilter->Decompress(nInput);
219
220    // stage 1: multiple predictors (order 2 and offset 1)
221
222    int p1 = m_pInputBuffer[-1];
223    int p2 = m_pInputBuffer[-1] - m_pInputBuffer[-2];
224    int p3 = m_pInputBuffer[-2] - m_pInputBuffer[-3];
225    int p4 = m_pInputBuffer[-3] - m_pInputBuffer[-4];
226
227    m_pInputBuffer[0] = nInput + (((p1 * m_aryM[0]) + (p2 * m_aryM[1]) + (p3 * m_aryM[2]) + (p4 * m_aryM[3])) >> 9);
228
229    if (nInput > 0)
230    {
231        m_aryM[0] -= ((p1 >> 30) & 2) - 1;
232        m_aryM[1] -= ((p2 >> 30) & 2) - 1;
233        m_aryM[2] -= ((p3 >> 30) & 2) - 1;
234        m_aryM[3] -= ((p4 >> 30) & 2) - 1;
235    }
236    else if (nInput < 0)
237    {
238        m_aryM[0] += ((p1 >> 30) & 2) - 1;
239        m_aryM[1] += ((p2 >> 30) & 2) - 1;
240        m_aryM[2] += ((p3 >> 30) & 2) - 1;
241        m_aryM[3] += ((p4 >> 30) & 2) - 1;
242    }
243
244    int nRetVal = m_pInputBuffer[0] + ((m_nLastValue * 31) >> 5);
245    m_nLastValue = nRetVal;
246
247    m_nCurrentIndex++;
248    m_pInputBuffer++;
249
250    return nRetVal;
251}
252
253/*****************************************************************************************
254CPredictorDecompress3950toCurrent
255*****************************************************************************************/
256CPredictorDecompress3950toCurrent::CPredictorDecompress3950toCurrent(int nCompressionLevel, int nVersion)
257    : IPredictorDecompress(nCompressionLevel, nVersion)
258{
259    m_nVersion = nVersion;
260
261    if (nCompressionLevel == COMPRESSION_LEVEL_FAST)
262    {
263        m_pNNFilter = NULL;
264        m_pNNFilter1 = NULL;
265        m_pNNFilter2 = NULL;
266    }
267    else if (nCompressionLevel == COMPRESSION_LEVEL_NORMAL)
268    {
269        m_pNNFilter = new CNNFilter(16, 11, nVersion);
270        m_pNNFilter1 = NULL;
271        m_pNNFilter2 = NULL;
272    }
273    else if (nCompressionLevel == COMPRESSION_LEVEL_HIGH)
274    {
275        m_pNNFilter = new CNNFilter(64, 11, nVersion);
276        m_pNNFilter1 = NULL;
277        m_pNNFilter2 = NULL;
278    }
279    else if (nCompressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH)
280    {
281        m_pNNFilter = new CNNFilter(256, 13, nVersion);
282        m_pNNFilter1 = new CNNFilter(32, 10, nVersion);
283        m_pNNFilter2 = NULL;
284    }
285    else if (nCompressionLevel == COMPRESSION_LEVEL_INSANE)
286    {
287        m_pNNFilter = new CNNFilter(1024 + 256, 15, MAC_VERSION_NUMBER);
288        m_pNNFilter1 = new CNNFilter(256, 13, MAC_VERSION_NUMBER);
289        m_pNNFilter2 = new CNNFilter(16, 11, MAC_VERSION_NUMBER);
290
291    }
292    else
293    {
294        throw(1);
295    }
296}
297
298CPredictorDecompress3950toCurrent::~CPredictorDecompress3950toCurrent()
299{
300    SAFE_DELETE(m_pNNFilter)
301    SAFE_DELETE(m_pNNFilter1)
302    SAFE_DELETE(m_pNNFilter2)
303}
304
305int CPredictorDecompress3950toCurrent::Flush()
306{
307    if (m_pNNFilter) m_pNNFilter->Flush();
308    if (m_pNNFilter1) m_pNNFilter1->Flush();
309    if (m_pNNFilter2) m_pNNFilter2->Flush();
310
311    ZeroMemory(m_aryMA, sizeof(m_aryMA));
312    ZeroMemory(m_aryMB, sizeof(m_aryMB));
313
314    m_rbPredictionA.Flush();
315    m_rbPredictionB.Flush();
316    m_rbAdaptA.Flush();
317    m_rbAdaptB.Flush();
318
319    m_aryMA[0] = 360;
320    m_aryMA[1] = 317;
321    m_aryMA[2] = -109;
322    m_aryMA[3] = 98;
323
324    m_Stage1FilterA.Flush();
325    m_Stage1FilterB.Flush();
326
327    m_nLastValueA = 0;
328
329    m_nCurrentIndex = 0;
330
331    return ERROR_SUCCESS;
332}
333
334int CPredictorDecompress3950toCurrent::DecompressValue(int nA, int nB)
335{
336    if (m_nCurrentIndex == WINDOW_BLOCKS)
337    {
338        // copy forward and adjust pointers
339        m_rbPredictionA.Roll();    m_rbPredictionB.Roll();
340        m_rbAdaptA.Roll(); m_rbAdaptB.Roll();
341
342        m_nCurrentIndex = 0;
343    }
344
345    // stage 2: NNFilter
346    if (m_pNNFilter2)
347        nA = m_pNNFilter2->Decompress(nA);
348    if (m_pNNFilter1)
349        nA = m_pNNFilter1->Decompress(nA);
350    if (m_pNNFilter)
351        nA = m_pNNFilter->Decompress(nA);
352
353    // stage 1: multiple predictors (order 2 and offset 1)
354    m_rbPredictionA[0] = m_nLastValueA;
355    m_rbPredictionA[-1] = m_rbPredictionA[0] - m_rbPredictionA[-1];
356
357    m_rbPredictionB[0] = m_Stage1FilterB.Compress(nB);
358    m_rbPredictionB[-1] = m_rbPredictionB[0] - m_rbPredictionB[-1];
359
360    int nPredictionA = (m_rbPredictionA[0] * m_aryMA[0]) + (m_rbPredictionA[-1] * m_aryMA[1]) + (m_rbPredictionA[-2] * m_aryMA[2]) + (m_rbPredictionA[-3] * m_aryMA[3]);
361    int nPredictionB = (m_rbPredictionB[0] * m_aryMB[0]) + (m_rbPredictionB[-1] * m_aryMB[1]) + (m_rbPredictionB[-2] * m_aryMB[2]) + (m_rbPredictionB[-3] * m_aryMB[3]) + (m_rbPredictionB[-4] * m_aryMB[4]);
362
363    int nCurrentA = nA + ((nPredictionA + (nPredictionB >> 1)) >> 10);
364
365    m_rbAdaptA[0] = (m_rbPredictionA[0]) ? ((m_rbPredictionA[0] >> 30) & 2) - 1 : 0;
366    m_rbAdaptA[-1] = (m_rbPredictionA[-1]) ? ((m_rbPredictionA[-1] >> 30) & 2) - 1 : 0;
367
368    m_rbAdaptB[0] = (m_rbPredictionB[0]) ? ((m_rbPredictionB[0] >> 30) & 2) - 1 : 0;
369    m_rbAdaptB[-1] = (m_rbPredictionB[-1]) ? ((m_rbPredictionB[-1] >> 30) & 2) - 1 : 0;
370
371    if (nA > 0)
372    {
373        m_aryMA[0] -= m_rbAdaptA[0];
374        m_aryMA[1] -= m_rbAdaptA[-1];
375        m_aryMA[2] -= m_rbAdaptA[-2];
376        m_aryMA[3] -= m_rbAdaptA[-3];
377
378        m_aryMB[0] -= m_rbAdaptB[0];
379        m_aryMB[1] -= m_rbAdaptB[-1];
380        m_aryMB[2] -= m_rbAdaptB[-2];
381        m_aryMB[3] -= m_rbAdaptB[-3];
382        m_aryMB[4] -= m_rbAdaptB[-4];
383    }
384    else if (nA < 0)
385    {
386        m_aryMA[0] += m_rbAdaptA[0];
387        m_aryMA[1] += m_rbAdaptA[-1];
388        m_aryMA[2] += m_rbAdaptA[-2];
389        m_aryMA[3] += m_rbAdaptA[-3];
390
391        m_aryMB[0] += m_rbAdaptB[0];
392        m_aryMB[1] += m_rbAdaptB[-1];
393        m_aryMB[2] += m_rbAdaptB[-2];
394        m_aryMB[3] += m_rbAdaptB[-3];
395        m_aryMB[4] += m_rbAdaptB[-4];
396    }
397
398    int nRetVal = m_Stage1FilterA.Decompress(nCurrentA);
399    m_nLastValueA = nCurrentA;
400
401    m_rbPredictionA.IncrementFast(); m_rbPredictionB.IncrementFast();
402    m_rbAdaptA.IncrementFast(); m_rbAdaptB.IncrementFast();
403
404    m_nCurrentIndex++;
405
406    return nRetVal;
407}
408