// File: /workspace/github_c_makefile_star2_O3/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 $0x18, %rsp
movl %ecx, %r13d
movq %rdx, 0x10(%rsp)
movq %rsi, %r12
movq %rdi, 0x8(%rsp)
movl %ecx, %edi
callq 0x4c0e
movq %rax, %rbx
leal -0x1(%r13), %edi
callq 0x4c0e
movq %rax, %r14
testq %rbx, %rbx
sete %al
testq %r14, %r14
sete %cl
orb %al, %cl
jne 0x4ac0
movl $0x8, %edx
movq %r12, %rdi
movq %rsp, %rsi
callq 0x4e4a
cmpq $0x8, %rax
jne 0x4a95
movl 0x4(%rsp), %r15d
testq %r15, %r15
je 0x4a87
cmpl %r13d, %r15d
ja 0x4a87
movl (%rsp), %ebp
leal -0x1(%rbp), %eax
cmpl %r15d, %eax
jae 0x4a87
movq %rbx, %rsi
cmpl %r15d, %ebp
je 0x4a33
movq %r14, %rsi
movq %r12, %rdi
movq %rbp, %rdx
callq 0x4e4a
testq %rax, %rax
js 0x4aa8
cmpq %rbp, %rax
jne 0x4a9a
cmpl %r15d, %ebp
je 0x4a6a
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movq %rbp, %rdx
movq %rbx, %rcx
movq %r15, %r8
xorl %r9d, %r9d
callq 0x2ab7
testl %eax, %eax
jne 0x4aad
movq 0x10(%rsp), %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x4f7b
testl %eax, %eax
je 0x49f4
movl %eax, %r15d
jmp 0x4ac7
movq 0x8(%r12), %rsi
leaq 0x29cf(%rip), %rdi      # 0x7462
jmp 0x4ab9
testq %rax, %rax
jle 0x4aa8
movq 0x8(%r12), %rsi
leaq 0x29cd(%rip), %rdi      # 0x7473
jmp 0x4ab9
movq %rax, %r15
jmp 0x4ac7
movq 0x8(%r12), %rsi
leaq 0x29d5(%rip), %rdi      # 0x748e
xorl %eax, %eax
callq 0x4b84
movq $-0x1, %r15
movq %r14, %rdi
callq 0x1040
movq %rbx, %rdi
callq 0x1040
movl %r15d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq