// File: /workspace/github_c_makefile_star2_O2/albinoloverats[P]hide/src/hide.c
// Function: main
int main(int argc, char **argv)
{
	if (argc < 2 || argc > 5)
	{
		fprintf(stderr, "Usage: %s [-f] <source image> <file to hide> <output image>\n", argv[0]);
		fprintf(stderr, "       %s [-f] <image> <recovered file>\n", argv[0]);
		fprintf(stderr, "       %s <image>\n", argv[0]);
		find_supported_formats(DIR_LIBRARY, NULL);
		return EXIT_FAILURE;
	}
	else if (argc == 2)
	{
		struct stat s;
		if (stat(argv[1], &s) < 0 && errno == ENOENT)
		{
			fprintf(stderr, "Could not read file %s\n", argv[1]);
			return errno;
		}
		image_info_t image_info = { argv[1], NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL };
#ifndef __DEBUG_JPEG__
		void *so = find_supported_formats(DIR_LIBRARY, &image_info);
		if (!so)
			return errno;
#else
		extern uint64_t info_jpeg(image_info_t *image_info);
		extern void free_jpeg(image_info_t image_info);
		image_info.info = info_jpeg;
		image_info.free = free_jpeg;
#endif
		if (!image_info.info)
		{
			fprintf(stderr, "Unsupported image format\n");
			find_supported_formats(DIR_LIBRARY, NULL);
			errno = EFTYPE;
		}
		else
		{
			setlocale(LC_NUMERIC, "");
			printf("File capacity: %'" PRIu64 " bytes\n", image_info.info(&image_info));
			image_info.free(image_info);
			errno = EXIT_SUCCESS;
		}
#ifndef __DEBUG_JPEG__
		dlclose(so);
#endif
		return errno;
	}

	int o = strcmp(argv[1], "-f") ? 0 : 1;

	hide_files_t files = { argv[o + 1], argv[o + 2], argv[o + 3] };
	process_options_t options = { files, o };

#ifndef __DEBUG__
	{
		cli_status_e ui_status = CLI_INIT;
		cli_progress_s ui_current = { 0, 1, NULL }; /* updated after reading image */
		cli_progress_s ui_total   = { 0, 3, NULL }; /* maximum of 3 steps (read, update, write) */
		ui.status = &ui_status;
		ui.current = &ui_current;
		ui.total = &ui_total;
	}
	/*
	 * TODO start process() in own thread, then call cli_display()
	 *
	 * remember that process() will have to set the status once it's finished
	 */
	pthread_t t;
	pthread_attr_t a;
	pthread_attr_init(&a);
	pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE);
	pthread_create(&t, &a, process, &options);
	pthread_attr_destroy(&a);

	cli_display(&ui);

	pthread_join(t, NULL);
#else
	process(&options);
#endif

	return errno;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x150, %rsp            # imm = 0x150
