/*-----------------------------------------------------------*/ /* 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 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 #include #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 */ /*-----------------------------------------------------------*/