// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/samtools-0.1.18/bgzf.c
// Function: deflate_block
static
int
deflate_block(BGZF* fp, int block_length)
{
    // Deflate the block in fp->uncompressed_block into fp->compressed_block.
    // Also adds an extra field that stores the compressed block length.

    bgzf_byte_t* buffer = fp->compressed_block;
    int buffer_size = fp->compressed_block_size;

    // Init gzip header
    buffer[0] = GZIP_ID1;
    buffer[1] = GZIP_ID2;
    buffer[2] = CM_DEFLATE;
    buffer[3] = FLG_FEXTRA;
    buffer[4] = 0; // mtime
    buffer[5] = 0;
    buffer[6] = 0;
    buffer[7] = 0;
    buffer[8] = 0;
    buffer[9] = OS_UNKNOWN;
    buffer[10] = BGZF_XLEN;
    buffer[11] = 0;
    buffer[12] = BGZF_ID1;
    buffer[13] = BGZF_ID2;
    buffer[14] = BGZF_LEN;
    buffer[15] = 0;
    buffer[16] = 0; // placeholder for block length
    buffer[17] = 0;

    // loop to retry for blocks that do not compress enough
    int input_length = block_length;
    int compressed_length = 0;
    while (1) {
        z_stream zs;
        zs.zalloc = NULL;
        zs.zfree = NULL;
        zs.next_in = fp->uncompressed_block;
        zs.avail_in = input_length;
        zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH];
        zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH;

        int status = deflateInit2(&zs, fp->compress_level, Z_DEFLATED,
                                  GZIP_WINDOW_BITS, Z_DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY);
        if (status != Z_OK) {
            report_error(fp, "deflate init failed");
            return -1;
        }
        status = deflate(&zs, Z_FINISH);
        if (status != Z_STREAM_END) {
            deflateEnd(&zs);
            if (status == Z_OK) {
                // Not enough space in buffer.
                // Can happen in the rare case the input doesn't compress enough.
                // Reduce the amount of input until it fits.
                input_length -= 1024;
                if (input_length <= 0) {
                    // should never happen
                    report_error(fp, "input reduction failed");
                    return -1;
                }
                continue;
            }
            report_error(fp, "deflate failed");
            return -1;
        }
        status = deflateEnd(&zs);
        if (status != Z_OK) {
            report_error(fp, "deflate end failed");
            return -1;
        }
        compressed_length = zs.total_out;
        compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH;
        if (compressed_length > MAX_BLOCK_SIZE) {
            // should never happen
            report_error(fp, "deflate overflow");
            return -1;
        }
        break;
    }

    packInt16((uint8_t*)&buffer[16], compressed_length-1);
    uint32_t crc = crc32(0L, NULL, 0L);
    crc = crc32(crc, fp->uncompressed_block, input_length);
    packInt32((uint8_t*)&buffer[compressed_length-8], crc);
    packInt32((uint8_t*)&buffer[compressed_length-4], input_length);

    int remaining = block_length - input_length;
    if (remaining > 0) {
        if (remaining > input_length) {
            // should never happen (check so we can use memcpy)
            report_error(fp, "remainder too large");
            return -1;
        }
        memcpy(fp->uncompressed_block,
               fp->uncompressed_block + input_length,
               remaining);
    }
    fp->block_offset = remaining;
    return compressed_length;
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0xb8(%rsp)
movl %esi, 0xb4(%rsp)
movq 0xb8(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0xa8(%rsp)
movq 0xb8(%rsp), %rax
movl 0x1c(%rax), %eax
movl %eax, 0xa4(%rsp)
movq 0xa8(%rsp), %rax
movb $0x1f, (%rax)
movq 0xa8(%rsp), %rax
movb $-0x75, 0x1(%rax)
movq 0xa8(%rsp), %rax
movb $0x8, 0x2(%rax)
movq 0xa8(%rsp), %rax
movb $0x4, 0x3(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x4(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x5(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x6(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x7(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x8(%rax)
movq 0xa8(%rsp), %rax
movb $-0x1, 0x9(%rax)
movq 0xa8(%rsp), %rax
movb $0x6, 0xa(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0xb(%rax)
movq 0xa8(%rsp), %rax
movb $0x42, 0xc(%rax)
movq 0xa8(%rsp), %rax
movb $0x43, 0xd(%rax)
movq 0xa8(%rsp), %rax
movb $0x2, 0xe(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0xf(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x10(%rax)
movq 0xa8(%rsp), %rax
movb $0x0, 0x11(%rax)
movl 0xb4(%rsp), %eax
movl %eax, 0xa0(%rsp)
movl $0x0, 0x9c(%rsp)
movq $0x0, 0x68(%rsp)
movq $0x0, 0x70(%rsp)
movq 0xb8(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x28(%rsp)
movl 0xa0(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0xa8(%rsp), %rax
addq $0x12, %rax
movq %rax, 0x40(%rsp)
movl 0xa4(%rsp), %eax
subl $0x12, %eax
subl $0x8, %eax
movl %eax, 0x48(%rsp)
movq 0xb8(%rsp), %rax
movswl 0x8(%rax), %esi
leaq 0x28(%rsp), %rdi
movl $0x8, %r8d
movl $0xfffffff1, %ecx       # imm = 0xFFFFFFF1
xorl %r9d, %r9d
leaq 0xab32a(%rip), %rax     # 0x5a2e0c
movl %r8d, %edx
movq %rax, (%rsp)
movl $0x70, 0x8(%rsp)
callq 0x3afc70
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
je 0x4f7b25
movq 0xb8(%rsp), %rdi
leaq 0xc527e(%rip), %rsi     # 0x5bcd8e
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
leaq 0x28(%rsp), %rdi
movl $0x4, %esi
callq 0x3b13f0
movl %eax, 0x24(%rsp)
cmpl $0x1, 0x24(%rsp)
je 0x4f7bba
leaq 0x28(%rsp), %rdi
callq 0x3b0110
cmpl $0x0, 0x24(%rsp)
jne 0x4f7b96
movl 0xa0(%rsp), %eax
subl $0x400, %eax            # imm = 0x400
movl %eax, 0xa0(%rsp)
cmpl $0x0, 0xa0(%rsp)
jg 0x4f7b91
movq 0xb8(%rsp), %rdi
leaq 0xc5226(%rip), %rsi     # 0x5bcda2
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
jmp 0x4f7a6c
movq 0xb8(%rsp), %rdi
leaq 0xc5214(%rip), %rsi     # 0x5bcdb9
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
leaq 0x28(%rsp), %rdi
callq 0x3b0110
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
je 0x4f7bf3
movq 0xb8(%rsp), %rdi
leaq 0xc51ea(%rip), %rsi     # 0x5bcdc8
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
movq 0x50(%rsp), %rax
movl %eax, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
addl $0x1a, %eax
movl %eax, 0x9c(%rsp)
cmpl $0x10000, 0x9c(%rsp) # imm = 0x10000
jle 0x4f7c41
movq 0xb8(%rsp), %rdi
leaq 0xc51af(%rip), %rsi     # 0x5bcddb
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
jmp 0x4f7c43
movq 0xa8(%rsp), %rdi
addq $0x10, %rdi
movl 0x9c(%rsp), %eax
subl $0x1, %eax
movzwl %ax, %esi
callq 0x4f8cf0
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
movq %rsi, %rdi
callq 0x50a8c0
movl %eax, 0x20(%rsp)
movl 0x20(%rsp), %eax
movl %eax, %edi
movq 0xb8(%rsp), %rax
movq 0x20(%rax), %rsi
movl 0xa0(%rsp), %edx
callq 0x50a8c0
movl %eax, 0x20(%rsp)
movq 0xa8(%rsp), %rdi
movl 0x9c(%rsp), %eax
subl $0x8, %eax
cltq
addq %rax, %rdi
movl 0x20(%rsp), %esi
callq 0x4f8d20
movq 0xa8(%rsp), %rdi
movl 0x9c(%rsp), %eax
subl $0x4, %eax
cltq
addq %rax, %rdi
movl 0xa0(%rsp), %esi
callq 0x4f8d20
movl 0xb4(%rsp), %eax
subl 0xa0(%rsp), %eax
movl %eax, 0x1c(%rsp)
cmpl $0x0, 0x1c(%rsp)
jle 0x4f7d4c
movl 0x1c(%rsp), %eax
cmpl 0xa0(%rsp), %eax
jle 0x4f7d1f
movq 0xb8(%rsp), %rdi
leaq 0xc50df(%rip), %rsi     # 0x5bcdec
callq 0x4f72e0
movl $0xffffffff, 0xc4(%rsp) # imm = 0xFFFFFFFF
jmp 0x4f7d69
movq 0xb8(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0xb8(%rsp), %rax
movq 0x20(%rax), %rsi
movslq 0xa0(%rsp), %rax
addq %rax, %rsi
movslq 0x1c(%rsp), %rdx
callq 0x19610
movl 0x1c(%rsp), %ecx
movq 0xb8(%rsp), %rax
movl %ecx, 0x3c(%rax)
movl 0x9c(%rsp), %eax
movl %eax, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
addq $0xc8, %rsp
retq
nopl (%rax,%rax)