// File: karel-brinda[P]ococo/ext/htslib/cram/rANS_static.c
// Function: rans_uncompress_O0
unsigned char *rans_uncompress_O0(unsigned char *in, unsigned int in_size,
				  unsigned int *out_size) {
    /* Load in the static tables */
    unsigned char *cp = in + 9;
    int i, j, x, out_sz, in_sz, rle;
    char *out_buf;
    ari_decoder D;
    RansDecSymbol syms[256];

    memset(&D, 0, sizeof(D));

    if (*in++ != 0) // Order-0 check
	return NULL;
    
    in_sz  = ((in[0])<<0) | ((in[1])<<8) | ((in[2])<<16) | ((in[3])<<24);
    out_sz = ((in[4])<<0) | ((in[5])<<8) | ((in[6])<<16) | ((in[7])<<24);
    if (in_sz != in_size-9)
	return NULL;

    out_buf = malloc(out_sz);
    if (!out_buf)
	return NULL;

    //fprintf(stderr, "out_sz=%d\n", out_sz);

    // Precompute reverse lookup of frequency.
    rle = x = 0;
    j = *cp++;
    do {
	if ((D.fc[j].F = *cp++) >= 128) {
	    D.fc[j].F &= ~128;
	    D.fc[j].F = ((D.fc[j].F & 127) << 8) | *cp++;
	}
	D.fc[j].C = x;

	RansDecSymbolInit(&syms[j], D.fc[j].C, D.fc[j].F);

	/* Build reverse lookup table */
	if (!D.R) D.R = (unsigned char *)malloc(TOTFREQ);
	memset(&D.R[x], j, D.fc[j].F);

	x += D.fc[j].F;

	if (!rle && j+1 == *cp) {
	    j = *cp++;
	    rle = *cp++;
	} else if (rle) {
	    rle--;
	    j++;
	} else {
	    j = *cp++;
	}
    } while(j);

    assert(x < TOTFREQ);

    RansState rans0, rans1, rans2, rans3;
    uint8_t *ptr = cp;
    RansDecInit(&rans0, &ptr);
    RansDecInit(&rans1, &ptr);
    RansDecInit(&rans2, &ptr);
    RansDecInit(&rans3, &ptr);

    int out_end = (out_sz&~3);

    RansState R[4];
    R[0] = rans0;
    R[1] = rans1;
    R[2] = rans2;
    R[3] = rans3;
    uint32_t mask = (1u << TF_SHIFT)-1;

    for (i=0; i < out_end; i+=4) {
	uint32_t m[4] = {R[0] & mask,
			 R[1] & mask,
			 R[2] & mask,
			 R[3] & mask};
	uint8_t c[4] = {D.R[m[0]],
			D.R[m[1]],
			D.R[m[2]],
			D.R[m[3]]};
	out_buf[i+0] = c[0];
	out_buf[i+1] = c[1];
	out_buf[i+2] = c[2];
	out_buf[i+3] = c[3];

	// RansDecAdvanceSymbolStep(&R[0], &syms[c[0]], TF_SHIFT);
	// RansDecAdvanceSymbolStep(&R[1], &syms[c[1]], TF_SHIFT);
	// RansDecAdvanceSymbolStep(&R[2], &syms[c[2]], TF_SHIFT);
	// RansDecAdvanceSymbolStep(&R[3], &syms[c[3]], TF_SHIFT);
	R[0] = syms[c[0]].freq * (R[0]>>TF_SHIFT);
	R[1] = syms[c[1]].freq * (R[1]>>TF_SHIFT);
	R[2] = syms[c[2]].freq * (R[2]>>TF_SHIFT);
	R[3] = syms[c[3]].freq * (R[3]>>TF_SHIFT);

	R[0] += m[0] - syms[c[0]].start;
	R[1] += m[1] - syms[c[1]].start;
	R[2] += m[2] - syms[c[2]].start;
	R[3] += m[3] - syms[c[3]].start;

	RansDecRenorm(&R[0], &ptr);
	RansDecRenorm(&R[1], &ptr);
	RansDecRenorm(&R[2], &ptr);
	RansDecRenorm(&R[3], &ptr);
    }

    rans0 = R[0];
    rans1 = R[1];
    rans2 = R[2];
    rans3 = R[3];

    switch(out_sz&3) {
	unsigned char c;
    case 0:
	break;
    case 1:
	c = D.R[RansDecGet(&rans0, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end] = c;
	break;

    case 2:
	c = D.R[RansDecGet(&rans0, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end] = c;

	c = D.R[RansDecGet(&rans1, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans1, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end+1] = c;
	break;

    case 3:
	c = D.R[RansDecGet(&rans0, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end] = c;

	c = D.R[RansDecGet(&rans1, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans1, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end+1] = c;

	c = D.R[RansDecGet(&rans2, TF_SHIFT)];
	RansDecAdvanceSymbol(&rans2, &ptr, &syms[c], TF_SHIFT);
	out_buf[out_end+2] = c;
	break;
    }

    *out_size = out_sz;

    if (D.R) free(D.R);

    return (unsigned char *)out_buf;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xce0, %rsp            # imm = 0xCE0
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x9, %rax
movq %rax, -0x28(%rbp)
leaq -0x850(%rbp), %rdi
xorl %esi, %esi
movl $0x808, %edx            # imm = 0x808
callq 0x42d0
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0x58ce9
movq $0x0, -0x8(%rbp)
jmp 0x595a2
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
shll $0x0, %eax
movq -0x10(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
shll $0x8, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
shll $0x18, %ecx
orl %ecx, %eax
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x4(%rax), %eax
shll $0x0, %eax
movq -0x10(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
shll $0x8, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movzbl 0x6(%rcx), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movzbl 0x7(%rcx), %ecx
shll $0x18, %ecx
orl %ecx, %eax
movl %eax, -0x38(%rbp)
movl -0x3c(%rbp), %eax
movl -0x14(%rbp), %ecx
subl $0x9, %ecx
cmpl %ecx, %eax
je 0x58d6c
movq $0x0, -0x8(%rbp)
jmp 0x595a2
movslq -0x38(%rbp), %rdi
callq 0x47a0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x58d8d
movq $0x0, -0x8(%rbp)
jmp 0x595a2
movl $0x0, -0x34(%rbp)
movl $0x0, -0x40(%rbp)
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movzbl (%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movzbl (%rax), %eax
movslq -0x30(%rbp), %rcx
movl %eax, -0x850(%rbp,%rcx,8)
cmpl $0x80, %eax
jl 0x58e1c
movslq -0x30(%rbp), %rax
movl -0x850(%rbp,%rax,8), %ecx
andl $0xffffff7f, %ecx       # imm = 0xFFFFFF7F
movl %ecx, -0x850(%rbp,%rax,8)
movslq -0x30(%rbp), %rax
movl -0x850(%rbp,%rax,8), %ecx
andl $0x7f, %ecx
shll $0x8, %ecx
movq -0x28(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x28(%rbp)
movzbl (%rax), %eax
orl %eax, %ecx
movslq -0x30(%rbp), %rax
movl %ecx, -0x850(%rbp,%rax,8)
movl -0x34(%rbp), %ecx
movslq -0x30(%rbp), %rax
movl %ecx, -0x84c(%rbp,%rax,8)
movslq -0x30(%rbp), %rax
leaq -0xc50(%rbp), %rdi
shlq $0x2, %rax
addq %rax, %rdi
movslq -0x30(%rbp), %rax
movl -0x84c(%rbp,%rax,8), %esi
movslq -0x30(%rbp), %rax
movl -0x850(%rbp,%rax,8), %edx
callq 0x595b0
cmpq $0x0, -0x50(%rbp)
jne 0x58e6c
movl $0x1000, %edi           # imm = 0x1000
callq 0x47a0
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
movslq -0x34(%rbp), %rax
addq %rax, %rdi
movl -0x30(%rbp), %eax
movslq -0x30(%rbp), %rcx
movslq -0x850(%rbp,%rcx,8), %rdx
movzbl %al, %esi
callq 0x42d0
movslq -0x30(%rbp), %rax
movl -0x850(%rbp,%rax,8), %eax
addl -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x40(%rbp)
jne 0x58ee2
movl -0x30(%rbp), %eax
addl $0x1, %eax
movq -0x28(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x58ee2
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movzbl (%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movzbl (%rax), %eax
movl %eax, -0x40(%rbp)
jmp 0x58f13
cmpl $0x0, -0x40(%rbp)
je 0x58efc
movl -0x40(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x40(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x58f11
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movzbl (%rax), %eax
movl %eax, -0x30(%rbp)
jmp 0x58f13
jmp 0x58f15
cmpl $0x0, -0x30(%rbp)
jne 0x58db0
cmpl $0x1000, -0x34(%rbp)    # imm = 0x1000
jge 0x58f2a
jmp 0x58f49
leaq 0x24868(%rip), %rdi     # 0x7d799
leaq 0x247ff(%rip), %rsi     # 0x7d737
movl $0x104, %edx            # imm = 0x104
leaq 0x24861(%rip), %rcx     # 0x7d7a5
callq 0x4360
movq -0x28(%rbp), %rax
movq %rax, -0xc68(%rbp)
leaq -0xc54(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
callq 0x59640
leaq -0xc58(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
callq 0x59640
leaq -0xc5c(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
callq 0x59640
leaq -0xc60(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
callq 0x59640
movl -0x38(%rbp), %eax
andl $-0x4, %eax
movl %eax, -0xc6c(%rbp)
movl -0xc54(%rbp), %eax
movl %eax, -0xc80(%rbp)
movl -0xc58(%rbp), %eax
movl %eax, -0xc7c(%rbp)
movl -0xc5c(%rbp), %eax
movl %eax, -0xc78(%rbp)
movl -0xc60(%rbp), %eax
movl %eax, -0xc74(%rbp)
movl $0xfff, -0xc84(%rbp)    # imm = 0xFFF
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0xc6c(%rbp), %eax
jge 0x5925e
movl -0xc80(%rbp), %eax
andl -0xc84(%rbp), %eax
movl %eax, -0xca0(%rbp)
movl -0xc7c(%rbp), %eax
andl -0xc84(%rbp), %eax
movl %eax, -0xc9c(%rbp)
movl -0xc78(%rbp), %eax
andl -0xc84(%rbp), %eax
movl %eax, -0xc98(%rbp)
movl -0xc74(%rbp), %eax
andl -0xc84(%rbp), %eax
movl %eax, -0xc94(%rbp)
movq -0x50(%rbp), %rax
movl -0xca0(%rbp), %ecx
movb (%rax,%rcx), %al
movb %al, -0xca4(%rbp)
movq -0x50(%rbp), %rax
movl -0xc9c(%rbp), %ecx
movb (%rax,%rcx), %al
movb %al, -0xca3(%rbp)
movq -0x50(%rbp), %rax
movl -0xc98(%rbp), %ecx
movb (%rax,%rcx), %al
movb %al, -0xca2(%rbp)
movq -0x50(%rbp), %rax
movl -0xc94(%rbp), %ecx
movb (%rax,%rcx), %al
movb %al, -0xca1(%rbp)
movb -0xca4(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movb -0xca3(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movb -0xca2(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movb -0xca1(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movzbl -0xca4(%rbp), %eax
movzwl -0xc4e(%rbp,%rax,4), %eax
movl -0xc80(%rbp), %ecx
shrl $0xc, %ecx
imull %ecx, %eax
movl %eax, -0xc80(%rbp)
movzbl -0xca3(%rbp), %eax
movzwl -0xc4e(%rbp,%rax,4), %eax
movl -0xc7c(%rbp), %ecx
shrl $0xc, %ecx
imull %ecx, %eax
movl %eax, -0xc7c(%rbp)
movzbl -0xca2(%rbp), %eax
movzwl -0xc4e(%rbp,%rax,4), %eax
movl -0xc78(%rbp), %ecx
shrl $0xc, %ecx
imull %ecx, %eax
movl %eax, -0xc78(%rbp)
movzbl -0xca1(%rbp), %eax
movzwl -0xc4e(%rbp,%rax,4), %eax
movl -0xc74(%rbp), %ecx
shrl $0xc, %ecx
imull %ecx, %eax
movl %eax, -0xc74(%rbp)
movl -0xca0(%rbp), %eax
movzbl -0xca4(%rbp), %ecx
movzwl -0xc50(%rbp,%rcx,4), %ecx
subl %ecx, %eax
addl -0xc80(%rbp), %eax
movl %eax, -0xc80(%rbp)
movl -0xc9c(%rbp), %eax
movzbl -0xca3(%rbp), %ecx
movzwl -0xc50(%rbp,%rcx,4), %ecx
subl %ecx, %eax
addl -0xc7c(%rbp), %eax
movl %eax, -0xc7c(%rbp)
movl -0xc98(%rbp), %eax
movzbl -0xca2(%rbp), %ecx
movzwl -0xc50(%rbp,%rcx,4), %ecx
subl %ecx, %eax
addl -0xc78(%rbp), %eax
movl %eax, -0xc78(%rbp)
movl -0xc94(%rbp), %eax
movzbl -0xca1(%rbp), %ecx
movzwl -0xc50(%rbp,%rcx,4), %ecx
subl %ecx, %eax
addl -0xc74(%rbp), %eax
movl %eax, -0xc74(%rbp)
leaq -0xc80(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
callq 0x596c0
leaq -0xc80(%rbp), %rdi
addq $0x4, %rdi
leaq -0xc68(%rbp), %rsi
callq 0x596c0
leaq -0xc80(%rbp), %rdi
addq $0x8, %rdi
leaq -0xc68(%rbp), %rsi
callq 0x596c0
leaq -0xc80(%rbp), %rdi
addq $0xc, %rdi
leaq -0xc68(%rbp), %rsi
callq 0x596c0
movl -0x2c(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x2c(%rbp)
jmp 0x58fed
movl -0xc80(%rbp), %eax
movl %eax, -0xc54(%rbp)
movl -0xc7c(%rbp), %eax
movl %eax, -0xc58(%rbp)
movl -0xc78(%rbp), %eax
movl %eax, -0xc5c(%rbp)
movl -0xc74(%rbp), %eax
movl %eax, -0xc60(%rbp)
movl -0x38(%rbp), %eax
andl $0x3, %eax
movl %eax, %ecx
movq %rcx, -0xcb0(%rbp)
subl $0x3, %eax
ja 0x59581
movq -0xcb0(%rbp), %rax
leaq 0x2446c(%rip), %rcx     # 0x7d720
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x59581
movq -0x50(%rbp), %rax
movq %rax, -0xcb8(%rbp)
leaq -0xc54(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xcb8(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc54(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movslq -0xc6c(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x59581
movq -0x50(%rbp), %rax
movq %rax, -0xcc8(%rbp)
leaq -0xc54(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xcc8(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc54(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movslq -0xc6c(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
movq %rax, -0xcc0(%rbp)
leaq -0xc58(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xcc0(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc58(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0xc6c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x59581
movq -0x50(%rbp), %rax
movq %rax, -0xce0(%rbp)
leaq -0xc54(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xce0(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc54(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movslq -0xc6c(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
movq %rax, -0xcd8(%rbp)
leaq -0xc58(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xcd8(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc58(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0xc6c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
movq %rax, -0xcd0(%rbp)
leaq -0xc5c(%rbp), %rdi
movl $0xc, %esi
callq 0x59730
movl %eax, %ecx
movq -0xcd0(%rbp), %rax
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0xca5(%rbp)
movzbl -0xca5(%rbp), %eax
leaq -0xc50(%rbp), %rdx
shlq $0x2, %rax
addq %rax, %rdx
leaq -0xc5c(%rbp), %rdi
leaq -0xc68(%rbp), %rsi
movl $0xc, %ecx
callq 0x59760
movb -0xca5(%rbp), %dl
movq -0x48(%rbp), %rax
movl -0xc6c(%rbp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x38(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
cmpq $0x0, -0x50(%rbp)
je 0x5959a
movq -0x50(%rbp), %rdi
callq 0x46a0
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xce0, %rsp            # imm = 0xCE0
popq %rbp
retq
nop