// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/hts.c
// Function: hts_itr_multi_cram
int hts_itr_multi_cram(const hts_idx_t *idx, hts_itr_t *iter)
{
    const hts_cram_idx_t *cidx = (const hts_cram_idx_t *) idx;
    int tid, i, n_off = 0;
    uint32_t j;
    hts_pos_t beg, end;
    hts_reglist_t *curr_reg;
    hts_pair32_t *curr_intv;
    hts_pair64_max_t *off = NULL, *tmp;
    cram_index *e = NULL;

    if (!cidx || !iter || !iter->multi)
        return -1;

    iter->is_cram = 1;
    iter->read_rest = 0;
    iter->off = NULL;
    iter->n_off = 0;
    iter->curr_off = 0;
    iter->i = -1;

    for (i=0; i<iter->n_reg; i++) {

        curr_reg = &iter->reg_list[i];
        tid = curr_reg->tid;

        if (tid >= 0) {
            tmp = realloc(off, (n_off + curr_reg->count) * sizeof(*off));
            if (!tmp)
                goto err;
            off = tmp;

            for (j=0; j < curr_reg->count; j++) {
                curr_intv = &curr_reg->intervals[j];
                if (curr_intv->end < curr_intv->beg)
                    continue;

                beg = curr_intv->beg;
                end = curr_intv->end;

/* First, fetch the container overlapping 'beg' and assign its file offset to u, then
 * find the container overlapping 'end' and assign the relative end of the slice to v.
 * The cram_ptell function will adjust with the container offset, which is not stored
 * in the index.
 */
                e = cram_index_query(cidx->cram, tid, beg+1, NULL);
                if (e) {
                    off[n_off].u = e->offset;
                    // hts_pair64_max_t::max is now used to link
                    // file offsets to region list entries.
                    // The iterator can use this to decide if it
                    // can skip some file regions.
                    off[n_off].max = ((uint64_t) tid << 32) | j;

                    if (end >= HTS_POS_MAX) {
                       e = cram_index_last(cidx->cram, tid, NULL);
                    } else {
                       e = cram_index_query_last(cidx->cram, tid, end+1);
                    }

                    if (e) {
                        off[n_off++].v = e->e_next
                            ? e->e_next->offset
                            : e->offset + e->slice + e->len;
                    } else {
                        hts_log_warning("Could not set offset end for region %d:%"PRIhts_pos"-%"PRIhts_pos". Skipping", tid, beg, end);
                    }
                }
            }
        } else {
            switch (tid) {
                case HTS_IDX_NOCOOR:
                    e = cram_index_query(cidx->cram, tid, 1, NULL);
                    if (e) {
                        iter->nocoor = 1;
                        iter->nocoor_off = e->offset;
                    } else {
                        hts_log_warning("No index entry for NOCOOR region");
                    }
                    break;
                case HTS_IDX_START:
                    e = cram_index_query(cidx->cram, tid, 1, NULL);
                    if (e) {
                        iter->read_rest = 1;
                        tmp = realloc(off, sizeof(*off));
                        if (!tmp)
                            goto err;
                        off = tmp;
                        off[0].u = e->offset;
                        off[0].v = 0;
                        n_off=1;
                    } else {
                        hts_log_warning("No index entries");
                    }
                    break;
                case HTS_IDX_REST:
                    break;
                case HTS_IDX_NONE:
                    iter->finished = 1;
                    break;
                default:
                    hts_log_error("Query with tid=%d not implemented for CRAM files", tid);
            }
        }
    }

    if (n_off) {
        ks_introsort(_off_max, n_off, off);
        iter->n_off = n_off; iter->off = off;
    }

    if(!n_off && !iter->nocoor)
        iter->finished = 1;

    return 0;

 err:
    free(off);
    return -1;
}

