// File: /workspace/github_cpp_makefile_star2_O2/cristian-bicheru[P]arith/./arith.h
// Function: arith::UncompressBuffer(std::vector<unsigned char, std::allocator<unsigned char>>&, arith::CodecProbabilityTable&, buffer::CodecByteStream&, unsigned long)
void UncompressBuffer(std::vector<unsigned char>& InputBuffer,
                          CodecProbabilityTable& ProbabilityTable,
                          buffer::CodecByteStream& OutputBuffer,
                          uint64_t UncompressedSize) {
        uint8_t shift = InputBuffer[256*4+8];
        uint8_t residual_byte = InputBuffer[256*4+9];
        buffer::CodecBitIterator Buffer(InputBuffer, 256*4+10);
        uint64_t high = MAXVAL;
        uint64_t low = 0ull;
        uint64_t value = 0ull;
        uint64_t range, denom, count, pLow, pUp;
        denom = ProbabilityTable.GetDenom();
        uint8_t byte;

        // Rate Stuff
        auto StartTime = std::chrono::high_resolution_clock::now();
        uint64_t StartSize = UncompressedSize;
        uint64_t BufSizePct = UncompressedSize/100ull;

        if (shift != 0) {
            for (uint8_t i = 0; i < shift; i++) {
                OutputBuffer.WriteBit((residual_byte>>(shift-i-1u))&1u);
            }
        }

        for (uint8_t i = 0; i < 32; i++) {
            value <<= 1ull;
            value += Buffer.ReadBit();
        }

        while (UncompressedSize > 1) {

            if ((UncompressedSize<<44ll>>44ull) == 0ull) {
                std::cout << "\33[2K\r";
                std::cout << "Uncompressing... " << 101ull-UncompressedSize/BufSizePct << "%  @" << (StartSize-UncompressedSize)/std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - StartTime).count() << " Bytes/Second." << std::flush;
            }

            range = high-low+1ull;
            count = ((value - low + 1ull) * denom - 1ull) / range;
            std::tie(pLow, pUp, byte) = ProbabilityTable.DecodeFromCount(count);
            OutputBuffer.WriteByte(byte);
            high = low + (range*pUp)/denom - 1ull;
            low = low + (range*pLow)/denom;

            while (true) {
                if (high < HALF) {
                    //pass;
                } else if (low >= HALF) {
                    value -= HALF;
                    low -= HALF;
                    high -= HALF;
                } else if (high < THREE_QUARTERS && low >= QUARTER) {
                    value -= QUARTER;
                    low -= QUARTER;
                    high -= QUARTER;
                } else {
                    break;
                }
                low <<= 1ull;
                high <<= 1ull;
                high++;
                value <<= 1ull;
                value += Buffer.ReadBit();
            }


            UncompressedSize--;
        }

        for (uint8_t i = 0; i < 8u-shift; i++) {
            OutputBuffer.WriteBit((residual_byte>>(7u-i))&1u);
        }

        std::cout << std::endl;
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rcx, %rbx
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %rsi
movq (%rdi), %rax
movzbl 0x408(%rax), %r12d
movzbl 0x409(%rax), %ebp
leaq 0xd0(%rsp), %r14
movq %r14, %rdi
callq 0x36a0
leaq 0x38(%rsp), %rdi
movl $0x40a, %edx            # imm = 0x40A
movq %r14, %rsi
callq 0x36ea
movq %r14, %rdi
callq 0x44a6
movq %r13, 0x80(%rsp)
movl 0x400(%r13), %eax
movq %rax, 0x30(%rsp)
callq 0x2030
movq %rax, 0x68(%rsp)
pushq $0x64
popq %rcx
movq %rbx, 0x20(%rsp)
movq %rbx, %rax
xorl %edx, %edx
divq %rcx
movq %rax, 0x70(%rsp)
testl %r12d, %r12d
je 0x2b11
leal -0x1(%r12), %ebx
cmpl $-0x1, %ebx
je 0x2b11
xorl %esi, %esi
btl %ebx, %ebp
setb %sil
movq %r15, %rdi
callq 0x3718
decl %ebx
jmp 0x2af7
movq %r15, 0x28(%rsp)
movq 0x38(%rsp), %rax
movq 0x50(%rsp), %rcx
movb $0x20, %dl
movq 0x58(%rsp), %rdi
xorl %r15d, %r15d
pushq $0x7
popq %rsi
subb $0x1, %dl
jb 0x2b68
movzbl (%rax,%rcx), %r8d
testq %rdi, %rdi
je 0x2b42
leaq -0x1(%rdi), %r9
jmp 0x2b4d
incq %rcx
movq %rcx, 0x50(%rsp)
movq %rsi, %r9
addq %r15, %r15
movq %r9, 0x58(%rsp)
xorl %r10d, %r10d
btl %edi, %r8d
setb %r10b
orq %r10, %r15
movq %r9, %rdi
jmp 0x2b2d
movq %r12, 0x60(%rsp)
movl %ebp, 0x1c(%rsp)
movl $0x80000000, %ebx       # imm = 0x80000000
leaq 0x7fffffff(%rbx), %r13
xorl %r12d, %r12d
movq $-0x80000000, %r14      # imm = 0x80000000
movq $-0x40000000, %rbp      # imm = 0xC0000000
movq 0x20(%rsp), %rax
cmpq $0x1, %rax
jbe 0x2dc5
movq %rax, 0x10(%rsp)
shlq $0x2c, %rax
jne 0x2c79
movq 0xa415(%rip), %rdi      # 0xcfc8
leaq 0x5486(%rip), %rsi      # 0x8040
callq 0x21b0
movq 0xa402(%rip), %rdi      # 0xcfc8
leaq 0x549d(%rip), %rsi      # 0x806a
callq 0x21b0
movq %rax, %rdi
movq 0x10(%rsp), %rax
xorl %edx, %edx
divq 0x70(%rsp)
pushq $0x65
popq %rsi
subq %rax, %rsi
callq 0x2100
movq %rax, %rdi
leaq 0x5460(%rip), %rsi      # 0x8056
callq 0x21b0
movq %rax, 0x78(%rsp)
movq 0x20(%rsp), %rax
subq 0x10(%rsp), %rax
movq %rax, %xmm0
punpckldq 0x53f9(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x5401(%rip), %xmm0     # 0x8020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0xc0(%rsp)
callq 0x2030
subq 0x68(%rsp), %rax
cvtsi2sd %rax, %xmm1
divsd 0x53ed(%rip), %xmm1     # 0x8038
movapd 0xc0(%rsp), %xmm0
divsd %xmm1, %xmm0
movq 0x78(%rsp), %rdi
callq 0x2290
movq %rax, %rdi
leaq 0x53ef(%rip), %rsi      # 0x805b
callq 0x21b0
movq %rax, %rdi
callq 0x2120
subq %r12, %r13
incq %r13
movq %r15, %rax
subq %r12, %rax
incq %rax
imulq 0x30(%rsp), %rax
decq %rax
xorl %edx, %edx
divq %r13
leaq 0xb4(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq %rax, %rdx
callq 0x375a
leaq 0xf(%rsp), %rax
movq %rax, 0x98(%rsp)
leaq 0x88(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x90(%rsp), %rax
movq %rax, 0xa8(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0xb4(%rsp), %rsi
callq 0x37d4
movzbl 0xf(%rsp), %esi
movq 0x28(%rsp), %rdi
callq 0x3616
movq 0x88(%rsp), %rax
imulq %r13, %rax
xorl %edx, %edx
movq 0x30(%rsp), %rcx
divq %rcx
leaq (%r12,%rax), %rsi
decq %rsi
imulq 0x90(%rsp), %r13
movq %r13, %rax
xorl %edx, %edx
divq %rcx
addq %rax, %r12
movq 0x38(%rsp), %rax
movq 0x50(%rsp), %rcx
movq 0x58(%rsp), %rdx
movq %rsi, %r13
cmpq %rbx, %r13
jb 0x2d79
movq %r12, %rsi
shrq $0x1f, %rsi
je 0x2d5b
addq %r14, %r15
addq %r14, %r12
addq %r14, %r13
jmp 0x2d79
leaq 0x40000000(%rbx), %rsi
cmpq %rsi, %r13
jae 0x2db8
cmpq $0x40000000, %r12       # imm = 0x40000000
jb 0x2db8
addq %rbp, %r15
addq %rbp, %r12
addq %rbp, %r13
movzbl (%rax,%rcx), %esi
testq %rdx, %rdx
je 0x2d88
leaq -0x1(%rdx), %rdi
jmp 0x2d93
incq %rcx
movq %rcx, 0x50(%rsp)
pushq $0x7
popq %rdi
addq %r12, %r12
leaq 0x1(,%r13,2), %r13
addq %r15, %r15
movq %rdi, 0x58(%rsp)
xorl %r8d, %r8d
btl %edx, %esi
setb %r8b
orq %r8, %r15
movq %rdi, %rdx
jmp 0x2d42
movq 0x10(%rsp), %rax
decq %rax
jmp 0x2b93
pushq $0x8
popq %rbx
subl 0x60(%rsp), %ebx
xorl %ebp, %ebp
movq 0x28(%rsp), %r14
movl 0x1c(%rsp), %r15d
movzbl %bpl, %eax
cmpl %eax, %ebx
jbe 0x2dff
movb $0x7, %al
subb %bpl, %al
movzbl %al, %eax
xorl %esi, %esi
btl %eax, %r15d
setb %sil
movq %r14, %rdi
callq 0x3718
incb %bpl
jmp 0x2dd8
movq 0xa1c2(%rip), %rdi      # 0xcfc8
callq 0x20c0
leaq 0x38(%rsp), %rdi
callq 0x44a6
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2e31
jmp 0x2e31
jmp 0x2e31
jmp 0x2e31
jmp 0x2e31
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x44a6
movq %rbx, %rdi
callq 0x22e0