// File: /workspace/github_cpp_makefile_star2_O2/karel-brinda[P]ococo/ext/htslib/cram/rANS_static.c
// Function: rans_compress_O1
unsigned char *rans_compress_O1(unsigned char *in, unsigned int in_size,
				unsigned int *out_size) {
    unsigned char *out_buf = NULL, *out_end, *cp;
    unsigned int last_i, tab_size, rle_i, rle_j;
    RansEncSymbol (*syms)[256] = NULL;  /* syms[256][256] */
    int (*F)[256] = NULL;               /* F[256][256]    */
    int *T = NULL;                      /* T[256]         */
    int i, j;
    unsigned char c;

    if (in_size < 4)
	return rans_compress_O0(in, in_size, out_size);

    syms = malloc(256 * sizeof(*syms));
    if (!syms) goto cleanup;
    F = calloc(256, sizeof(*F));
    if (!F) goto cleanup;
    T = calloc(256, sizeof(*T));
    if (!T) goto cleanup;
    out_buf = malloc(1.05*in_size + 257*257*3 + 9);
    if (!out_buf) goto cleanup;

    out_end = out_buf + (int)(1.05*in_size) + 257*257*3 + 9;
    cp = out_buf+9;

    //for (last = 0, i=in_size-1; i>=0; i--) {
    //	F[last][c = in[i]]++;
    //	T[last]++;
    //	last = c;
    //}

    for (last_i=i=0; i<in_size; i++) {
	F[last_i][c = in[i]]++;
	T[last_i]++;
	last_i = c;
    }
    F[0][in[1*(in_size>>2)]]++;
    F[0][in[2*(in_size>>2)]]++;
    F[0][in[3*(in_size>>2)]]++;
    T[0]+=3;

    // Normalise so T[i] == TOTFREQ
    for (rle_i = i = 0; i < 256; i++) {
	int t2, m, M;
	unsigned int x;

	if (T[i] == 0)
	    continue;

	//uint64_t p = (TOTFREQ * TOTFREQ) / t;
	double p = ((double)TOTFREQ)/T[i];
	for (t2 = m = M = j = 0; j < 256; j++) {
	    if (!F[i][j])
		continue;

	    if (m < F[i][j])
		m = F[i][j], M = j;

	    //if ((F[i][j] = (F[i][j] * p) / TOTFREQ) == 0)
	    if ((F[i][j] *= p) == 0)
		F[i][j] = 1;
	    t2 += F[i][j];
	}

	t2++;
	if (t2 < TOTFREQ)
	    F[i][M] += TOTFREQ-t2;
	else
	    F[i][M] -= t2-TOTFREQ;

	// Store frequency table
	// i
	if (rle_i) {
	    rle_i--;
	} else {
	    *cp++ = i;
	    // FIXME: could use order-0 statistics to observe which alphabet
	    // symbols are present and base RLE on that ordering instead.
	    if (i && T[i-1]) {
		for(rle_i=i+1; rle_i<256 && T[rle_i]; rle_i++)
		    ;
		rle_i -= i+1;
		*cp++ = rle_i;
	    }
	}

	int *F_i_ = F[i];
	x = 0;
	rle_j = 0;
	for (j = 0; j < 256; j++) {
	    if (F_i_[j]) {
		//fprintf(stderr, "F[%d][%d]=%d, x=%d\n", i, j, F_i_[j], x);

		// j
		if (rle_j) {
		    rle_j--;
		} else {
		    *cp++ = j;
		    if (!rle_j && j && F_i_[j-1]) {
			for(rle_j=j+1; rle_j<256 && F_i_[rle_j]; rle_j++)
			    ;
			rle_j -= j+1;
			*cp++ = rle_j;
		    }
		}

		// F_i_[j]
		if (F_i_[j]<128) {
		    *cp++ = F_i_[j];
		} else {
		    *cp++ = 128 | (F_i_[j]>>8);
		    *cp++ = F_i_[j]&0xff;
		}

		RansEncSymbolInit(&syms[i][j], x, F_i_[j], TF_SHIFT);
		x += F_i_[j];
	    }
	}
	*cp++ = 0;
    }
    *cp++ = 0;

    //write(1, out_buf+4, cp-(out_buf+4));
    tab_size = cp - out_buf;
    assert(tab_size < 257*257*3);

    RansState rans0, rans1, rans2, rans3;
    RansEncInit(&rans0);
    RansEncInit(&rans1);
    RansEncInit(&rans2);
    RansEncInit(&rans3);

    uint8_t* ptr = out_end;

    int isz4 = in_size>>2;
    int i0 = 1*isz4-2;
    int i1 = 2*isz4-2;
    int i2 = 3*isz4-2;
    int i3 = 4*isz4-2;

    unsigned char l0 = in[i0+1];
    unsigned char l1 = in[i1+1];
    unsigned char l2 = in[i2+1];
    unsigned char l3 = in[i3+1];

    // Deal with the remainder
    l3 = in[in_size-1];
    for (i3 = in_size-2; i3 > 4*isz4-2; i3--) {
	unsigned char c3 = in[i3];
	RansEncPutSymbol(&rans3, &ptr, &syms[c3][l3]);
	l3 = c3;
    }

    for (; i0 >= 0; i0--, i1--, i2--, i3--) {
	unsigned char c0, c1, c2, c3;
	RansEncSymbol *s3 = &syms[c3 = in[i3]][l3];
	RansEncSymbol *s2 = &syms[c2 = in[i2]][l2];
	RansEncSymbol *s1 = &syms[c1 = in[i1]][l1];
	RansEncSymbol *s0 = &syms[c0 = in[i0]][l0];

	RansEncPutSymbol(&rans3, &ptr, s3);
	RansEncPutSymbol(&rans2, &ptr, s2);
	RansEncPutSymbol(&rans1, &ptr, s1);
	RansEncPutSymbol(&rans0, &ptr, s0);

	l0 = c0;
	l1 = c1;
	l2 = c2;
	l3 = c3;
    }

    RansEncPutSymbol(&rans3, &ptr, &syms[0][l3]);
    RansEncPutSymbol(&rans2, &ptr, &syms[0][l2]);
    RansEncPutSymbol(&rans1, &ptr, &syms[0][l1]);
    RansEncPutSymbol(&rans0, &ptr, &syms[0][l0]);

    RansEncFlush(&rans3, &ptr);
    RansEncFlush(&rans2, &ptr);
    RansEncFlush(&rans1, &ptr);
    RansEncFlush(&rans0, &ptr);

    *out_size = (out_end - ptr) + tab_size;

    cp = out_buf;
    *cp++ = 1; // order

    *cp++ = ((*out_size-9)>> 0) & 0xff;
    *cp++ = ((*out_size-9)>> 8) & 0xff;
    *cp++ = ((*out_size-9)>>16) & 0xff;
    *cp++ = ((*out_size-9)>>24) & 0xff;

    *cp++ = (in_size>> 0) & 0xff;
    *cp++ = (in_size>> 8) & 0xff;
    *cp++ = (in_size>>16) & 0xff;
    *cp++ = (in_size>>24) & 0xff;

    memmove(out_buf + tab_size, ptr, out_end-ptr);

 cleanup:
    free(syms);
    free(F);
    free(T);

    return out_buf;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdx, %r14
movl %esi, %ebx
movq %rdi, %r13
cmpl $0x3, %esi
ja 0x311fe
movq %r13, %rdi
movl %ebx, %esi
movq %r14, %rdx
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x30754
movl $0x100000, %edi         # imm = 0x100000
callq 0x46f0
movq %rax, 0x18(%rsp)
testq %rax, %rax
je 0x312f8
movq %rbx, 0x30(%rsp)
movl $0x100, %edi            # imm = 0x100
movl $0x400, %esi            # imm = 0x400
callq 0x4370
testq %rax, %rax
je 0x312f8
movq %rax, %rbx
movq %r14, 0xa8(%rsp)
pushq $0x4
popq %rsi
movl $0x100, %edi            # imm = 0x100
callq 0x4370
testq %rax, %rax
je 0x3190a
movq %rax, %r14
movl 0x30(%rsp), %eax
movq %rax, 0x40(%rsp)
cvtsi2sd %rax, %xmm1
mulsd 0x1468b(%rip), %xmm1    # 0x458f8
movsd 0x150b3(%rip), %xmm0    # 0x46328
movsd %xmm1, 0x8(%rsp)
addsd %xmm1, %xmm0
addsd 0x150a9(%rip), %xmm0    # 0x46330
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1267d(%rip), %xmm0    # 0x43918
cvttsd2si %xmm0, %rdi
andq %rcx, %rdi
orq %rax, %rdi
callq 0x46f0
testq %rax, %rax
je 0x312fd
movq %rax, %rcx
cvttsd2si 0x8(%rsp), %eax
cltq
movq %rcx, 0x58(%rsp)
addq %rcx, %rax
addq $0x3060c, %rax          # imm = 0x3060C
movq %rax, 0x90(%rsp)
xorl %eax, %eax
xorl %ecx, %ecx
cmpq %rax, 0x40(%rsp)
je 0x3132e
movzbl (%r13,%rax), %edx
incl (%r14,%rcx,4)
shlq $0xa, %rcx
addq %rbx, %rcx
incl (%rcx,%rdx,4)
incq %rax
movq %rdx, %rcx
jmp 0x312d5
xorl %r14d, %r14d
xorl %ebx, %ebx
xorl %ebp, %ebp
movq 0x18(%rsp), %rdi
callq 0x4600
movq %rbx, %rdi
callq 0x4600
movq %r14, %rdi
callq 0x4600
movq %rbp, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x30(%rsp), %rax
movl %eax, %ecx
shrl $0x2, %ecx
movzbl (%r13,%rcx), %eax
incl (%rbx,%rax,4)
movzbl (%r13,%rcx,2), %eax
incl (%rbx,%rax,4)
movq %rcx, 0x88(%rsp)
leaq (%rcx,%rcx,2), %rax
movq %rax, 0x80(%rsp)
movzbl (%r13,%rax), %eax
incl (%rbx,%rax,4)
addl $0x3, (%r14)
movq 0x58(%rsp), %rax
leaq 0x9(%rax), %r8
movq %r14, %r9
addq $0x4, %r9
leaq 0x4(%rbx), %r15
xorl %r10d, %r10d
pushq $0x1
popq %rbp
movq %rbx, %r11
movq $0x0, 0x38(%rsp)
movq %rbx, 0xa0(%rsp)
movq %r14, 0x98(%rsp)
movq %r13, 0x48(%rsp)
cmpq $0x100, %r10            # imm = 0x100
je 0x315fc
movl (%r14,%r10,4), %eax
testl %eax, %eax
je 0x31598
cvtsi2sd %eax, %xmm1
movsd 0x14f6d(%rip), %xmm0    # 0x46338
divsd %xmm1, %xmm0
xorl %ecx, %ecx
xorl %eax, %eax
xorl %esi, %esi
xorl %edx, %edx
cmpq $0x100, %rcx            # imm = 0x100
je 0x3140d
movl (%r11,%rcx,4), %edi
testl %edi, %edi
je 0x31408
cmpl %edi, %esi
cmovlel %edi, %esi
cmovll %ecx, %edx
cvtsi2sd %edi, %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %edi
cmpl $0x1, %edi
adcl $0x0, %edi
movl %edi, (%r11,%rcx,4)
addl %edi, %eax
incq %rcx
jmp 0x313d7
movslq %edx, %rcx
movq %r10, %r12
shlq $0xa, %r12
addq %rbx, %r12
movl (%r12,%rcx,4), %edx
subl %eax, %edx
addl $0xfff, %edx            # imm = 0xFFF
movl %edx, (%r12,%rcx,4)
movq 0x38(%rsp), %rcx
testl %ecx, %ecx
je 0x315b7
decl %ecx
movq %r8, %rax
movq %rcx, 0x38(%rsp)
movq %rbp, 0xb0(%rsp)
movq %r11, 0x60(%rsp)
movq %r9, 0x70(%rsp)
xorl %ebx, %ebx
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
movq %r15, 0x68(%rsp)
xorl %esi, %esi
xorl %edx, %edx
cmpq $0x100, %rbx            # imm = 0x100
je 0x31563
cmpl $0x0, (%r12,%rbx,4)
je 0x31501
testl %edx, %edx
je 0x31510
decl %edx
movq %rax, %r14
movl (%r12,%rbx,4), %eax
cmpl $0x80, %eax
movq %rdi, 0x8(%rsp)
movq %r15, 0x50(%rsp)
movl %edx, 0x14(%rsp)
jge 0x314a9
pushq $0x1
popq %rdx
movq %r14, %rcx
jmp 0x314bc
shrl $0x8, %eax
orb $-0x80, %al
leaq 0x1(%r14), %rcx
movb %al, (%r14)
movl (%r12,%rbx,4), %eax
pushq $0x2
popq %rdx
addq %rdx, %r14
movb %al, (%rcx)
movq %r10, %rax
shlq $0xc, %rax
addq 0x18(%rsp), %rax
movq %rbx, %rdi
shlq $0x4, %rdi
addq %rax, %rdi
movl (%r12,%rbx,4), %ebp
movl %ebp, %edx
movq %r10, %r13
movl %esi, %r15d
callq 0x30bac
movl %r15d, %esi
movq %r13, %r10
addl %ebp, %esi
movq %r14, %rax
movq 0x8(%rsp), %rdi
movq 0x50(%rsp), %r15
movl 0x14(%rsp), %edx
incq %rbx
decq %rdi
addq $0x4, %r15
jmp 0x31463
leaq 0x1(%rax), %r14
movb %bl, (%rax)
xorl %edx, %edx
testq %rbx, %rbx
je 0x31488
cmpl $0x0, -0x4(%r12,%rbx,4)
je 0x31488
xorl %ecx, %ecx
leaq (%rbx,%rcx), %rdx
cmpq $0xff, %rdx
je 0x31548
cmpl $0x0, (%r15,%rcx,4)
je 0x3154f
incq %rcx
jmp 0x3152f
movl $0x100, %ecx            # imm = 0x100
jmp 0x31551
subl %edi, %ecx
movl %ebx, %edx
notl %edx
addl %ecx, %edx
movb %dl, 0x1(%rax)
addq $0x2, %rax
jmp 0x31485
movb $0x0, (%rax)
incq %rax
movq %rax, %r8
movq 0xa0(%rsp), %rbx
movq 0x98(%rsp), %r14
movq 0x48(%rsp), %r13
movq 0x70(%rsp), %r9
movq 0x68(%rsp), %r15
movq 0x60(%rsp), %r11
movq 0xb0(%rsp), %rbp
incq %r10
incq %rbp
movl $0x400, %eax            # imm = 0x400
addq %rax, %r11
addq $0x4, %r9
addq %rax, %r15
movq 0x58(%rsp), %rax
jmp 0x313a6
leaq 0x1(%r8), %rax
movb %r10b, (%r8)
xorl %ecx, %ecx
testq %r10, %r10
je 0x3143c
cmpl $0x0, -0x4(%r14,%r10,4)
je 0x3143c
xorl %ecx, %ecx
leaq (%rcx,%rbp), %rax
cmpq $0xff, %rax
ja 0x315ef
cmpl $0x0, (%r9,%rcx,4)
je 0x315ef
incq %rcx
jmp 0x315d7
movb %cl, 0x1(%r8)
addq $0x2, %r8
jmp 0x31439
movb $0x0, (%r8)
subq %rax, %r8
incq %r8
movq %r8, 0x60(%rsp)
cmpl $0x30603, %r8d          # imm = 0x30603
jae 0x31912
movl $0x800000, %eax         # imm = 0x800000
movl %eax, 0x2c(%rsp)
movl %eax, 0x28(%rsp)
movl %eax, 0x24(%rsp)
leaq 0x4(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x78(%rsp), %rcx
movq 0x90(%rsp), %rax
movq %rax, (%rcx)
movq 0x30(%rsp), %rcx
movl %ecx, %ebx
andl $-0x4, %ebx
addl $-0x2, %ebx
movq 0x88(%rsp), %rax
movb -0x1(%r13,%rax), %r8b
movb -0x1(%r13,%rax,2), %r12b
movslq 0x80(%rsp), %rax
movb -0x1(%r13,%rax), %sil
leal -0x1(%rcx), %eax
movb (%r13,%rax), %dl
leal -0x2(%rcx), %ebp
movslq %ebp, %rax
movq %rax, 0x50(%rsp)
cmpl %ebx, %ebp
jle 0x316ca
movl %ebp, %eax
movq 0x48(%rsp), %rcx
movzbl (%rcx,%rax), %r14d
movl %r14d, %eax
shll $0xc, %eax
movzbl %dl, %edx
shll $0x4, %edx
addq 0x18(%rsp), %rdx
addq %rax, %rdx
leaq 0x4(%rsp), %rdi
movl %esi, %r13d
leaq 0x78(%rsp), %rsi
movl %r8d, %r15d
callq 0x30c69
movl %r15d, %r8d
movl %r13d, %esi
decl %ebp
decq 0x50(%rsp)
movl %r14d, %edx
jmp 0x3167f
movq 0x88(%rsp), %rax
leal -0x2(%rax), %ebx
movq 0x80(%rsp), %rax
addl $-0x2, %eax
movq 0x40(%rsp), %rcx
shrl %ecx
andl $-0x2, %ecx
movq %rcx, 0x40(%rsp)
cltq
movq %rax, 0x68(%rsp)
movq 0x48(%rsp), %rcx
movzbl %dl, %edx
movzbl %sil, %r15d
movzbl %r12b, %ebp
movzbl %r8b, %r12d
testl %ebx, %ebx
js 0x317f0
movq 0x50(%rsp), %rax
movzbl (%rcx,%rax), %eax
movl %eax, 0x14(%rsp)
shll $0xc, %eax
shll $0x4, %edx
movq %rcx, 0x8(%rsp)
movq 0x18(%rsp), %rcx
addq %rcx, %rdx
addq %rax, %rdx
movq 0x68(%rsp), %rax
movq 0x8(%rsp), %rsi
movzbl (%rsi,%rax), %eax
movl %eax, 0x38(%rsp)
shll $0xc, %eax
shll $0x4, %r15d
addq %rcx, %r15
addq %rax, %r15
movq 0x40(%rsp), %rax
movq 0x8(%rsp), %rsi
movzbl -0x2(%rsi,%rax), %eax
movl %eax, 0x70(%rsp)
shll $0xc, %eax
shll $0x4, %ebp
addq %rcx, %rbp
addq %rax, %rbp
movl %ebx, %eax
movq 0x48(%rsp), %rsi
movzbl (%rsi,%rax), %r14d
movl %r14d, %eax
shll $0xc, %eax
shll $0x4, %r12d
addq %rcx, %r12
addq %rax, %r12
leaq 0x4(%rsp), %rdi
leaq 0x78(%rsp), %r13
movq %r13, %rsi
callq 0x30c69
leaq 0x24(%rsp), %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x30c69
leaq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x30c69
leaq 0x2c(%rsp), %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x30c69
movq 0x8(%rsp), %rcx
movl %r14d, %r8d
movl 0x14(%rsp), %edx
movl 0x70(%rsp), %r12d
movl 0x38(%rsp), %esi
decl %ebx
decq %rcx
jmp 0x316fb
shll $0x4, %edx
movq 0x18(%rsp), %rbx
addq %rbx, %rdx
leaq 0x4(%rsp), %rdi
leaq 0x78(%rsp), %r13
movq %r13, %rsi
callq 0x30c69
shll $0x4, %r15d
addq %rbx, %r15
leaq 0x24(%rsp), %r14
movq %r14, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x30c69
shll $0x4, %ebp
addq %rbx, %rbp
leaq 0x28(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x30c69
shll $0x4, %r12d
addq %rbx, %r12
leaq 0x2c(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x30c69
leaq 0x4(%rsp), %rax
movl (%rax), %eax
movq (%r13), %rsi
movl %eax, -0x4(%rsi)
movl (%r14), %eax
movl %eax, -0x8(%rsi)
movl (%r15), %eax
movl %eax, -0xc(%rsi)
movl (%rbp), %eax
movl %eax, -0x10(%rsi)
addq $-0x10, %rsi
movq 0x90(%rsp), %rdx
subq %rsi, %rdx
movq 0x60(%rsp), %rdi
movl %edi, %eax
andl $0x3ffff, %eax          # imm = 0x3FFFF
addq %rdx, %rdi
movq 0xa8(%rsp), %rcx
movl %edi, (%rcx)
movq 0x58(%rsp), %rbp
movb $0x1, (%rbp)
movl %edi, %ecx
addb $-0x9, %cl
movb %cl, 0x1(%rbp)
leal 0xfff7(%rdi), %ecx
movb %ch, 0x2(%rbp)
leal 0xfffff7(%rdi), %ecx
shrl $0x10, %ecx
movb %cl, 0x3(%rbp)
leal -0x9(%rdi), %ecx
shrl $0x18, %ecx
movb %cl, 0x4(%rbp)
movq 0x30(%rsp), %rbx
movb %bl, 0x5(%rbp)
movb %bh, 0x6(%rbp)
movl %ebx, %ecx
shrl $0x10, %ecx
movb %cl, 0x7(%rbp)
shrl $0x18, %ebx
movb %bl, 0x8(%rbp)
movq %rbp, %rdi
addq %rax, %rdi
callq 0x48b0
movq 0xa0(%rsp), %rbx
movq 0x98(%rsp), %r14
jmp 0x312ff
xorl %r14d, %r14d
jmp 0x312fd
leaq 0x14b0d(%rip), %rdi     # 0x46426
leaq 0x14a47(%rip), %rsi     # 0x46367
leaq 0x14b14(%rip), %rcx     # 0x4643b
movl $0x1e3, %edx            # imm = 0x1E3
callq 0x4360