// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/bgzf.c
// Function: bgzf_compress
int bgzf_compress(void *_dst, size_t *dlen, const void *src, size_t slen, int level)
{
    uint32_t crc;
    z_stream zs;
    uint8_t *dst = (uint8_t*)_dst;

    if (level == 0) {
    uncomp:
        // Uncompressed data
        if (*dlen < slen+5 + BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH) return -1;
        dst[BLOCK_HEADER_LENGTH] = 1; // BFINAL=1, BTYPE=00; see RFC1951
        u16_to_le(slen,  &dst[BLOCK_HEADER_LENGTH+1]); // length
        u16_to_le(~slen, &dst[BLOCK_HEADER_LENGTH+3]); // ones-complement length
        memcpy(dst + BLOCK_HEADER_LENGTH+5, src, slen);
        *dlen = slen+5 + BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH;
    } else {
        // compress the body
        zs.zalloc = NULL; zs.zfree = NULL;
        zs.msg = NULL;
        zs.next_in  = (Bytef*)src;
        zs.avail_in = slen;
        zs.next_out = dst + BLOCK_HEADER_LENGTH;
        zs.avail_out = *dlen - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH;
        int ret = deflateInit2(&zs, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); // -15 to disable zlib header/footer
        if (ret!=Z_OK) {
            hts_log_error("Call to deflateInit2 failed: %s", bgzf_zerr(ret, &zs));
            return -1;
        }
        if ((ret = deflate(&zs, Z_FINISH)) != Z_STREAM_END) {
            if (ret == Z_OK && zs.avail_out == 0) {
                deflateEnd(&zs);
                goto uncomp;
            } else {
                hts_log_error("Deflate operation failed: %s", bgzf_zerr(ret, ret == Z_DATA_ERROR ? &zs : NULL));
            }
            return -1;
        }
        // If we used up the entire output buffer, then we either ran out of
        // room or we *just* fitted, but either way we may as well store
        // uncompressed for faster decode.
        if (zs.avail_out == 0) {
            deflateEnd(&zs);
            goto uncomp;
        }
        if ((ret = deflateEnd(&zs)) != Z_OK) {
            hts_log_error("Call to deflateEnd failed: %s", bgzf_zerr(ret, NULL));
            return -1;
        }
        *dlen = zs.total_out + BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH;
    }

    // write the header
    memcpy(dst, g_magic, BLOCK_HEADER_LENGTH); // the last two bytes are a place holder for the length of the block
    packInt16(&dst[16], *dlen - 1); // write the compressed length; -1 to fit 2 bytes
    // write the footer
    crc = crc32(crc32(0L, NULL, 0L), (Bytef*)src, slen);
    packInt32((uint8_t*)&dst[*dlen - 8], crc);
    packInt32((uint8_t*)&dst[*dlen - 4], slen);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rcx, %rbx
movq %rdx, %r12
movq %rsi, %r15
movq %rdi, %r14
testl %r8d, %r8d
je 0xad08
leaq 0x8(%rsp), %rdi
movq $0x0, 0x30(%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x40(%rdi)
movq %r12, (%rdi)
movl %ebx, 0x8(%rdi)
leaq 0x12(%r14), %rax
movq %rax, 0x18(%rdi)
movl (%r15), %eax
addl $-0x1a, %eax
movl %eax, 0x20(%rdi)
leaq 0x89d71(%rip), %rax     # 0x949c0
movl %r8d, %esi
movl $0x8, %edx
movl $0xfffffff1, %ecx       # imm = 0xFFFFFFF1
movl $0x8, %r8d
xorl %r9d, %r9d
pushq $0x70
pushq %rax
callq 0x4080
addq $0x10, %rsp
testl %eax, %eax
je 0xaca9
leaq 0x8(%rsp), %rsi
movl %eax, %edi
callq 0xadc9
leaq 0x89d3f(%rip), %rsi     # 0x949c7
leaq 0x89d46(%rip), %rdx     # 0x949d5
movl $0x1, %edi
movq %rax, %rcx
xorl %eax, %eax
callq 0x13de5
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
jmp 0xad83
leaq 0x8(%rsp), %r13
movq %r13, %rdi
movl $0x4, %esi
callq 0x41f0
cmpl $0x1, %eax
jne 0xacf2
cmpl $0x0, 0x28(%rsp)
je 0xacfe
leaq 0x8(%rsp), %rdi
callq 0x42a0
testl %eax, %eax
je 0xadbb
movl %eax, %edi
xorl %esi, %esi
callq 0xadc9
leaq 0x89cde(%rip), %rsi     # 0x949c7
leaq 0x89d22(%rip), %rdx     # 0x94a12
jmp 0xac8f
movl 0x28(%rsp), %ecx
orl %eax, %ecx
jne 0xad95
leaq 0x8(%rsp), %rdi
callq 0x42a0
leaq 0x1f(%rbx), %rbp
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
cmpq %rbp, (%r15)
jb 0xad83
movb $0x1, 0x12(%r14)
movw %bx, 0x13(%r14)
movl %ebx, %eax
notl %eax
movw %ax, 0x15(%r14)
leaq 0x17(%r14), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x43c0
movq %rbp, (%r15)
movaps 0x89c2d(%rip), %xmm0    # 0x94970
movups %xmm0, (%r14)
movw $0x0, 0x10(%r14)
movl (%r15), %eax
decl %eax
movw %ax, 0x10(%r14)
xorl %r13d, %r13d
xorl %edi, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4320
movq %rax, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x4320
movq (%r15), %rcx
movl %eax, -0x8(%r14,%rcx)
movq (%r15), %rax
movl %ebx, -0x4(%r14,%rax)
movl %r13d, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ecx, %ecx
cmpl $-0x3, %eax
cmovneq %rcx, %r13
movl %eax, %edi
movq %r13, %rsi
callq 0xadc9
leaq 0x89c18(%rip), %rsi     # 0x949c7
leaq 0x89c3f(%rip), %rdx     # 0x949f5
jmp 0xac8f
movq 0x30(%rsp), %rbp
addq $0x1a, %rbp
jmp 0xad39