// Assembly:
testq %rdi, %rdi
sete %dl
testq %rsi, %rsi
sete %cl
pushq $-0x1
popq %rax
orb %dl, %cl
jne 0x15c09
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r14
movl (%rsi), %ecx
testb $0x10, %cl
je 0x15bfb
movq %rdi, %r13
andl $-0x6, %ecx
orl $0x4, %ecx
movl %ecx, (%r14)
andq $0x0, 0x60(%r14)
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
movq %rax, 0x8(%r14)
andq $0x0, 0x50(%r14)
xorl %ebx, %ebx
movl $0x0, 0x4(%rsp)
xorl %ebp, %ebp
movq %r14, 0x20(%rsp)
movq %rdi, 0x18(%rsp)
movslq 0x10(%r14), %rax
cmpq %rax, %rbx
jge 0x15bbf
movq 0x28(%r14), %r15
imulq $0x28, %rbx, %rax
movl 0x10(%r15,%rax), %ecx
testl %ecx, %ecx
js 0x15ad0
movq %rcx, 0x8(%rsp)
movq %rbx, 0x28(%rsp)
addq %rax, %r15
movl 0x14(%r15), %eax
addl 0x4(%rsp), %eax
imulq $0x18, %rax, %rsi
movq %rbp, %rdi
callq 0x4840
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x15bde
movq 0x8(%rsp), %rsi
movq %rsi, %rax
shlq $0x20, %rax
movq %rax, 0x30(%rsp)
pushq $0x8
popq %r14
xorl %ebx, %ebx
movl 0x14(%r15), %eax
cmpq %rax, %rbx
jae 0x15ab9
movq 0x8(%r15), %rax
movq -0x8(%rax,%r14), %r12
movq (%rax,%r14), %rbp
cmpq %r12, %rbp
jl 0x15aad
movq 0x8(%r13), %rdi
leaq 0x1(%r12), %rdx
xorl %ecx, %ecx
callq 0x3d600
testq %rax, %rax
je 0x15aa8
movq 0x28(%rax), %rax
movslq 0x4(%rsp), %rcx
movq %r13, %rdx
imulq $0x18, %rcx, %r13
movq 0x10(%rsp), %rcx
movq %rax, (%rcx,%r13)
movq 0x30(%rsp), %rax
addq %rbx, %rax
movq %rax, 0x10(%rcx,%r13)
movq 0x8(%rdx), %rdi
movabsq $0x7fffffff7fffffff, %rax # imm = 0x7FFFFFFF7FFFFFFF
cmpq %rax, %rbp
jl 0x15a35
movq 0x8(%rsp), %rsi
xorl %edx, %edx
callq 0x3d7f8
jmp 0x15a43
leaq 0x1(%rbp), %rdx
movq 0x8(%rsp), %rsi
callq 0x3d84c
testq %rax, %rax
je 0x15a57
movq 0x30(%rax), %rcx
testq %rcx, %rcx
je 0x15a87
movq 0x28(%rcx), %rax
jmp 0x15a96
pushq $0x3
popq %rdi
leaq 0x62b54(%rip), %rsi     # 0x785b5
leaq 0x62b60(%rip), %rdx     # 0x785c8
movq 0x8(%rsp), %r13
movl %r13d, %ecx
movq %r12, %r8
movq %rbp, %r9
xorl %eax, %eax
callq 0x110c6
movq %r13, %rsi
movq 0x18(%rsp), %r13
jmp 0x15aad
movslq 0x20(%rax), %rcx
addq 0x28(%rax), %rcx
movslq 0x24(%rax), %rax
addq %rcx, %rax
addq 0x10(%rsp), %r13
incl 0x4(%rsp)
movq %rax, 0x8(%r13)
movq 0x18(%rsp), %r13
movq 0x8(%rsp), %rsi
incq %rbx
addq $0x10, %r14
jmp 0x159b2
movq 0x10(%rsp), %rbp
movq 0x20(%rsp), %r14
movq 0x28(%rsp), %rbx
incq %rbx
jmp 0x1594a
leal 0x5(%rcx), %eax
cmpl $0x3, %eax
ja 0x15b65
leaq 0x61dbd(%rip), %rcx     # 0x778a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
orb $0x2, (%r14)
jmp 0x15ac8
movq %rbx, %r15
movq 0x8(%r13), %rdi
pushq $-0x3
popq %rsi
pushq $0x1
popq %rdx
xorl %ecx, %ecx
callq 0x3d600
testq %rax, %rax
je 0x15b82
movq %rax, %rbx
orb $0x1, (%r14)
movq %rbp, %rdi
pushq $0x18
popq %rsi
callq 0x4840
testq %rax, %rax
je 0x15bde
movq 0x28(%rbx), %rcx
movq %rcx, (%rax)
andq $0x0, 0x8(%rax)
pushq $0x1
popq %rcx
movl %ecx, 0x4(%rsp)
movq %rax, %rbp
jmp 0x15b9a
movq 0x8(%r13), %rdi
pushq $-0x2
popq %rsi
pushq $0x1
popq %rdx
xorl %ecx, %ecx
callq 0x3d600
testq %rax, %rax
je 0x15ba2
orb $0x8, (%r14)
movq 0x28(%rax), %rax
movq %rax, 0x58(%r14)
jmp 0x15ac8
pushq $0x1
popq %rdi
leaq 0x62a46(%rip), %rsi     # 0x785b5
leaq 0x62abd(%rip), %rdx     # 0x78633
xorl %eax, %eax
callq 0x110c6
jmp 0x15ac8
pushq $0x3
popq %rdi
leaq 0x62a29(%rip), %rsi     # 0x785b5
leaq 0x62a8f(%rip), %rdx     # 0x78622
xorl %eax, %eax
callq 0x110c6
movq %r15, %rbx
jmp 0x15ac8
pushq $0x3
popq %rdi
leaq 0x62a09(%rip), %rsi     # 0x785b5
leaq 0x62a4e(%rip), %rdx     # 0x78601
xorl %eax, %eax
callq 0x110c6
jmp 0x15ac8
movl 0x4(%rsp), %ebx
testl %ebx, %ebx
je 0x15beb
movslq %ebx, %rdi
movq %rbp, %rsi
callq 0x14de0
movl %ebx, 0x8(%r14)
movq %rbp, 0x60(%r14)
xorl %eax, %eax
jmp 0x15bfb
movq %rbp, %rdi
callq 0x45c0
pushq $-0x1
popq %rax
jmp 0x15bfb
movl (%r14), %ecx
xorl %eax, %eax
testb $0x8, %cl
jne 0x15bfb
orl $0x2, %ecx
movl %ecx, (%r14)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq