// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/cram/cram_io.c
// Function: cram_read_SAM_hdr
sam_hdr_t *cram_read_SAM_hdr(cram_fd *fd) {
    int32_t header_len;
    char *header;
    sam_hdr_t *hdr;

    /* 1.1 onwards stores the header in the first block of a container */
    if (CRAM_MAJOR_VERS(fd->version) == 1) {
        /* Length */
        if (-1 == int32_decode(fd, &header_len))
            return NULL;

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        if (header_len > FUZZ_ALLOC_LIMIT)
            return NULL;
#endif

        /* Alloc and read */
        if (header_len < 0 || NULL == (header = malloc((size_t) header_len+1)))
            return NULL;

        if (header_len != hread(fd->fp, header, header_len)) {
            free(header);
            return NULL;
        }
        header[header_len] = '\0';

        fd->first_container += 4 + header_len;
    } else {
        cram_container *c = cram_read_container(fd);
        cram_block *b;
        int i;
        int64_t len;

        if (!c)
            return NULL;

        fd->first_container += c->length + c->offset;
        fd->curr_position = fd->first_container;

        if (c->num_blocks < 1) {
            cram_free_container(c);
            return NULL;
        }

        if (!(b = cram_read_block(fd))) {
            cram_free_container(c);
            return NULL;
        }
        if (cram_uncompress_block(b) != 0) {
            cram_free_container(c);
            cram_free_block(b);
            return NULL;
        }

        len = b->comp_size + 2 + 4*(CRAM_MAJOR_VERS(fd->version) >= 3) +
            fd->vv.varint_size(b->content_id) +
            fd->vv.varint_size(b->uncomp_size) +
            fd->vv.varint_size(b->comp_size);

        /* Extract header from 1st block */
        if (-1 == int32_get_blk(b, &header_len) ||
            header_len < 0 || /* Spec. says signed...  why? */
            b->uncomp_size - 4 < header_len) {
            cram_free_container(c);
            cram_free_block(b);
            return NULL;
        }
        if (NULL == (header = malloc((size_t) header_len+1))) {
            cram_free_container(c);
            cram_free_block(b);
            return NULL;
        }
        memcpy(header, BLOCK_END(b), header_len);
        header[header_len] = '\0';
        cram_free_block(b);

        /* Consume any remaining blocks */
        for (i = 1; i < c->num_blocks; i++) {
            if (!(b = cram_read_block(fd))) {
                cram_free_container(c);
                free(header);
                return NULL;
            }
            len += b->comp_size + 2 + 4*(CRAM_MAJOR_VERS(fd->version) >= 3) +
                fd->vv.varint_size(b->content_id) +
                fd->vv.varint_size(b->uncomp_size) +
                fd->vv.varint_size(b->comp_size);
            cram_free_block(b);
        }

        if (c->length > 0 && len > 0 && c->length > len) {
            // Consume padding
            char *pads = malloc(c->length - len);
            if (!pads) {
                cram_free_container(c);
                free(header);
                return NULL;
            }

            if (c->length - len != hread(fd->fp, pads, c->length - len)) {
                cram_free_container(c);
                free(header);
                free(pads);
                return NULL;
            }
            free(pads);
        }

        cram_free_container(c);
    }

    /* Parse */
    hdr = sam_hdr_init();
    if (!hdr) {
        free(header);
        return NULL;
    }

    if (-1 == sam_hdr_add_lines(hdr, header, header_len)) {
        free(header);
        sam_hdr_destroy(hdr);
        return NULL;
    }

    hdr->l_text = header_len;
    hdr->text = header;

    return hdr;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movl $0xffffff00, %eax       # imm = 0xFFFFFF00
andl 0xc(%rdi), %eax
cmpl $0x100, %eax            # imm = 0x100
jne 0x51a06
movq (%rbx), %rdi
leaq 0x1c(%rsp), %rsi
callq 0x4c8af
cmpl $-0x1, %eax
je 0x51c7e
movl 0x1c(%rsp), %r12d
testl %r12d, %r12d
js 0x51c7e
leaq 0x1(%r12), %rdi
callq 0x4680
testq %rax, %rax
je 0x51c7e
movq %rax, %rbp
movq (%rbx), %r13
movq 0x8(%r13), %rsi
movq 0x10(%r13), %r15
subq %rsi, %r15
cmpq %r12, %r15
movq %r12, %r14
cmovbq %r15, %r14
movq %rax, %rdi
movq %r14, %rdx
callq 0x43c0
addq %r14, 0x8(%r13)
cmpq %r12, %r15
jae 0x519aa
testb $0x2, 0x30(%r13)
je 0x519aa
movq %r13, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %r14, %rcx
callq 0xf129
movq %rax, %r14
cmpq %r12, %r14
jne 0x51c76
movb $0x0, (%rbp,%r12)
movq 0x8880(%rbx), %rax
addq %r12, %rax
addq $0x4, %rax
movq %rax, 0x8880(%rbx)
callq 0x220e0
testq %rax, %rax
je 0x51c76
movq %rax, %rbx
movl %r12d, %r14d
movq %rax, %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x85354
cmpl $-0x1, %eax
je 0x51c5c
movq %r14, 0x8(%rbx)
movq %rbp, 0x28(%rbx)
jmp 0x51c80
movq %rbx, %rdi
callq 0x5032e
testq %rax, %rax
je 0x51c7e
movq %rax, %r14
movslq (%rax), %rax
addq 0x40(%r14), %rax
addq 0x8880(%rbx), %rax
movq %rax, 0x8880(%rbx)
movq %rax, 0x8888(%rbx)
cmpl $0x0, 0x2c(%r14)
jle 0x51c40
movq %rbx, %rdi
callq 0x4c6b7
testq %rax, %rax
je 0x51c40
movq %rax, %r13
movq %rax, %rdi
callq 0x4ced7
testl %eax, %eax
jne 0x51c4a
xorl %r15d, %r15d
cmpl $0x300, 0xc(%rbx)       # imm = 0x300
setge %r15b
shll $0x2, %r15d
addl 0x10(%r13), %r15d
movslq 0xc(%r13), %rdi
callq *0x8a08(%rbx)
movl %eax, 0x4(%rsp)
movslq 0x14(%r13), %rdi
callq *0x8a08(%rbx)
movl %eax, 0x10(%rsp)
movslq 0x10(%r13), %rdi
callq *0x8a08(%rbx)
movslq 0x14(%r13), %rdx
movq 0x30(%r13), %rbp
movq %rdx, %rcx
subq %rbp, %rcx
cmpq $0x4, %rcx
jb 0x51c4a
movq 0x20(%r13), %rsi
movl (%rsi,%rbp), %r12d
addq $0x4, %rbp
movq %rbp, 0x30(%r13)
testl %r12d, %r12d
sets %cl
addl $-0x4, %edx
cmpl %r12d, %edx
setl %dl
orb %cl, %dl
cmpb $0x1, %dl
je 0x51c4a
movq %rsi, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movl %r12d, %eax
movq %rax, 0x8(%rsp)
leaq 0x1(%rax), %rdi
callq 0x4680
testq %rax, %rax
je 0x51c4a
movq %rax, %rcx
movl 0x4(%rsp), %eax
addl 0x10(%rsp), %eax
addl %eax, %r15d
movq 0x28(%rsp), %rax
addl %r15d, %eax
addl $0x2, %eax
movslq %eax, %r15
movq 0x20(%rsp), %rsi
addq %rbp, %rsi
movq %rcx, %rbp
movq %rcx, %rdi
movq 0x8(%rsp), %rdx
callq 0x43c0
movq 0x8(%rsp), %rax
movb $0x0, (%rbp,%rax)
movq %r13, %rdi
callq 0x4ceb6
cmpl $0x2, 0x2c(%r14)
jl 0x51bec
movl $0x1, %eax
movq %rbp, 0x30(%rsp)
movl %eax, 0x4(%rsp)
movq %rbx, %rdi
callq 0x4c6b7
testq %rax, %rax
je 0x51c6e
movq %rax, %r13
xorl %ebp, %ebp
cmpl $0x300, 0xc(%rbx)       # imm = 0x300
setge %bpl
shll $0x2, %ebp
addl 0x10(%rax), %ebp
movslq 0xc(%rax), %rdi
callq *0x8a08(%rbx)
movl %eax, 0x8(%rsp)
movslq 0x14(%r13), %rdi
callq *0x8a08(%rbx)
movq %r15, 0x10(%rsp)
movl %eax, %r15d
addl 0x8(%rsp), %r15d
addl %ebp, %r15d
movq 0x30(%rsp), %rbp
movslq 0x10(%r13), %rdi
callq *0x8a08(%rbx)
addl %r15d, %eax
addl $0x2, %eax
movq 0x10(%rsp), %r15
cltq
addq %rax, %r15
movq %r13, %rdi
callq 0x4ceb6
movl 0x4(%rsp), %eax
incl %eax
cmpl 0x2c(%r14), %eax
jl 0x51b62
movslq (%r14), %r13
testq %r13, %r13
jle 0x51c33
testq %r15, %r15
jle 0x51c33
subq %r15, %r13
jbe 0x51c33
movq %rbp, %r15
movq %r13, %rdi
callq 0x4680
testq %rax, %rax
je 0x51c92
movq %rax, %rbp
movq (%rbx), %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x4b15c
cmpq %rax, %r13
jne 0x51c9f
movq %rbp, %rdi
callq 0x45c0
movq %r15, %rbp
movq %r14, %rdi
callq 0x4fe2e
jmp 0x519ce
movq %r14, %rdi
callq 0x4fe2e
jmp 0x51c7e
movq %r14, %rdi
callq 0x4fe2e
movq %r13, %rdi
callq 0x4ceb6
jmp 0x51c7e
movq %rbp, %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x22102
jmp 0x51c7e
movq %r14, %rdi
callq 0x4fe2e
movq %rbp, %rdi
callq 0x45c0
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x4fe2e
movq %r15, %rdi
jmp 0x51c79
movq %r14, %rdi
callq 0x4fe2e
movq %r15, %rdi
callq 0x45c0
jmp 0x51c76