// File: /workspace/github_c_makefile_star2_O1/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 0x56af7
movl %r9d, %r13d
movq %rcx, %r12
movq %rdx, %r15
movl 0xc0(%rsp), %ebp
leaq 0x468e3(%rip), %rcx     # 0x9d36c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x20000, %ecx          # imm = 0x20000
cmpl $0x5, %r8d
je 0x56aab
movslq %r8d, %rax
leaq 0x46fd9(%rip), %rdx     # 0x9da80
orl -0x44(%rdx,%rax,4), %ecx
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x66fa6
jmp 0x56aee
xorl %eax, %eax
cmpl $0x6, %r8d
je 0x56ad6
movslq %r8d, %rax
leaq 0x46fae(%rip), %rcx     # 0x9da80
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 0x5ab80
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), %r13
movl 0x18(%r13), %eax
movslq %eax, %r12
leaq 0x18(,%r12,8), %rdi
callq 0x4680
testq %rax, %rax
je 0x56d99
movq %rax, %r14
movl %r12d, (%rax)
addq $0x18, %rax
movq %rax, 0x8(%r14)
leaq (%r14,%r12,4), %rcx
addq $0x18, %rcx
movq %rcx, 0x10(%r14)
cmpl $0x0, 0x18(%r13)
jle 0x56baf
movl $0xf8, %ecx
addq 0x30(%rbx), %rcx
leaq (%rax,%r12,4), %rdx
xorl %esi, %esi
movl -0xec(%rcx), %edi
movl %edi, (%rdx,%rsi,4)
leaq 0x1(%rsi), %rdi
movslq 0x18(%r13), %r9
movq %rcx, %r8
cmpq %r9, %rdi
jl 0x56b8e
movq 0x10(%rbx), %r8
movq 0x60(%r8), %r8
addq $0x14, %r8
movl (%r8), %r8d
subl -0x90(%rcx), %r8d
movl %r8d, (%rax,%rsi,4)
movslq 0x18(%r13), %r8
addq $0x90, %rcx
movq %rdi, %rsi
cmpq %r8, %rdi
jl 0x56b69
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 0x5f7b3
addq $0x10, %rsp
movq %rax, %rbx
movq %r14, %rdi
callq 0x45c0
movq %rbx, %rax
jmp 0x56afa
movq %rsi, 0x8(%rsp)
movq %r15, %xmm0
punpckldq 0x41b03(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x41b0b(%rip), %xmm0    # 0x98710
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd 0x46f97(%rip), %xmm1    # 0x9dbb0
addsd 0x40c7f(%rip), %xmm1    # 0x978a0
cvttsd2si %xmm1, %ebx
movslq %ebx, %rdi
callq 0x4680
testq %rax, %rax
je 0x56d99
movq %rax, %r14
movq %r12, 0x10(%rsp)
xorpd %xmm0, %xmm0
leaq 0x18(%rsp), %rdi
movupd %xmm0, 0x40(%rdi)
xorl %r12d, %r12d
movq %r12, 0x50(%rdi)
movq 0x8(%rsp), %rax
movq %rax, (%rdi)
movl %r15d, 0x8(%rdi)
movq %r12, 0x10(%rdi)
movq %r14, 0x18(%rdi)
movl %ebx, 0x20(%rdi)
movq %r12, 0x28(%rdi)
movl $0x0, 0x58(%rdi)
leaq 0x40d04(%rip), %rax     # 0x97980
movl %r13d, %esi
movl $0x8, %edx
movl $0x1f, %ecx
movl $0x9, %r8d
movl %ebp, %r9d
pushq $0x70
pushq %rax
callq 0x4080
addq $0x10, %rsp
testl %eax, %eax
je 0x56def
movq 0x48(%rsp), %rcx
leaq 0x47640(%rip), %rsi     # 0x9e2f2
leaq 0x4764a(%rip), %rdx     # 0x9e303
xorl %r14d, %r14d
jmp 0x56eae
cmpl $0x3, %r13d
movl $0x3, %edx
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 0x7d090
movq %rax, %r14
movslq (%rbx), %rax
jmp 0x56af3
xorl %ecx, %ecx
cmpl $0x4, %r8d
setne %cl
leaq 0x18(%rsp), %rbx
movq %rsi, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x7a444
jmp 0x56aee
movq %rsi, %rbx
movq %r15, %xmm0
punpckldq 0x419d6(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x419de(%rip), %xmm0    # 0x98710
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd 0x46e5a(%rip), %xmm1    # 0x9dba0
addsd 0x46e5a(%rip), %xmm1    # 0x9dba8
cvttsd2si %xmm1, %rax
movl %eax, 0x18(%rsp)
movl %eax, %edi
callq 0x4680
testq %rax, %rax
je 0x56d99
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
addq $0x10, %rsp
testl %eax, %eax
je 0x56ebf
movq %r14, %rdi
callq 0x45c0
xorl %r14d, %r14d
jmp 0x56af7
movq %r15, %rdi
movq %rsi, 0x8(%rsp)
callq 0x48a0
movq %rax, %rbx
xorl %r14d, %r14d
movq %r14, (%r12)
movq %rax, %rdi
callq 0x4680
movq %rax, %rbp
movl %r13d, %edi
movl $0x1, %esi
xorl %edx, %edx
movq 0x8(%rsp), %rcx
movq %r15, %r8
movq %rax, %r9
pushq %rbx
pushq %r12
callq 0x42e0
addq $0x10, %rsp
testl %eax, %eax
cmoveq %rbp, %r14
jmp 0x56af7
leaq 0x18(%rsp), %r15
cmpl $0x0, 0x20(%rsp)
je 0x56e4a
movslq %r12d, %rax
leaq (%r14,%rax), %rcx
movq %rcx, 0x30(%rsp)
movl %ebx, %ecx
subl %eax, %ecx
movl %ecx, 0x38(%rsp)
jle 0x56ec8
movq %r15, %rdi
xorl %esi, %esi
callq 0x41f0
movl %ebx, %r12d
subl 0x38(%rsp), %r12d
testl %eax, %eax
je 0x56df4
movq 0x48(%rsp), %rcx
leaq 0x474bb(%rip), %rsi     # 0x9e2f2
leaq 0x47517(%rip), %rdx     # 0x9e355
movl $0x1, %edi
xorl %eax, %eax
callq 0x14378
leaq 0x18(%rsp), %rdi
movl $0x4, %esi
callq 0x41f0
cmpl $0x1, %eax
je 0x56e7d
movq 0x48(%rsp), %rcx
leaq 0x47488(%rip), %rsi     # 0x9e2f2
leaq 0x474e4(%rip), %rdx     # 0x9e355
movl $0x1, %edi
xorl %eax, %eax
callq 0x14378
leaq 0x18(%rsp), %rdi
movq 0x28(%rdi), %rax
movq 0x10(%rsp), %rcx
movq %rax, (%rcx)
callq 0x42a0
testl %eax, %eax
je 0x56af7
movq 0x48(%rsp), %rcx
leaq 0x4744b(%rip), %rsi     # 0x9e2f2
leaq 0x474a7(%rip), %rdx     # 0x9e355
movl $0x1, %edi
xorl %eax, %eax
callq 0x14378
jmp 0x56af7
movl 0x18(%rsp), %eax
jmp 0x56af3
leaq 0x47423(%rip), %rsi     # 0x9e2f2
leaq 0x47452(%rip), %rdx     # 0x9e328
xorl %r14d, %r14d
movl $0x1, %edi
xorl %eax, %eax
callq 0x14378
jmp 0x56af7