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