629 lines
20 KiB
C++
629 lines
20 KiB
C++
/* Copyright 2018 Dirk Steinke
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License. */
|
|
|
|
#ifndef PREFLATE_STATISTICAL_CODEC_H
|
|
#define PREFLATE_STATISTICAL_CODEC_H
|
|
|
|
#include <vector>
|
|
#include "support/arithmetic_coder.h"
|
|
#include "support/bit_helper.h"
|
|
#include "support/bitstream.h"
|
|
#include "support/memstream.h"
|
|
#include "preflate_parameter_estimator.h"
|
|
#include "preflate_statistical_model.h"
|
|
|
|
template <unsigned N>
|
|
struct PreflateSubModel {
|
|
static const unsigned L = N;
|
|
PreflateSubModel() {}
|
|
|
|
void build(const unsigned(&arr)[N], const unsigned defval, const uint8_t prec = 16) {
|
|
build_impl(arr, defval, prec);
|
|
}
|
|
void buildDefault(const unsigned defval);
|
|
void extract(unsigned(&arr)[N]) {
|
|
for (unsigned i = 0; i < N; ++i) {
|
|
arr[i] = bounds[rids[i] + 1] - bounds[rids[i]];
|
|
}
|
|
}
|
|
void read(ArithmeticDecoder&, const uint8_t);
|
|
void write(ArithmeticEncoder&, const uint8_t) const;
|
|
void encode(ArithmeticEncoder& codec, const unsigned item) const {
|
|
if (!isFixed) {
|
|
size_t idx = rids[item];
|
|
codec.encodeShiftScale(scaleDownBits, scaledDownBounds[idx], scaledDownBounds[idx + 1]);
|
|
}
|
|
}
|
|
unsigned decode(ArithmeticDecoder& codec) const {
|
|
if (isFixed) {
|
|
return ids[N - 1];
|
|
}
|
|
unsigned val = codec.decodeShiftScale(scaleDownBits, scaledDownBounds, N);
|
|
return ids[val];
|
|
}
|
|
bool isEqualTo(const PreflateSubModel<N>& m) const;
|
|
|
|
unsigned bounds[N + 1];
|
|
unsigned scaledDownBounds[N + 1];
|
|
unsigned short ids[N + 1], rids[N + 1];
|
|
uint8_t scaleDownBits;
|
|
bool isDefault, isFixed;
|
|
|
|
private:
|
|
void build_impl(const unsigned* arr, const unsigned defval, const uint8_t prec);
|
|
void build_scale_down();
|
|
template <unsigned NEG, unsigned POS>
|
|
friend struct PreflateCorrectionSubModel;
|
|
};
|
|
|
|
template <>
|
|
struct PreflateSubModel<0u> {
|
|
static const unsigned L = 0u;
|
|
PreflateSubModel() {}
|
|
|
|
// void build(const unsigned(&arr)[1], const unsigned defval, const uint8_t prec = 16) {}
|
|
void buildDefault(const unsigned defval) {}
|
|
void read(ArithmeticDecoder&, const uint8_t) {}
|
|
void write(ArithmeticEncoder&, const uint8_t) const {}
|
|
void encode(ArithmeticEncoder& codec, const unsigned item) const {}
|
|
unsigned decode(ArithmeticDecoder& codec) const { return 0; }
|
|
bool isEqualTo(const PreflateSubModel<0u>& m) const { return true; }
|
|
|
|
enum { isDefault = 1, isFixed = 1 };
|
|
|
|
private:
|
|
void build_impl(const unsigned* arr, const unsigned defval, const uint8_t prec) {}
|
|
template <unsigned NEG, unsigned POS>
|
|
friend struct PreflateCorrectionSubModel;
|
|
};
|
|
|
|
template <unsigned NEG, unsigned POS>
|
|
struct PreflateCorrectionSubModel {
|
|
static const unsigned LNEG = NEG;
|
|
static const unsigned LPOS = POS;
|
|
PreflateCorrectionSubModel() {}
|
|
void build(const unsigned(&arr)[NEG + 1 + POS], const int defval, const uint8_t prec = 16) {
|
|
build_impl(arr, defval, prec);
|
|
}
|
|
void buildDefault(const unsigned defval);
|
|
void read(ArithmeticDecoder&, const uint8_t);
|
|
void write(ArithmeticEncoder&, const uint8_t) const;
|
|
void encode(ArithmeticEncoder& codec, const unsigned actvalue,
|
|
const unsigned refvalue,
|
|
const unsigned minvalue,
|
|
const unsigned maxvalue) {
|
|
int diff = actvalue - refvalue;
|
|
if (diff == 0) {
|
|
sign.encode(codec, 0);
|
|
return;
|
|
}
|
|
if (diff > 0) {
|
|
sign.encode(codec, 1);
|
|
if (diff >= (int)POS) {
|
|
pos.encode(codec, POS - 1);
|
|
codec.encodeBits(diff - POS, bitLength(maxvalue - POS - refvalue));
|
|
} else {
|
|
pos.encode(codec, diff - 1);
|
|
}
|
|
} else {
|
|
sign.encode(codec, 2);
|
|
if (-diff >= (int)NEG) {
|
|
neg.encode(codec, NEG - 1);
|
|
codec.encodeBits(-diff - NEG, bitLength(refvalue - NEG - minvalue));
|
|
} else {
|
|
neg.encode(codec, -diff - 1);
|
|
}
|
|
}
|
|
}
|
|
unsigned decode(ArithmeticDecoder& codec,
|
|
const unsigned refvalue,
|
|
const unsigned minvalue,
|
|
const unsigned maxvalue) {
|
|
unsigned s = sign.decode(codec);
|
|
if (s == 0) {
|
|
return refvalue;
|
|
}
|
|
if (s == 1) {
|
|
int diff = pos.decode(codec);
|
|
if (diff >= (int)(POS - 1)) {
|
|
return refvalue + codec.decodeBits(bitLength(maxvalue - POS - refvalue)) + POS;
|
|
} else {
|
|
return refvalue + diff + 1;
|
|
}
|
|
} else {
|
|
int diff = neg.decode(codec);
|
|
if (diff >= (int)(NEG - 1)) {
|
|
return refvalue - codec.decodeBits(bitLength(refvalue - NEG - minvalue)) - NEG;
|
|
} else {
|
|
return refvalue - diff - 1;
|
|
}
|
|
}
|
|
}
|
|
bool isEqualTo(const PreflateCorrectionSubModel<NEG, POS>& m) const;
|
|
|
|
PreflateSubModel<3> sign;
|
|
PreflateSubModel<POS> pos;
|
|
PreflateSubModel<NEG> neg;
|
|
bool isDefault;
|
|
|
|
private:
|
|
void build_impl(const unsigned* arr, const int defval, const uint8_t prec);
|
|
};
|
|
|
|
struct PreflateModelCodec {
|
|
PreflateSubModel<2> nonDefaultValue;
|
|
uint8_t MBprecision;
|
|
uint8_t MBprecisionP1;
|
|
bool blockFullDefault;
|
|
bool treecodeFullDefault;
|
|
bool tokenFullDefault;
|
|
unsigned totalModels, defaultingModels;
|
|
|
|
PreflateModelCodec();
|
|
void initDefault();
|
|
void read(const PreflateStatisticsCounter&);
|
|
void readFromStream(ArithmeticDecoder&);
|
|
void writeToStream(ArithmeticEncoder&);
|
|
};
|
|
|
|
struct PreflateBaseModel {
|
|
public:
|
|
PreflateBaseModel();
|
|
void setEncoderStream(ArithmeticEncoder*);
|
|
void setDecoderStream(ArithmeticDecoder*);
|
|
|
|
static void encodeValue(ArithmeticEncoder& codec, const unsigned value, const unsigned maxBits) {
|
|
#ifdef _DEBUG
|
|
_ASSERT(value < (1 << maxBits));
|
|
#endif
|
|
return codec.encodeBits(value, maxBits);
|
|
}
|
|
void encodeValue(const unsigned value, const unsigned maxBits) {
|
|
encodeValue(*encoder, value, maxBits);
|
|
}
|
|
static unsigned decodeValue(ArithmeticDecoder& codec, const unsigned maxBits) {
|
|
return codec.decodeBits(maxBits);
|
|
}
|
|
unsigned decodeValue(const unsigned maxBits) {
|
|
return decodeValue(*decoder, maxBits);
|
|
}
|
|
|
|
protected:
|
|
template <unsigned N>
|
|
void readSubModel(PreflateSubModel<N>& sm, const bool isFullDef, const PreflateModelCodec& cc,
|
|
const unsigned defVal, const uint8_t prec = 16);
|
|
|
|
template <unsigned N, unsigned M>
|
|
void readSubModel(PreflateCorrectionSubModel<N, M>& sm, const bool isFullDef, const PreflateModelCodec& cc,
|
|
const unsigned defVal, const uint8_t prec = 16);
|
|
|
|
template <unsigned N>
|
|
void writeSubModel(const PreflateSubModel<N>& sm, const bool isFullDef, const PreflateModelCodec& cc,
|
|
const unsigned defVal, const uint8_t prec = 16);
|
|
|
|
template <unsigned N, unsigned M>
|
|
void writeSubModel(const PreflateCorrectionSubModel<N, M>& sm, const bool isFullDef, const PreflateModelCodec& cc,
|
|
const unsigned defVal, const uint8_t prec = 16);
|
|
|
|
ArithmeticEncoder* encoder;
|
|
ArithmeticDecoder* decoder;
|
|
};
|
|
|
|
struct PreflateBlockPredictionModel : public PreflateBaseModel {
|
|
public:
|
|
void read(const PreflateStatisticsCounter::BlockPrediction&, const PreflateModelCodec&);
|
|
void readFromStream(const PreflateModelCodec&);
|
|
void writeToStream(const PreflateModelCodec&);
|
|
|
|
unsigned decodeBlockType() {
|
|
return blockType.decode(*decoder);
|
|
}
|
|
bool decodeEOBMisprediction() {
|
|
return EOBMisprediction.decode(*decoder);
|
|
}
|
|
bool decodeNonZeroPadding() {
|
|
return nonZeroPadding.decode(*decoder);
|
|
}
|
|
|
|
void encodeBlockType(const unsigned type) {
|
|
blockType.encode(*encoder, type);
|
|
}
|
|
void encodeEOBMisprediction(const bool misprediction) {
|
|
EOBMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeNonZeroPadding(const bool nonzeropadding) {
|
|
nonZeroPadding.encode(*encoder, nonzeropadding);
|
|
}
|
|
|
|
bool isEqualTo(const PreflateBlockPredictionModel& m) const;
|
|
|
|
private:
|
|
PreflateSubModel<3> blockType;
|
|
PreflateSubModel<2> EOBMisprediction;
|
|
PreflateSubModel<2> nonZeroPadding;
|
|
unsigned precision;
|
|
};
|
|
|
|
struct PreflateTreeCodePredictionModel : public PreflateBaseModel {
|
|
public:
|
|
void read(const PreflateStatisticsCounter::TreeCodePrediction&, const PreflateModelCodec& cc);
|
|
void readFromStream(const PreflateModelCodec& cc);
|
|
void writeToStream(const PreflateModelCodec& cc);
|
|
|
|
bool decodeTreeCodeCountMisprediction() {
|
|
return TCCountMisprediction.decode(*decoder);
|
|
}
|
|
bool decodeLiteralCountMisprediction() {
|
|
return LCountMisprediction.decode(*decoder);
|
|
}
|
|
bool decodeDistanceCountMisprediction() {
|
|
return DCountMisprediction.decode(*decoder);
|
|
}
|
|
int decodeTreeCodeBitLengthCorrection(unsigned predval) {
|
|
return TCBitlengthCorrection.decode(*decoder, predval, 0, 7);
|
|
}
|
|
unsigned decodeLDTypeCorrection(unsigned predtype) {
|
|
return DerivedLDTypeReplacement[predtype].decode(*decoder);
|
|
}
|
|
unsigned decodeRepeatCountCorrection(const unsigned predval, const unsigned ldtype) {
|
|
static const uint8_t minVal[4] = {0, 3, 3, 11};
|
|
static const uint8_t lenVal[4] = {0, 3, 7, 127};
|
|
return LDRepeatCountCorrection.decode(*decoder, predval, minVal[ldtype], minVal[ldtype] + lenVal[ldtype]);
|
|
}
|
|
int decodeLDBitLengthCorrection(unsigned predval) {
|
|
return LDBitlengthCorrection.decode(*decoder, predval, 0, 15);
|
|
}
|
|
|
|
void encodeTreeCodeCountMisprediction(const bool misprediction) {
|
|
TCCountMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeLiteralCountMisprediction(const bool misprediction) {
|
|
LCountMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeDistanceCountMisprediction(const bool misprediction) {
|
|
DCountMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeTreeCodeBitLengthCorrection(const unsigned predval, const unsigned actval) {
|
|
TCBitlengthCorrection.encode(*encoder, actval, predval, 0, 7);
|
|
}
|
|
void encodeLDTypeCorrection(const unsigned predval, const unsigned actval) {
|
|
DerivedLDTypeReplacement[predval].encode(*encoder, actval);
|
|
}
|
|
void encodeRepeatCountCorrection(const unsigned predval, const unsigned actval, unsigned ldtype) {
|
|
static const uint8_t minVal[4] = {0, 3, 3, 11};
|
|
static const uint8_t lenVal[4] = {0, 3, 7, 127};
|
|
LDRepeatCountCorrection.encode(*encoder, actval, predval, minVal[ldtype], minVal[ldtype] + lenVal[ldtype]);
|
|
}
|
|
void encodeLDBitLengthCorrection(const unsigned predval, const unsigned actval) {
|
|
LDBitlengthCorrection.encode(*encoder, actval, predval, 0, 15);
|
|
}
|
|
|
|
bool isEqualTo(const PreflateTreeCodePredictionModel& m) const;
|
|
|
|
private:
|
|
void deriveLDTypeReplacement();
|
|
|
|
PreflateSubModel<2> TCCountMisprediction;
|
|
PreflateSubModel<2> LCountMisprediction;
|
|
PreflateSubModel<2> DCountMisprediction;
|
|
PreflateSubModel<2> LDTypeMisprediction[4];
|
|
PreflateSubModel<4> LDTypeReplacementBase;
|
|
PreflateCorrectionSubModel<1, 1> LDRepeatCountCorrection;
|
|
PreflateCorrectionSubModel<3, 3> TCBitlengthCorrection;
|
|
PreflateCorrectionSubModel<4, 4> LDBitlengthCorrection;
|
|
PreflateSubModel<4> DerivedLDTypeReplacement[4];
|
|
};
|
|
|
|
struct PreflateTokenPredictionModel : public PreflateBaseModel {
|
|
public:
|
|
void read(const PreflateStatisticsCounter::TokenPrediction&, const PreflateModelCodec& cc);
|
|
void readFromStream(const PreflateModelCodec& cc);
|
|
void writeToStream(const PreflateModelCodec& cc);
|
|
|
|
bool decodeLiteralPredictionWrong() {
|
|
return LITMisprediction.decode(*decoder);
|
|
}
|
|
bool decodeReferencePredictionWrong() {
|
|
return REFMisprediction.decode(*decoder);
|
|
}
|
|
int decodeLenCorrection(const unsigned predval) {
|
|
return LENCorrection.decode(*decoder, predval, 3, 258);
|
|
}
|
|
unsigned decodeDistOnlyCorrection() {
|
|
return DISTOnlyCorrection.decode(*decoder, 0, 0, 32767);
|
|
}
|
|
unsigned decodeDistAfterLenCorrection() {
|
|
return DISTAfterLenCorrection.decode(*decoder, 0, 0, 32767);
|
|
}
|
|
bool decodeIrregularLen258() {
|
|
return IrregularLen258Encoding.decode(*decoder);
|
|
}
|
|
|
|
void encodeLiteralPredictionWrong(const bool misprediction) {
|
|
LITMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeReferencePredictionWrong(const bool misprediction) {
|
|
REFMisprediction.encode(*encoder, misprediction);
|
|
}
|
|
void encodeLenCorrection(const unsigned predval, const unsigned actval) {
|
|
LENCorrection.encode(*encoder, actval, predval, 3, 258);
|
|
}
|
|
void encodeDistOnlyCorrection(const unsigned hops) {
|
|
DISTOnlyCorrection.encode(*encoder, hops, 0, 0, 32767);
|
|
}
|
|
void encodeDistAfterLenCorrection(const unsigned hops) {
|
|
DISTAfterLenCorrection.encode(*encoder, hops, 0, 0, 32767);
|
|
}
|
|
void encodeIrregularLen258(const bool irregular) {
|
|
IrregularLen258Encoding.encode(*encoder, irregular);
|
|
}
|
|
|
|
bool isEqualTo(const PreflateTokenPredictionModel& m) const;
|
|
|
|
private:
|
|
PreflateSubModel<2> LITMisprediction;
|
|
PreflateSubModel<2> REFMisprediction;
|
|
PreflateCorrectionSubModel<6, 6> LENCorrection;
|
|
PreflateCorrectionSubModel<0, 3> DISTAfterLenCorrection;
|
|
PreflateCorrectionSubModel<0, 3> DISTOnlyCorrection;
|
|
PreflateSubModel<2> IrregularLen258Encoding;
|
|
};
|
|
|
|
struct PreflatePredictionModel {
|
|
PreflatePredictionModel();
|
|
~PreflatePredictionModel();
|
|
|
|
void read(const PreflateStatisticsCounter& model, const PreflateModelCodec& cc);
|
|
void setEncoderStream(ArithmeticEncoder* codec);
|
|
void setDecoderStream(ArithmeticDecoder* codec);
|
|
void readFromStream(const PreflateModelCodec& cc);
|
|
void writeToStream(const PreflateModelCodec& cc);
|
|
|
|
bool isEqualTo(const PreflatePredictionModel& m) const;
|
|
|
|
protected:
|
|
// Blocks
|
|
PreflateBlockPredictionModel block;
|
|
// Tree codes
|
|
PreflateTreeCodePredictionModel treecode;
|
|
// Tokens
|
|
PreflateTokenPredictionModel token;
|
|
};
|
|
|
|
struct PreflatePredictionEncoder : public PreflatePredictionModel {
|
|
PreflatePredictionEncoder();
|
|
|
|
void start(const PreflatePredictionModel&, const PreflateParameters&, const unsigned modelId);
|
|
std::vector<uint8_t> end();
|
|
|
|
void encodeValue(const unsigned value, const unsigned maxBits) {
|
|
encoder->encodeBits(value, maxBits);
|
|
}
|
|
|
|
// Block
|
|
void encodeBlockType(const unsigned type) {
|
|
block.encodeBlockType(type);
|
|
}
|
|
void encodeEOBMisprediction(const bool misprediction) {
|
|
block.encodeEOBMisprediction(misprediction);
|
|
}
|
|
void encodeNonZeroPadding(const bool nonzeropadding) {
|
|
block.encodeNonZeroPadding(nonzeropadding);
|
|
}
|
|
// Tree codes
|
|
void encodeTreeCodeCountMisprediction(const bool misprediction) {
|
|
treecode.encodeTreeCodeCountMisprediction(misprediction);
|
|
}
|
|
void encodeLiteralCountMisprediction(const bool misprediction) {
|
|
treecode.encodeLiteralCountMisprediction(misprediction);
|
|
}
|
|
void encodeDistanceCountMisprediction(const bool misprediction) {
|
|
treecode.encodeDistanceCountMisprediction(misprediction);
|
|
}
|
|
void encodeTreeCodeBitLengthCorrection(const unsigned predval, const unsigned actval) {
|
|
treecode.encodeTreeCodeBitLengthCorrection(predval, actval);
|
|
}
|
|
void encodeLDTypeCorrection(const unsigned predval, const unsigned actval) {
|
|
treecode.encodeLDTypeCorrection(predval, actval);
|
|
}
|
|
void encodeRepeatCountCorrection(const unsigned predval, const unsigned actval, unsigned ldtype) {
|
|
treecode.encodeRepeatCountCorrection(predval, actval, ldtype);
|
|
}
|
|
void encodeLDBitLengthCorrection(const unsigned predval, const unsigned actval) {
|
|
treecode.encodeLDBitLengthCorrection(predval, actval);
|
|
}
|
|
// Token
|
|
void encodeLiteralPredictionWrong(const bool misprediction) {
|
|
token.encodeLiteralPredictionWrong(misprediction);
|
|
}
|
|
void encodeReferencePredictionWrong(const bool misprediction) {
|
|
token.encodeReferencePredictionWrong(misprediction);
|
|
}
|
|
void encodeLenCorrection(const unsigned predval, const unsigned actval) {
|
|
token.encodeLenCorrection(predval, actval);
|
|
}
|
|
void encodeDistOnlyCorrection(const unsigned hops) {
|
|
token.encodeDistOnlyCorrection(hops);
|
|
}
|
|
void encodeDistAfterLenCorrection(const unsigned hops) {
|
|
token.encodeDistAfterLenCorrection(hops);
|
|
}
|
|
void encodeIrregularLen258(const bool irregular) {
|
|
token.encodeIrregularLen258(irregular);
|
|
}
|
|
|
|
const PreflateParameters& parameters() const {
|
|
return params;
|
|
}
|
|
|
|
unsigned modelId() const {
|
|
return modelid;
|
|
}
|
|
|
|
private:
|
|
PreflateParameters params;
|
|
unsigned modelid;
|
|
MemStream* storage;
|
|
BitOutputStream* bos;
|
|
ArithmeticEncoder* encoder;
|
|
};
|
|
|
|
struct PreflatePredictionDecoder : public PreflatePredictionModel {
|
|
PreflatePredictionDecoder();
|
|
void start(const PreflatePredictionModel&, const PreflateParameters&,
|
|
const std::vector<uint8_t>&, size_t off0, size_t size);
|
|
void end();
|
|
|
|
unsigned decodeValue(const unsigned maxBits) {
|
|
return decoder->decodeBits(maxBits);
|
|
}
|
|
// Block
|
|
unsigned decodeBlockType() {
|
|
return block.decodeBlockType();
|
|
}
|
|
bool decodeEOBMisprediction() {
|
|
return block.decodeEOBMisprediction();
|
|
}
|
|
bool decodeNonZeroPadding() {
|
|
return block.decodeNonZeroPadding();
|
|
}
|
|
// Tree codes
|
|
bool decodeTreeCodeCountMisprediction() {
|
|
return treecode.decodeTreeCodeCountMisprediction();
|
|
}
|
|
bool decodeLiteralCountMisprediction() {
|
|
return treecode.decodeLiteralCountMisprediction();
|
|
}
|
|
bool decodeDistanceCountMisprediction() {
|
|
return treecode.decodeDistanceCountMisprediction();
|
|
}
|
|
int decodeTreeCodeBitLengthCorrection(unsigned predval) {
|
|
return treecode.decodeTreeCodeBitLengthCorrection(predval);
|
|
}
|
|
unsigned decodeLDTypeCorrection(unsigned predtype) {
|
|
return treecode.decodeLDTypeCorrection(predtype);
|
|
}
|
|
unsigned decodeRepeatCountCorrection(const unsigned predval, const unsigned ldtype) {
|
|
return treecode.decodeRepeatCountCorrection(predval, ldtype);
|
|
}
|
|
unsigned decodeLDBitLengthCorrection(unsigned predval) {
|
|
return treecode.decodeLDBitLengthCorrection(predval);
|
|
}
|
|
// Token
|
|
bool decodeLiteralPredictionWrong() {
|
|
return token.decodeLiteralPredictionWrong();
|
|
}
|
|
bool decodeReferencePredictionWrong() {
|
|
return token.decodeReferencePredictionWrong();
|
|
}
|
|
int decodeLenCorrection(const unsigned predval) {
|
|
return token.decodeLenCorrection(predval);
|
|
}
|
|
unsigned decodeDistOnlyCorrection() {
|
|
return token.decodeDistOnlyCorrection();
|
|
}
|
|
unsigned decodeDistAfterLenCorrection() {
|
|
return token.decodeDistAfterLenCorrection();
|
|
}
|
|
bool decodeIrregularLen258() {
|
|
return token.decodeIrregularLen258();
|
|
}
|
|
|
|
private:
|
|
PreflateParameters params;
|
|
MemStream* storage;
|
|
BitInputStream* bis;
|
|
ArithmeticDecoder* decoder;
|
|
};
|
|
|
|
struct PreflateMetaEncoder {
|
|
PreflateMetaEncoder();
|
|
~PreflateMetaEncoder();
|
|
|
|
bool error() const {
|
|
return inError;
|
|
}
|
|
unsigned addModel(const PreflateStatisticsCounter&, const PreflateParameters&);
|
|
|
|
bool beginMetaBlockWithModel(PreflatePredictionEncoder&, const unsigned modelId);
|
|
bool endMetaBlock(PreflatePredictionEncoder&, const size_t uncompressed);
|
|
std::vector<unsigned char> finish();
|
|
|
|
private:
|
|
struct modelType {
|
|
unsigned writtenId;
|
|
PreflateStatisticsCounter counter;
|
|
PreflatePredictionModel model;
|
|
PreflateParameters params;
|
|
PreflateModelCodec mcodec;
|
|
};
|
|
struct metaBlockInfo {
|
|
unsigned modelId;
|
|
size_t reconSize;
|
|
size_t uncompressedSize;
|
|
};
|
|
|
|
bool inError;
|
|
std::vector<modelType> modelList;
|
|
std::vector<metaBlockInfo> blockList;
|
|
std::vector<uint8_t> reconData;
|
|
};
|
|
|
|
struct PreflateMetaDecoder {
|
|
PreflateMetaDecoder(const std::vector<uint8_t>& reconData, const uint64_t uncompressedSize);
|
|
~PreflateMetaDecoder();
|
|
|
|
bool error() const {
|
|
return inError;
|
|
}
|
|
size_t metaBlockCount() const {
|
|
return blockList.size();
|
|
}
|
|
uint64_t metaBlockUncompressedStartOfs(const size_t metaBlockId) const {
|
|
return blockList[metaBlockId].uncompressedStartOfs;
|
|
}
|
|
size_t metaBlockUncompressedSize(const size_t metaBlockId) const {
|
|
return blockList[metaBlockId].uncompressedSize;
|
|
}
|
|
|
|
bool beginMetaBlock(PreflatePredictionDecoder&, PreflateParameters&, const size_t index);
|
|
bool endMetaBlock(PreflatePredictionDecoder&);
|
|
void finish();
|
|
|
|
private:
|
|
struct modelType {
|
|
PreflatePredictionModel model;
|
|
PreflateParameters params;
|
|
PreflateModelCodec mcodec;
|
|
};
|
|
struct metaBlockInfo {
|
|
unsigned modelId;
|
|
size_t reconStartOfs;
|
|
size_t reconSize;
|
|
uint64_t uncompressedStartOfs;
|
|
uint64_t uncompressedSize;
|
|
};
|
|
|
|
bool inError;
|
|
|
|
const std::vector<uint8_t>& reconData;
|
|
const uint64_t uncompressedSize;
|
|
std::vector<modelType> modelList;
|
|
std::vector<metaBlockInfo> blockList;
|
|
};
|
|
|
|
bool isEqual(const PreflatePredictionModel&, const PreflatePredictionModel&);
|
|
|
|
#endif /* PREFLATE_STATISTICAL_CODEC_H */
|