// File: /workspace/github_c_makefile_star2_O3/arkanis[P]iir_gauss_blur/blur.c
// Function: main
int main(int argc, char** argv) {
	float sigma = 10.0;
	
	char* usage = "Usage: blur [-h] [-s sigma] [-r radius16] [-R radius1] input-file output-file\n"
		"Blur an image and save it as PNG.\n";
	int opt;
	while ( (opt = getopt(argc, argv, "s:r:R:h")) != -1 ) {
		switch(opt) {
			case 's':
				sigma = strtof(optarg, NULL);
				break;
			case 'r':
				sigma = (1.0 / 1.42) * strtof(optarg, NULL);
				break;
			case 'R':
				sigma = (1.0 / 3.66) * strtof(optarg, NULL);
				break;
			case 'h':
				fprintf(stderr,
					"%s\n"
					"  -s sigma     The sigma of the gauss normal distribution (number >= 0.5).\n"
					"               Larger values result in a stronger blur.\n"
					"  -r radius16  Automatically calculate a sigma so that one pixel gets visibly\n"
					"               blurred acros that radius. A white pixel can change the\n"
					"               brightness by 16 at that radius (hence the name) which is an\n"
					"               barely visible change.\n"
					"  -R radius1   Automatically calculate a sigma so that one pixel can't change\n"
					"               other pixels outside that radius (change is lower than 1\n"
					"               brighness).\n"
					"  -h           display this help and exit.\n"
					"\n"
					"You can use either sigma, radius16 or radius1 to specify the strengh of the\n"
					"blur. If more than one is specified the last option is used.\n"
					"\n"
					"Both radius16 and radius1 are very crude approximations and work more or less\n"
					"well up to 100 (haven't tested any higher).\n"
					"\n"
					"The performance is independent of the blur strengh (sigma). This tool is an\n"
					"implementation of the paper \"Recursive implementaion of the Gaussian filter\"\n"
					"by Ian T. Young and Lucas J. van Vliet.\n"
					"\n"
					"stb_image and stb_image_write by Sean Barrett and others is used to read and\n"
					"write images.\n",
					usage
				);
				return 0;
			default:
				fprintf(stderr, "%s", usage);
				return 1;
		}
	}
	
	// Need at least two filenames after the last option
	if (argc < optind + 2) {
		fprintf(stderr, "%s", usage);
		return 1;
	}
	
	int width = 0, height = 0, components = 1;
	uint8_t* image = stbi_load(argv[optind], &width, &height, &components, 0);
	if (image == NULL) {
		fprintf(stderr, "Failed to load %s: %s.\n", argv[optind], stbi_failure_reason());
		return 2;
	}
	
	iir_gauss_blur(width, height, components, image, sigma);
	
	if ( stbi_write_png(argv[optind+1], width, height, components, image, 0) == 0 ) {
		fprintf(stderr, "Failed to save %s.\n", argv[optind+1]);
		return 3;
	}
	
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movl %edi, %ebp
movss 0xd588(%rip), %xmm0     # 0x1303c
movss %xmm0, 0x8(%rsp)
leaq 0xfa88(%rip), %r14      # 0x15549
movq 0x14510(%rip), %r15     # 0x19fd8
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x11a0
cmpl $0x71, %eax
jle 0x5afa
cmpl $0x72, %eax
je 0x5b17
cmpl $0x73, %eax
jne 0x5beb
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
movss %xmm0, 0x8(%rsp)
jmp 0x5ac8
cmpl $0x52, %eax
jne 0x5b39
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm0
mulsd 0xf803(%rip), %xmm0     # 0x15318
jmp 0x5b2d
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm0
mulsd 0xf7f3(%rip), %xmm0     # 0x15320
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
jmp 0x5ac8
cmpl $-0x1, %eax
jne 0x5bdd
movq 0x14487(%rip), %r13     # 0x19fd0
movslq (%r13), %rax
leal 0x2(%rax), %ecx
cmpl %ebp, %ecx
jg 0x5bf2
xorl %ebp, %ebp
leaq 0x14(%rsp), %rsi
movl %ebp, (%rsi)
leaq 0x10(%rsp), %rdx
movl %ebp, (%rdx)
leaq 0xc(%rsp), %rcx
movl $0x1, (%rcx)
movq (%rbx,%rax,8), %rdi
xorl %r8d, %r8d
callq 0x13a0
testq %rax, %rax
je 0x5bfe
movq %rax, %r14
movl 0x14(%rsp), %r15d
movl 0x10(%rsp), %r12d
movzbl 0xc(%rsp), %edx
movl %r15d, %edi
movl %r12d, %esi
movq %rax, %rcx
movss 0x8(%rsp), %xmm0
callq 0x54a6
movslq (%r13), %rax
movq 0x8(%rbx,%rax,8), %rdi
movl 0xc(%rsp), %ecx
movl %r15d, %esi
movl %r12d, %edx
movq %r14, %r8
xorl %r9d, %r9d
callq 0x4b02
testl %eax, %eax
je 0x5c0d
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x68, %eax
jne 0x5beb
callq 0x11e0
xorl %ebp, %ebp
jmp 0x5bcc
callq 0x127b
jmp 0x5bf7
callq 0x1265
movl $0x1, %ebp
jmp 0x5bcc
movq %rbx, %rdi
callq 0x122f
movl $0x2, %ebp
jmp 0x5bcc
movq %rbx, %rdi
callq 0x11ff
movl $0x3, %ebp
jmp 0x5bcc