// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movss 0x18e16(%rip), %xmm0    # 0x20034
movss %xmm0, -0x14(%rbp)
leaq 0x1acad(%rip), %rax     # 0x21ed7
movq %rax, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x1ad0c(%rip), %rdx     # 0x21f48
callq 0x11a0
movl %eax, -0x24(%rbp)
cmpl $-0x1, %eax
je 0x7344
movl -0x24(%rbp), %eax
addl $-0x52, %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x21, %eax
ja 0x7317
movq -0x40(%rbp), %rax
leaq 0x18e2b(%rip), %rcx     # 0x20098
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x1fd5b(%rip), %rax     # 0x26fd8
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10a0
movss %xmm0, -0x14(%rbp)
jmp 0x733f
movq 0x1fd3e(%rip), %rax     # 0x26fd8
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm1
movsd 0x1aa66(%rip), %xmm0    # 0x21d18
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x14(%rbp)
jmp 0x733f
movq 0x1fd10(%rip), %rax     # 0x26fd8
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10a0
cvtss2sd %xmm0, %xmm1
movsd 0x1aa30(%rip), %xmm0    # 0x21d10
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x14(%rbp)
jmp 0x733f
movq 0x1fd02(%rip), %rax     # 0x26ff8
movq (%rax), %rdi
movq -0x20(%rbp), %rdx
leaq 0x1ac4c(%rip), %rsi     # 0x21f50
movb $0x0, %al
callq 0x10f0
movl $0x0, -0x4(%rbp)
jmp 0x749d
movq 0x1fcda(%rip), %rax     # 0x26ff8
movq (%rax), %rdi
movq -0x20(%rbp), %rdx
leaq 0x1b0b1(%rip), %rsi     # 0x223dd
movb $0x0, %al
callq 0x10f0
movl $0x1, -0x4(%rbp)
jmp 0x749d
jmp 0x722e
movl -0x8(%rbp), %eax
movq 0x1fc82(%rip), %rcx     # 0x26fd0
movl (%rcx), %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
jge 0x737f
movq 0x1fc9a(%rip), %rax     # 0x26ff8
movq (%rax), %rdi
movq -0x20(%rbp), %rdx
leaq 0x1b071(%rip), %rsi     # 0x223dd
movb $0x0, %al
callq 0x10f0
movl $0x1, -0x4(%rbp)
jmp 0x749d
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x1, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x1fc31(%rip), %rcx     # 0x26fd0
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rdi
leaq -0x28(%rbp), %rsi
leaq -0x2c(%rbp), %rdx
leaq -0x30(%rbp), %rcx
xorl %r8d, %r8d
callq 0x1320
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x7413
movq 0x1fc2c(%rip), %rax     # 0x26ff8
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x1fbf2(%rip), %rcx     # 0x26fd0
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
callq 0x12d0
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rdx
movq %rax, %rcx
leaq 0x1afe0(%rip), %rsi     # 0x223e0
movb $0x0, %al
callq 0x10f0
movl $0x2, -0x4(%rbp)
jmp 0x749d
movl -0x28(%rbp), %edi
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %eax
movq -0x38(%rbp), %rcx
movss -0x14(%rbp), %xmm0
movzbl %al, %edx
callq 0x63a0
movq -0x10(%rbp), %rax
movq 0x1fb98(%rip), %rcx     # 0x26fd0
movl (%rcx), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
movl -0x28(%rbp), %esi
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ecx
movq -0x38(%rbp), %r8
xorl %r9d, %r9d
callq 0x57a0
cmpl $0x0, %eax
jne 0x7496
movq 0x1fb93(%rip), %rax     # 0x26ff8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x1fb5d(%rip), %rcx     # 0x26fd0
movl (%rcx), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdx
leaq 0x1af72(%rip), %rsi     # 0x223f8
movb $0x0, %al
callq 0x10f0
movl $0x3, -0x4(%rbp)
jmp 0x749d
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)