// File: /workspace/github_cpp_makefile_star2_O1/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 $0x88, %rsp
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %rsi
movq (%rdi), %rax
movzbl 0x408(%rax), %ecx
movq %rcx, 0x20(%rsp)
movzbl 0x409(%rax), %ebp
leaq 0x70(%rsp), %r15
movq %r15, %rdi
callq 0x3c64
movq (%r15), %r12
xorpd %xmm0, %xmm0
movapd %xmm0, (%r15)
movq $0x0, 0x10(%r15)
movq 0x20(%rsp), %r15
movq %r13, 0x68(%rsp)
movl 0x400(%r13), %eax
movq %rax, 0x38(%rsp)
callq 0x2040
movq %rax, 0x60(%rsp)
movq %rbx, 0x8(%rsp)
shrq $0x2, %rbx
movabsq $0x28f5c28f5c28f5c3, %rcx # imm = 0x28F5C28F5C28F5C3
movq %rbx, %rax
mulq %rcx
movq %rdx, 0x28(%rsp)
testl %r15d, %r15d
je 0x2d87
leal -0x1(%r15), %ebx
xorl %esi, %esi
btl %ebx, %ebp
setb %sil
movq %r14, %rdi
callq 0x3cb0
addl $-0x1, %ebx
jb 0x2d71
movl %ebp, 0x1c(%rsp)
movq %r14, 0x30(%rsp)
shrq $0x2, 0x28(%rsp)
movl $0x40a, %edi            # imm = 0x40A
movl $0x7, %eax
movb $0x20, %cl
xorl %r14d, %r14d
movl $0x7, %r8d
movl $0x40a, %edx            # imm = 0x40A
movq %r8, %rsi
cmpq $0x1, %r8
adcq $0x0, %rdx
subq $0x1, %rsi
cmovbq %rax, %rsi
movzbl (%r12,%rdi), %edi
xorl %r9d, %r9d
btl %r8d, %edi
setb %r9b
leaq (%r9,%r14,2), %r14
movq %rsi, %r8
movq %rdx, %rdi
decb %cl
jne 0x2db3
cmpq $0x2, 0x8(%rsp)
jb 0x300e
movl $0x80000000, %eax       # imm = 0x80000000
leaq 0x7fffffff(%rax), %r13
movl $0x40e, %ebp            # imm = 0x40E
xorl %r15d, %r15d
movq 0x8(%rsp), %rax
movl $0x7, %ebx
movq %rax, 0x10(%rsp)
shlq $0x2c, %rax
jne 0x2f02
movl $0x5, %edx
movq 0xa1a2(%rip), %rdi      # 0xcfc8
leaq 0x623b(%rip), %rsi      # 0x9068
callq 0x2220
movl $0x11, %edx
movq 0xa18a(%rip), %rdi      # 0xcfc8
leaq 0x624d(%rip), %rsi      # 0x9092
callq 0x2220
movq 0x10(%rsp), %rax
xorl %edx, %edx
divq 0x28(%rsp)
movl $0x65, %esi
subq %rax, %rsi
movq 0xa163(%rip), %rdi      # 0xcfc8
callq 0x2120
movq %rax, (%rsp)
movl $0x4, %edx
movq (%rsp), %rdi
leaq 0x6200(%rip), %rsi      # 0x907e
callq 0x2220
movq 0x8(%rsp), %rax
subq 0x10(%rsp), %rax
movq %rax, %xmm0
punpckldq 0x6176(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x617e(%rip), %xmm0     # 0x9020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x50(%rsp)
callq 0x2040
subq 0x60(%rsp), %rax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd 0x617a(%rip), %xmm1     # 0x9048
movapd 0x50(%rsp), %xmm0
divsd %xmm1, %xmm0
movq (%rsp), %rdi
callq 0x22d0
movl $0xe, %edx
movq %rax, %rdi
leaq 0x6193(%rip), %rsi      # 0x9083
movq %rax, (%rsp)
callq 0x2220
movq (%rsp), %rdi
callq 0x2140
subq %r15, %r13
incq %r13
movq %r14, %rax
subq %r15, %rax
incq %rax
imulq 0x38(%rsp), %rax
decq %rax
xorl %edx, %edx
divq %r13
leaq 0x44(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq %rax, %rdx
callq 0x3d08
movl 0x48(%rsp), %eax
movq %rax, 0x50(%rsp)
movl 0x4c(%rsp), %eax
movq %rax, (%rsp)
movzbl 0x44(%rsp), %esi
movq 0x30(%rsp), %rdi
callq 0x3bd6
movq 0x50(%rsp), %rax
imulq %r13, %rax
xorl %edx, %edx
movq 0x38(%rsp), %rcx
divq %rcx
movq (%rsp), %rdx
imulq %r13, %rdx
leaq (%r15,%rax), %r13
decq %r13
movq %rdx, %rax
xorl %edx, %edx
divq %rcx
addq %rax, %r15
movl $0x80000000, %eax       # imm = 0x80000000
cmpq %rax, %r13
jb 0x2fc3
movq %r15, %rax
shrq $0x1f, %rax
je 0x2f9a
movq $-0x80000000, %rax      # imm = 0x80000000
jmp 0x2fba
movl $0x80000000, %eax       # imm = 0x80000000
addq $0x40000000, %rax       # imm = 0x40000000
cmpq %rax, %r13
jae 0x2ffc
cmpq $0x40000000, %r15       # imm = 0x40000000
jb 0x2ffc
movq $-0x40000000, %rax      # imm = 0xC0000000
addq %rax, %r14
addq %rax, %r15
addq %rax, %r13
cmpq $0x1, %rbx
movzbl (%r12,%rbp), %eax
adcq $0x0, %rbp
movq %rbx, %rcx
subq $0x1, %rcx
movl $0x7, %edx
cmovbq %rdx, %rcx
addq %r15, %r15
leaq 0x1(,%r13,2), %r13
xorl %edx, %edx
btl %ebx, %eax
setb %dl
leaq (%rdx,%r14,2), %r14
movq %rcx, %rbx
jmp 0x2f7e
movq 0x10(%rsp), %rax
decq %rax
cmpq $0x1, %rax
ja 0x2e0b
movq 0x20(%rsp), %r15
subl $0x8, %r15d
movq 0x30(%rsp), %r14
movl 0x1c(%rsp), %ebp
je 0x304c
negl %r15d
xorl %eax, %eax
movb $0x1, %bl
movb $0x7, %cl
subb %al, %cl
movzbl %cl, %eax
xorl %esi, %esi
btl %eax, %ebp
setb %sil
movq %r14, %rdi
callq 0x3cb0
movzbl %bl, %eax
leal 0x1(%rax), %ebx
cmpl %eax, %r15d
ja 0x3029
movq 0x9f75(%rip), %rdi      # 0xcfc8
movq (%rdi), %rax
addq -0x18(%rax), %rdi
movl $0xa, %esi
callq 0x21d0
movsbl %al, %esi
movq 0x9f5a(%rip), %rdi      # 0xcfc8
callq 0x2030
movq %rax, %rdi
callq 0x2140
testq %r12, %r12
je 0x3088
movq %r12, %rdi
callq 0x21c0
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x30a4
jmp 0x30a4
jmp 0x30a4
jmp 0x30a4
jmp 0x30a4
movq %rax, %r14
testq %r12, %r12
je 0x30b4
movq %r12, %rdi
callq 0x21c0
movq %r14, %rdi
callq 0x2320