📄 arith.cc
字号:
// Copyright 1996 John M. Danskin 7/30/96//// Permission is granted to use this software for any purpose as// long as this notice stays attached to this software.//// These objects implement arithmetic coding as described in// Bell, Cleary, and Witten "Text Compression" Prentice Hall.#include <iostream.h>#include <iomanip.h>#include <assert.h>#include <math.h>#include "global.hh"#include "BitIO.h"#include "iHisto.h"#include "Arith.h"const int CodingValues::CodeValueBits = 16;const long CodingValues::MaxFreq = ((long)1 << (CodeValueBits - 2)) - 1;const long CodingValues::One = ((long)1 << CodeValueBits) - 1;const long CodingValues::Qtr = One / 4 + 1;const long CodingValues::Half = 2 * Qtr;const long CodingValues::ThreeQtr = 3 * Qtr;ArithEncoder::ArithEncoder(BitOut &bo) : output(bo){ low = 0; high = One; bitsToFollow = 0;}voidArithEncoder::flush(void){ for (int i = 0; i < CodeValueBits; i++) { if (low >= Half) { bpf(1); low -= Half; } else { bpf(0); } low = 2 * low; } output.flush();}void ArithEncoder::Encode(int count, int countLeft, int countTot){ // cerr << "Encode(" << count << ", " << countLeft << ", " << countTot << ")\n"; assert(count); long range = high - low + 1; high = low + (range * (countLeft + count)) / countTot - 1; low = low + (range * countLeft) / countTot; while (1) { if (high < Half) { bpf(0); } else if (low >= Half) { bpf(1); low -= Half; high -= Half; } else if (low >= Qtr && high < ThreeQtr) { bitsToFollow++; low -= Qtr; high -= Qtr; } else { break; } low = 2 * low; high = 2 * high + 1; }}ArithDecoder::ArithDecoder(BitIn &bi) : input(bi){ low = 0; high = One; value = 0; for (int i = 0; i < CodeValueBits; i++) { value = (value << 1) + input.input_bit(); }}intArithDecoder::Decode(iHistogram &h){ long range; int cum; int answer; int ct, ctLeft, ctTotal; ctTotal = h.TotalCount(); range = high - low + 1; cum = (((long)(value - low) + 1) * ctTotal - 1) / range; answer = h.Symbol(cum); ct = h.Count(answer); ctLeft = h.LeftCount(answer); // cerr << "Decoder : cum= " << cum << "-> " << answer << "\n"; // cerr << " ct = " << ct << " ctLeft = " << ctLeft << " ctTotal = " << ctTotal << "\n"; high = low + (range * (ctLeft + ct)) / ctTotal - 1; low = low + (range * ctLeft) / ctTotal; while (1) { if (high < Half) { ; } else if (low >= Half) { value -= Half; low -= Half; high -= Half; } else if (low >= Qtr && high < ThreeQtr) { value -= Qtr; low -= Qtr; high -= Qtr; } else break; low = 2 * low; high = 2 * high + 1; value = 2 * value + input.input_bit(); } return answer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -