// File: /workspace/github_c_makefile_star2_O2/jsummers[P]deark/modules/zoo.c
// Function: de_run_zoo_filter
static void de_run_zoo_filter(deark *c, de_module_params *mparams)
{
	dbuf *outf = NULL;
	struct de_crcobj *crco = NULL;
	int use_lzh = 0;
	u32 crc_reported;
	u32 crc_calculated;
	struct de_dfilter_in_params dcmpri;
	struct de_dfilter_out_params dcmpro;
	struct de_dfilter_results dres;

	if(c->infile->len<6) goto done;

	use_lzh = de_get_ext_option_bool(c, "zoo_filter:lzh", -1);
	if(use_lzh<0) {
		if(dbuf_is_all_zeroes(c->infile, c->infile->len-4, 2)) {
			use_lzh = 1;
		}
		else {
			use_lzh = 0;
		}
	}

	de_declare_fmtf(c, "Zoo filter, LZ%s", (use_lzh?"H":"D"));

	crc_reported = (u32)de_getu32le(c->infile->len-2);
	de_dbg(c, "crc (reported): 0x%04x", (UI)crc_reported);

	outf = dbuf_create_output_file(c, "bin", NULL, 0);
	dbuf_enable_wbuffer(outf);
	crco = de_crcobj_create(c, DE_CRCOBJ_CRC16_ARC);
	dbuf_set_writelistener(outf, de_writelistener_for_crc, (void*)crco);

	de_dfilter_init_objects(c, &dcmpri, &dcmpro, &dres);
	dcmpri.f = c->infile;
	dcmpri.pos = 2;
	dcmpri.len = c->infile->len - 4;

	dcmpro.f = outf;
	dcmpro.len_known = 0;

	if(use_lzh) {
		decompress_lzh(c, &dcmpri, &dcmpro, &dres);
	}
	else {
		decompress_lzd(c, &dcmpri, &dcmpro, &dres);
	}
	dbuf_flush(dcmpro.f);

	if(dres.errcode) {
		de_err(c, "%s", de_dfilter_get_errmsg(c, &dres));
		goto done;
	}

	crc_calculated = de_crcobj_getval(crco);
	de_dbg(c, "crc (calculated): 0x%04x", (UI)crc_calculated);
	if(crc_calculated != crc_reported) {
		de_err(c, "CRC check failed");
		goto done;
	}

done:
	dbuf_close(outf);
	de_crcobj_destroy(crco);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq 0x18(%rdi), %rax
cmpq $0x6, 0x18(%rax)
jge 0xd7787
xorl %r15d, %r15d
xorl %r14d, %r14d
jmp 0xd7914
movq %rdi, %rbx
leaq 0x60496(%rip), %rsi     # 0x137c27
pushq $-0x1
popq %rdx
callq 0xdfae5
movl %eax, %ebp
testl %eax, %eax
jns 0xd77bb
movq 0x18(%rbx), %rdi
movq 0x18(%rdi), %rsi
addq $-0x4, %rsi
pushq $0x2
popq %rdx
callq 0xe66d2
xorl %ebp, %ebp
testl %eax, %eax
setne %bpl
testl %ebp, %ebp
leaq 0x673dc(%rip), %rax     # 0x13eba0
leaq 0x5d6b9(%rip), %rdx     # 0x134e84
cmoveq %rax, %rdx
leaq 0x60460(%rip), %rsi     # 0x137c36
movq %rbx, %rdi
xorl %eax, %eax
callq 0xe0824
movq 0x18(%rbx), %rdi
movq 0x18(%rdi), %rsi
addq $-0x2, %rsi
callq 0xe409f
leaq 0x601e4(%rip), %rsi     # 0x1379dc
movq %rbx, %rdi
movq %rax, 0x8(%rsp)
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
leaq 0x50ccd(%rip), %rsi     # 0x1284dd
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xe4e62
movq %rax, %r14
movq %rax, %rdi
callq 0xe589c
pushq $0x21
popq %rsi
movq %rbx, %rdi
callq 0xe0ae9
movq %rax, %r15
leaq 0xea85(%rip), %rsi      # 0xe62c1
movq %r14, %rdi
movq %rax, %rdx
callq 0xe629a
leaq 0x28(%rsp), %r13
leaq 0x10(%rsp), %r12
leaq 0x48(%rsp), %rcx
movq %rbx, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xee7ee
movq 0x18(%rbx), %rax
movq %rax, (%r13)
movq $0x2, 0x8(%r13)
movq 0x18(%rax), %rax
addq $-0x4, %rax
movq %rax, 0x10(%r13)
movq %r14, (%r12)
movb $0x0, 0x8(%r12)
leaq 0x28(%rsp), %rsi
leaq 0x10(%rsp), %rdx
leaq 0x48(%rsp), %rcx
movq %rbx, %rdi
testl %ebp, %ebp
je 0xd78a7
callq 0xd7f9e
jmp 0xd78ac
callq 0xd7f74
movq 0x10(%rsp), %rdi
callq 0xe58e8
cmpl $0x0, 0x48(%rsp)
je 0xd78e0
leaq 0x48(%rsp), %rsi
movq %rbx, %rdi
callq 0xee7bc
leaq 0x3042e(%rip), %rsi     # 0x107cff
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xdf2a5
jmp 0xd7914
movq %r15, %rdi
callq 0xe0e95
movl %eax, %ebp
leaq 0x30966(%rip), %rsi     # 0x108257
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
cmpl 0x8(%rsp), %ebp
je 0xd7914
leaq 0x302b6(%rip), %rsi     # 0x107bc0
movq %rbx, %rdi
xorl %eax, %eax
callq 0xdf2a5
movq %r14, %rdi
callq 0xe5591
movq %r15, %rdi
callq 0xe0e8d
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq