// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/cram/cram_encode.c
// Function: cram_allocate_block
static int cram_allocate_block(cram_codec *codec, cram_slice *s, int ds_id) {
    if (!codec)
        return 0;

    switch(codec->codec) {
    // Codecs which are hard-coded to use the CORE block
    case E_GOLOMB:
    case E_HUFFMAN:
    case E_BETA:
    case E_SUBEXP:
    case E_GOLOMB_RICE:
    case E_GAMMA:
        codec->out = s->block[0];
        break;

    // Codecs which don't use external blocks
    case E_CONST_BYTE:
    case E_CONST_INT:
       codec->out = NULL;
       break;

    // Codecs that emit directly to external blocks
    case E_EXTERNAL:
    case E_VARINT_UNSIGNED:
    case E_VARINT_SIGNED:
        if (!(s->block[ds_id] = cram_new_block(EXTERNAL, ds_id)))
            return -1;
        codec->u.external.content_id = ds_id;
        codec->out = s->block[ds_id];
        break;

    case E_BYTE_ARRAY_STOP: // Why no sub-codec?
        if (!(s->block[ds_id] = cram_new_block(EXTERNAL, ds_id)))
            return -1;
        codec->u.byte_array_stop.content_id = ds_id;
        codec->out = s->block[ds_id];
        break;


    // Codecs that contain sub-codecs which may in turn emit to external blocks
    case E_BYTE_ARRAY_LEN: {
        cram_codec *bal = codec->u.e_byte_array_len.len_codec;
        if (cram_allocate_block(bal, s, bal->u.external.content_id))
            return -1;
        bal = codec->u.e_byte_array_len.val_codec;
        if (cram_allocate_block(bal, s, bal->u.external.content_id))
            return -1;

        break;
    }

    case E_XRLE:
        if (cram_allocate_block(codec->u.e_xrle.len_codec, s, ds_id))
                                //ds_id == DS_QS ? DS_QS_len : ds_id))
            return -1;
        if (cram_allocate_block(codec->u.e_xrle.lit_codec, s, ds_id))
            return -1;

        break;

    case E_XPACK:
        if (cram_allocate_block(codec->u.e_xpack.sub_codec, s, ds_id))
            return -1;
        codec->out = cram_new_block(0, 0); // ephemeral
        if (!codec->out)
            return -1;

        break;

    case E_XDELTA:
        if (cram_allocate_block(codec->u.e_xdelta.sub_codec, s, ds_id))
            return -1;
        codec->out = cram_new_block(0, 0); // ephemeral
        if (!codec->out)
            return -1;

        break;

    default:
        break;
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x3c0ff
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
movl (%rdi), %eax
leal -0x1(%rax), %ecx
cmpl $0x8, %ecx
ja 0x3bfff
leaq 0x3f6b3(%rip), %rax     # 0x7b6a0
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x10(%r14), %rcx
jmp 0x3c0f8
addl $-0x29, %eax
cmpl $0xc, %eax
ja 0x3c0ff
leaq 0x3f6b2(%rip), %rcx     # 0x7b6c4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
pushq $0x4
popq %rdi
movl %r15d, %esi
callq 0x3f426
movq 0x10(%r14), %rdx
movslq %r15d, %rcx
movq %rax, (%rdx,%rcx,8)
testq %rax, %rax
je 0x3c10e
movl %r15d, 0x60(%rbx)
jmp 0x3c0f0
xorl %eax, %eax
jmp 0x3c0fb
movq 0x70(%rbx), %rdi
jmp 0x3c07d
movq 0x78(%rbx), %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x3bfc3
pushq $-0x1
popq %rbp
testl %eax, %eax
jne 0x3c101
movq 0x80(%rbx), %rdi
movq %r14, %rsi
movl %r15d, %edx
jmp 0x3c0c6
movq 0x78(%rbx), %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x3bfc3
pushq $-0x1
popq %rbp
testl %eax, %eax
jne 0x3c101
xorl %edi, %edi
xorl %esi, %esi
callq 0x3f426
movq %rax, 0x8(%rbx)
testq %rax, %rax
jne 0x3c0ff
jmp 0x3c101
movq 0x78(%rbx), %rdi
movl 0x60(%rdi), %edx
movq %r14, %rsi
callq 0x3bfc3
pushq $-0x1
popq %rbp
testl %eax, %eax
jne 0x3c101
movq 0x80(%rbx), %rdi
movl 0x60(%rdi), %edx
movq %r14, %rsi
callq 0x3bfc3
testl %eax, %eax
jne 0x3c101
jmp 0x3c0ff
pushq $0x4
popq %rdi
movl %r15d, %esi
callq 0x3f426
movq 0x10(%r14), %rdx
movslq %r15d, %rcx
movq %rax, (%rdx,%rcx,8)
testq %rax, %rax
je 0x3c10e
movl %r15d, 0x64(%rbx)
shlq $0x3, %rcx
addq 0x10(%r14), %rcx
movq (%rcx), %rax
movq %rax, 0x8(%rbx)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
popq %rbp
jmp 0x3c101