fb25e53b4f
Strip out Sort Transform from Libbsc copy. Reduce Libbsc memory use. Avoid redundant adler32 of data block in Libbsc.
1363 lines
61 KiB
C++
1363 lines
61 KiB
C++
/*-----------------------------------------------------------*/
|
|
/* Block Sorting, Lossless Data Compression Library. */
|
|
/* Quantized Local Frequency Coding functions */
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*--
|
|
|
|
This file is a part of bsc and/or libbsc, a program and a library for
|
|
lossless, block-sorting data compression.
|
|
|
|
Copyright (c) 2009-2012 Ilya Grebnov <ilya.grebnov@gmail.com>
|
|
|
|
See file AUTHORS for a full list of contributors.
|
|
|
|
The bsc and libbsc is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or (at your
|
|
option) any later version.
|
|
|
|
The bsc and libbsc is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with the bsc and libbsc. If not, see http://www.gnu.org/licenses/.
|
|
|
|
Please see the files COPYING and COPYING.LIB for full copyright information.
|
|
|
|
See also the bsc and libbsc web site:
|
|
http://libbsc.com/ for more information.
|
|
|
|
--*/
|
|
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
|
|
#include "qlfc.h"
|
|
|
|
#include "../../libbsc.h"
|
|
#include "../../platform/platform.h"
|
|
|
|
#include "../common/rangecoder.h"
|
|
#include "../common/tables.h"
|
|
#include "../common/predictor.h"
|
|
|
|
#include "qlfc_model.h"
|
|
|
|
int bsc_qlfc_init(int features)
|
|
{
|
|
return bsc_qlfc_init_static_model();
|
|
}
|
|
|
|
unsigned char * bsc_qlfc_transform(const unsigned char * RESTRICT input, unsigned char * RESTRICT buffer, int n, unsigned char * RESTRICT MTFTable)
|
|
{
|
|
unsigned char Flag[ALPHABET_SIZE];
|
|
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) Flag[i] = 0;
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) MTFTable[i] = i;
|
|
|
|
if (input[n - 1] == 0)
|
|
{
|
|
MTFTable[0] = 1; MTFTable[1] = 0;
|
|
}
|
|
|
|
int index = n, nSymbols = 0;
|
|
for (int i = n - 1; i >= 0;)
|
|
{
|
|
unsigned char currentChar = input[i--];
|
|
for (; (i >= 0) && (input[i] == currentChar); --i) ;
|
|
|
|
unsigned char previousChar = MTFTable[0], rank = 1; MTFTable[0] = currentChar;
|
|
while (true)
|
|
{
|
|
unsigned char temporaryChar0 = MTFTable[rank + 0]; MTFTable[rank + 0] = previousChar;
|
|
if (temporaryChar0 == currentChar) { rank += 0; break; }
|
|
|
|
unsigned char temporaryChar1 = MTFTable[rank + 1]; MTFTable[rank + 1] = temporaryChar0;
|
|
if (temporaryChar1 == currentChar) { rank += 1; break; }
|
|
|
|
unsigned char temporaryChar2 = MTFTable[rank + 2]; MTFTable[rank + 2] = temporaryChar1;
|
|
if (temporaryChar2 == currentChar) { rank += 2; break; }
|
|
|
|
unsigned char temporaryChar3 = MTFTable[rank + 3]; MTFTable[rank + 3] = temporaryChar2;
|
|
if (temporaryChar3 == currentChar) { rank += 3; break; }
|
|
|
|
rank += 4; previousChar = temporaryChar3;
|
|
}
|
|
|
|
if (Flag[currentChar] == 0)
|
|
{
|
|
Flag[currentChar] = 1;
|
|
rank = nSymbols++;
|
|
}
|
|
|
|
buffer[--index] = rank;
|
|
}
|
|
|
|
buffer[n - 1] = 1;
|
|
|
|
for (int rank = 1; rank < ALPHABET_SIZE; ++rank)
|
|
{
|
|
if (Flag[MTFTable[rank]] == 0)
|
|
{
|
|
MTFTable[rank] = MTFTable[rank - 1];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return buffer + index;
|
|
}
|
|
|
|
int bsc_qlfc_adaptive_encode(const unsigned char * input, unsigned char * output, unsigned char * buffer, int inputSize, int outputSize, QlfcStatisticalModel * model)
|
|
{
|
|
unsigned char MTFTable[ALPHABET_SIZE];
|
|
|
|
bsc_qlfc_init_model(model);
|
|
|
|
int contextRank0 = 0;
|
|
int contextRank4 = 0;
|
|
int contextRun = 0;
|
|
int maxRank = 7;
|
|
int avgRank = 0;
|
|
|
|
unsigned char rankHistory[ALPHABET_SIZE], runHistory[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i)
|
|
{
|
|
rankHistory[i] = runHistory[i] = 0;
|
|
}
|
|
|
|
unsigned char * rankArray = bsc_qlfc_transform(input, buffer, inputSize, MTFTable);
|
|
|
|
RangeCoder coder;
|
|
|
|
coder.InitEncoder(output, outputSize);
|
|
coder.EncodeWord((unsigned int)inputSize);
|
|
|
|
unsigned char usedChar[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) usedChar[i] = 0;
|
|
|
|
int prevChar = -1;
|
|
for (int rank = 0; rank < ALPHABET_SIZE; ++rank)
|
|
{
|
|
int currentChar = MTFTable[rank];
|
|
|
|
for (int bit = 7; bit >= 0; --bit)
|
|
{
|
|
bool bit0 = false, bit1 = false;
|
|
|
|
for (int c = 0; c < ALPHABET_SIZE; ++c)
|
|
{
|
|
if (c == prevChar || usedChar[c] == 0)
|
|
{
|
|
if ((currentChar >> (bit + 1)) == (c >> (bit + 1)))
|
|
{
|
|
if (c & (1 << bit)) bit1 = true; else bit0 = true;
|
|
if (bit0 && bit1) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bit0 && bit1)
|
|
{
|
|
coder.EncodeBit(currentChar & (1 << bit));
|
|
}
|
|
}
|
|
|
|
if (currentChar == prevChar)
|
|
{
|
|
maxRank = bsc_log2_256(rank - 1);
|
|
break;
|
|
}
|
|
|
|
prevChar = currentChar; usedChar[currentChar] = 1;
|
|
}
|
|
|
|
for (const unsigned char * inputEnd = input + inputSize; input < inputEnd;)
|
|
{
|
|
if (coder.CheckEOB())
|
|
{
|
|
return LIBBSC_NOT_COMPRESSIBLE;
|
|
}
|
|
|
|
int currentChar = *input, runSize;
|
|
{
|
|
const unsigned char * inputStart = input++;
|
|
while (true)
|
|
{
|
|
if (input <= inputEnd - 4)
|
|
{
|
|
if (input[0] != currentChar) { input += 0; break; }
|
|
if (input[1] != currentChar) { input += 1; break; }
|
|
if (input[2] != currentChar) { input += 2; break; }
|
|
if (input[3] != currentChar) { input += 3; break; }
|
|
|
|
input += 4;
|
|
}
|
|
else
|
|
{
|
|
while ((input < inputEnd) && (*input == currentChar)) ++input;
|
|
break;
|
|
}
|
|
}
|
|
|
|
runSize = (int)(input - inputStart);
|
|
}
|
|
|
|
int rank = *rankArray++;
|
|
int history = rankHistory[currentChar];
|
|
int state = model_rank_state(contextRank4, contextRun, history);
|
|
|
|
short * RESTRICT statePredictor = & model->Rank.StateModel[state];
|
|
short * RESTRICT charPredictor = & model->Rank.CharModel[currentChar];
|
|
short * RESTRICT staticPredictor = & model->Rank.StaticModel;
|
|
ProbabilityMixer * RESTRICT mixer = & model->mixerOfRank[currentChar];
|
|
|
|
if (avgRank < 32)
|
|
{
|
|
if (rank == 1)
|
|
{
|
|
rankHistory[currentChar] = 0;
|
|
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RANK_TS_TH0, M_RANK_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RANK_TC_TH0, M_RANK_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RANK_TP_TH0, M_RANK_TP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RANK_TM_LR0, M_RANK_TM_LR1, M_RANK_TM_LR2, M_RANK_TM_TH0, M_RANK_TM_AR0));
|
|
}
|
|
else
|
|
{
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RANK_TS_TH1, M_RANK_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RANK_TC_TH1, M_RANK_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RANK_TP_TH1, M_RANK_TP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RANK_TM_LR0, M_RANK_TM_LR1, M_RANK_TM_LR2, M_RANK_TM_TH1, M_RANK_TM_AR1));
|
|
}
|
|
|
|
int bitRankSize = bsc_log2_256(rank); rankHistory[currentChar] = bitRankSize;
|
|
|
|
statePredictor = & model->Rank.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Rank.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Exponent.StaticModel[0];
|
|
mixer = & model->mixerOfRankExponent[history < 1 ? 1 : history][1];
|
|
|
|
for (int bit = 1; bit < bitRankSize; ++bit, ++statePredictor, ++charPredictor, ++staticPredictor)
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RANK_ES_TH1, M_RANK_ES_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RANK_EC_TH1, M_RANK_EC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RANK_EP_TH1, M_RANK_EP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RANK_EM_LR0, M_RANK_EM_LR1, M_RANK_EM_LR2, M_RANK_EM_TH1, M_RANK_EM_AR1));
|
|
|
|
mixer = & model->mixerOfRankExponent[history <= bit ? bit + 1 : history][bit + 1];
|
|
}
|
|
if (bitRankSize < maxRank)
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RANK_ES_TH0, M_RANK_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RANK_EC_TH0, M_RANK_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RANK_EP_TH0, M_RANK_EP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RANK_EM_LR0, M_RANK_EM_LR1, M_RANK_EM_LR2, M_RANK_EM_TH0, M_RANK_EM_AR0));
|
|
}
|
|
|
|
statePredictor = & model->Rank.Mantissa[bitRankSize].StateModel[state][0];
|
|
charPredictor = & model->Rank.Mantissa[bitRankSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Mantissa[bitRankSize].StaticModel[0];
|
|
mixer = & model->mixerOfRankMantissa[bitRankSize];
|
|
|
|
for (int context = 1, bit = bitRankSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (rank & (1 << bit))
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], M_RANK_MS_TH1, M_RANK_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], M_RANK_MC_TH1, M_RANK_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], M_RANK_MP_TH1, M_RANK_MP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RANK_MM_LR0, M_RANK_MM_LR1, M_RANK_MM_LR2, M_RANK_MM_TH1, M_RANK_MM_AR1));
|
|
|
|
context += context + 1;
|
|
}
|
|
else
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], M_RANK_MS_TH0, M_RANK_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], M_RANK_MC_TH0, M_RANK_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], M_RANK_MP_TH0, M_RANK_MP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RANK_MM_LR0, M_RANK_MM_LR1, M_RANK_MM_LR2, M_RANK_MM_TH0, M_RANK_MM_AR0));
|
|
|
|
context += context;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rankHistory[currentChar] = bsc_log2_256(rank);
|
|
|
|
statePredictor = & model->Rank.Escape.StateModel[state][0];
|
|
charPredictor = & model->Rank.Escape.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Escape.StaticModel[0];
|
|
|
|
for (int context = 1, bit = maxRank; bit >= 0; --bit)
|
|
{
|
|
mixer = & model->mixerOfRankEscape[context];
|
|
|
|
if (rank & (1 << bit))
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], M_RANK_PS_TH1, M_RANK_PS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], M_RANK_PC_TH1, M_RANK_PC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], M_RANK_PP_TH1, M_RANK_PP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RANK_PM_LR0, M_RANK_PM_LR1, M_RANK_PM_LR2, M_RANK_PM_TH1, M_RANK_PM_AR1));
|
|
|
|
context += context + 1;
|
|
}
|
|
else
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], M_RANK_PS_TH0, M_RANK_PS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], M_RANK_PC_TH0, M_RANK_PC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], M_RANK_PP_TH0, M_RANK_PP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RANK_PM_LR0, M_RANK_PM_LR1, M_RANK_PM_LR2, M_RANK_PM_TH0, M_RANK_PM_AR0));
|
|
|
|
context += context;
|
|
}
|
|
}
|
|
}
|
|
|
|
avgRank = (avgRank * 124 + rank * 4) >> 7;
|
|
rank = rank - 1;
|
|
history = runHistory[currentChar];
|
|
state = model_run_state(contextRank0, contextRun, rank, history);
|
|
statePredictor = & model->Run.StateModel[state];
|
|
charPredictor = & model->Run.CharModel[currentChar];
|
|
staticPredictor = & model->Run.StaticModel;
|
|
mixer = & model->mixerOfRun[currentChar];
|
|
|
|
if (runSize == 1)
|
|
{
|
|
runHistory[currentChar] = (runHistory[currentChar] + 2) >> 2;
|
|
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RUN_TS_TH0, M_RUN_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RUN_TC_TH0, M_RUN_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RUN_TP_TH0, M_RUN_TP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RUN_TM_LR0, M_RUN_TM_LR1, M_RUN_TM_LR2, M_RUN_TM_TH0, M_RUN_TM_AR0));
|
|
}
|
|
else
|
|
{
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RUN_TS_TH1, M_RUN_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RUN_TC_TH1, M_RUN_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RUN_TP_TH1, M_RUN_TP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RUN_TM_LR0, M_RUN_TM_LR1, M_RUN_TM_LR2, M_RUN_TM_TH1, M_RUN_TM_AR1));
|
|
}
|
|
|
|
int bitRunSize = bsc_log2(runSize); runHistory[currentChar] = (runHistory[currentChar] + 3 * bitRunSize + 3) >> 2;
|
|
|
|
statePredictor = & model->Run.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Run.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Exponent.StaticModel[0];
|
|
mixer = & model->mixerOfRunExponent[history < 1 ? 1 : history][1];
|
|
|
|
for (int bit = 1; bit < bitRunSize; ++bit, ++statePredictor, ++charPredictor, ++staticPredictor)
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RUN_ES_TH1, M_RUN_ES_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RUN_EC_TH1, M_RUN_EC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RUN_EP_TH1, M_RUN_EP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RUN_EM_LR0, M_RUN_EM_LR1, M_RUN_EM_LR2, M_RUN_EM_TH1, M_RUN_EM_AR1));
|
|
|
|
mixer = & model->mixerOfRunExponent[history <= bit ? bit + 1 : history][bit + 1];
|
|
}
|
|
{
|
|
int probability0 = *charPredictor, probability1 = *statePredictor, probability2 = *staticPredictor;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RUN_ES_TH0, M_RUN_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RUN_EC_TH0, M_RUN_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RUN_EP_TH0, M_RUN_EP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RUN_EM_LR0, M_RUN_EM_LR1, M_RUN_EM_LR2, M_RUN_EM_TH0, M_RUN_EM_AR0));
|
|
}
|
|
|
|
statePredictor = & model->Run.Mantissa[bitRunSize].StateModel[state][0];
|
|
charPredictor = & model->Run.Mantissa[bitRunSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Mantissa[bitRunSize].StaticModel[0];
|
|
mixer = & model->mixerOfRunMantissa[bitRunSize];
|
|
|
|
for (int context = 1, bit = bitRunSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (runSize & (1 << bit))
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], M_RUN_MS_TH1, M_RUN_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], M_RUN_MC_TH1, M_RUN_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], M_RUN_MP_TH1, M_RUN_MP_AR1);
|
|
|
|
coder.EncodeBit1(mixer->MixupAndUpdateBit1(probability0, probability1, probability2, M_RUN_MM_LR0, M_RUN_MM_LR1, M_RUN_MM_LR2, M_RUN_MM_TH1, M_RUN_MM_AR1));
|
|
|
|
if (bitRunSize <= 5) context += context + 1; else context++;
|
|
}
|
|
else
|
|
{
|
|
int probability0 = charPredictor[context], probability1 = statePredictor[context], probability2 = staticPredictor[context];
|
|
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], M_RUN_MS_TH0, M_RUN_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], M_RUN_MC_TH0, M_RUN_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], M_RUN_MP_TH0, M_RUN_MP_AR0);
|
|
|
|
coder.EncodeBit0(mixer->MixupAndUpdateBit0(probability0, probability1, probability2, M_RUN_MM_LR0, M_RUN_MM_LR1, M_RUN_MM_LR2, M_RUN_MM_TH0, M_RUN_MM_AR0));
|
|
|
|
if (bitRunSize <= 5) context += context + 0; else context++;
|
|
}
|
|
}
|
|
}
|
|
|
|
contextRank0 = ((contextRank0 << 1) | (rank == 0 ? 1 : 0)) & 0x7;
|
|
contextRank4 = ((contextRank4 << 2) | (rank < 3 ? rank : 3)) & 0xff;
|
|
contextRun = ((contextRun << 1) | (runSize < 3 ? 1 : 0)) & 0xf;
|
|
}
|
|
|
|
return coder.FinishEncoder();
|
|
}
|
|
|
|
int bsc_qlfc_static_encode(const unsigned char * input, unsigned char * output, unsigned char * buffer, int inputSize, int outputSize, QlfcStatisticalModel * model)
|
|
{
|
|
unsigned char MTFTable[ALPHABET_SIZE];
|
|
|
|
bsc_qlfc_init_model(model);
|
|
|
|
int contextRank0 = 0;
|
|
int contextRank4 = 0;
|
|
int contextRun = 0;
|
|
int maxRank = 7;
|
|
int avgRank = 0;
|
|
|
|
unsigned char rankHistory[ALPHABET_SIZE], runHistory[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i)
|
|
{
|
|
rankHistory[i] = runHistory[i] = 0;
|
|
}
|
|
|
|
unsigned char * rankArray = bsc_qlfc_transform(input, buffer, inputSize, MTFTable);
|
|
|
|
RangeCoder coder;
|
|
|
|
coder.InitEncoder(output, outputSize);
|
|
coder.EncodeWord((unsigned int)inputSize);
|
|
|
|
unsigned char usedChar[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) usedChar[i] = 0;
|
|
|
|
int prevChar = -1;
|
|
for (int rank = 0; rank < ALPHABET_SIZE; ++rank)
|
|
{
|
|
int currentChar = MTFTable[rank];
|
|
|
|
for (int bit = 7; bit >= 0; --bit)
|
|
{
|
|
bool bit0 = false, bit1 = false;
|
|
|
|
for (int c = 0; c < ALPHABET_SIZE; ++c)
|
|
{
|
|
if (c == prevChar || usedChar[c] == 0)
|
|
{
|
|
if ((currentChar >> (bit + 1)) == (c >> (bit + 1)))
|
|
{
|
|
if (c & (1 << bit)) bit1 = true; else bit0 = true;
|
|
if (bit0 && bit1) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bit0 && bit1)
|
|
{
|
|
coder.EncodeBit(currentChar & (1 << bit));
|
|
}
|
|
}
|
|
|
|
if (currentChar == prevChar)
|
|
{
|
|
maxRank = bsc_log2_256(rank - 1);
|
|
break;
|
|
}
|
|
|
|
prevChar = currentChar; usedChar[currentChar] = 1;
|
|
}
|
|
|
|
for (const unsigned char * inputEnd = input + inputSize; input < inputEnd;)
|
|
{
|
|
if (coder.CheckEOB())
|
|
{
|
|
return LIBBSC_NOT_COMPRESSIBLE;
|
|
}
|
|
|
|
int currentChar = *input, runSize;
|
|
{
|
|
const unsigned char * inputStart = input++;
|
|
while (true)
|
|
{
|
|
if (input <= inputEnd - 4)
|
|
{
|
|
if (input[0] != currentChar) { input += 0; break; }
|
|
if (input[1] != currentChar) { input += 1; break; }
|
|
if (input[2] != currentChar) { input += 2; break; }
|
|
if (input[3] != currentChar) { input += 3; break; }
|
|
|
|
input += 4;
|
|
}
|
|
else
|
|
{
|
|
while ((input < inputEnd) && (*input == currentChar)) ++input;
|
|
break;
|
|
}
|
|
}
|
|
|
|
runSize = (int)(input - inputStart);
|
|
}
|
|
|
|
int rank = *rankArray++;
|
|
int history = rankHistory[currentChar];
|
|
int state = model_rank_state(contextRank4, contextRun, history);
|
|
|
|
short * RESTRICT statePredictor = & model->Rank.StateModel[state];
|
|
short * RESTRICT charPredictor = & model->Rank.CharModel[currentChar];
|
|
short * RESTRICT staticPredictor = & model->Rank.StaticModel;
|
|
|
|
if (avgRank < 32)
|
|
{
|
|
if (rank == 1)
|
|
{
|
|
rankHistory[currentChar] = 0;
|
|
|
|
int probability = ((*charPredictor) * F_RANK_TM_LR0 + (*statePredictor) * F_RANK_TM_LR1 + (*staticPredictor) * F_RANK_TM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RANK_TS_TH0, F_RANK_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RANK_TC_TH0, F_RANK_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RANK_TP_TH0, F_RANK_TP_AR0);
|
|
|
|
coder.EncodeBit0(probability);
|
|
}
|
|
else
|
|
{
|
|
{
|
|
int probability = ((*charPredictor) * F_RANK_TM_LR0 + (*statePredictor) * F_RANK_TM_LR1 + (*staticPredictor) * F_RANK_TM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RANK_TS_TH1, F_RANK_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RANK_TC_TH1, F_RANK_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RANK_TP_TH1, F_RANK_TP_AR1);
|
|
|
|
coder.EncodeBit1(probability);
|
|
}
|
|
|
|
int bitRankSize = bsc_log2_256(rank); rankHistory[currentChar] = bitRankSize;
|
|
|
|
statePredictor = & model->Rank.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Rank.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Exponent.StaticModel[0];
|
|
|
|
for (int bit = 1; bit < bitRankSize; ++bit, ++statePredictor, ++charPredictor, ++staticPredictor)
|
|
{
|
|
int probability = ((*charPredictor) * F_RANK_EM_LR0 + (*statePredictor) * F_RANK_EM_LR1 + (*staticPredictor) * F_RANK_EM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RANK_ES_TH1, F_RANK_ES_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RANK_EC_TH1, F_RANK_EC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RANK_EP_TH1, F_RANK_EP_AR1);
|
|
|
|
coder.EncodeBit1(probability);
|
|
}
|
|
if (bitRankSize < maxRank)
|
|
{
|
|
int probability = ((*charPredictor) * F_RANK_EM_LR0 + (*statePredictor) * F_RANK_EM_LR1 + (*staticPredictor) * F_RANK_EM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RANK_ES_TH0, F_RANK_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RANK_EC_TH0, F_RANK_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RANK_EP_TH0, F_RANK_EP_AR0);
|
|
|
|
coder.EncodeBit0(probability);
|
|
}
|
|
|
|
statePredictor = & model->Rank.Mantissa[bitRankSize].StateModel[state][0];
|
|
charPredictor = & model->Rank.Mantissa[bitRankSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Mantissa[bitRankSize].StaticModel[0];
|
|
|
|
for (int context = 1, bit = bitRankSize - 1; bit >= 0; --bit)
|
|
{
|
|
int probability = (charPredictor[context] * F_RANK_MM_LR0 + statePredictor[context] * F_RANK_MM_LR1 + staticPredictor[context] * F_RANK_MM_LR2) >> 5;
|
|
|
|
if (rank & (1 << bit))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], F_RANK_MS_TH1, F_RANK_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], F_RANK_MC_TH1, F_RANK_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], F_RANK_MP_TH1, F_RANK_MP_AR1);
|
|
|
|
coder.EncodeBit1(probability); context += context + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], F_RANK_MS_TH0, F_RANK_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], F_RANK_MC_TH0, F_RANK_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], F_RANK_MP_TH0, F_RANK_MP_AR0);
|
|
|
|
coder.EncodeBit0(probability); context += context;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rankHistory[currentChar] = bsc_log2_256(rank);
|
|
|
|
statePredictor = & model->Rank.Escape.StateModel[state][0];
|
|
charPredictor = & model->Rank.Escape.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Escape.StaticModel[0];
|
|
|
|
for (int context = 1, bit = maxRank; bit >= 0; --bit)
|
|
{
|
|
int probability = (charPredictor[context] * F_RANK_PM_LR0 + statePredictor[context] * F_RANK_PM_LR1 + staticPredictor[context] * F_RANK_PM_LR2) >> 5;
|
|
|
|
if (rank & (1 << bit))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], F_RANK_PS_TH1, F_RANK_PS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], F_RANK_PC_TH1, F_RANK_PC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], F_RANK_PP_TH1, F_RANK_PP_AR1);
|
|
|
|
coder.EncodeBit1(probability); context += context + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], F_RANK_PS_TH0, F_RANK_PS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], F_RANK_PC_TH0, F_RANK_PC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], F_RANK_PP_TH0, F_RANK_PP_AR0);
|
|
|
|
coder.EncodeBit0(probability); context += context;
|
|
}
|
|
}
|
|
}
|
|
|
|
avgRank = (avgRank * 124 + rank * 4) >> 7;
|
|
rank = rank - 1;
|
|
history = runHistory[currentChar];
|
|
state = model_run_state(contextRank0, contextRun, rank, history);
|
|
statePredictor = & model->Run.StateModel[state];
|
|
charPredictor = & model->Run.CharModel[currentChar];
|
|
staticPredictor = & model->Run.StaticModel;
|
|
|
|
if (runSize == 1)
|
|
{
|
|
runHistory[currentChar] = (runHistory[currentChar] + 2) >> 2;
|
|
|
|
int probability = ((*charPredictor) * F_RUN_TM_LR0 + (*statePredictor) * F_RUN_TM_LR1 + (*staticPredictor) * F_RUN_TM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RUN_TS_TH0, F_RUN_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RUN_TC_TH0, F_RUN_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RUN_TP_TH0, F_RUN_TP_AR0);
|
|
|
|
coder.EncodeBit0(probability);
|
|
}
|
|
else
|
|
{
|
|
{
|
|
int probability = ((*charPredictor) * F_RUN_TM_LR0 + (*statePredictor) * F_RUN_TM_LR1 + (*staticPredictor) * F_RUN_TM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RUN_TS_TH1, F_RUN_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RUN_TC_TH1, F_RUN_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RUN_TP_TH1, F_RUN_TP_AR1);
|
|
|
|
coder.EncodeBit1(probability);
|
|
}
|
|
|
|
int bitRunSize = bsc_log2(runSize); runHistory[currentChar] = (runHistory[currentChar] + 3 * bitRunSize + 3) >> 2;
|
|
|
|
statePredictor = & model->Run.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Run.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Exponent.StaticModel[0];
|
|
|
|
for (int bit = 1; bit < bitRunSize; ++bit, ++statePredictor, ++charPredictor, ++staticPredictor)
|
|
{
|
|
int probability = ((*charPredictor) * F_RUN_EM_LR0 + (*statePredictor) * F_RUN_EM_LR1 + (*staticPredictor) * F_RUN_EM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RUN_ES_TH1, F_RUN_ES_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RUN_EC_TH1, F_RUN_EC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RUN_EP_TH1, F_RUN_EP_AR1);
|
|
|
|
coder.EncodeBit1(probability);
|
|
}
|
|
{
|
|
int probability = ((*charPredictor) * F_RUN_EM_LR0 + (*statePredictor) * F_RUN_EM_LR1 + (*staticPredictor) * F_RUN_EM_LR2) >> 5;
|
|
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RUN_ES_TH0, F_RUN_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RUN_EC_TH0, F_RUN_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RUN_EP_TH0, F_RUN_EP_AR0);
|
|
|
|
coder.EncodeBit0(probability);
|
|
}
|
|
|
|
statePredictor = & model->Run.Mantissa[bitRunSize].StateModel[state][0];
|
|
charPredictor = & model->Run.Mantissa[bitRunSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Mantissa[bitRunSize].StaticModel[0];
|
|
|
|
for (int context = 1, bit = bitRunSize - 1; bit >= 0; --bit)
|
|
{
|
|
int probability = (charPredictor[context] * F_RUN_MM_LR0 + statePredictor[context] * F_RUN_MM_LR1 + staticPredictor[context] * F_RUN_MM_LR2) >> 5;
|
|
if (runSize & (1 << bit))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], F_RUN_MS_TH1, F_RUN_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], F_RUN_MC_TH1, F_RUN_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], F_RUN_MP_TH1, F_RUN_MP_AR1);
|
|
|
|
coder.EncodeBit1(probability); if (bitRunSize <= 5) context += context + 1; else context++;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], F_RUN_MS_TH0, F_RUN_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], F_RUN_MC_TH0, F_RUN_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], F_RUN_MP_TH0, F_RUN_MP_AR0);
|
|
|
|
coder.EncodeBit0(probability); if (bitRunSize <= 5) context += context + 0; else context++;
|
|
}
|
|
}
|
|
}
|
|
|
|
contextRank0 = ((contextRank0 << 1) | (rank == 0 ? 1 : 0)) & 0x7;
|
|
contextRank4 = ((contextRank4 << 2) | (rank < 3 ? rank : 3)) & 0xff;
|
|
contextRun = ((contextRun << 1) | (runSize < 3 ? 1 : 0)) & 0xf;
|
|
}
|
|
|
|
return coder.FinishEncoder();
|
|
}
|
|
|
|
int bsc_qlfc_adaptive_decode(const unsigned char * input, unsigned char * output, QlfcStatisticalModel * model)
|
|
{
|
|
RangeCoder coder;
|
|
|
|
unsigned char MTFTable[ALPHABET_SIZE];
|
|
|
|
bsc_qlfc_init_model(model);
|
|
|
|
int contextRank0 = 0;
|
|
int contextRank4 = 0;
|
|
int contextRun = 0;
|
|
int maxRank = 7;
|
|
int avgRank = 0;
|
|
|
|
unsigned char rankHistory[ALPHABET_SIZE], runHistory[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i)
|
|
{
|
|
rankHistory[i] = runHistory[i] = 0;
|
|
}
|
|
|
|
coder.InitDecoder(input);
|
|
int n = (int)coder.DecodeWord();
|
|
|
|
unsigned char usedChar[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) usedChar[i] = 0;
|
|
|
|
int prevChar = -1;
|
|
for (int rank = 0; rank < ALPHABET_SIZE; ++rank)
|
|
{
|
|
int currentChar = 0;
|
|
|
|
for (int bit = 7; bit >= 0; --bit)
|
|
{
|
|
bool bit0 = false, bit1 = false;
|
|
|
|
for (int c = 0; c < ALPHABET_SIZE; ++c)
|
|
{
|
|
if (c == prevChar || usedChar[c] == 0)
|
|
{
|
|
if (currentChar == (c >> (bit + 1)))
|
|
{
|
|
if (c & (1 << bit)) bit1 = true; else bit0 = true;
|
|
if (bit0 && bit1) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bit0 && bit1)
|
|
{
|
|
currentChar += currentChar + coder.DecodeBit();
|
|
}
|
|
else
|
|
{
|
|
if (bit0) currentChar += currentChar + 0;
|
|
if (bit1) currentChar += currentChar + 1;
|
|
}
|
|
}
|
|
|
|
MTFTable[rank] = currentChar;
|
|
|
|
if (currentChar == prevChar)
|
|
{
|
|
maxRank = bsc_log2_256(rank - 1);
|
|
break;
|
|
}
|
|
|
|
prevChar = currentChar; usedChar[currentChar] = 1;
|
|
}
|
|
|
|
for (int i = 0; i < n;)
|
|
{
|
|
int currentChar = MTFTable[0];
|
|
int history = rankHistory[currentChar];
|
|
int state = model_rank_state(contextRank4, contextRun, history);
|
|
|
|
short * RESTRICT statePredictor = & model->Rank.StateModel[state];
|
|
short * RESTRICT charPredictor = & model->Rank.CharModel[currentChar];
|
|
short * RESTRICT staticPredictor = & model->Rank.StaticModel;
|
|
ProbabilityMixer * RESTRICT mixer = & model->mixerOfRank[currentChar];
|
|
|
|
int rank = 1;
|
|
if (avgRank < 32)
|
|
{
|
|
if (coder.DecodeBit(mixer->Mixup(*charPredictor, *statePredictor, *staticPredictor)))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RANK_TS_TH1, M_RANK_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RANK_TC_TH1, M_RANK_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RANK_TP_TH1, M_RANK_TP_AR1);
|
|
mixer->UpdateBit1(M_RANK_TM_LR0, M_RANK_TM_LR1, M_RANK_TM_LR2, M_RANK_TM_TH1, M_RANK_TM_AR1);
|
|
|
|
statePredictor = & model->Rank.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Rank.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Exponent.StaticModel[0];
|
|
mixer = & model->mixerOfRankExponent[history < 1 ? 1 : history][1];
|
|
|
|
int bitRankSize = 1;
|
|
while (true)
|
|
{
|
|
if (bitRankSize == maxRank) break;
|
|
if (coder.DecodeBit(mixer->Mixup(*charPredictor, *statePredictor, *staticPredictor)))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RANK_ES_TH1, M_RANK_ES_AR1); statePredictor++;
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RANK_EC_TH1, M_RANK_EC_AR1); charPredictor++;
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RANK_EP_TH1, M_RANK_EP_AR1); staticPredictor++;
|
|
mixer->UpdateBit1(M_RANK_EM_LR0, M_RANK_EM_LR1, M_RANK_EM_LR2, M_RANK_EM_TH1, M_RANK_EM_AR1);
|
|
bitRankSize++;
|
|
mixer = & model->mixerOfRankExponent[history < bitRankSize ? bitRankSize : history][bitRankSize];
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RANK_ES_TH0, M_RANK_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RANK_EC_TH0, M_RANK_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RANK_EP_TH0, M_RANK_EP_AR0);
|
|
mixer->UpdateBit0(M_RANK_EM_LR0, M_RANK_EM_LR1, M_RANK_EM_LR2, M_RANK_EM_TH0, M_RANK_EM_AR0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
rankHistory[currentChar] = bitRankSize;
|
|
|
|
statePredictor = & model->Rank.Mantissa[bitRankSize].StateModel[state][0];
|
|
charPredictor = & model->Rank.Mantissa[bitRankSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Mantissa[bitRankSize].StaticModel[0];
|
|
mixer = & model->mixerOfRankMantissa[bitRankSize];
|
|
|
|
for (int bit = bitRankSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (coder.DecodeBit(mixer->Mixup(charPredictor[rank], statePredictor[rank], staticPredictor[rank])))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[rank], M_RANK_MS_TH1, M_RANK_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[rank], M_RANK_MC_TH1, M_RANK_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[rank], M_RANK_MP_TH1, M_RANK_MP_AR1);
|
|
mixer->UpdateBit1(M_RANK_MM_LR0, M_RANK_MM_LR1, M_RANK_MM_LR2, M_RANK_MM_TH1, M_RANK_MM_AR1);
|
|
rank += rank + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[rank], M_RANK_MS_TH0, M_RANK_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[rank], M_RANK_MC_TH0, M_RANK_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[rank], M_RANK_MP_TH0, M_RANK_MP_AR0);
|
|
mixer->UpdateBit0(M_RANK_MM_LR0, M_RANK_MM_LR1, M_RANK_MM_LR2, M_RANK_MM_TH0, M_RANK_MM_AR0);
|
|
rank += rank;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rankHistory[currentChar] = 0;
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RANK_TS_TH0, M_RANK_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RANK_TC_TH0, M_RANK_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RANK_TP_TH0, M_RANK_TP_AR0);
|
|
mixer->UpdateBit0(M_RANK_TM_LR0, M_RANK_TM_LR1, M_RANK_TM_LR2, M_RANK_TM_TH0, M_RANK_TM_AR0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
statePredictor = & model->Rank.Escape.StateModel[state][0];
|
|
charPredictor = & model->Rank.Escape.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Escape.StaticModel[0];
|
|
|
|
rank = 0;
|
|
for (int context = 1, bit = maxRank; bit >= 0; --bit)
|
|
{
|
|
mixer = & model->mixerOfRankEscape[context];
|
|
|
|
if (coder.DecodeBit(mixer->Mixup(charPredictor[context], statePredictor[context], staticPredictor[context])))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], M_RANK_PS_TH1, M_RANK_PS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], M_RANK_PC_TH1, M_RANK_PC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], M_RANK_PP_TH1, M_RANK_PP_AR1);
|
|
mixer->UpdateBit1(M_RANK_PM_LR0, M_RANK_PM_LR1, M_RANK_PM_LR2, M_RANK_PM_TH1, M_RANK_PM_AR1);
|
|
context += context + 1; rank += rank + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], M_RANK_PS_TH0, M_RANK_PS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], M_RANK_PC_TH0, M_RANK_PC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], M_RANK_PP_TH0, M_RANK_PP_AR0);
|
|
mixer->UpdateBit0(M_RANK_PM_LR0, M_RANK_PM_LR1, M_RANK_PM_LR2, M_RANK_PM_TH0, M_RANK_PM_AR0);
|
|
context += context; rank += rank;
|
|
}
|
|
}
|
|
|
|
rankHistory[currentChar] = bsc_log2_256(rank);
|
|
}
|
|
|
|
{
|
|
for (int r = 0; r < rank; ++r)
|
|
{
|
|
MTFTable[r] = MTFTable[r + 1];
|
|
}
|
|
MTFTable[rank] = currentChar;
|
|
}
|
|
|
|
avgRank = (avgRank * 124 + rank * 4) >> 7;
|
|
rank = rank - 1;
|
|
history = runHistory[currentChar];
|
|
state = model_run_state(contextRank0, contextRun, rank, history);
|
|
statePredictor = & model->Run.StateModel[state];
|
|
charPredictor = & model->Run.CharModel[currentChar];
|
|
staticPredictor = & model->Run.StaticModel;
|
|
mixer = & model->mixerOfRun[currentChar];
|
|
|
|
int runSize = 1;
|
|
if (coder.DecodeBit(mixer->Mixup(*charPredictor, *statePredictor, *staticPredictor)))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RUN_TS_TH1, M_RUN_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RUN_TC_TH1, M_RUN_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RUN_TP_TH1, M_RUN_TP_AR1);
|
|
mixer->UpdateBit1(M_RUN_TM_LR0, M_RUN_TM_LR1, M_RUN_TM_LR2, M_RUN_TM_TH1, M_RUN_TM_AR1);
|
|
|
|
statePredictor = & model->Run.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Run.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Exponent.StaticModel[0];
|
|
mixer = & model->mixerOfRunExponent[history < 1 ? 1 : history][1];
|
|
|
|
int bitRunSize = 1;
|
|
while (true)
|
|
{
|
|
if (coder.DecodeBit(mixer->Mixup(*charPredictor, *statePredictor, *staticPredictor)))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, M_RUN_ES_TH1, M_RUN_ES_AR1); statePredictor++;
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, M_RUN_EC_TH1, M_RUN_EC_AR1); charPredictor++;
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, M_RUN_EP_TH1, M_RUN_EP_AR1); staticPredictor++;
|
|
mixer->UpdateBit1(M_RUN_EM_LR0, M_RUN_EM_LR1, M_RUN_EM_LR2, M_RUN_EM_TH1, M_RUN_EM_AR1);
|
|
bitRunSize++; mixer = & model->mixerOfRunExponent[history < bitRunSize ? bitRunSize : history][bitRunSize];
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RUN_ES_TH0, M_RUN_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RUN_EC_TH0, M_RUN_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RUN_EP_TH0, M_RUN_EP_AR0);
|
|
mixer->UpdateBit0(M_RUN_EM_LR0, M_RUN_EM_LR1, M_RUN_EM_LR2, M_RUN_EM_TH0, M_RUN_EM_AR0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
runHistory[currentChar] = (runHistory[currentChar] + 3 * bitRunSize + 3) >> 2;
|
|
|
|
statePredictor = & model->Run.Mantissa[bitRunSize].StateModel[state][0];
|
|
charPredictor = & model->Run.Mantissa[bitRunSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Mantissa[bitRunSize].StaticModel[0];
|
|
mixer = & model->mixerOfRunMantissa[bitRunSize];
|
|
|
|
for (int context = 1, bit = bitRunSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (coder.DecodeBit(mixer->Mixup(charPredictor[context], statePredictor[context], staticPredictor[context])))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], M_RUN_MS_TH1, M_RUN_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], M_RUN_MC_TH1, M_RUN_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], M_RUN_MP_TH1, M_RUN_MP_AR1);
|
|
mixer->UpdateBit1(M_RUN_MM_LR0, M_RUN_MM_LR1, M_RUN_MM_LR2, M_RUN_MM_TH1, M_RUN_MM_AR1);
|
|
runSize += runSize + 1; if (bitRunSize <= 5) context += context + 1; else context++;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], M_RUN_MS_TH0, M_RUN_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], M_RUN_MC_TH0, M_RUN_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], M_RUN_MP_TH0, M_RUN_MP_AR0);
|
|
mixer->UpdateBit0(M_RUN_MM_LR0, M_RUN_MM_LR1, M_RUN_MM_LR2, M_RUN_MM_TH0, M_RUN_MM_AR0);
|
|
runSize += runSize; if (bitRunSize <= 5) context += context; else context++;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
runHistory[currentChar] = (runHistory[currentChar] + 2) >> 2;
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, M_RUN_TS_TH0, M_RUN_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, M_RUN_TC_TH0, M_RUN_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, M_RUN_TP_TH0, M_RUN_TP_AR0);
|
|
mixer->UpdateBit0(M_RUN_TM_LR0, M_RUN_TM_LR1, M_RUN_TM_LR2, M_RUN_TM_TH0, M_RUN_TM_AR0);
|
|
}
|
|
|
|
contextRank0 = ((contextRank0 << 1) | (rank == 0 ? 1 : 0)) & 0x7;
|
|
contextRank4 = ((contextRank4 << 2) | (rank < 3 ? rank : 3)) & 0xff;
|
|
contextRun = ((contextRun << 1) | (runSize < 3 ? 1 : 0)) & 0xf;
|
|
|
|
for (; runSize > 0; --runSize) output[i++] = currentChar;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
int bsc_qlfc_static_decode(const unsigned char * input, unsigned char * output, QlfcStatisticalModel * model)
|
|
{
|
|
RangeCoder coder;
|
|
|
|
unsigned char MTFTable[ALPHABET_SIZE];
|
|
|
|
bsc_qlfc_init_model(model);
|
|
|
|
int contextRank0 = 0;
|
|
int contextRank4 = 0;
|
|
int contextRun = 0;
|
|
int maxRank = 7;
|
|
int avgRank = 0;
|
|
|
|
unsigned char rankHistory[ALPHABET_SIZE], runHistory[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i)
|
|
{
|
|
rankHistory[i] = runHistory[i] = 0;
|
|
}
|
|
|
|
coder.InitDecoder(input);
|
|
int n = (int)coder.DecodeWord();
|
|
|
|
unsigned char usedChar[ALPHABET_SIZE];
|
|
for (int i = 0; i < ALPHABET_SIZE; ++i) usedChar[i] = 0;
|
|
|
|
int prevChar = -1;
|
|
for (int rank = 0; rank < ALPHABET_SIZE; ++rank)
|
|
{
|
|
int currentChar = 0;
|
|
|
|
for (int bit = 7; bit >= 0; --bit)
|
|
{
|
|
bool bit0 = false, bit1 = false;
|
|
|
|
for (int c = 0; c < ALPHABET_SIZE; ++c)
|
|
{
|
|
if (c == prevChar || usedChar[c] == 0)
|
|
{
|
|
if (currentChar == (c >> (bit + 1)))
|
|
{
|
|
if (c & (1 << bit)) bit1 = true; else bit0 = true;
|
|
if (bit0 && bit1) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bit0 && bit1)
|
|
{
|
|
currentChar += currentChar + coder.DecodeBit();
|
|
}
|
|
else
|
|
{
|
|
if (bit0) currentChar += currentChar + 0;
|
|
if (bit1) currentChar += currentChar + 1;
|
|
}
|
|
}
|
|
|
|
MTFTable[rank] = currentChar;
|
|
|
|
if (currentChar == prevChar)
|
|
{
|
|
maxRank = bsc_log2_256(rank - 1);
|
|
break;
|
|
}
|
|
|
|
prevChar = currentChar; usedChar[currentChar] = 1;
|
|
}
|
|
|
|
for (int i = 0; i < n;)
|
|
{
|
|
int currentChar = MTFTable[0];
|
|
int history = rankHistory[currentChar];
|
|
int state = model_rank_state(contextRank4, contextRun, history);
|
|
|
|
short * RESTRICT statePredictor = & model->Rank.StateModel[state];
|
|
short * RESTRICT charPredictor = & model->Rank.CharModel[currentChar];
|
|
short * RESTRICT staticPredictor = & model->Rank.StaticModel;
|
|
|
|
int rank = 1;
|
|
if (avgRank < 32)
|
|
{
|
|
if (coder.DecodeBit((*charPredictor * F_RANK_TM_LR0 + *statePredictor * F_RANK_TM_LR1 + *staticPredictor * F_RANK_TM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RANK_TS_TH1, F_RANK_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RANK_TC_TH1, F_RANK_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RANK_TP_TH1, F_RANK_TP_AR1);
|
|
|
|
statePredictor = & model->Rank.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Rank.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Exponent.StaticModel[0];
|
|
|
|
int bitRankSize = 1;
|
|
while (true)
|
|
{
|
|
if (bitRankSize == maxRank) break;
|
|
if (coder.DecodeBit((*charPredictor * F_RANK_EM_LR0 + *statePredictor * F_RANK_EM_LR1 + *staticPredictor * F_RANK_EM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RANK_ES_TH1, F_RANK_ES_AR1); statePredictor++;
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RANK_EC_TH1, F_RANK_EC_AR1); charPredictor++;
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RANK_EP_TH1, F_RANK_EP_AR1); staticPredictor++;
|
|
bitRankSize++;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RANK_ES_TH0, F_RANK_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RANK_EC_TH0, F_RANK_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RANK_EP_TH0, F_RANK_EP_AR0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
rankHistory[currentChar] = bitRankSize;
|
|
|
|
statePredictor = & model->Rank.Mantissa[bitRankSize].StateModel[state][0];
|
|
charPredictor = & model->Rank.Mantissa[bitRankSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Mantissa[bitRankSize].StaticModel[0];
|
|
|
|
for (int bit = bitRankSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (coder.DecodeBit((charPredictor[rank] * F_RANK_MM_LR0 + statePredictor[rank] * F_RANK_MM_LR1 + staticPredictor[rank] * F_RANK_MM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[rank], F_RANK_MS_TH1, F_RANK_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[rank], F_RANK_MC_TH1, F_RANK_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[rank], F_RANK_MP_TH1, F_RANK_MP_AR1);
|
|
rank += rank + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[rank], F_RANK_MS_TH0, F_RANK_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[rank], F_RANK_MC_TH0, F_RANK_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[rank], F_RANK_MP_TH0, F_RANK_MP_AR0);
|
|
rank += rank;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rankHistory[currentChar] = 0;
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RANK_TS_TH0, F_RANK_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RANK_TC_TH0, F_RANK_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RANK_TP_TH0, F_RANK_TP_AR0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
statePredictor = & model->Rank.Escape.StateModel[state][0];
|
|
charPredictor = & model->Rank.Escape.CharModel[currentChar][0];
|
|
staticPredictor = & model->Rank.Escape.StaticModel[0];
|
|
|
|
rank = 0;
|
|
for (int context = 1, bit = maxRank; bit >= 0; --bit)
|
|
{
|
|
if (coder.DecodeBit((charPredictor[context] * F_RANK_PM_LR0 + statePredictor[context] * F_RANK_PM_LR1 + staticPredictor[context] * F_RANK_PM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], F_RANK_PS_TH1, F_RANK_PS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], F_RANK_PC_TH1, F_RANK_PC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], F_RANK_PP_TH1, F_RANK_PP_AR1);
|
|
context += context + 1; rank += rank + 1;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], F_RANK_PS_TH0, F_RANK_PS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], F_RANK_PC_TH0, F_RANK_PC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], F_RANK_PP_TH0, F_RANK_PP_AR0);
|
|
context += context; rank += rank;
|
|
}
|
|
}
|
|
|
|
rankHistory[currentChar] = bsc_log2_256(rank);
|
|
}
|
|
|
|
{
|
|
for (int r = 0; r < rank; ++r)
|
|
{
|
|
MTFTable[r] = MTFTable[r + 1];
|
|
}
|
|
MTFTable[rank] = currentChar;
|
|
}
|
|
|
|
avgRank = (avgRank * 124 + rank * 4) >> 7;
|
|
rank = rank - 1;
|
|
history = runHistory[currentChar];
|
|
state = model_run_state(contextRank0, contextRun, rank, history);
|
|
statePredictor = & model->Run.StateModel[state];
|
|
charPredictor = & model->Run.CharModel[currentChar];
|
|
staticPredictor = & model->Run.StaticModel;
|
|
|
|
int runSize = 1;
|
|
if (coder.DecodeBit((*charPredictor * F_RUN_TM_LR0 + *statePredictor * F_RUN_TM_LR1 + *staticPredictor * F_RUN_TM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RUN_TS_TH1, F_RUN_TS_AR1);
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RUN_TC_TH1, F_RUN_TC_AR1);
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RUN_TP_TH1, F_RUN_TP_AR1);
|
|
|
|
statePredictor = & model->Run.Exponent.StateModel[state][0];
|
|
charPredictor = & model->Run.Exponent.CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Exponent.StaticModel[0];
|
|
|
|
int bitRunSize = 1;
|
|
while (true)
|
|
{
|
|
if (coder.DecodeBit((*charPredictor * F_RUN_EM_LR0 + *statePredictor * F_RUN_EM_LR1 + *staticPredictor * F_RUN_EM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(*statePredictor, F_RUN_ES_TH1, F_RUN_ES_AR1); statePredictor++;
|
|
ProbabilityCounter::UpdateBit1(*charPredictor, F_RUN_EC_TH1, F_RUN_EC_AR1); charPredictor++;
|
|
ProbabilityCounter::UpdateBit1(*staticPredictor, F_RUN_EP_TH1, F_RUN_EP_AR1); staticPredictor++;
|
|
bitRunSize++;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RUN_ES_TH0, F_RUN_ES_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RUN_EC_TH0, F_RUN_EC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RUN_EP_TH0, F_RUN_EP_AR0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
runHistory[currentChar] = (runHistory[currentChar] + 3 * bitRunSize + 3) >> 2;
|
|
|
|
statePredictor = & model->Run.Mantissa[bitRunSize].StateModel[state][0];
|
|
charPredictor = & model->Run.Mantissa[bitRunSize].CharModel[currentChar][0];
|
|
staticPredictor = & model->Run.Mantissa[bitRunSize].StaticModel[0];
|
|
|
|
for (int context = 1, bit = bitRunSize - 1; bit >= 0; --bit)
|
|
{
|
|
if (coder.DecodeBit((charPredictor[context] * F_RUN_MM_LR0 + statePredictor[context] * F_RUN_MM_LR1 + staticPredictor[context] * F_RUN_MM_LR2) >> 5))
|
|
{
|
|
ProbabilityCounter::UpdateBit1(statePredictor[context], F_RUN_MS_TH1, F_RUN_MS_AR1);
|
|
ProbabilityCounter::UpdateBit1(charPredictor[context], F_RUN_MC_TH1, F_RUN_MC_AR1);
|
|
ProbabilityCounter::UpdateBit1(staticPredictor[context], F_RUN_MP_TH1, F_RUN_MP_AR1);
|
|
runSize += runSize + 1; if (bitRunSize <= 5) context += context + 1; else context++;
|
|
}
|
|
else
|
|
{
|
|
ProbabilityCounter::UpdateBit0(statePredictor[context], F_RUN_MS_TH0, F_RUN_MS_AR0);
|
|
ProbabilityCounter::UpdateBit0(charPredictor[context], F_RUN_MC_TH0, F_RUN_MC_AR0);
|
|
ProbabilityCounter::UpdateBit0(staticPredictor[context], F_RUN_MP_TH0, F_RUN_MP_AR0);
|
|
runSize += runSize; if (bitRunSize <= 5) context += context; else context++;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
runHistory[currentChar] = (runHistory[currentChar] + 2) >> 2;
|
|
ProbabilityCounter::UpdateBit0(*statePredictor, F_RUN_TS_TH0, F_RUN_TS_AR0);
|
|
ProbabilityCounter::UpdateBit0(*charPredictor, F_RUN_TC_TH0, F_RUN_TC_AR0);
|
|
ProbabilityCounter::UpdateBit0(*staticPredictor, F_RUN_TP_TH0, F_RUN_TP_AR0);
|
|
}
|
|
|
|
contextRank0 = ((contextRank0 << 1) | (rank == 0 ? 1 : 0)) & 0x7;
|
|
contextRank4 = ((contextRank4 << 2) | (rank < 3 ? rank : 3)) & 0xff;
|
|
contextRun = ((contextRun << 1) | (runSize < 3 ? 1 : 0)) & 0xf;
|
|
|
|
for (; runSize > 0; --runSize) output[i++] = currentChar;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
int bsc_qlfc_static_encode_block(const unsigned char * input, unsigned char * output, int inputSize, int outputSize)
|
|
{
|
|
if (QlfcStatisticalModel * model = (QlfcStatisticalModel *)bsc_malloc(sizeof(QlfcStatisticalModel)))
|
|
{
|
|
if (unsigned char * buffer = (unsigned char *)bsc_malloc(inputSize * sizeof(unsigned char)))
|
|
{
|
|
int result = bsc_qlfc_static_encode(input, output, buffer, inputSize, outputSize, model);
|
|
|
|
bsc_free(buffer); bsc_free(model);
|
|
|
|
return result;
|
|
};
|
|
bsc_free(model);
|
|
};
|
|
return LIBBSC_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
int bsc_qlfc_adaptive_encode_block(const unsigned char * input, unsigned char * output, int inputSize, int outputSize)
|
|
{
|
|
if (QlfcStatisticalModel * model = (QlfcStatisticalModel *)bsc_malloc(sizeof(QlfcStatisticalModel)))
|
|
{
|
|
if (unsigned char * buffer = (unsigned char *)bsc_malloc(inputSize * sizeof(unsigned char)))
|
|
{
|
|
int result = bsc_qlfc_adaptive_encode(input, output, buffer, inputSize, outputSize, model);
|
|
|
|
bsc_free(buffer); bsc_free(model);
|
|
|
|
return result;
|
|
};
|
|
bsc_free(model);
|
|
};
|
|
return LIBBSC_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
int bsc_qlfc_static_decode_block(const unsigned char * input, unsigned char * output)
|
|
{
|
|
if (QlfcStatisticalModel * model = (QlfcStatisticalModel *)bsc_malloc(sizeof(QlfcStatisticalModel)))
|
|
{
|
|
int result = bsc_qlfc_static_decode(input, output, model);
|
|
|
|
bsc_free(model);
|
|
|
|
return result;
|
|
};
|
|
return LIBBSC_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
int bsc_qlfc_adaptive_decode_block(const unsigned char * input, unsigned char * output)
|
|
{
|
|
if (QlfcStatisticalModel * model = (QlfcStatisticalModel *)bsc_malloc(sizeof(QlfcStatisticalModel)))
|
|
{
|
|
int result = bsc_qlfc_adaptive_decode(input, output, model);
|
|
|
|
bsc_free(model);
|
|
|
|
return result;
|
|
};
|
|
return LIBBSC_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
/* End qlfc.cpp */
|
|
/*-----------------------------------------------------------*/
|