// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/cram/cram_io.c
// Function: cram_compress_by_method
static char *cram_compress_by_method(cram_slice *s, char *in, size_t in_size,
                                     int content_id, size_t *out_size,
                                     enum cram_block_method_int method,
                                     int level, int strat) {
    switch (method) {
    case GZIP:
    case GZIP_RLE:
    case GZIP_1:
        // Read names bizarrely benefit from zlib over libdeflate for
        // mid-range compression levels.  Focusing purely of ratio or
        // speed, libdeflate still wins.  It also seems to win for
        // other data series too.
        //
        // Eg RN at level 5;  libdeflate=55.9MB  zlib=51.6MB
#ifdef HAVE_LIBDEFLATE
#  if (LIBDEFLATE_VERSION_MAJOR < 1 || (LIBDEFLATE_VERSION_MAJOR == 1 && LIBDEFLATE_VERSION_MINOR <= 8))
        if (content_id == DS_RN && level >= 4 && level <= 7)
            return zlib_mem_deflate(in, in_size, out_size, level, strat);
        else
#  endif
            return libdeflate_deflate(in, in_size, out_size, level, strat);
#else
        return zlib_mem_deflate(in, in_size, out_size, level, strat);
#endif

    case BZIP2: {
#ifdef HAVE_LIBBZ2
        unsigned int comp_size = in_size*1.01 + 600;
        char *comp = malloc(comp_size);
        if (!comp)
            return NULL;

        if (BZ_OK != BZ2_bzBuffToBuffCompress(comp, &comp_size,
                                              in, in_size,
                                              level, 0, 30)) {
            free(comp);
            return NULL;
        }
        *out_size = comp_size;
        return comp;
#else
        return NULL;
#endif
    }

    case FQZ:
    case FQZ_b:
    case FQZ_c:
    case FQZ_d: {
        // Extract the necessary portion of the slice into an fqz_slice struct.
        // These previously were the same thing, but this permits us to detach
        // the codec from the rest of this CRAM implementation.
        fqz_slice *f = malloc(2*s->hdr->num_records * sizeof(uint32_t) + sizeof(fqz_slice));
        if (!f)
            return NULL;
        f->num_records = s->hdr->num_records;
        f->len = (uint32_t *)(((char *)f) + sizeof(fqz_slice));
        f->flags = f->len + s->hdr->num_records;
        int i;
        for (i = 0; i < s->hdr->num_records; i++) {
            f->flags[i] = s->crecs[i].flags;
            f->len[i] = (i+1 < s->hdr->num_records
                         ? s->crecs[i+1].qual - s->crecs[i].qual
                         : s->block[DS_QS]->uncomp_size - s->crecs[i].qual);
        }
        char *comp = fqz_compress(strat & 0xff /* cram vers */, f,
                                  in, in_size, out_size, strat >> 8, NULL);
        free(f);
        return comp;
    }

    case LZMA:
#ifdef HAVE_LIBLZMA
        return lzma_mem_deflate(in, in_size, out_size, level);
#else
        return NULL;
#endif

    case RANS0:
    case RANS1: {
        unsigned int out_size_i;
        unsigned char *cp;
        cp = rans_compress((unsigned char *)in, in_size, &out_size_i,
                           method == RANS0 ? 0 : 1);
        *out_size = out_size_i;
        return (char *)cp;
    }

    case RANS_PR0:
    case RANS_PR1:
    case RANS_PR64:
    case RANS_PR9:
    case RANS_PR128:
    case RANS_PR129:
    case RANS_PR192:
    case RANS_PR193: {
        unsigned int out_size_i;
        unsigned char *cp;

        // see enum cram_block. We map RANS_* methods to order bit-fields
        static int methmap[] = { 1, 64,9, 128,129, 192,193 };

        int m = method == RANS_PR0 ? 0 : methmap[method - RANS_PR1];
        cp = rans_compress_4x16((unsigned char *)in, in_size, &out_size_i,
                                m | RANS_ORDER_SIMD_AUTO);
        *out_size = out_size_i;
        return (char *)cp;
    }

    case ARITH_PR0:
    case ARITH_PR1:
    case ARITH_PR64:
    case ARITH_PR9:
    case ARITH_PR128:
    case ARITH_PR129:
    case ARITH_PR192:
    case ARITH_PR193: {
        unsigned int out_size_i;
        unsigned char *cp;

        // see enum cram_block. We map ARITH_* methods to order bit-fields
        static int methmap[] = { 1, 64,9, 128,129, 192,193 };

        cp = arith_compress_to((unsigned char *)in, in_size, NULL, &out_size_i,
                               method == ARITH_PR0 ? 0 : methmap[method - ARITH_PR1]);
        *out_size = out_size_i;
        return (char *)cp;
    }

    case TOK3:
    case TOKA: {
        int out_len;
        int lev = level;
        if (method == TOK3 && lev > 3)
            lev = 3;
        uint8_t *cp = tok3_encode_names(in, in_size, lev, strat, &out_len, NULL);
        *out_size = out_len;
        return (char *)cp;
    }

    case RAW:
        break;

    default:
        return NULL;
    }

    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
xorl %r14d, %r14d
leal -0x1(%r8), %eax
cmpl $0x1e, %eax
ja 0x45e6a
movl %r9d, %r13d
movq %rcx, %r12
movq %rdx, %r15
movl 0xc0(%rsp), %ebp
leaq 0x36540(%rip), %rcx     # 0x7c33c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x20000, %ecx          # imm = 0x20000
cmpl $0x5, %r8d
je 0x45e1e
movslq %r8d, %rax
leaq 0x36c36(%rip), %rdx     # 0x7ca50
orl -0x44(%rdx,%rax,4), %ecx
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x50986
jmp 0x45e61
xorl %eax, %eax
cmpl $0x6, %r8d
je 0x45e49
movslq %r8d, %rax
leaq 0x36c0b(%rip), %rcx     # 0x7ca50
movl -0x64(%rcx,%rax,4), %eax
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
xorl %edx, %edx
movq %rbx, %rcx
movl %eax, %r8d
callq 0x4947c
movq %rax, %r14
movl (%rbx), %eax
movq %rax, (%r12)
movq %r14, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rdi, %rbx
movq %rsi, 0x8(%rsp)
movq %r12, 0x10(%rsp)
movq (%rdi), %rax
movl 0x18(%rax), %r13d
movslq %r13d, %r12
leaq 0x18(,%r12,8), %rdi
callq 0x4680
testq %rax, %rax
je 0x460ee
movq %rax, %r14
movl %r12d, (%rax)
addq $0x18, %rax
movq %rax, 0x8(%r14)
leaq (%r14,%r12,4), %rax
addq $0x18, %rax
movq %rax, 0x10(%r14)
movl $0xf8, %ecx
xorl %edx, %edx
cmpq %r12, %rdx
jge 0x45fe0
movq 0x30(%rbx), %rsi
movl -0xec(%rsi,%rcx), %edi
movl %edi, (%rax,%rdx,4)
leal 0x1(%rdx), %edi
cmpl %edi, %r13d
jle 0x45ef2
leaq (%rsi,%rcx), %rdi
jmp 0x45efe
movq 0x10(%rbx), %rdi
movq 0x60(%rdi), %rdi
addq $0x14, %rdi
movl (%rdi), %edi
subl -0x90(%rsi,%rcx), %edi
movl %edi, 0x18(%r14,%rdx,4)
addq $0x90, %rcx
incq %rdx
jmp 0x45ecd
movq %rsi, 0x8(%rsp)
movq %r15, %xmm0
punpckldq 0x31836(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x3183e(%rip), %xmm0    # 0x77770
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd 0x36c62(%rip), %xmm1    # 0x7cba8
addsd 0x30952(%rip), %xmm1    # 0x768a0
cvttsd2si %xmm1, %ebx
movslq %ebx, %rdi
callq 0x4680
testq %rax, %rax
je 0x460ee
movq %rax, %r14
leaq 0x18(%rsp), %rdi
andq $0x0, 0x50(%rdi)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x40(%rdi)
movq 0x8(%rsp), %rax
movq %rax, (%rdi)
movl %r15d, 0x8(%rdi)
andq $0x0, 0x10(%rdi)
movq %r14, 0x18(%rdi)
movl %ebx, 0x20(%rdi)
andq $0x0, 0x28(%rdi)
andl $0x0, 0x58(%rdi)
leaq 0x309cf(%rip), %rax     # 0x76970
pushq $0x8
popq %rdx
pushq $0x1f
popq %rcx
pushq $0x9
popq %r8
movl %r13d, %esi
movl %ebp, %r9d
pushq $0x70
pushq %rax
callq 0x4080
addq $0x10, %rsp
testl %eax, %eax
je 0x46141
movq 0x48(%rsp), %rcx
leaq 0x37314(%rip), %rsi     # 0x7d2e5
leaq 0x3731e(%rip), %rdx     # 0x7d2f6
xorl %r14d, %r14d
jmp 0x461f6
movzbl %bpl, %edi
sarl $0x8, %ebp
subq $0x8, %rsp
movq %r14, %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rcx
movq 0x18(%rsp), %r8
movl %ebp, %r9d
pushq $0x0
callq 0x4c209
popq %rcx
popq %rdx
movq %rax, %rbx
movq %r14, %rdi
callq 0x45c0
movq %rbx, %rax
jmp 0x45e6d
cmpl $0x3, %r13d
pushq $0x3
popq %rdx
cmovll %r13d, %edx
cmpl $0x8, %r8d
cmovnel %r13d, %edx
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
movl %ebp, %ecx
movq %rbx, %r8
xorl %r9d, %r9d
callq 0x61598
movq %rax, %r14
movslq (%rbx), %rax
jmp 0x45e66
xorl %ecx, %ecx
cmpl $0x4, %r8d
setne %cl
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x5f048
jmp 0x45e61
movq %rsi, %rbx
movq %r15, %xmm0
punpckldq 0x316df(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x316e7(%rip), %xmm0    # 0x77770
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd 0x36afb(%rip), %xmm1    # 0x7cb98
addsd 0x36afb(%rip), %xmm1    # 0x7cba0
cvttsd2si %xmm1, %rax
movl %eax, 0x18(%rsp)
movl %eax, %edi
callq 0x4680
testq %rax, %rax
je 0x460ee
movq %rax, %r14
subq $0x8, %rsp
leaq 0x20(%rsp), %rsi
movq %rax, %rdi
movq %rbx, %rdx
movl %r15d, %ecx
movl %r13d, %r8d
xorl %r9d, %r9d
pushq $0x1e
callq 0x4280
popq %rcx
popq %rdx
testl %eax, %eax
je 0x46205
movq %r14, %rdi
callq 0x45c0
xorl %r14d, %r14d
jmp 0x45e6a
movq %r15, %rdi
movq %rsi, 0x8(%rsp)
callq 0x48a0
movq %rax, %rbx
andq $0x0, (%r12)
movq %rax, %rdi
callq 0x4680
movq %rax, %rbp
xorl %r14d, %r14d
pushq $0x1
popq %rsi
movl %r13d, %edi
xorl %edx, %edx
movq 0x8(%rsp), %rcx
movq %r15, %r8
movq %rax, %r9
pushq %rbx
pushq %r12
callq 0x42e0
popq %rcx
popq %rdx
testl %eax, %eax
cmoveq %rbp, %r14
jmp 0x45e6a
xorl %ecx, %ecx
leaq 0x18(%rsp), %r15
cmpl $0x0, 0x20(%rsp)
je 0x4619a
movslq %ecx, %rax
leaq (%r14,%rax), %rcx
movq %rcx, 0x30(%rsp)
movl %ebx, %ecx
subl %eax, %ecx
movl %ecx, 0x38(%rsp)
jle 0x4620e
movq %r15, %rdi
xorl %esi, %esi
callq 0x41f0
movl %ebx, %ecx
subl 0x38(%rsp), %ecx
testl %eax, %eax
je 0x46148
movq 0x48(%rsp), %rcx
leaq 0x3715c(%rip), %rsi     # 0x7d2e5
leaq 0x371b8(%rip), %rdx     # 0x7d348
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x110c6
leaq 0x18(%rsp), %rdi
pushq $0x4
popq %rsi
callq 0x41f0
cmpl $0x1, %eax
je 0x461c9
movq 0x48(%rsp), %rcx
leaq 0x3712d(%rip), %rsi     # 0x7d2e5
leaq 0x37189(%rip), %rdx     # 0x7d348
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x110c6
leaq 0x18(%rsp), %rdi
movq 0x28(%rdi), %rax
movq %rax, (%r12)
callq 0x42a0
testl %eax, %eax
je 0x45e6a
movq 0x48(%rsp), %rcx
leaq 0x370f6(%rip), %rsi     # 0x7d2e5
leaq 0x37152(%rip), %rdx     # 0x7d348
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x110c6
jmp 0x45e6a
movl 0x18(%rsp), %eax
jmp 0x45e66
leaq 0x370d0(%rip), %rsi     # 0x7d2e5
leaq 0x370ff(%rip), %rdx     # 0x7d31b
xorl %r14d, %r14d
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x110c6
jmp 0x45e6a