// File: /workspace/github_c_makefile_star2_O2/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 0x43b08
leaq 0xc(%rsp), %rsi
movq %rbx, %rdi
callq 0x3f620
cmpl $-0x1, %eax
je 0x43cea
movl 0xc(%rsp), %r14d
testl %r14d, %r14d
js 0x43cea
leaq 0x1(%r14), %rdi
callq 0x4680
testq %rax, %rax
je 0x43cea
movq %rax, %r15
movq (%rbx), %rdi
movq %rax, %rsi
movq %r14, %rdx
callq 0x3e674
cmpq %r14, %rax
jne 0x43ce2
movb $0x0, (%r15,%r14)
movq 0x8880(%rbx), %rax
addq %r14, %rax
addq $0x4, %rax
movq %rax, 0x8880(%rbx)
callq 0x1d600
testq %rax, %rax
je 0x43ce2
movq %rax, %rbx
movl %r14d, %r14d
movq %rax, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x6a11d
cmpl $-0x1, %eax
je 0x43cfe
movq %r14, 0x8(%rbx)
movq %r15, 0x28(%rbx)
jmp 0x43cec
movq %rbx, %rdi
callq 0x427b3
testq %rax, %rax
je 0x43cea
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 0x43cc6
movq %rbx, %rdi
callq 0x3f467
testq %rax, %rax
je 0x43cc6
movq %rax, %r13
movq %rax, %rdi
callq 0x3f918
testl %eax, %eax
jne 0x43cd0
xorl %ebp, %ebp
cmpl $0x300, 0xc(%rbx)       # imm = 0x300
setge %bpl
shll $0x2, %ebp
addl 0x10(%r13), %ebp
movslq 0xc(%r13), %rdi
callq *0x8a08(%rbx)
movl %eax, %r12d
movslq 0x14(%r13), %rdi
callq *0x8a08(%rbx)
movl %eax, 0x20(%rsp)
movslq 0x10(%r13), %rdi
callq *0x8a08(%rbx)
movq %rax, 0x18(%rsp)
leaq 0xc(%rsp), %r15
movq %r13, %rdi
movq %r15, %rsi
callq 0x3f1fb
cmpl $-0x1, %eax
sete %al
movl (%r15), %edx
testl %edx, %edx
sets %cl
orb %al, %cl
jne 0x43cd0
movl 0x14(%r13), %eax
addl $-0x4, %eax
cmpl %edx, %eax
jl 0x43cd0
movq %rdx, 0x28(%rsp)
movl %edx, %eax
movq %rax, 0x30(%rsp)
leaq 0x1(%rax), %rdi
callq 0x4680
testq %rax, %rax
je 0x43cd0
movq %rax, %r15
addl 0x20(%rsp), %r12d
addl %r12d, %ebp
movq 0x18(%rsp), %rax
addl %ebp, %eax
addl $0x2, %eax
movslq %eax, %r12
movq 0x20(%r13), %rsi
addq 0x30(%r13), %rsi
movq %r15, %rdi
movq 0x30(%rsp), %rbp
movq %rbp, %rdx
callq 0x43c0
movq %r15, 0x10(%rsp)
movb $0x0, (%r15,%rbp)
movq %r13, %rdi
callq 0x3f8fc
pushq $0x1
popq %rbp
cmpl 0x2c(%r14), %ebp
jge 0x43d10
movq %rbx, %rdi
callq 0x3f467
testq %rax, %rax
je 0x43d64
movq %rax, %r13
movq %r12, 0x20(%rsp)
xorl %r12d, %r12d
cmpl $0x300, 0xc(%rbx)       # imm = 0x300
setge %r12b
shll $0x2, %r12d
addl 0x10(%rax), %r12d
movslq 0xc(%rax), %rdi
callq *0x8a08(%rbx)
movl %ebp, 0x18(%rsp)
movl %eax, %ebp
movslq 0x14(%r13), %rdi
callq *0x8a08(%rbx)
movl %eax, %r15d
addl %ebp, %r15d
movl 0x18(%rsp), %ebp
addl %r12d, %r15d
movq 0x20(%rsp), %r12
movslq 0x10(%r13), %rdi
callq *0x8a08(%rbx)
addl %r15d, %eax
addl $0x2, %eax
cltq
addq %rax, %r12
movq %r13, %rdi
callq 0x3f8fc
incl %ebp
jmp 0x43c3d
movq %r14, %rdi
callq 0x4237d
jmp 0x43cea
movq %r14, %rdi
callq 0x4237d
movq %r13, %rdi
callq 0x3f8fc
jmp 0x43cea
movq %r15, %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 %r15, %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x1d61e
jmp 0x43cea
movslq (%r14), %r13
testq %r13, %r13
jle 0x43d4d
testq %r12, %r12
jle 0x43d4d
subq %r12, %r13
jbe 0x43d4d
movq %r13, %rdi
callq 0x4680
testq %rax, %rax
je 0x43d64
movq %rax, %rbp
movq (%rbx), %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x3e674
cmpq %rax, %r13
jne 0x43d76
movq %rbp, %rdi
callq 0x45c0
movq %r14, %rdi
callq 0x4237d
movq 0x10(%rsp), %r15
movq 0x28(%rsp), %r14
jmp 0x43ad0
movq %r14, %rdi
callq 0x4237d
movq 0x10(%rsp), %rdi
jmp 0x43ce5
movq %r14, %rdi
callq 0x4237d
movq 0x10(%rsp), %rdi
callq 0x45c0
movq %rbp, %rdi
jmp 0x43ce5