r5sdk/r5dev/thirdparty/lzham/include/lzham_symbol_codec.h
IcePixelx dedd7867cd Squashed commit of the following:
commit 4da14d7ddecc0d8c322fc7ee372be67481fb0b99
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Sat Jan 15 20:13:11 2022 +0100

    Cleaned up native server browser and commented functions.

commit b366e4ce826c9c7dbeb2af26cb6c34656b2c93f2
Author: r-ex <67599507+r-ex@users.noreply.github.com>
Date:   Sat Jan 15 17:57:18 2022 +0000

    sq server browser clean up (#63)

    * sq server browser clean up

    * Properly loop through std::vector on GetAvailableMaps.

    Co-authored-by: IcePixelx <41352111+PixieCore@users.noreply.github.com>

commit 829e122cead5521d5ffa57daa7e9fbd10755d68f
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Sat Jan 15 15:25:19 2022 +0100

    SQ Serverbrowser V1 push. Clean-up following after @r-ex fixed SQ things.

commit 29fe6be989f176321406e4e521da406e65229acd
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Fri Jan 14 20:59:06 2022 +0100

    Fix pre-compiled headers for imgui_utility.cpp

commit f2f8a088bfbc8b7311f2efb402963eb3b0802a46
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 20:51:32 2022 +0100

    Fix compiler error caused merge from separate branch

commit 1c5df4e178a29234139c3ebf06b25fcd795689ea
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 20:45:36 2022 +0100

    Ansi terminal color support + big optimizations on all log systems + 'Warning()' hook

    * Ansi colors can now be enabled with the '-ansiclr- flag.
    * All loggers have been optimized and are all initialized only once at process startup.
    * New hook for 'Warning()' print function with warning level.

commit 012a317c846ba4fcf727ffb97678ee080f2dd976
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 15:39:09 2022 +0100

    Update init.cpp

commit a14480e7cfdb869d222da04275f2619ca1405ce3
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 15:38:48 2022 +0100

    Update stdafx.h

commit bdc67e90cb5624ee5d9f8a3620fe64a0d80726a5
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 15:37:08 2022 +0100

    Set default spdlog level to trace

commit 96ee434d4e58a79a091cb0fee0caa5d838f629df
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 14 15:36:51 2022 +0100

    Fix missing header errors for SpdLog

commit 6bbb16dcb9f821e6f71bbfa9f0b4b12167907f43
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Fri Jan 14 20:39:11 2022 +0100

    Fix sendrequest crash. Due to htResults being null.

commit 5612c7a3a7e38f725b17e98d17d06f146135feae
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 12 13:11:11 2022 +0100

    This seems no longer needed for dedicated servers

    Shader/texture assets are no longer loaded where the pointer parameters to the asset unloading function won't be out of scope anymore

commit e6254e3a036b26a70b4dc29df7f8a5082a0f5297
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 12 13:09:06 2022 +0100

    Fix issue with ImGui windows where input could loose focus and not work

    'ImGui_ImplWin32_WndProcHandler' has to be called at all times from the HwndProc handler as it has to track all events to prevent issues with input.

commit de3b3f53bd2c32015e9accaed873d06a722ab7da
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 12 02:53:07 2022 +0100

    Optimizations + QoL improvements/cleanup

    * IConsole overlay now clears the oldest log entries to stay under the vector limit instead of clearing the whole vector.
    * IConsole code cleanup.
    * IBrowser code cleanup, reordered class methods.
    * Use ConVar utilities to get/set values for strings in IBrowser and IConsole.
    * New ConVar's for RUI console overlay to tweak colors.

commit 44102abbcca2d088dcb253da8ec7c9b869064139
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Mon Jan 10 02:47:19 2022 +0100

    Execute dev configs when '-devsdk' parameter is passed

commit 8d1023212abd8e2b250f5fb7b33fdfa329b07b40
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Mon Jan 10 02:24:30 2022 +0100

    Small alignment

commit 38d9d431c9aaef1ede7b6ceb594aa9b9971c261f
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Mon Jan 10 02:03:31 2022 +0100

    Fix potential bug where 'cm_return_false_cmdquery_all' cvar would never work

commit c0f24e64ff04bacb8d5b51961de1687dfb75bc71
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Mon Jan 10 01:31:25 2022 +0100

    Rename global cvar pointer

commit 0146f22e0a8bcd7ec137bb205d117cea49f533dc
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Mon Jan 10 01:20:44 2022 +0100

    Implement CommandLine utilities

commit 64c07af6e067bc85385a78981d29770eebd3eb6b
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Sun Jan 9 17:17:05 2022 +0100

    Cleanup to use new ConVar utilities

commit 19f5010bd26e010746436766c05515dff85d7695
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Sun Jan 9 16:29:36 2022 +0100

    Fix compiler error + rename debug dll's

    Rename for easier debugging and config separation

commit c292d8ad46b22c7a34c6d3caf8143e131e8dd997
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Sun Jan 9 16:14:17 2022 +0100

    Implement new ConVar features

    Slight cleanup with new ConVar features to be used throughout the SDK

commit 0177c17da94dc977f85babe2aa8168cefb56bf45
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Sat Jan 8 02:05:33 2022 +0100

    Draw simulation stats and GPU stats to debug text overlay

commit 21a10e201b6ea7afd4ffdd7d6b9668806085b6a5
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Sun Jan 9 14:36:22 2022 +0100

    Typos.

commit ae09372cc79053f5515529e403402494ffa6dfe4
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Sun Jan 9 14:35:43 2022 +0100

    Pylon system changes.

commit 98a428ace9226442fa623a0870af9f7e12f35eb0
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Jan 7 01:03:35 2022 +0100

    Fix S2 crash when launching a different version

commit c98301d175b8b1b80b2f480bc29e0703cf12c350
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Jan 6 17:30:10 2022 +0100

    Fix LZHAM recompiling pch for each implementation file

commit b80be10c4dc2c1f27917cd68a2c4c47819ee5fe5
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Jan 6 15:08:39 2022 +0100

    Compile LZHAM with the solution. Fix missing detours files for sdklauncher

commit a0b7bbf3661cc9b4d2d0cdefe9050a78f1c2bc67
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Jan 6 02:22:28 2022 +0100

    Compile Microsoft Detours with the solution

commit 9a3175fb6df047445e26ca3d4692e42f01cbabc8
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Jan 6 01:51:55 2022 +0100

    Fix console input text reclaim to reflect latest ImGui changes

commit 556894b3e3d81e41fa461321a749f50aa0eb169f
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 5 23:50:14 2022 +0100

    Add connect command fix back

    Accidentally removed.

commit 1612c439d2bb68fea29b4804b67c7de7a2aeaed7
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 5 23:44:01 2022 +0100

    Fix project filters

commit 47fdd4211d3088a84aeb93e425288928d1b37e70
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 5 23:43:51 2022 +0100

    Fix for S3

    For some reason the same byte pattern wasn't found in the miles dll for the S3 game, even though they where identical. Changed the byte patterns to search for the last 2 bytes of the instruction as well and made the conditional jmp instructions, unconditional for making sure mileswin64.dll doesn't close the process when a debugger is found.

commit d52bd5eeec4f9f86422b3864446521c4ca46f02b
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 5 22:56:49 2022 +0100

    Initial support for S1

commit 7c3994dfc280d8312632c9256f40a776c13158a4
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Wed Jan 5 19:23:53 2022 +0100

    dedicated refuselist

commit c486c2d59354b3672709013c24454017fdce5cf2
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Jan 5 02:07:37 2022 +0100

    Portability to S2 completed

    CServer functions are evolving quite heavily over these seasons, so these need a bit of work

commit fbcea85631fe9ee1b378a3fc6657908230b85403
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Tue Jan 4 12:11:59 2022 +0100

    Fix compiler error caused by merging commits from different branches

commit 84e7729ca045c05e4add7f05d09d032833e39a7b
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Tue Jan 4 11:53:54 2022 +0100

    Add client and debug utilities + cleanup

commit 477152b35443246dace6f5b4deccd52ea1cc6e9c
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Dec 31 03:45:48 2021 +0100

    Fix compiler error

commit 5f664d8e6ba9a2e0bd72c29c5f4ba5279e29e75a
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Fri Dec 31 03:41:33 2021 +0100

    Create signatures for all used Dedicated functions

commit 2c7ced128d8c48a5abf8fd64dbb06909dc632f35
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Dec 30 22:13:15 2021 +0100

    Heavy dedicated cleanup

    * Since the material mode is set to '2', all of the render loops and shader loading functions are no longer called. These have all been removed.
    * Added description for patches that missed them
    * Traced root caller/cause for certain patches to skip even more unnecessary code and save more memory.

commit 22c0b5c867664a2524c18d865dbc54ff067dda22
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Dec 30 17:20:41 2021 +0100

    Dedicated server improvements

commit 6d4f7e345f38872ce45751604b40871b969cec8f
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Dec 30 02:47:42 2021 +0100

    Fix a typo

commit 39a8a8fd30612522a274e1474c9a66e5019aeea3
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Thu Dec 30 02:36:43 2021 +0100

    Implement patch to enable 'DrawAllOverlays()'.

commit 83129e88f8a6033f8f4c13e3cac639097068cb3c
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 22:59:34 2021 +0100

    Fix LLVM compiler error

commit c48ed7f7a53a9985e3c2642db3639007d7c9129a
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 18:06:37 2021 +0100

    Rename dedicated variables

commit d1ba2bd56720a0776824a8e309d7d859704244bc
Author: IcePixelx <41352111+PixieCore@users.noreply.github.com>
Date:   Wed Dec 29 15:35:48 2021 +0100

    Fixed changelevel, needs more research tho.

commit 46950125716c05171f25a12d8805811112e90551
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 13:58:03 2021 +0100

    Fix 'C_PropDoor' not spawning properly on the server

commit 6a9a00735a9d4b8c415acc248c83e6e8d6dc2ff1
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 13:57:16 2021 +0100

    Rename hooked command callbacks

commit b514f928a69a9c4ac1d3d1e5c662f93a1f0d131d
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 02:16:21 2021 +0100

    Use a separate executable for dedicated server

    The dedicated server still has directx dll imports which will cause issues with ReShade or 3DMigoto, or trying to load it on a headless machine with no directx installed. The imports have to be cleared to avoid issues. The most convenient approach is to do this with a separate exe rather then patching it in runtime.

commit bc8f9400d3911e360757059700a31510e329546d
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Wed Dec 29 00:18:56 2021 +0100

    Fix collisions for headless dedicated server

commit 0e36aa647ffb15ca4f8c76b0431f7c3a83741d80
Author: Amos <48657826+Mauler125@users.noreply.github.com>
Date:   Tue Dec 28 20:19:17 2021 +0100

    Dedicated without ShaderApi and DirectX pre-alpha

    The instruction at 'CalcPropStaticFrustumCull' [0x14028F3B0 + 0x5C7] moves RSP + 0x70 into the R13 register.
    RSP + 0x70 seems to contain a pointer to collission data for that particular prop model.
    When running NoShaderApi() and passing the dedicated server the '-noshaderapi' command line parameter, RSP + 0x70 will be a nullptr.
    This has to be fixed to have prop static collissions on the server.
2022-01-15 21:16:20 +01:00

557 lines
20 KiB
C++

// File: lzham_symbol_codec.h
// See Copyright Notice and license at the end of include/lzham.h
#pragma once
#include "lzham_prefix_coding.h"
namespace lzham
{
class symbol_codec;
class adaptive_arith_data_model;
const uint cSymbolCodecArithMinLen = 0x01000000U;
const uint cSymbolCodecArithMaxLen = 0xFFFFFFFFU;
const uint cSymbolCodecArithProbBits = 11;
const uint cSymbolCodecArithProbScale = 1 << cSymbolCodecArithProbBits;
const uint cSymbolCodecArithProbHalfScale = 1 << (cSymbolCodecArithProbBits - 1);
const uint cSymbolCodecArithProbMoveBits = 5;
typedef uint64 bit_cost_t;
const uint32 cBitCostScaleShift = 24;
const uint32 cBitCostScale = (1U << cBitCostScaleShift);
const bit_cost_t cBitCostMax = UINT64_MAX;
inline bit_cost_t convert_to_scaled_bitcost(uint bits) { LZHAM_ASSERT(bits <= 255); uint32 scaled_bits = bits << cBitCostScaleShift; return static_cast<bit_cost_t>(scaled_bits); }
extern uint32 g_prob_cost[cSymbolCodecArithProbScale];
class raw_quasi_adaptive_huffman_data_model
{
public:
raw_quasi_adaptive_huffman_data_model(bool encoding = true, uint total_syms = 0, bool fast_encoding = false, bool use_polar_codes = false);
raw_quasi_adaptive_huffman_data_model(const raw_quasi_adaptive_huffman_data_model& other);
~raw_quasi_adaptive_huffman_data_model();
bool assign(const raw_quasi_adaptive_huffman_data_model& rhs);
raw_quasi_adaptive_huffman_data_model& operator= (const raw_quasi_adaptive_huffman_data_model& rhs);
void clear();
bool init(bool encoding, uint total_syms, bool fast_encoding, bool use_polar_codes, const uint16 *pInitial_sym_freq = NULL);
bool reset();
inline uint get_total_syms() const { return m_total_syms; }
void rescale();
void reset_update_rate();
bool update(uint sym);
inline bit_cost_t get_cost(uint sym) const { return convert_to_scaled_bitcost(m_code_sizes[sym]); }
public:
lzham::vector<uint16> m_initial_sym_freq;
lzham::vector<uint16> m_sym_freq;
lzham::vector<uint16> m_codes;
lzham::vector<uint8> m_code_sizes;
prefix_coding::decoder_tables* m_pDecode_tables;
uint m_total_syms;
uint m_max_cycle;
uint m_update_cycle;
uint m_symbols_until_update;
uint m_total_count;
uint8 m_decoder_table_bits;
bool m_encoding;
bool m_fast_updating;
bool m_use_polar_codes;
bool update();
friend class symbol_codec;
};
struct quasi_adaptive_huffman_data_model : public raw_quasi_adaptive_huffman_data_model
{
#if LZHAM_64BIT_POINTERS
// Ensures sizeof(quasi_adaptive_huffman_data_model) is 128 bytes on x64 (it's 64 on x86).
char m_unused_alignment[128 - sizeof(raw_quasi_adaptive_huffman_data_model)];
#endif
};
class adaptive_bit_model
{
public:
adaptive_bit_model();
adaptive_bit_model(float prob0);
adaptive_bit_model(const adaptive_bit_model& other);
inline adaptive_bit_model& operator= (const adaptive_bit_model& rhs) { m_bit_0_prob = rhs.m_bit_0_prob; return *this; }
inline void clear() { m_bit_0_prob = 1U << (cSymbolCodecArithProbBits - 1); }
void set_probability_0(float prob0);
inline void update(uint bit)
{
if (!bit)
m_bit_0_prob += ((cSymbolCodecArithProbScale - m_bit_0_prob) >> cSymbolCodecArithProbMoveBits);
else
m_bit_0_prob -= (m_bit_0_prob >> cSymbolCodecArithProbMoveBits);
LZHAM_ASSERT(m_bit_0_prob >= 1);
LZHAM_ASSERT(m_bit_0_prob < cSymbolCodecArithProbScale);
}
inline bit_cost_t get_cost(uint bit) const { return g_prob_cost[bit ? (cSymbolCodecArithProbScale - m_bit_0_prob) : m_bit_0_prob]; }
public:
uint16 m_bit_0_prob;
friend class symbol_codec;
friend class adaptive_arith_data_model;
};
// This class is not actually used by LZHAM - it's only here for comparison/experimental purposes.
class adaptive_arith_data_model
{
public:
adaptive_arith_data_model(bool encoding = true, uint total_syms = 0);
adaptive_arith_data_model(const adaptive_arith_data_model& other);
~adaptive_arith_data_model();
adaptive_arith_data_model& operator= (const adaptive_arith_data_model& rhs);
void clear();
bool init(bool encoding, uint total_syms);
bool init(bool encoding, uint total_syms, bool fast_encoding, bool use_polar_codes = false) { LZHAM_NOTE_UNUSED(fast_encoding), LZHAM_NOTE_UNUSED(use_polar_codes); return init(encoding, total_syms); }
void reset();
void reset_update_rate();
bool update(uint sym);
uint get_total_syms() const { return m_total_syms; }
bit_cost_t get_cost(uint sym) const;
public:
uint m_total_syms;
typedef lzham::vector<adaptive_bit_model> adaptive_bit_model_vector;
adaptive_bit_model_vector m_probs;
friend class symbol_codec;
};
#if LZHAM_CPU_HAS_64BIT_REGISTERS
#define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 1
#else
#define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 0
#endif
class symbol_codec
{
public:
symbol_codec();
void reset();
// clear() is like reset(), except it also frees all memory.
void clear();
// Encoding
bool start_encoding(uint expected_file_size);
bool encode_bits(uint bits, uint num_bits);
bool encode_arith_init();
bool encode_align_to_byte();
bool encode(uint sym, quasi_adaptive_huffman_data_model& model);
bool encode(uint bit, adaptive_bit_model& model, bool update_model = true);
bool encode(uint sym, adaptive_arith_data_model& model);
inline uint encode_get_total_bits_written() const { return m_total_bits_written; }
bool stop_encoding(bool support_arith);
const lzham::vector<uint8>& get_encoding_buf() const { return m_output_buf; }
lzham::vector<uint8>& get_encoding_buf() { return m_output_buf; }
// Decoding
typedef void (*need_bytes_func_ptr)(size_t num_bytes_consumed, void *pPrivate_data, const uint8* &pBuf, size_t &buf_size, bool &eof_flag);
bool start_decoding(const uint8* pBuf, size_t buf_size, bool eof_flag = true, need_bytes_func_ptr pNeed_bytes_func = NULL, void *pPrivate_data = NULL);
inline void decode_set_input_buffer(const uint8* pBuf, size_t buf_size, const uint8* pBuf_next, bool eof_flag)
{
m_pDecode_buf = pBuf;
m_pDecode_buf_next = pBuf_next;
m_decode_buf_size = buf_size;
m_pDecode_buf_end = pBuf + buf_size;
m_decode_buf_eof = eof_flag;
}
inline uint64 decode_get_bytes_consumed() const { return m_pDecode_buf_next - m_pDecode_buf; }
inline uint64 decode_get_bits_remaining() const { return ((m_pDecode_buf_end - m_pDecode_buf_next) << 3) + m_bit_count; }
void start_arith_decoding();
uint decode_bits(uint num_bits);
uint decode_peek_bits(uint num_bits);
void decode_remove_bits(uint num_bits);
void decode_align_to_byte();
int decode_remove_byte_from_bit_buf();
uint decode(quasi_adaptive_huffman_data_model& model);
uint decode(adaptive_bit_model& model, bool update_model = true);
uint decode(adaptive_arith_data_model& model);
uint64 stop_decoding();
uint get_total_model_updates() const { return m_total_model_updates; }
public:
const uint8* m_pDecode_buf;
const uint8* m_pDecode_buf_next;
const uint8* m_pDecode_buf_end;
size_t m_decode_buf_size;
bool m_decode_buf_eof;
need_bytes_func_ptr m_pDecode_need_bytes_func;
void* m_pDecode_private_data;
#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
typedef uint64 bit_buf_t;
enum { cBitBufSize = 64 };
#else
typedef uint32 bit_buf_t;
enum { cBitBufSize = 32 };
#endif
bit_buf_t m_bit_buf;
int m_bit_count;
uint m_total_model_updates;
lzham::vector<uint8> m_output_buf;
lzham::vector<uint8> m_arith_output_buf;
struct output_symbol
{
uint m_bits;
enum
{
cArithSym = -1,
cAlignToByteSym = -2,
cArithInit = -3
};
int16 m_num_bits;
uint16 m_arith_prob0;
};
lzham::vector<output_symbol> m_output_syms;
uint m_total_bits_written;
uint m_arith_base;
uint m_arith_value;
uint m_arith_length;
uint m_arith_total_bits;
quasi_adaptive_huffman_data_model* m_pSaved_huff_model;
void* m_pSaved_model;
uint m_saved_node_index;
bool put_bits_init(uint expected_size);
bool record_put_bits(uint bits, uint num_bits);
void arith_propagate_carry();
bool arith_renorm_enc_interval();
void arith_start_encoding();
bool arith_stop_encoding();
bool put_bits(uint bits, uint num_bits);
bool put_bits_align_to_byte();
bool flush_bits();
bool assemble_output_buf();
uint get_bits(uint num_bits);
void remove_bits(uint num_bits);
void decode_need_bytes();
enum
{
cNull,
cEncoding,
cDecoding
} m_mode;
};
// Optional macros for faster decompression. These macros implement the symbol_codec class's decode functionality.
// This is hard to debug (and just plain ugly), but using these macros eliminate function calls, and they place the most important
// member variables on the stack so they're hopefully put in registers (avoiding horrible load hit stores on some CPU's).
// The user must define the LZHAM_DECODE_NEEDS_BYTES macro, which is invoked when the decode buffer is exhausted.
#define LZHAM_SYMBOL_CODEC_DECODE_DECLARE(codec) \
uint arith_value = 0; \
uint arith_length = 0; \
symbol_codec::bit_buf_t bit_buf = 0; \
int bit_count = 0; \
const uint8* pDecode_buf_next = NULL;
#define LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
arith_value = codec.m_arith_value; \
arith_length = codec.m_arith_length; \
bit_buf = codec.m_bit_buf; \
bit_count = codec.m_bit_count; \
pDecode_buf_next = codec.m_pDecode_buf_next;
#define LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
codec.m_arith_value = arith_value; \
codec.m_arith_length = arith_length; \
codec.m_bit_buf = bit_buf; \
codec.m_bit_count = bit_count; \
codec.m_pDecode_buf_next = pDecode_buf_next;
// The user must declare the LZHAM_DECODE_NEEDS_BYTES macro.
#define LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, result, num_bits) \
{ \
while (LZHAM_BUILTIN_EXPECT(bit_count < (int)(num_bits), 0)) \
{ \
uint r; \
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
{ \
if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
{ \
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
LZHAM_DECODE_NEEDS_BYTES \
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
} \
r = 0; \
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) r = *pDecode_buf_next++; \
} \
else \
r = *pDecode_buf_next++; \
bit_count += 8; \
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(r) << (symbol_codec::cBitBufSize - bit_count)); \
} \
result = (num_bits) ? static_cast<uint>(bit_buf >> (symbol_codec::cBitBufSize - (num_bits))) : 0; \
bit_buf <<= (num_bits); \
bit_count -= (num_bits); \
}
#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, result, model) \
{ \
adaptive_bit_model *pModel; \
pModel = &model; \
while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
{ \
uint c; codec.m_pSaved_model = pModel; \
LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
pModel = static_cast<adaptive_bit_model*>(codec.m_pSaved_model); \
arith_value = (arith_value << 8) | c; \
arith_length <<= 8; \
} \
uint x = pModel->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
result = (arith_value >= x); \
if (!result) \
{ \
pModel->m_bit_0_prob += ((cSymbolCodecArithProbScale - pModel->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
arith_length = x; \
} \
else \
{ \
pModel->m_bit_0_prob -= (pModel->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
arith_value -= x; \
arith_length -= x; \
} \
}
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_ARITHMETIC(codec, result, model) \
{ \
adaptive_arith_data_model *pArith_data_model; \
pArith_data_model = &model; \
uint node_index; \
node_index = 1; \
do \
{ \
while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
{ \
uint c; codec.m_saved_node_index = node_index; codec.m_pSaved_model = pArith_data_model; \
LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
node_index = codec.m_saved_node_index; pArith_data_model = static_cast<adaptive_arith_data_model *>(codec.m_pSaved_model); \
arith_value = (arith_value << 8) | c; \
arith_length <<= 8; \
} \
adaptive_bit_model *pBit_model; pBit_model = &pArith_data_model->m_probs[node_index]; \
uint x = pBit_model->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
uint bit; bit = (arith_value >= x); \
if (!bit) \
{ \
pBit_model->m_bit_0_prob += ((cSymbolCodecArithProbScale - pBit_model->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
arith_length = x; \
} \
else \
{ \
pBit_model->m_bit_0_prob -= (pBit_model->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
arith_value -= x; \
arith_length -= x; \
} \
node_index = (node_index << 1) + bit; \
} while (node_index < pArith_data_model->m_total_syms); \
result = node_index - pArith_data_model->m_total_syms; \
}
#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
{ \
quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
pModel = &model; pTables = model.m_pDecode_tables; \
if (LZHAM_BUILTIN_EXPECT(bit_count < 24, 0)) \
{ \
uint c; \
pDecode_buf_next += sizeof(uint32); \
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next >= codec.m_pDecode_buf_end, 0)) \
{ \
pDecode_buf_next -= sizeof(uint32); \
while (bit_count < 24) \
{ \
if (!codec.m_decode_buf_eof) \
{ \
codec.m_pSaved_huff_model = pModel; \
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
LZHAM_DECODE_NEEDS_BYTES \
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
} \
c = 0; if (pDecode_buf_next < codec.m_pDecode_buf_end) c = *pDecode_buf_next++; \
bit_count += 8; \
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
} \
} \
else \
{ \
c = LZHAM_READ_BIG_ENDIAN_UINT32(pDecode_buf_next - sizeof(uint32)); \
bit_count += 32; \
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
} \
} \
uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
uint len; \
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
{ \
uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
result = t & UINT16_MAX; \
len = t >> 16; \
} \
else \
{ \
len = pTables->m_decode_start_code_size; \
for ( ; ; ) \
{ \
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
break; \
len++; \
} \
int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
if (((uint)val_ptr >= pModel->m_total_syms)) val_ptr = 0; \
result = pTables->m_sorted_symbol_order[val_ptr]; \
} \
bit_buf <<= len; \
bit_count -= len; \
uint freq = pModel->m_sym_freq[result]; \
freq++; \
pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
LZHAM_ASSERT(freq <= UINT16_MAX); \
if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
{ \
pModel->update(); \
} \
}
#else
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
{ \
quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
pModel = &model; pTables = model.m_pDecode_tables; \
while (LZHAM_BUILTIN_EXPECT(bit_count < (symbol_codec::cBitBufSize - 8), 1)) \
{ \
uint c; \
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
{ \
if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
{ \
codec.m_pSaved_huff_model = pModel; \
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
LZHAM_DECODE_NEEDS_BYTES \
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
} \
c = 0; if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) c = *pDecode_buf_next++; \
} \
else \
c = *pDecode_buf_next++; \
bit_count += 8; \
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
} \
uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
uint len; \
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
{ \
uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
result = t & UINT16_MAX; \
len = t >> 16; \
} \
else \
{ \
len = pTables->m_decode_start_code_size; \
for ( ; ; ) \
{ \
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
break; \
len++; \
} \
int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
if (LZHAM_BUILTIN_EXPECT(((uint)val_ptr >= pModel->m_total_syms), 0)) val_ptr = 0; \
result = pTables->m_sorted_symbol_order[val_ptr]; \
} \
bit_buf <<= len; \
bit_count -= len; \
uint freq = pModel->m_sym_freq[result]; \
freq++; \
pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
LZHAM_ASSERT(freq <= UINT16_MAX); \
if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
{ \
pModel->update(); \
} \
}
#endif
#define LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec) if (bit_count & 7) { int dummy_result; LZHAM_NOTE_UNUSED(dummy_result); LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, dummy_result, bit_count & 7); }
#define LZHAM_SYMBOL_CODEC_DECODE_REMOVE_BYTE_FROM_BIT_BUF(codec, result) \
{ \
result = -1; \
if (bit_count >= 8) \
{ \
result = static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - 8)); \
bit_buf <<= 8; \
bit_count -= 8; \
} \
}
#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_START(codec) \
{ \
for ( arith_value = 0, arith_length = 0; arith_length < 4; ++arith_length ) \
{ \
uint val; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, val, 8); \
arith_value = (arith_value << 8) | val; \
} \
arith_length = cSymbolCodecArithMaxLen; \
}
} // namespace lzham