// File: /workspace/github_c_makefile_star2_O1/ebiggers[P]xpack/programs/xpack.c
// Function: do_decompress
static int
do_decompress(struct xpack_decompressor *decompressor, struct file_stream *in,
	      struct file_stream *out, u32 chunk_size)
{
	void *original_buf = xmalloc(chunk_size);
	void *compressed_buf = xmalloc(chunk_size - 1);
	ssize_t ret = -1;
	struct xpack_chunk_header chunk_hdr;

	if (original_buf == NULL || compressed_buf == NULL)
		goto out;

	while ((ret = xread(in, &chunk_hdr, sizeof(chunk_hdr)))
			== sizeof(chunk_hdr))
	{
		u32 original_size;
		u32 stored_size;
		enum decompress_result result;

		bswap_chunk_header(&chunk_hdr);
		original_size = chunk_hdr.original_size;
		stored_size = chunk_hdr.stored_size;

		if (original_size < 1 || original_size > chunk_size ||
		    stored_size < 1 || stored_size > original_size) {
			msg("%"TS": file corrupt", in->name);
			ret = -1;
			goto out;
		}

		ret = xread(in, (stored_size == original_size) ?
				original_buf : compressed_buf, stored_size);
		if (ret < 0)
			goto out;

		if (ret != stored_size) {
			msg("%"TS": unexpected end-of-file", in->name);
			ret = -1;
			goto out;
		}

		if (stored_size != original_size) {
			/* Chunk was stored compressed */
			result = xpack_decompress(decompressor,
						  compressed_buf, stored_size,
						  original_buf, original_size,
						  NULL);
			if (result != DECOMPRESS_SUCCESS) {
				msg("%"TS": data corrupt", in->name);
				ret = -1;
				goto out;
			}
		}

		ret = full_write(out, original_buf, original_size);
		if (ret != 0)
			goto out;
	}
	if (ret > 0) {
		msg("%"TS": unexpected end-of-file", in->name);
		ret = -1;
	}
out:
	free(compressed_buf);
	free(original_buf);
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %ecx, %r12d
movq %rdx, 0x20(%rsp)
movq %rsi, %r15
movq %rdi, 0x18(%rsp)
movl %ecx, %edi
callq 0x4bea
movq %rax, %rbx
leal -0x1(%r12), %edi
callq 0x4bea
testq %rbx, %rbx
sete %dl
movq %rax, 0x8(%rsp)
testq %rax, %rax
sete %cl
orb %dl, %cl
movq $-0x1, %rbp
jne 0x499e
movl $0x8, %edx
movq %r15, %rdi
leaq 0x10(%rsp), %rsi
callq 0x4e29
cmpq $0x8, %rax
jne 0x497d
movl 0x14(%rsp), %r13d
testq %r13, %r13
je 0x48ca
movl 0x10(%rsp), %r14d
cmpl %r12d, %r13d
seta %al
leal -0x1(%r14), %ecx
cmpl %r13d, %ecx
setae %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x48f0
movq 0x8(%r15), %rsi
xorl %r14d, %r14d
leaq 0x2b8a(%rip), %rdi      # 0x7462
xorl %eax, %eax
callq 0x4b60
movq $-0x1, %rbp
testb %r14b, %r14b
jne 0x4888
jmp 0x499e
cmpl %r13d, %r14d
movq 0x8(%rsp), %rsi
cmoveq %rbx, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x4e29
movq %rax, %rbp
testq %rax, %rax
js 0x4948
cmpq %r14, %rbp
jne 0x494d
cmpl %r13d, %r14d
je 0x4960
movq 0x18(%rsp), %rdi
movq 0x8(%rsp), %rsi
movq %r14, %rdx
movq %rbx, %rcx
movq %r13, %r8
xorl %r9d, %r9d
callq 0x2a9b
testl %eax, %eax
je 0x4960
movq 0x8(%r15), %rsi
xorl %r14d, %r14d
leaq 0x2b48(%rip), %rdi      # 0x748e
jmp 0x48d8
xorl %r14d, %r14d
jmp 0x48e6
movq 0x8(%r15), %rsi
xorl %r14d, %r14d
leaq 0x2b18(%rip), %rdi      # 0x7473
jmp 0x48d8
movq 0x20(%rsp), %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x4f74
testl %eax, %eax
sete %r14b
movl %eax, %ebp
jmp 0x48e6
movq %rax, %rbp
testq %rax, %rax
jle 0x499e
movq 0x8(%r15), %rsi
leaq 0x2ae3(%rip), %rdi      # 0x7473
xorl %eax, %eax
callq 0x4b60
movq $-0x1, %rbp
movq 0x8(%rsp), %rdi
callq 0x1040
movq %rbx, %rdi
callq 0x1040
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq