// File: /workspace/github_c_makefile_star2_O2/CerfVert94[P]lenet_cnn/main.c
// Function: main
int main(void){
	#if !defined(_CONV_WEIGHTS_)
	char Input[10][29*29] = {};

	//Load gray scale image.
	const char *bmp_path[10] = {"./Data/0.bmp",
								"./Data/1.bmp",
								"./Data/2.bmp",
								"./Data/3.bmp",
								"./Data/4.bmp",
								"./Data/5.bmp",
								"./Data/6.bmp",
								"./Data/7.bmp",
								"./Data/8.bmp",
								"./Data/9.bmp"};
	int nb_idx, input_idx, result;
	
	for (nb_idx = 0; nb_idx < 10; nb_idx++) {
		// Read the image
		read_data(bmp_path[nb_idx], Input[nb_idx]);
		// Print the handwritten digit : 
		for(input_idx = 0; input_idx < IMG_WIDTH * IMG_HEIGHT; input_idx++) {
			if((input_idx % IMG_WIDTH) == 0)
				fputc('\n',stdout);
			
			fputc(Input[nb_idx][input_idx] + '0',stdout);
		}
		fputc('\n',stdout);
		
		// Run the neural network to recognized the digit : 
		result = evaluate(Input[nb_idx]);
		printf("The recognized digit is %d\n", result);	
		if (nb_idx != result) {
			fprintf(stderr, "Recognized digit is a mismatch : %d =/= %d\n", nb_idx, result);
			exit(EXIT_FAILURE);
		}
		
	}
	write_data(Input, 10);
	fprintf(stdout, "Success\n");
	#else
	#define NB_WEIGHTS_LAYER1 ((5 * 5 + 1) * 6)
	#define NB_WEIGHTS_LAYER2 (((5 * 5 + 1) * 6) * 50)
	#define NB_WEIGHTS_LAYER3 ((5 * 5 * 50 + 1) * 100)
	#define NB_WEIGHTS_LAYER4 ((100 + 1) * 10)
	
	FILE *ptr_file1, *ptr_file2;
	// Create new header files.
	ptr_file1 = fopen("short_weight.h", "wb");
	ptr_file2 = fopen("char_weight.h", "wb");
	// Null pointer signifies an error :
	if (!ptr_file1 || !ptr_file2) {
		fprintf(stdout, "Failed creating new header files\n");
		exit(EXIT_FAILURE);
	}
	
	fprintf(ptr_file1, "#ifndef _SHORT_WEIGHT_H_\n#define _SHORT_WEIGHT_H_\n");
	fprintf(ptr_file2, "#ifndef _CHAR_WEIGHT_H_\n#define _CHAR_WEIGHT_H_\n");
	write_weights(ptr_file1, ptr_file2, "Layer1_Weights_CPU", Layer1_Weights_CPU, NB_WEIGHTS_LAYER1);
	write_weights(ptr_file1, ptr_file2, "Layer2_Weights_CPU", Layer2_Weights_CPU, NB_WEIGHTS_LAYER2);
	write_weights(ptr_file1, ptr_file2, "Layer3_Weights_CPU", Layer3_Weights_CPU, NB_WEIGHTS_LAYER3);
	write_weights(ptr_file1, ptr_file2, "Layer4_Weights_CPU", Layer4_Weights_CPU, NB_WEIGHTS_LAYER4);
	fprintf(ptr_file1, "#endif\n");
	fprintf(ptr_file2, "#endif\n");
	fclose(ptr_file1);
	fclose(ptr_file2);
	#endif
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20f8, %rsp           # imm = 0x20F8
leaq -0x2120(%rbp), %rbx
movl $0x20da, %edx           # imm = 0x20DA
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1060
movq 0x2cf7(%rip), %r13      # 0x3fd8
xorl %edx, %edx
cmpq $0xa, %rdx
je 0x13b2
leaq 0xecc(%rip), %rax       # 0x21c0
movslq (%rax,%rdx,4), %rdi
addq %rax, %rdi
movq %rdx, -0x38(%rbp)
imulq $0x349, %rdx, %rax      # imm = 0x349
leaq (%rax,%rbp), %rsi
addq $-0x2120, %rsi          # imm = 0xDEE0
movq %rsi, -0x30(%rbp)
callq 0x140e
movq $-0x349, %r15           # imm = 0xFCB7
xorl %r12d, %r12d
xorl %r14d, %r14d
movl %r12d, %eax
xorl %edx, %edx
movw $0x1d, %cx
divw %cx
testq %r15, %r15
je 0x136f
imull $0x1d, %eax, %eax
addl %r14d, %eax
testw %ax, %ax
jne 0x134f
movq (%r13), %rsi
pushq $0xa
popq %rdi
callq 0x1080
movsbl 0x349(%rbx,%r15), %edi
addl $0x30, %edi
movq (%r13), %rsi
callq 0x1080
decl %r14d
incl %r12d
incq %r15
jmp 0x1327
movq (%r13), %rsi
pushq $0xa
popq %rdi
callq 0x1080
movq -0x30(%rbp), %rdi
callq 0x11fc
movl %eax, %r12d
leaq 0xd0c(%rip), %rdi       # 0x209a
movl %eax, %esi
xorl %eax, %eax
callq 0x1040
movl %r12d, %eax
movq -0x38(%rbp), %rdx
cmpq %rax, %rdx
jne 0x13eb
incq %rdx
addq $0x349, %rbx            # imm = 0x349
jmp 0x12e3
leaq -0x2120(%rbp), %rdi
pushq $0xa
popq %rsi
callq 0x1516
movq (%r13), %rcx
leaq 0xd16(%rip), %rdi       # 0x20e2
pushq $0x8
popq %rsi
pushq $0x1
popq %rdx
callq 0x10f0
xorl %eax, %eax
addq $0x20f8, %rsp           # imm = 0x20F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2c06(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xcba(%rip), %rsi       # 0x20b6
movl %r12d, %ecx
xorl %eax, %eax
callq 0x1090
pushq $0x1
popq %rdi
callq 0x10e0