// File: /workspace/github_c_makefile_star2_O3/albinoloverats[P]hide/src/hide.c
// Function: process_file
static int process_file(data_info_t data_info, image_info_t image_info, void (*progress_update)(uint64_t, uint64_t))
{
	errno = EXIT_SUCCESS;

	int64_t f = 0;
	uint8_t *map = NULL;

	if ((f = open(data_info.file, data_info.hide ? O_RDONLY : (O_RDWR | O_CREAT), S_IRUSR | S_IWUSR)) < 0)
		die("Could not open %s", data_info.file);
	if (data_info.hide && (map = mmap(NULL, ntohll(data_info.size), PROT_READ, MAP_SHARED, f, 0)) == MAP_FAILED)
		die("Could not map file %s into memory", data_info.file);

	uint8_t *z = (uint8_t *)&data_info.size;
	for (uint64_t i = 0, y = 0; y < image_info.height; y++)
	{
		uint8_t *row = image_info.buffer[y];
		for (uint64_t x = 0; x < image_info.width; x++)
		{
			uint8_t *ptr = &(row[x * image_info.bpp]);

			if (data_info.hide)
			{
				unsigned char c;
				if (y == 0 && x < sizeof data_info.size && !data_info.fill)
					c = z[x];
				else if (i < ntohll(data_info.size))
					c = map[i];
				else /* TODO use something more secure */
					c = (uint8_t)lrand48();
				ptr[0] = (ptr[0] & 0xF8) | ((c & 0xE0) >> 5); // r 3 lsb
				ptr[1] = (ptr[1] & 0xFC) | ((c & 0x18) >> 3); // g 2 lsb
				ptr[2] = (ptr[2] & 0xF8) |  (c & 0x07);       // b 3 lsb
			}
			else
			{
				unsigned char c = (ptr[0] & 0x07) << 5;
				c |= (ptr[1] & 0x03) << 3;
				c |= (ptr[2] & 0x07);
				if (y == 0 && x < sizeof data_info.size && !data_info.fill)
				{
					z[x] = c;
					if (x == sizeof data_info.size - 1)
					{
						ftruncate(f, ntohll(data_info.size));
						if ((map = mmap(NULL, ntohll(data_info.size), PROT_READ | PROT_WRITE, MAP_SHARED, f, 0)) == MAP_FAILED)
							die("Could not map file %s into memory", data_info.file);
					}
				}
				else if (data_info.fill && map == NULL)
				{
					data_info.size = htonll(image_info.height * image_info.width * image_info.bpp);
					ftruncate(f, ntohll(data_info.size));
					if ((map = mmap(NULL, ntohll(data_info.size), PROT_READ | PROT_WRITE, MAP_SHARED, f, 0)) == MAP_FAILED)
						die("Could not map file %s into memory", data_info.file);
					map[i] = c;
					errno = EXIT_SUCCESS;
				}
				else
					map[i] = c;
			}
			if (y > 0 || x >= sizeof data_info.size)
			{
				i++;
				if (progress_update)
					progress_update(i, ntohll(data_info.size));
			}
			if (map && i >= ntohll(data_info.size) && !data_info.fill)
				goto done;
		}
	}

done:
	munmap(map, ntohll(data_info.size));
	close(f);
	return errno;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
callq 0x2060
xorl %ecx, %ecx
movq %rax, 0x10(%rsp)
movl %ecx, (%rax)
movq 0x50(%rsp), %r15
movb 0x60(%rsp), %bl
testb %bl, %bl
movl $0x42, %esi
cmovnel %ecx, %esi
movq %r15, %rdi
movl $0x180, %edx            # imm = 0x180
xorl %eax, %eax
callq 0x22f0
movl %eax, 0x4(%rsp)
testl %eax, %eax
js 0x3387
leaq 0x50(%rsp), %rdi
testb %bl, %bl
je 0x305d
movq 0x8(%rdi), %rsi
bswapq %rsi
xorl %edi, %edi
movl $0x1, %edx
movl $0x1, %ecx
movl 0x4(%rsp), %r8d
xorl %r9d, %r9d
callq 0x2240
leaq 0x50(%rsp), %rdi
movq %rax, %r14
cmpq $-0x1, %rax
jne 0x3060
leaq 0x216c(%rip), %rdi      # 0x51c4
jmp 0x338e
xorl %r14d, %r14d
leaq 0x68(%rsp), %r8
movq 0x28(%r8), %rax
testq %rax, %rax
je 0x333e
movq 0x30(%r8), %r15
xorl %r9d, %r9d
xorl %ebp, %ebp
testq %r15, %r15
je 0x332f
movq 0x40(%r8), %rax
movq (%rax,%r9,8), %r13
xorl %r12d, %r12d
movq %r9, 0x8(%rsp)
movzwl 0x38(%r8), %eax
movq %r12, %rbx
imulq %rax, %rbx
cmpb $0x1, 0x10(%rdi)
jne 0x30da
testq %r9, %r9
setne %al
cmpq $0x8, %r12
setae %cl
orb %al, %cl
jne 0x30c1
cmpb $0x0, 0x11(%rdi)
je 0x3286
movq 0x8(%rdi), %rax
bswapq %rax
cmpq %rax, %rbp
jae 0x326a
movb (%r14,%rbp), %al
jmp 0x328b
testq %r9, %r9
sete %dl
movb (%r13,%rbx), %cl
movb 0x1(%r13,%rbx), %sil
shlb $0x5, %cl
shlb $0x3, %sil
andb $0x18, %sil
orb %cl, %sil
movb 0x2(%r13,%rbx), %bl
andb $0x7, %bl
orb %sil, %bl
cmpq $0x8, %r12
setb %cl
andb %dl, %cl
movb 0x11(%rdi), %dl
movl %ecx, %esi
notb %sil
orb %dl, %sil
testb $0x1, %sil
je 0x320f
orb %dl, %cl
testb $0x1, %cl
je 0x3280
testq %r14, %r14
jne 0x3280
imulq %rax, %r15
imulq 0x28(%r8), %r15
movq %r15, %rsi
bswapq %rsi
movq %rsi, 0x8(%rdi)
movq %rsi, %rax
shrq $0x38, %rax
movq %rsi, %rcx
shrq $0x28, %rcx
andl $0xff00, %ecx           # imm = 0xFF00
movq %rsi, %rdx
shrq $0x18, %rdx
andl $0xff0000, %edx         # imm = 0xFF0000
movq %rsi, %rdi
shrq $0x8, %rdi
andl $0xff000000, %edi       # imm = 0xFF000000
movl %esi, %r8d
andl $0xff000000, %r8d       # imm = 0xFF000000
shlq $0x8, %r8
movl %esi, %r9d
andl $0xff0000, %r9d         # imm = 0xFF0000
shlq $0x18, %r9
movl %esi, %r10d
andl $0xff00, %r10d          # imm = 0xFF00
shlq $0x28, %r10
shlq $0x38, %rsi
orq %rax, %rsi
orq %rcx, %rsi
orq %rdx, %rsi
orq %rdi, %rsi
orq %r8, %rsi
orq %r9, %rsi
orq %r10, %rsi
movl 0x4(%rsp), %r14d
movl %r14d, %edi
callq 0x22d0
xorl %edi, %edi
movq %r15, %rsi
movl $0x3, %edx
movl $0x1, %ecx
movl %r14d, %r8d
xorl %r9d, %r9d
callq 0x2240
cmpq $-0x1, %rax
je 0x3371
movq %rax, %r14
movb %bl, (%rax,%rbp)
movq 0x10(%rsp), %rax
movl $0x0, (%rax)
leaq 0x50(%rsp), %rdi
leaq 0x68(%rsp), %r8
movq 0x8(%rsp), %r9
jmp 0x32c9
movb %bl, 0x8(%rdi,%r12)
cmpq $0x7, %r12
jne 0x32c9
movq 0x8(%rdi), %r14
bswapq %r14
movl 0x4(%rsp), %ebx
movl %ebx, %edi
movq %r14, %rsi
callq 0x22d0
xorl %edi, %edi
movq %r14, %rsi
movl $0x3, %edx
movl $0x1, %ecx
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0x2240
movq 0x8(%rsp), %r9
leaq 0x68(%rsp), %r8
leaq 0x50(%rsp), %rdi
movq %rax, %r14
cmpq $-0x1, %rax
jne 0x32c9
jmp 0x336c
callq 0x2280
movq 0x8(%rsp), %r9
leaq 0x68(%rsp), %r8
leaq 0x50(%rsp), %rdi
jmp 0x328b
movb %bl, (%r14,%rbp)
jmp 0x32c9
movb 0x8(%rdi,%r12), %al
movb (%r13,%rbx), %cl
movb 0x1(%r13,%rbx), %dl
andb $-0x8, %cl
movl %eax, %esi
shrb $0x5, %sil
orb %cl, %sil
movb %sil, (%r13,%rbx)
andb $-0x4, %dl
movl %eax, %ecx
shrb $0x3, %cl
andb $0x3, %cl
orb %dl, %cl
movb %cl, 0x1(%r13,%rbx)
movb 0x2(%r13,%rbx), %cl
andb $-0x8, %cl
andb $0x7, %al
orb %cl, %al
movb %al, 0x2(%r13,%rbx)
testq %r9, %r9
sete %al
cmpq $0x8, %r12
setb %cl
testb %cl, %al
jne 0x3302
incq %rbp
movq 0x8(%rdi), %rax
bswapq %rax
cmpq %rax, %rbp
setae %cl
testq %rbp, %rbp
sete %dl
orb %cl, %dl
jne 0x3302
movq 0x4f15(%rip), %rcx      # 0x8210
movq %rbp, (%rcx)
movq %rax, 0x8(%rcx)
testq %r14, %r14
je 0x3319
movq 0x8(%rdi), %rax
bswapq %rax
cmpq %rax, %rbp
jb 0x3319
cmpb $0x1, 0x11(%rdi)
jne 0x333e
incq %r12
movq 0x30(%r8), %r15
cmpq %r15, %r12
jb 0x3094
movq 0x28(%r8), %rax
jmp 0x3332
xorl %r15d, %r15d
incq %r9
cmpq %rax, %r9
jb 0x307b
movq 0x8(%rdi), %rsi
bswapq %rsi
movq %r14, %rdi
callq 0x22b0
movl 0x4(%rsp), %edi
callq 0x21a0
movq 0x10(%rsp), %rax
movl (%rax), %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rdi), %rsi
jmp 0x3379
leaq 0x50(%rsp), %rax
movq (%rax), %rsi
leaq 0x1e44(%rip), %rdi      # 0x51c4
xorl %eax, %eax
callq 0x3804
leaq 0x1e24(%rip), %rdi      # 0x51b2
movq %r15, %rsi
jmp 0x3380