// File: gvaumour[P]cache-simulator/src/common.cc
// Function: writeBMPimage(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, int, std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>, std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>, std::vector<std::vector<int, std::allocator<int>>, std::allocator<std::vector<int, std::allocator<int>>>>)
void writeBMPimage(std::string image_name , int width , int height , vector< vector<int> > red, vector< vector<int> > blue, vector< vector<int> > green )
{
	FILE *f;
	int factor = 4;
	unsigned char *img = NULL;
	int w = width;
	int h = height*factor;
	int filesize = 54 + 3*w*h;

	img = (unsigned char *)malloc(3*w*h);
	memset(img,0,3*w*h);
	unsigned char r,g,b;
	int a = 0;
	
	for(int i=0; i<width; i++)
	{
	    a = 0;
	    for(int j=0; j<height; j++)
	    {
		r = red[i][j];
		g = green[i][j];
		b = blue[i][j];
		
		for(int k = 0 ; k < factor;k++)
		{
			img[(i+a*w)*3+2] = (unsigned char)(r);
			img[(i+a*w)*3+1] = (unsigned char)(g);
			img[(i+a*w)*3+0] = (unsigned char)(b);
			a++;
		}
	    }
	}

	unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
	unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
	unsigned char bmppad[3] = {0,0,0};

	bmpfileheader[ 2] = (unsigned char)(filesize    );
	bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
	bmpfileheader[ 4] = (unsigned char)(filesize>>16);
	bmpfileheader[ 5] = (unsigned char)(filesize>>24);

	bmpinfoheader[ 4] = (unsigned char)(       w    );
	bmpinfoheader[ 5] = (unsigned char)(       w>> 8);
	bmpinfoheader[ 6] = (unsigned char)(       w>>16);
	bmpinfoheader[ 7] = (unsigned char)(       w>>24);
	bmpinfoheader[ 8] = (unsigned char)(       h    );
	bmpinfoheader[ 9] = (unsigned char)(       h>> 8);
	bmpinfoheader[10] = (unsigned char)(       h>>16);
	bmpinfoheader[11] = (unsigned char)(       h>>24);

	f = fopen(image_name.c_str(),"wb");
	fwrite(bmpfileheader,1,14,f);
	fwrite(bmpinfoheader,1,40,f);
	for(int i=0; i<h; i++)
	{
	    fwrite(img+(w*(h-i-1)*3),3,w,f);
	    fwrite(bmppad,1,(4-(w*3)%4)%4,f);
	}

	free(img);
	fclose(f);
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0x8(%rsp)
movq %rcx, 0x10(%rsp)
movq %r8, 0x18(%rsp)
movq %r9, 0x20(%rsp)
movq %rdi, 0xc0(%rsp)
movl %esi, 0xbc(%rsp)
movl %edx, 0xb8(%rsp)
movq %rcx, 0xb0(%rsp)
movq %r8, 0xa8(%rsp)
movq %r9, 0xa0(%rsp)
movl $0x4, 0x94(%rsp)
movq $0x0, 0x88(%rsp)
movl 0xbc(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0xb8(%rsp), %eax
imull 0x94(%rsp), %eax
movl %eax, 0x80(%rsp)
imull $0x3, 0x84(%rsp), %eax
imull 0x80(%rsp), %eax
addl $0x36, %eax
movl %eax, 0x7c(%rsp)
imull $0x3, 0x84(%rsp), %eax
imull 0x80(%rsp), %eax
movslq %eax, %rdi
callq 0x5500
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
imull $0x3, 0x84(%rsp), %eax
imull 0x80(%rsp), %eax
movslq %eax, %rdx
xorl %esi, %esi
callq 0x5210
movl $0x0, 0x74(%rsp)
movl $0x0, 0x70(%rsp)
movl 0x70(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jge 0x667ab
movl $0x0, 0x74(%rsp)
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0xb8(%rsp), %eax
jge 0x66799
movq 0x10(%rsp), %rdi
movslq 0x70(%rsp), %rsi
callq 0xef70
movq %rax, %rdi
movslq 0x6c(%rsp), %rsi
callq 0xef90
movq 0x20(%rsp), %rdi
movl (%rax), %eax
movb %al, 0x7b(%rsp)
movslq 0x70(%rsp), %rsi
callq 0xef70
movq %rax, %rdi
movslq 0x6c(%rsp), %rsi
callq 0xef90
movq 0x18(%rsp), %rdi
movl (%rax), %eax
movb %al, 0x7a(%rsp)
movslq 0x70(%rsp), %rsi
callq 0xef70
movq %rax, %rdi
movslq 0x6c(%rsp), %rsi
callq 0xef90
movl (%rax), %eax
movb %al, 0x79(%rsp)
movl $0x0, 0x68(%rsp)
movl 0x68(%rsp), %eax
cmpl 0x94(%rsp), %eax
jge 0x66787
movb 0x7b(%rsp), %dl
movq 0x88(%rsp), %rax
movl 0x70(%rsp), %ecx
movl 0x74(%rsp), %esi
imull 0x84(%rsp), %esi
addl %esi, %ecx
imull $0x3, %ecx, %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movb 0x7a(%rsp), %dl
movq 0x88(%rsp), %rax
movl 0x70(%rsp), %ecx
movl 0x74(%rsp), %esi
imull 0x84(%rsp), %esi
addl %esi, %ecx
imull $0x3, %ecx, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movb 0x79(%rsp), %dl
movq 0x88(%rsp), %rax
movl 0x70(%rsp), %ecx
movl 0x74(%rsp), %esi
imull 0x84(%rsp), %esi
addl %esi, %ecx
imull $0x3, %ecx, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0x666dd
jmp 0x66789
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x6665e
jmp 0x6679b
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x70(%rsp)
jmp 0x6663d
movq 0xda26(%rip), %rax      # 0x741d8
movq %rax, 0x5a(%rsp)
movl 0xda23(%rip), %eax      # 0x741e0
movl %eax, 0x62(%rsp)
movw 0xda1c(%rip), %ax       # 0x741e4
movw %ax, 0x66(%rsp)
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
movl $0x28, %edx
callq 0x5210
movb $0x28, 0x30(%rsp)
movb $0x1, 0x3c(%rsp)
movb $0x18, 0x3e(%rsp)
leaq 0x2d(%rsp), %rdi
xorl %esi, %esi
movl $0x3, %edx
callq 0x5210
movq 0x8(%rsp), %rdi
movl 0x7c(%rsp), %eax
movb %al, 0x5c(%rsp)
movl 0x7c(%rsp), %eax
sarl $0x8, %eax
movb %al, 0x5d(%rsp)
movl 0x7c(%rsp), %eax
sarl $0x10, %eax
movb %al, 0x5e(%rsp)
movl 0x7c(%rsp), %eax
sarl $0x18, %eax
movb %al, 0x5f(%rsp)
movl 0x84(%rsp), %eax
movb %al, 0x34(%rsp)
movl 0x84(%rsp), %eax
sarl $0x8, %eax
movb %al, 0x35(%rsp)
movl 0x84(%rsp), %eax
sarl $0x10, %eax
movb %al, 0x36(%rsp)
movl 0x84(%rsp), %eax
sarl $0x18, %eax
movb %al, 0x37(%rsp)
movl 0x80(%rsp), %eax
movb %al, 0x38(%rsp)
movl 0x80(%rsp), %eax
sarl $0x8, %eax
movb %al, 0x39(%rsp)
movl 0x80(%rsp), %eax
sarl $0x10, %eax
movb %al, 0x3a(%rsp)
movl 0x80(%rsp), %eax
sarl $0x18, %eax
movb %al, 0x3b(%rsp)
callq 0x51a0
movq %rax, %rdi
leaq 0xd8bc(%rip), %rsi      # 0x74161
callq 0x5460
movq %rax, 0x98(%rsp)
leaq 0x5a(%rsp), %rdi
movq 0x98(%rsp), %rcx
movl $0x1, %esi
movl $0xe, %edx
callq 0x5720
leaq 0x30(%rsp), %rdi
movq 0x98(%rsp), %rcx
movl $0x1, %esi
movl $0x28, %edx
callq 0x5720
movl $0x0, 0x28(%rsp)
movl 0x28(%rsp), %eax
cmpl 0x80(%rsp), %eax
jge 0x6698e
movq 0x88(%rsp), %rdi
movl 0x84(%rsp), %eax
movl 0x80(%rsp), %ecx
subl 0x28(%rsp), %ecx
subl $0x1, %ecx
imull %ecx, %eax
imull $0x3, %eax, %eax
cltq
addq %rax, %rdi
movslq 0x84(%rsp), %rdx
movq 0x98(%rsp), %rcx
movl $0x3, %esi
callq 0x5720
leaq 0x2d(%rsp), %rdi
imull $0x3, 0x84(%rsp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl $0x4, %eax
subl %edx, %eax
movl $0x4, %ecx
cltd
idivl %ecx
movslq %edx, %rdx
movq 0x98(%rsp), %rcx
movl $0x1, %esi
callq 0x5720
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x668f2
movq 0x88(%rsp), %rdi
callq 0x5480
movq 0x98(%rsp), %rdi
callq 0x5390
addq $0xc8, %rsp
retq