// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movl %ecx, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, %edi
callq 0x2890
movq %rax, 0x40(%rsp)
movl 0x4c(%rsp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %edi
callq 0x2890
movq %rax, 0x38(%rsp)
movq $-0x1, 0x30(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x20c5
cmpq $0x0, 0x38(%rsp)
jne 0x20ca
jmp 0x2288
jmp 0x20cc
movq 0x58(%rsp), %rdi
leaq 0x28(%rsp), %rsi
movl $0x8, %edx
callq 0x2cb0
movq %rax, 0x30(%rsp)
cmpq $0x8, %rax
jne 0x225e
leaq 0x28(%rsp), %rdi
callq 0x2300
movl 0x2c(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x20(%rsp)
cmpl $0x1, 0x24(%rsp)
jb 0x212b
movl 0x24(%rsp), %eax
cmpl 0x4c(%rsp), %eax
ja 0x212b
cmpl $0x1, 0x20(%rsp)
jb 0x212b
movl 0x20(%rsp), %eax
cmpl 0x24(%rsp), %eax
jbe 0x2150
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xe524(%rip), %rdi      # 0x1065f
movb $0x0, %al
callq 0x2660
movq $-0x1, 0x30(%rsp)
jmp 0x2288
movq 0x58(%rsp), %rax
movq %rax, 0x10(%rsp)
movl 0x20(%rsp), %eax
cmpl 0x24(%rsp), %eax
jne 0x2170
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
jmp 0x217a
movq 0x38(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rsi
movl 0x20(%rsp), %eax
movl %eax, %edx
callq 0x2cb0
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jge 0x21a1
jmp 0x2288
movq 0x30(%rsp), %rax
movl 0x20(%rsp), %ecx
cmpq %rcx, %rax
je 0x21d4
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xe4b1(%rip), %rdi      # 0x10670
movb $0x0, %al
callq 0x2660
movq $-0x1, 0x30(%rsp)
jmp 0x2288
movl 0x20(%rsp), %eax
cmpl 0x24(%rsp), %eax
je 0x2233
movq 0x60(%rsp), %rdi
movq 0x38(%rsp), %rsi
movl 0x20(%rsp), %eax
movl %eax, %edx
movq 0x40(%rsp), %rcx
movl 0x24(%rsp), %eax
movl %eax, %r8d
xorl %eax, %eax
movl %eax, %r9d
callq 0xbfc0
movl %eax, 0x1c(%rsp)
cmpl $0x0, 0x1c(%rsp)
je 0x2231
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xe46c(%rip), %rdi      # 0x1068b
movb $0x0, %al
callq 0x2660
movq $-0x1, 0x30(%rsp)
jmp 0x2288
jmp 0x2233
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x24(%rsp), %eax
movl %eax, %edx
callq 0x2ef0
cltq
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0x2259
jmp 0x2288
jmp 0x20cc
cmpq $0x0, 0x30(%rsp)
jle 0x2286
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xe3fa(%rip), %rdi      # 0x10670
movb $0x0, %al
callq 0x2660
movq $-0x1, 0x30(%rsp)
jmp 0x2288
movq 0x38(%rsp), %rdi
callq 0x1040
movq 0x40(%rsp), %rdi
callq 0x1040
movq 0x30(%rsp), %rax
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)