// File: /workspace/github_c_makefile_star2_O2/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 0xa8ed(%rip), %xmm0     # 0x1003c
movss %xmm0, 0x8(%rsp)
leaq 0xcd25(%rip), %r14      # 0x12481
movq 0x12875(%rip), %r15     # 0x17fd8
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x11a0
cmpl $0x52, %eax
je 0x57a9
cmpl $0x72, %eax
je 0x5791
cmpl $0x73, %eax
jne 0x57cb
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
movss %xmm0, 0x8(%rsp)
jmp 0x5763
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm0
mulsd 0xcab1(%rip), %xmm0     # 0x12258
jmp 0x57bf
movq (%r15), %rdi
xorl %esi, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm0
mulsd 0xca91(%rip), %xmm0     # 0x12250
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
jmp 0x5763
cmpl $-0x1, %eax
jne 0x588d
movq 0x127f5(%rip), %r13     # 0x17fd0
movslq (%r13), %rax
leal 0x2(%rax), %ecx
cmpl %ebp, %ecx
jg 0x58b5
leaq 0x14(%rsp), %rsi
andl $0x0, (%rsi)
leaq 0x10(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0xc(%rsp), %rcx
movl $0x1, (%rcx)
movq (%rbx,%rax,8), %rdi
xorl %ebp, %ebp
xorl %r8d, %r8d
callq 0x12e0
testq %rax, %rax
je 0x58cf
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 0x51c5
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 0x4964
testl %eax, %eax
jne 0x58f9
movq 0x12789(%rip), %rax     # 0x17ff8
movq (%rax), %rdi
movslq (%r13), %rax
movq 0x8(%rbx,%rax,8), %rdx
leaq 0xd0ac(%rip), %rsi      # 0x1292e
xorl %eax, %eax
callq 0x10e0
pushq $0x3
jmp 0x58f8
cmpl $0x68, %eax
jne 0x58b5
movq 0x1275f(%rip), %rax     # 0x17ff8
movq (%rax), %rdi
leaq 0xcbe6(%rip), %rsi      # 0x12489
leaq 0xcb66(%rip), %rdx      # 0x12410
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x10e0
jmp 0x58f9
movq 0x1273c(%rip), %rax     # 0x17ff8
movq (%rax), %rsi
leaq 0xcb4a(%rip), %rdi      # 0x12410
callq 0x1090
pushq $0x1
jmp 0x58f8
movq 0x12722(%rip), %rax     # 0x17ff8
movq (%rax), %rdi
movslq (%r13), %rax
movq (%rbx,%rax,8), %rdx
movq 0x12850(%rip), %rcx     # 0x18138
leaq 0xd027(%rip), %rsi      # 0x12916
xorl %eax, %eax
callq 0x10e0
pushq $0x2
popq %rbp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq