// File: /workspace/github_c_makefile_star2_O2/jsummers[P]deark/modules/zoo.c
// Function: de_run_zoo_z
static void de_run_zoo_z(deark *c, de_module_params *mparams)
{
	dbuf *outf = NULL;
	static const u8 archivehdr[34] = {0x5a,0x4f,0x4f,0x20,0x31,0x2e,0x32,0x30,0x20,0x41,
		0x72,0x63,0x68,0x69,0x76,0x65,0x2e,0x1a,0x00,0x00,0xdc,0xa7,0xc4,0xfd,0x22,0x00,
		0x00,0x00,0xde,0xff,0xff,0xff,0x01,0x01};
	struct zoo_z_ctx *zctx = NULL;
	int need_errmsg = 0;

	de_declare_fmtf(c, "Zoo Z, DOS-compatible");

	zctx = de_malloc(c, sizeof(struct zoo_z_ctx));
	if(dbuf_memcmp(c->infile, 0, "\xfe\x07\x01", 3)) {
		de_err(c, "File not in Zoo Z format, or not a supported version");
		goto done;
	}

	need_errmsg = 1;
	zctx->cmpr_len = de_getu32le(14);
	de_dbg(c, "compressed size: %"I64_FMT, zctx->cmpr_len);
	zctx->comment_len = de_getu16le(20);
	de_dbg(c, "comment: size=%d", (int)zctx->comment_len);

	// Figure out where everything will go.
	zctx->outf_member_pos = 34;
	zctx->outf_leader_pos = zctx->outf_member_pos + 52;
	zctx->outf_cmpr_pos = zctx->outf_leader_pos + 5;
	zctx->outf_comment_pos = zctx->outf_cmpr_pos + zctx->cmpr_len;
	zctx->outf_trailer_pos = zctx->outf_comment_pos + zctx->comment_len;
	zctx->inf_comment_pos = 36;
	zctx->inf_cmpr_pos = zctx->inf_comment_pos + zctx->comment_len;

	if(zctx->inf_comment_pos+zctx->comment_len > c->infile->len) goto done;
	if(zctx->inf_cmpr_pos+zctx->cmpr_len > c->infile->len) goto done;

	outf = dbuf_create_output_file(c, "zoo", NULL, 0);

	// Archive header
	dbuf_write(outf, archivehdr, 34);

	// Main member header
	dbuf_writeu32le(outf, ZOO_SIGNATURE);
	dbuf_writebyte(outf, 1); // "type"
	dbuf_copy(c->infile, 3, 1, outf); // packing method

	dbuf_writeu32le(outf, zctx->outf_trailer_pos);
	dbuf_writeu32le(outf, zctx->outf_cmpr_pos);

	// date, time, crc, sizeorig, sizenow, maj ver, min ver
	dbuf_copy(c->infile, 4, 16, outf);

	dbuf_writebyte(outf, 0); // "deleted" flag
	dbuf_writebyte(outf, 0); // file structure / reserved
	dbuf_writeu32le(outf, zctx->comment_len?zctx->outf_comment_pos:0);
	dbuf_writeu16le(outf, zctx->comment_len);
	dbuf_copy(c->infile, 22, 13, outf); // filename
	dbuf_writebyte(outf, 0x4f); // ??? This seems to be what Zoo does

	dbuf_write(outf, (const u8*)"@)#(\0", 5); // leader
	dbuf_copy(c->infile, zctx->inf_cmpr_pos, zctx->cmpr_len, outf); // cmpr data

	if(zctx->comment_len) {
		dbuf_copy(c->infile, zctx->inf_comment_pos, zctx->comment_len, outf);
	}

	dbuf_writeu32le(outf, ZOO_SIGNATURE);
	dbuf_write_zeroes(outf, 48);
	need_errmsg = 0;

done:
	dbuf_close(outf);
	if(need_errmsg) {
		de_err(c, "Conversion to Zoo format failed");
	}
	de_free(c, zctx);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x6024b(%rip), %rsi     # 0x137c47
xorl %eax, %eax
callq 0xe0824
pushq $0x48
popq %rsi
movq %rbx, %rdi
callq 0xdecaf
movq %rax, %r14
movq 0x18(%rbx), %rdi
leaq 0x60241(%rip), %rdx     # 0x137c5d
pushq $0x3
popq %rcx
xorl %esi, %esi
callq 0xe4d48
testl %eax, %eax
je 0xd7a43
leaq 0x60230(%rip), %rsi     # 0x137c61
xorl %r15d, %r15d
movq %rbx, %rdi
xorl %eax, %eax
callq 0xdf2a5
jmp 0xd7c2f
movq 0x18(%rbx), %rdi
pushq $0xe
popq %rsi
callq 0xe409f
movq %rax, 0x28(%r14)
leaq 0x3986d(%rip), %rsi     # 0x1112c7
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xde896
movq 0x18(%rbx), %rdi
pushq $0x14
popq %rsi
callq 0xe3fa3
movq %rax, 0x10(%r14)
leaq 0x60218(%rip), %rsi     # 0x137c96
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
movq $0x22, (%r14)
movq $0x56, 0x18(%r14)
movq $0x5b, 0x20(%r14)
movq 0x10(%r14), %rax
movq 0x28(%r14), %rcx
leaq 0x5b(%rcx), %rdx
movq %rdx, 0x8(%r14)
leaq 0x5b(%rax,%rcx), %rdx
movq %rdx, 0x30(%r14)
movq $0x24, 0x38(%r14)
leaq 0x24(%rax), %rdx
movq %rdx, 0x40(%r14)
movq 0x18(%rbx), %rsi
movq 0x18(%rsi), %rsi
cmpq %rsi, %rdx
setg %dl
addq %rcx, %rax
addq $0x24, %rax
cmpq %rsi, %rax
setg %al
orb %dl, %al
je 0xd7b06
xorl %edi, %edi
callq 0xe5591
leaq 0x601b0(%rip), %rsi     # 0x137ca7
movq %rbx, %rdi
xorl %eax, %eax
callq 0xdf2a5
jmp 0xd7c37
leaq 0x5fb8b(%rip), %rsi     # 0x137698
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xe4e62
movq %rax, %r15
leaq 0x601aa(%rip), %rsi     # 0x137cd0
pushq $0x22
popq %rdx
movq %rax, %rdi
callq 0xe46ba
movl $0xfdc4a7dc, %esi       # imm = 0xFDC4A7DC
movq %r15, %rdi
callq 0xe5f7f
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0xe5bc5
movq 0x18(%rbx), %rdi
pushq $0x3
popq %rsi
pushq $0x1
popq %rdx
movq %r15, %rcx
callq 0xe45f4
movq 0x30(%r14), %rsi
movq %r15, %rdi
callq 0xe5f7f
movq 0x20(%r14), %rsi
movq %r15, %rdi
callq 0xe5f7f
movq 0x18(%rbx), %rdi
pushq $0x4
popq %rsi
pushq $0x10
popq %rdx
movq %r15, %rcx
callq 0xe45f4
movq %r15, %rdi
xorl %esi, %esi
callq 0xe5bc5
movq %r15, %rdi
xorl %esi, %esi
callq 0xe5bc5
cmpq $0x0, 0x10(%r14)
je 0xd7ba4
movq 0x8(%r14), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0xe5f7f
movq 0x10(%r14), %rsi
movq %r15, %rdi
callq 0xe5f08
movq 0x18(%rbx), %rdi
pushq $0x16
popq %rsi
pushq $0xd
popq %rdx
movq %r15, %rcx
callq 0xe45f4
pushq $0x4f
popq %rsi
movq %r15, %rdi
callq 0xe5bc5
leaq 0x60113(%rip), %rsi     # 0x137cf2
pushq $0x5
popq %rdx
movq %r15, %rdi
callq 0xe46ba
movq 0x18(%rbx), %rdi
movq 0x28(%r14), %rdx
movq 0x40(%r14), %rsi
movq %r15, %rcx
callq 0xe45f4
movq 0x10(%r14), %rdx
testq %rdx, %rdx
je 0xd7c17
movq 0x18(%rbx), %rdi
movq 0x38(%r14), %rsi
movq %r15, %rcx
callq 0xe45f4
movl $0xfdc4a7dc, %esi       # imm = 0xFDC4A7DC
movq %r15, %rdi
callq 0xe5f7f
pushq $0x30
popq %rsi
movq %r15, %rdi
callq 0xe5d20
movq %r15, %rdi
callq 0xe5591
movq %rbx, %rdi
movq %r14, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0xded32