// File: karel-brinda[P]ococo/ext/htslib/cram/cram_codecs.c
// Function: cram_codec_decoder2encoder
int cram_codec_decoder2encoder(cram_fd *fd, cram_codec *c) {
    int j;

    switch (c->codec) {
    case E_EXTERNAL:
	// shares struct with decode
	c->free = cram_external_encode_free;
	c->store = cram_external_encode_store;
	if (c->decode == cram_external_decode_int)
	    c->encode = cram_external_encode_int;
	else if (c->decode == cram_external_decode_char)
	    c->encode = cram_external_encode_char;
	else
	    return -1;
	break;

    case E_HUFFMAN: {
	// New structure, so switch.
	// FIXME: we huffman and e_huffman structs amended, we could
	// unify this.
	cram_codec *t = malloc(sizeof(*t));
	t->codec = E_HUFFMAN;
	t->free = cram_huffman_encode_free;
	t->store = cram_huffman_encode_store;
	t->e_huffman.codes = c->huffman.codes;
	t->e_huffman.nvals = c->huffman.ncodes;
	for (j = 0; j < t->e_huffman.nvals; j++) {
	    int32_t sym = t->e_huffman.codes[j].symbol;
	    if (sym >= -1 && sym < MAX_HUFF)
		t->e_huffman.val2code[sym+1] = j;
	}

	if (c->decode == cram_huffman_decode_char0)
	    t->encode = cram_huffman_encode_char0;
	else if (c->decode == cram_huffman_decode_char)
	    t->encode = cram_huffman_encode_char;
	else if (c->decode == cram_huffman_decode_int0)
	    t->encode = cram_huffman_encode_int0;
	else if (c->decode == cram_huffman_decode_int)
	    t->encode = cram_huffman_encode_int;
	else {
	    free(t);
	    return -1;
	}
	*c = *t;
	free(t);
	break;
    }

    case E_BETA:
	// shares struct with decode
	c->free = cram_beta_encode_free;
	c->store = cram_beta_encode_store;
	if (c->decode == cram_beta_decode_int)
	    c->encode = cram_beta_encode_int;
	else if (c->decode == cram_beta_decode_char)
	    c->encode = cram_beta_encode_char;
	else
	    return -1;
	break;

    case E_BYTE_ARRAY_LEN: {
	cram_codec *t = malloc(sizeof(*t));
	t->codec = E_BYTE_ARRAY_LEN;
	t->free   = cram_byte_array_len_encode_free;
	t->store  = cram_byte_array_len_encode_store;
	t->encode = cram_byte_array_len_encode;
	t->e_byte_array_len.len_codec = c->byte_array_len.len_codec;
	t->e_byte_array_len.val_codec = c->byte_array_len.val_codec;
	if (cram_codec_decoder2encoder(fd, t->e_byte_array_len.len_codec) == -1 ||
	    cram_codec_decoder2encoder(fd, t->e_byte_array_len.val_codec) == -1) {
	    t->free(t);
	    return -1;
	}

	// {len,val}_{encoding,dat} are undefined, but unused.
	// Leaving them unset here means we can test that assertion.
	*c = *t;
	free(t);
	break;
    }

    case E_BYTE_ARRAY_STOP:
	// shares struct with decode
	c->free   = cram_byte_array_stop_encode_free;
	c->store  = cram_byte_array_stop_encode_store;
	c->encode = cram_byte_array_stop_encode;
	break;

    default:
	return -1;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x5, %eax
ja 0x75d1e
movq -0x40(%rbp), %rax
leaq 0x905e(%rip), %rcx      # 0x7ea20
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x18(%rbp), %rax
leaq -0x7256(%rip), %rcx     # 0x6e780
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
leaq -0x7235(%rip), %rcx     # 0x6e7b0
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
leaq -0x7c94(%rip), %rcx     # 0x6dd60
cmpq %rcx, 0x18(%rax)
jne 0x75a0b
movq -0x18(%rbp), %rax
leaq -0x7415(%rip), %rcx     # 0x6e5f0
movq %rcx, 0x20(%rax)
jmp 0x75a3b
movq -0x18(%rbp), %rax
leaq -0x7986(%rip), %rcx     # 0x6e090
cmpq %rcx, 0x18(%rax)
jne 0x75a2d
movq -0x18(%rbp), %rax
leaq -0x73f7(%rip), %rcx     # 0x6e630
movq %rcx, 0x20(%rax)
jmp 0x75a39
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x75d2e
jmp 0x75a3b
jmp 0x75d27
movl $0x240, %edi            # imm = 0x240
callq 0x47a0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl $0x3, (%rax)
movq -0x28(%rbp), %rax
leaq -0x4323(%rip), %rcx     # 0x71740
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rax
leaq -0x42f2(%rip), %rcx     # 0x71780
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rax
movl 0x30(%rax), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x38(%rax)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x38(%rcx), %eax
jge 0x75aef
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x1c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
cmpl $-0x1, -0x2c(%rbp)
jl 0x75ae2
cmpl $0x80, -0x2c(%rbp)
jge 0x75ae2
movl -0x1c(%rbp), %edx
movq -0x28(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, 0x3c(%rax,%rcx,4)
jmp 0x75ae4
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x75a9b
movq -0x18(%rbp), %rax
leaq -0x508a(%rip), %rcx     # 0x70a70
cmpq %rcx, 0x18(%rax)
jne 0x75b14
movq -0x28(%rbp), %rax
leaq -0x474b(%rip), %rcx     # 0x713c0
movq %rcx, 0x20(%rax)
jmp 0x75b95
movq -0x18(%rbp), %rax
leaq -0x503f(%rip), %rcx     # 0x70ae0
cmpq %rcx, 0x18(%rax)
jne 0x75b36
movq -0x28(%rbp), %rax
leaq -0x4750(%rip), %rcx     # 0x713e0
movq %rcx, 0x20(%rax)
jmp 0x75b93
movq -0x18(%rbp), %rax
leaq -0x4ea1(%rip), %rcx     # 0x70ca0
cmpq %rcx, 0x18(%rax)
jne 0x75b58
movq -0x28(%rbp), %rax
leaq -0x45d2(%rip), %rcx     # 0x71580
movq %rcx, 0x20(%rax)
jmp 0x75b91
movq -0x18(%rbp), %rax
leaq -0x4e53(%rip), %rcx     # 0x70d10
cmpq %rcx, 0x18(%rax)
jne 0x75b7a
movq -0x28(%rbp), %rax
leaq -0x45d4(%rip), %rcx     # 0x715a0
movq %rcx, 0x20(%rax)
jmp 0x75b8f
movq -0x28(%rbp), %rdi
callq 0x46a0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x75d2e
jmp 0x75b91
jmp 0x75b93
jmp 0x75b95
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movl $0x240, %edx            # imm = 0x240
callq 0x4460
movq -0x28(%rbp), %rdi
callq 0x46a0
jmp 0x75d27
movq -0x18(%rbp), %rax
leaq -0x5c90(%rip), %rcx     # 0x6ff30
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
leaq -0x62cf(%rip), %rcx     # 0x6f900
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
leaq -0x6e0e(%rip), %rcx     # 0x6edd0
cmpq %rcx, 0x18(%rax)
jne 0x75bf5
movq -0x18(%rbp), %rax
leaq -0x602f(%rip), %rcx     # 0x6fbc0
movq %rcx, 0x20(%rax)
jmp 0x75c25
movq -0x18(%rbp), %rax
leaq -0x6850(%rip), %rcx     # 0x6f3b0
cmpq %rcx, 0x18(%rax)
jne 0x75c17
movq -0x18(%rbp), %rax
leaq -0x5d61(%rip), %rcx     # 0x6feb0
movq %rcx, 0x20(%rax)
jmp 0x75c23
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x75d2e
jmp 0x75c25
jmp 0x75d27
movl $0x240, %edi            # imm = 0x240
callq 0x47a0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movl $0x4, (%rax)
movq -0x38(%rbp), %rax
leaq -0x2b9d(%rip), %rcx     # 0x730b0
movq %rcx, 0x10(%rax)
movq -0x38(%rbp), %rax
leaq -0x2b3c(%rip), %rcx     # 0x73120
movq %rcx, 0x28(%rax)
movq -0x38(%rbp), %rax
leaq -0x2c3b(%rip), %rcx     # 0x73030
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rsi
callq 0x75990
cmpl $-0x1, %eax
je 0x75cbb
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x50(%rax), %rsi
callq 0x75990
cmpl $-0x1, %eax
jne 0x75cd2
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x38(%rbp), %rdi
callq *%rax
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x75d2e
movq -0x18(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl $0x240, %edx            # imm = 0x240
callq 0x4460
movq -0x38(%rbp), %rdi
callq 0x46a0
jmp 0x75d27
movq -0x18(%rbp), %rax
leaq -0x1afa(%rip), %rcx     # 0x74200
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
leaq -0x1ad9(%rip), %rcx     # 0x74230
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
leaq -0x1d88(%rip), %rcx     # 0x73f90
movq %rcx, 0x20(%rax)
jmp 0x75d27
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x75d2e
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)