movq %rsi, %rbx
leal -0x6(%rdi), %eax
cmpl $-0x5, %eax
jbe 0x2fa0
cmpl $0x2, %edi
jne 0x2eb0
movq 0x8(%rbx), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x2120
testl %eax, %eax
jns 0x2e10
callq 0x2060
cmpl $0x2, (%rax)
je 0x3036
xorps %xmm0, %xmm0
leaq 0x70(%rsp), %rsi
movups %xmm0, 0x38(%rsi)
movups %xmm0, 0x28(%rsi)
andq $0x0, 0x48(%rsi)
movups %xmm0, 0x18(%rsi)
movups %xmm0, 0x8(%rsi)
movq 0x8(%rbx), %rax
movq %rax, (%rsi)
leaq 0x21c9(%rip), %rdi      # 0x5004
callq 0x2763
testq %rax, %rax
je 0x2f85
movq %rax, %rbx
cmpq $0x0, 0x88(%rsp)
je 0x3004
leaq 0x2414(%rip), %rsi      # 0x5276
pushq $0x1
popq %rdi
callq 0x22c0
leaq 0x70(%rsp), %r14
movq %r14, %rdi
callq *0x18(%r14)
leaq 0x22dd(%rip), %rdi      # 0x515a
xorl %ebp, %ebp
movq %rax, %rsi
xorl %eax, %eax
callq 0x2140
pushq $0xa
popq %rcx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
callq *0x20(%r14)
callq 0x2060
movq %rax, %r14
movl %ebp, (%rax)
movq %rbx, %rdi
callq 0x23a0
jmp 0x2f8d
movq 0x8(%rbx), %rax
pushq $0x3
popq %rcx
pushq $0x2
popq %rdx
pushq $0x1
popq %rsi
cmpb $0x2d, (%rax)
jne 0x2edb
cmpb $0x66, 0x1(%rax)
jne 0x2edb
cmpb $0x0, 0x2(%rax)
sete %al
je 0x2ff6
leaq 0x8(%rbx), %rsi
jmp 0x2ee1
xorl %eax, %eax
leaq (%rbx,%rsi,8), %rsi
movq (%rsi), %rsi
movq (%rbx,%rdx,8), %rdx
movq (%rbx,%rcx,8), %rcx
leaq 0x70(%rsp), %rbx
movq %rsi, (%rbx)
movq %rdx, 0x8(%rbx)
movq %rcx, 0x10(%rbx)
movb %al, 0x18(%rbx)
leaq 0x54(%rsp), %rax
movq %rax, 0x52fd(%rip)      # 0x8208
leaq 0x52f6(%rip), %r14      # 0x8208
leaq 0xc0(%rsp), %rax
movq %rax, 0x52ef(%rip)      # 0x8210
leaq 0x58(%rsp), %rax
movq %rax, 0x52eb(%rip)      # 0x8218
leaq 0xc0(%rsp), %r15
movq %r15, %rdi
callq 0x21d0
movq %r15, %rdi
xorl %esi, %esi
callq 0x2230
leaq -0xa82(%rip), %rdx      # 0x24cc
leaq 0x58(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq %rbx, %rcx
callq 0x22e0
movq %r15, %rdi
callq 0x2310
movq %r14, %rdi
callq 0x3b86
movq (%r12), %rdi
xorl %esi, %esi
callq 0x2360
callq 0x2060
movl (%rax), %eax
jmp 0x2f90
callq 0x2060
movq %rax, %r14
movl (%r14), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x5051(%rip), %r14      # 0x7ff8
movq (%r14), %rdi
movq (%rbx), %rdx
leaq 0x2115(%rip), %rsi      # 0x50c9
xorl %eax, %eax
callq 0x2210
movq (%r14), %rdi
movq (%rbx), %rdx
leaq 0x213e(%rip), %rsi      # 0x5106
xorl %eax, %eax
callq 0x2210
movq (%r14), %rdi
movq (%rbx), %rdx
leaq 0x2153(%rip), %rsi      # 0x512f
xorl %eax, %eax
callq 0x2210
leaq 0x201a(%rip), %rdi      # 0x5004
xorl %esi, %esi
callq 0x2763
pushq $0x1
popq %rax
jmp 0x2f90
pushq $0x4
popq %rcx
pushq $0x3
popq %rdx
pushq $0x2
popq %rsi
jmp 0x2edd
movq 0x4fed(%rip), %rax      # 0x7ff8
movq (%rax), %rcx
leaq 0x1ff9(%rip), %rdi      # 0x500e
pushq $0x19
popq %rsi
pushq $0x1
popq %rdx
callq 0x2350
leaq 0x1fdd(%rip), %rdi      # 0x5004
xorl %esi, %esi
callq 0x2763
pushq $0x4f
popq %rbp
jmp 0x2e99
movq %rax, %r14
movq 0x4fb8(%rip), %rax      # 0x7ff8
movq (%rax), %rdi
movq 0x8(%rbx), %rdx
leaq 0x20f4(%rip), %rsi      # 0x5142
xorl %eax, %eax
callq 0x2210
jmp 0x2f8d