// File: kchan1[P]helloworld_test1/main.cpp
// Function: main
int main(int argc, char * arg[])

{	
	if (argc == 1){
		std::cout<<"Error: No filename submitted. Please input filename."<<std::endl;
		return 1;
	}

	int quant;

	if (argc >= 3){
		int arg2i = atoi(arg[2]);
		if (arg2i>=1){
			quant = arg2i;	
		}
		else{
		std::cout<<"Error: Qunatization scale must be a positive non-zero number."<<std::endl;
		return 1;
		}
	}
	else{
		quant = 20;
	}

	int depth;

	if (argc >= 4){
		int arg3i = atoi(arg[3]);
		if (arg3i>=1){
			depth = arg3i;	
		}
		else{
		std::cout<<"Error: Depth scale must be a positive non-zero number."<<std::endl;
		return 1;
		}
	}
	else{
		depth = 1;
	}
	

	//for handling the file
	std::string filename = arg[1];
	std::ifstream image_file;
	
	//buffers for reading the header
	unsigned char begin_of_bitmap[4];
	unsigned char width_data[4];
	unsigned char height_data[4];
	unsigned char pixel_bit_data[2];
	
	//secondary buffers for interpretting the header
	int bitmap_offset=0;
	int width =0;
	int image_width = 0;
	int height =0;
	int pixel_bits=0;
	
	//start reading 10 bytes after the beginning of the file
	image_file.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
	image_file.seekg(10, std::ifstream::beg);

	//read the first 4 bytes of the file which are interpretted for the header size
	image_file.read(reinterpret_cast<char*>(begin_of_bitmap),4);
	//B0*2^0 + B1*2^8 + B2*2^16 + B3*2^24
	for (int i=0; i<4; i++){
		bitmap_offset+=(int)begin_of_bitmap[i]*pow(2,i*8);
	//	std::cout<<(int)begin_of_bitmap[i]<<" ";
	}
	//std::cout<<std::endl;

	//std::cout<<bitmap_offset<<std::endl;

	//start reading 18 bytes after the beginning of the file
	image_file.seekg(18, std::ifstream::beg);
	//read 4 bytes as the width
	image_file.read(reinterpret_cast<char*>(width_data),4);
	for(int i=0; i<4; i++){
		width+=(int)width_data[i]*pow(2,i*8);
	}
	//BMP pads their formats into 4 byte sizes.
	width = (int)((3*8*width+31)/(32))*4;
	image_width = width;
	width /= 3;
	
	//read 4 bytes as the height
	image_file.read(reinterpret_cast<char*>(height_data),4);
	for(int i=0; i<4; i++){
		height+=(int)height_data[i]*pow(2,i*8);
	}

	//std::cout<<width<<" "<<height<<std::endl;

	//start reading 28 bytes after the beginning of the file
	image_file.seekg(28, std::ifstream::beg);
	
	//read 2 bytes of data as the number of bits per pixel
	image_file.read(reinterpret_cast<char*>(pixel_bit_data),2);
	for(int i=0; i<2; i++){
		pixel_bits+=(int)pixel_bit_data[i]*pow(2,i*8);
	}

	//we are restricting the program to 24-bit bitmaps
	if(pixel_bits != 24){
		std::cout<<"Image is not a 24-bit bitmap file. Please submit a properly formatted file."<<std::endl;
		return 1;
	}
	
	//holds all the of the header information
	unsigned char* image_header_data= new unsigned char[bitmap_offset];
	//holds the raw input image data BUT also the raw input image output
	unsigned char** imageData=new unsigned char*[height];
	double** image_data = new double*[height];
	char** image_data_char = new char*[height];
	//holds the image data separated into colors
	double** blue_data=new double*[height];
	double** green_data=new double*[height];
	double** red_data=new double*[height];

	//further initialize 2D arrays
	for (int i = 0; i<height; i++){
		imageData[i] = new unsigned char[image_width];
		image_data[i] = new double[image_width];
		image_data_char[i] = new char[image_width];
		blue_data[i] = new double[width];
		green_data[i] = new double[width];
		red_data[i] = new double[width];
	}	

	//read the header information(again?) into image_header_data
	image_file.seekg(0, std::ifstream::beg);
	image_file.read(reinterpret_cast<char*>(image_header_data),bitmap_offset);

	//read in the raw image data
	for (int i=0; i<height; i++){
		image_file.read(reinterpret_cast<char*>(imageData[i]),image_width);
	}

//	for (int i=0; i<height; i++){
//		std::cout<<imageData[i]<<" ";
//	}
//	std::cout<<std::endl;

/*	for (int i=0; i<10; i++){
		std::cout<<"[ ";
		for(int j = 0; j<10; j++){
			std::cout<<(int)imageData[i][j]<<" ";
		}
		std::cout<<"]"<<std::endl;
	}*/

	for(int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j++){
			image_data[i][j]=imageData[i][j];
		}
	}

	//separate imageData into the 3 colors
	for (int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j+=3){
			blue_data[i][j/3] = image_data[i][j];
		}
		for(int j = 1; j<image_width; j+=3){
			green_data[i][j/3] = image_data[i][j];
		}
		for(int j=2;j<image_width; j+=3){
			red_data[i][j/3] = image_data[i][j];
		}
	}
	
	//don't need to read the image anymore
	image_file.close();

/*
 *At this point, the image is properly loaded into several char arrays. They can be 
 numerically manipulated like normal numbers (each individual array entry)
 The arrays are:

 imageData <- all the pixels of the image.
 image_data <- all pixels in double form.
 blue_data <- all the blue pixel values.
 green_data <- all the green pixel values.
 red_data <- all the red pixel values.

 height <- original image height.
 width <- original image width.
 
 image_header_data <- the original image header
 *
 *
 *                            Subband Decomposition
 *========================================================================
 */

//	reconstruct((imageData),height,width*3,image_header_data,bitmap_offset,filename);
	
	int decomp_height = height;
	int decomp_width = width;
	int decomposition_loops = depth;
	
	//for the number of loops (hardcoded 3) decompose the arrays
	//each iteration creates the quarter-subarays for LL, LH, HL, HH
	//the quarter subarray LL is then further decomposed for another loop
	for(int i=0; i<decomposition_loops; i++){

	subband_decomp(blue_data,decomp_height,decomp_width);
	subband_decomp(green_data,decomp_height,decomp_width);
	subband_decomp(red_data,decomp_height,decomp_width);
	
	decomp_height/=2;
	decomp_width/=2;

	}

	/*for (int i = 0 ; i <height; i++){
		for(int j = 0; j<width; j++){
		std::cout<< blue_data[i][j]<<" ";
		}
		std::cout<<std::endl;
	}*/

	//read the colors back into imageData
	for (int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j+=3){
			image_data[i][j]=blue_data[i][j/3];
		}
		for(int j = 1; j<image_width; j+=3){
			image_data[i][j]=green_data[i][j/3];
		}
		for(int j=2;j<image_width; j+=3){
			image_data[i][j]=red_data[i][j/3];
		}
	}

	for (int i=0; i<height; i++){
		for(int j=0; j<image_width; j++){
			if (image_data[i][j]<0){
				image_data[i][j]=0;
			}
			if (image_data[i][j]>255){
				image_data[i][j]=255;
			}
		}
	}

	for(int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j++){
			imageData[i][j]=image_data[i][j];
		}
	}

	/*for (int i = 0 ; i <height; i++){
		for(int j = 0; j<width; j++){
		std::cout<<(int)imageData[i][j]<<" ";
		}
		std::cout<<std::endl;
	}*/
	
	reconstruct(imageData,height,image_width,image_header_data,bitmap_offset,filename+"subband");

	
	int recomp_height= height;
	int recomp_width = width;
	int num_decomps = decomposition_loops;

	prepare(blue_data,height,width,quant);
	prepare(green_data,height,width,quant);
	prepare(red_data,height,width,quant);

	/*for(int i = 0; i<height; i++){
		for(int j = 0; j<width; j++){
			std::cout<<(int)blue_data[i][j]<<" ";
		}
	}*/

	//for (int i = 0; i<20; i++){
	//	std::cout<<red_data[2][i]*20<<std::endl;
	//}

	compress(blue_data,green_data,red_data,height,width,image_header_data,bitmap_offset,filename,decomposition_loops,quant);
	
	/*for (int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j+=3){
			image_data_char[i][j]=blue_data[i][j/3];
		}
		for(int j = 1; j<image_width; j+=3){
			image_data_char[i][j]=green_data[i][j/3];
		}
		for(int j=2;j<image_width; j+=3){
			image_data_char[i][j]=red_data[i][j/3];
		}
		//for(int j=0; j<image_width; j++){
		//	std::cout<<(int)image_data_char[i][j]<<" ";
		//}
	}

	

	for (int i = num_decomps; i>=1; i--){
		recomp_height = height/pow(2,i-1);
		recomp_width = width/pow(2,i-1);
		subband_recomp(blue_data,recomp_height,recomp_width);
		subband_recomp(green_data,recomp_height,recomp_width);
		subband_recomp(red_data,recomp_height,recomp_width);
	}

	for (int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j+=3){
			image_data[i][j]=blue_data[i][j/3];
		}
		for(int j = 1; j<image_width; j+=3){
			image_data[i][j]=green_data[i][j/3];
		}
		for(int j=2;j<image_width; j+=3){
			image_data[i][j]=red_data[i][j/3];
		}
	}

	for (int i=0; i<height; i++){
		for(int j=0; j<image_width; j++){
			if (image_data[i][j]<0){
				image_data[i][j]=0;
			}
			if (image_data[i][j]>255){
				image_data[i][j]=255;
			}
		}
	}

	for(int i = 0; i<height; i++){
		for(int j = 0; j<image_width; j++){
			imageData[i][j]=image_data[i][j];
		}
	}

	
	reconstruct(imageData,height,image_width,image_header_data,bitmap_offset,"Testout2.bmp");
*/

/*
 *	So now imageData has the Subband Decomposition of the oringal image (decomposed twice).
 *	the compression portion hasn't happened yet, that involves choosing the threshold and such.
 *
 *
 *
 *
 *
 *=================================================================================
 */
	//clean up memory
	delete image_header_data;
	for(int i=0;i<height;i++)
	{
	  delete imageData[i];
	  delete blue_data[i];
	  delete green_data[i];
	  delete red_data[i];  
	}
	delete imageData;
	delete blue_data;
	delete green_data;
	delete red_data;
   return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4f0, %rsp            # imm = 0x4F0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x1, -0x8(%rbp)
jne 0x52bd
movq 0x3d42(%rip), %rdi      # 0x8fd8
leaq 0x1e55(%rip), %rsi      # 0x70f2
callq 0x2170
movq %rax, %rdi
movq 0x3d1c(%rip), %rsi      # 0x8fc8
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x6561
cmpl $0x3, -0x8(%rbp)
jl 0x5311
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x22a0
movl %eax, -0x18(%rbp)
cmpl $0x1, -0x18(%rbp)
jl 0x52e1
movl -0x18(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x530f
movq 0x3cf0(%rip), %rdi      # 0x8fd8
leaq 0x1e38(%rip), %rsi      # 0x7127
callq 0x2170
movq %rax, %rdi
movq 0x3cca(%rip), %rsi      # 0x8fc8
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x6561
jmp 0x5318
movl $0x14, -0x14(%rbp)
cmpl $0x4, -0x8(%rbp)
jl 0x536c
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x22a0
movl %eax, -0x20(%rbp)
cmpl $0x1, -0x20(%rbp)
jl 0x533c
movl -0x20(%rbp), %eax
movl %eax, -0x1c(%rbp)
jmp 0x536a
movq 0x3c95(%rip), %rdi      # 0x8fd8
leaq 0x1e1b(%rip), %rsi      # 0x7165
callq 0x2170
movq %rax, %rdi
movq 0x3c6f(%rip), %rsi      # 0x8fc8
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x6561
jmp 0x5373
movl $0x1, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x388(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x2300
movq -0x388(%rbp), %rsi
movq -0x380(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0x67a0
jmp 0x53ab
leaq -0x41(%rbp), %rdi
callq 0x21c0
leaq -0x260(%rbp), %rdi
callq 0x21f0
jmp 0x53c2
movl $0x0, -0x274(%rbp)
movl $0x0, -0x278(%rbp)
movl $0x0, -0x27c(%rbp)
movl $0x0, -0x280(%rbp)
movl $0x0, -0x284(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x20a0
movq %rax, -0x398(%rbp)
movl $0x8, %edi
movl $0x4, %esi
callq 0x6780
movl %eax, -0x38c(%rbp)
jmp 0x541b
movl -0x38c(%rbp), %edx
movq -0x398(%rbp), %rsi
leaq -0x260(%rbp), %rdi
callq 0x20f0
jmp 0x5436
leaq -0x260(%rbp), %rdi
movl $0xa, %esi
xorl %edx, %edx
callq 0x2240
jmp 0x544b
leaq -0x260(%rbp), %rdi
leaq -0x264(%rbp), %rsi
movl $0x4, %edx
callq 0x2220
jmp 0x5465
movl $0x0, -0x288(%rbp)
cmpl $0x4, -0x288(%rbp)
jge 0x5523
movslq -0x288(%rbp), %rax
movzbl -0x264(%rbp,%rax), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x3a0(%rbp)
movl -0x288(%rbp), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm1
movsd 0x1bf4(%rip), %xmm0     # 0x70a0
callq 0x22e0
movaps %xmm0, %xmm2
movsd -0x3a0(%rbp), %xmm0
cvtsi2sdl -0x274(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x274(%rbp)
movl -0x288(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x288(%rbp)
jmp 0x546f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x41(%rbp), %rdi
callq 0x21c0
jmp 0x656d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6556
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x654a
leaq -0x260(%rbp), %rdi
movl $0x12, %esi
xorl %edx, %edx
callq 0x2240
jmp 0x5538
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rsi
movl $0x4, %edx
callq 0x2220
jmp 0x5552
movl $0x0, -0x28c(%rbp)
cmpl $0x4, -0x28c(%rbp)
jge 0x55d0
movslq -0x28c(%rbp), %rax
movzbl -0x268(%rbp,%rax), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x3a8(%rbp)
movl -0x28c(%rbp), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm1
movsd 0x1b0b(%rip), %xmm0     # 0x70a0
callq 0x22e0
movaps %xmm0, %xmm2
movsd -0x3a8(%rbp), %xmm0
cvtsi2sdl -0x278(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x278(%rbp)
movl -0x28c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28c(%rbp)
jmp 0x555c
movl -0x278(%rbp), %eax
shll $0x3, %eax
movl %eax, %ecx
leal 0x1f(%rcx,%rcx,2), %eax
leal 0x3e(%rcx,%rcx,2), %ecx
testl %eax, %eax
cmovsl %ecx, %eax
sarl $0x5, %eax
shll $0x2, %eax
movl %eax, -0x278(%rbp)
movl -0x278(%rbp), %eax
movl %eax, -0x27c(%rbp)
movslq -0x278(%rbp), %rax
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
movl %eax, -0x278(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x26c(%rbp), %rsi
movl $0x4, %edx
callq 0x2220
jmp 0x563b
movl $0x0, -0x290(%rbp)
cmpl $0x4, -0x290(%rbp)
jge 0x56b9
movslq -0x290(%rbp), %rax
movzbl -0x26c(%rbp,%rax), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x3b0(%rbp)
movl -0x290(%rbp), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm1
movsd 0x1a22(%rip), %xmm0     # 0x70a0
callq 0x22e0
movaps %xmm0, %xmm2
movsd -0x3b0(%rbp), %xmm0
cvtsi2sdl -0x280(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x280(%rbp)
movl -0x290(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x290(%rbp)
jmp 0x5645
leaq -0x260(%rbp), %rdi
movl $0x1c, %esi
xorl %edx, %edx
callq 0x2240
jmp 0x56ce
leaq -0x260(%rbp), %rdi
leaq -0x26e(%rbp), %rsi
movl $0x2, %edx
callq 0x2220
jmp 0x56e8
movl $0x0, -0x294(%rbp)
cmpl $0x2, -0x294(%rbp)
jge 0x5766
movslq -0x294(%rbp), %rax
movzbl -0x26e(%rbp,%rax), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x3b8(%rbp)
movl -0x294(%rbp), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm1
movsd 0x1975(%rip), %xmm0     # 0x70a0
callq 0x22e0
movaps %xmm0, %xmm2
movsd -0x3b8(%rbp), %xmm0
cvtsi2sdl -0x284(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x284(%rbp)
movl -0x294(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x294(%rbp)
jmp 0x56f2
cmpl $0x18, -0x284(%rbp)
je 0x57b6
movq 0x3862(%rip), %rdi      # 0x8fd8
leaq 0x1a1f(%rip), %rsi      # 0x719c
callq 0x2170
movq %rax, -0x3c0(%rbp)
jmp 0x578b
movq -0x3c0(%rbp), %rdi
movq 0x382f(%rip), %rsi      # 0x8fc8
callq 0x21a0
jmp 0x57a0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x298(%rbp)
jmp 0x6533
movslq -0x274(%rbp), %rdi
callq 0x2030
movq %rax, -0x3c8(%rbp)
jmp 0x57cb
movq -0x3c8(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3d0(%rbp)
jmp 0x5804
movq -0x3d0(%rbp), %rax
movq %rax, -0x2a8(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3d8(%rbp)
jmp 0x583d
movq -0x3d8(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3e0(%rbp)
jmp 0x5876
movq -0x3e0(%rbp), %rax
movq %rax, -0x2b8(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3e8(%rbp)
jmp 0x58af
movq -0x3e8(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3f0(%rbp)
jmp 0x58e8
movq -0x3f0(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movslq -0x280(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x3f8(%rbp)
jmp 0x5921
movq -0x3f8(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movl $0x0, -0x2d4(%rbp)
movl -0x2d4(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x5acb
movslq -0x27c(%rbp), %rdi
callq 0x2030
movq %rax, -0x400(%rbp)
jmp 0x5960
movq -0x400(%rbp), %rdx
movq -0x2a8(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq -0x27c(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x408(%rbp)
jmp 0x59a4
movq -0x408(%rbp), %rdx
movq -0x2b0(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq -0x27c(%rbp), %rdi
callq 0x2030
movq %rax, -0x410(%rbp)
jmp 0x59d2
movq -0x410(%rbp), %rdx
movq -0x2b8(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq -0x278(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x418(%rbp)
jmp 0x5a16
movq -0x418(%rbp), %rdx
movq -0x2c0(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq -0x278(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x420(%rbp)
jmp 0x5a5a
movq -0x420(%rbp), %rdx
movq -0x2c8(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movslq -0x278(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x428(%rbp)
jmp 0x5a9e
movq -0x428(%rbp), %rdx
movq -0x2d0(%rbp), %rax
movslq -0x2d4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x2d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2d4(%rbp)
jmp 0x5939
xorl %edx, %edx
movl %edx, %esi
leaq -0x260(%rbp), %rdi
callq 0x2240
jmp 0x5add
movq -0x2a0(%rbp), %rsi
movslq -0x274(%rbp), %rdx
leaq -0x260(%rbp), %rdi
callq 0x2220
jmp 0x5af9
movl $0x0, -0x2d8(%rbp)
movl -0x2d8(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x5b4b
movq -0x2a8(%rbp), %rax
movslq -0x2d8(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movslq -0x27c(%rbp), %rdx
leaq -0x260(%rbp), %rdi
callq 0x2220
jmp 0x5b38
jmp 0x5b3a
movl -0x2d8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2d8(%rbp)
jmp 0x5b03
movl $0x0, -0x2dc(%rbp)
movl -0x2dc(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x5be1
movl $0x0, -0x2e0(%rbp)
movl -0x2e0(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5bcb
movq -0x2a8(%rbp), %rax
movslq -0x2dc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2e0(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cvtsi2sd %eax, %xmm0
movq -0x2b0(%rbp), %rax
movslq -0x2dc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2e0(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x2e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2e0(%rbp)
jmp 0x5b6d
jmp 0x5bcd
movl -0x2dc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2dc(%rbp)
jmp 0x5b55
movl $0x0, -0x2e4(%rbp)
movl -0x2e4(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x5d90
movl $0x0, -0x2e8(%rbp)
movl -0x2e8(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5c7c
movq -0x2b0(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2e8(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2c0(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x430(%rbp)
movl -0x2e8(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x430(%rbp), %rax
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x2e8(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x2e8(%rbp)
jmp 0x5c07
movl $0x1, -0x2ec(%rbp)
movl -0x2ec(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5cfb
movq -0x2b0(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2ec(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2c8(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x438(%rbp)
movl -0x2ec(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x438(%rbp), %rax
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x2ec(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x2ec(%rbp)
jmp 0x5c86
movl $0x2, -0x2f0(%rbp)
movl -0x2f0(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5d7a
movq -0x2b0(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2f0(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2d0(%rbp), %rax
movslq -0x2e4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x440(%rbp)
movl -0x2f0(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x440(%rbp), %rax
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x2f0(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x2f0(%rbp)
jmp 0x5d05
jmp 0x5d7c
movl -0x2e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2e4(%rbp)
jmp 0x5beb
leaq -0x260(%rbp), %rdi
callq 0x2060
jmp 0x5d9e
movl -0x280(%rbp), %eax
movl %eax, -0x2f4(%rbp)
movl -0x278(%rbp), %eax
movl %eax, -0x2f8(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x2fc(%rbp)
movl $0x0, -0x300(%rbp)
movl -0x300(%rbp), %eax
cmpl -0x2fc(%rbp), %eax
jge 0x5e65
movl -0x2f4(%rbp), %esi
movl -0x2f8(%rbp), %edx
leaq -0x2c0(%rbp), %rdi
callq 0x3640
jmp 0x5df5
movl -0x2f4(%rbp), %esi
movl -0x2f8(%rbp), %edx
leaq -0x2c8(%rbp), %rdi
callq 0x3640
jmp 0x5e0f
movl -0x2f4(%rbp), %esi
movl -0x2f8(%rbp), %edx
leaq -0x2d0(%rbp), %rdi
callq 0x3640
jmp 0x5e29
movl -0x2f4(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x2f4(%rbp)
movl -0x2f8(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x2f8(%rbp)
movl -0x300(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x300(%rbp)
jmp 0x5dc9
movl $0x0, -0x304(%rbp)
movl -0x304(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x6014
movl $0x0, -0x308(%rbp)
movl -0x308(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5f00
movq -0x2c0(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x448(%rbp)
movl -0x308(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x448(%rbp), %rax
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2b0(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x308(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x308(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x308(%rbp)
jmp 0x5e8b
movl $0x1, -0x30c(%rbp)
movl -0x30c(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5f7f
movq -0x2c8(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x450(%rbp)
movl -0x30c(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x450(%rbp), %rax
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2b0(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x30c(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x30c(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x30c(%rbp)
jmp 0x5f0a
movl $0x2, -0x310(%rbp)
movl -0x310(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x5ffe
movq -0x2d0(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x458(%rbp)
movl -0x310(%rbp), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x458(%rbp), %rax
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x2b0(%rbp), %rax
movslq -0x304(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x310(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x310(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x310(%rbp)
jmp 0x5f89
jmp 0x6000
movl -0x304(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x304(%rbp)
jmp 0x5e6f
movl $0x0, -0x314(%rbp)
movl -0x314(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x610e
movl $0x0, -0x318(%rbp)
movl -0x318(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x60f8
movq -0x2b0(%rbp), %rax
movslq -0x314(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x318(%rbp), %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x6090
movq -0x2b0(%rbp), %rax
movslq -0x314(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x318(%rbp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movq -0x2b0(%rbp), %rax
movslq -0x314(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x318(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd 0xfe2(%rip), %xmm1      # 0x7098
ucomisd %xmm1, %xmm0
jbe 0x60e2
movq -0x2b0(%rbp), %rax
movslq -0x314(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x318(%rbp), %rcx
movsd 0xfbb(%rip), %xmm0      # 0x7098
movsd %xmm0, (%rax,%rcx,8)
jmp 0x60e4
movl -0x318(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x318(%rbp)
jmp 0x603a
jmp 0x60fa
movl -0x314(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x314(%rbp)
jmp 0x601e
movl $0x0, -0x31c(%rbp)
movl -0x31c(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x61a1
movl $0x0, -0x320(%rbp)
movl -0x320(%rbp), %eax
cmpl -0x27c(%rbp), %eax
jge 0x618b
movq -0x2b0(%rbp), %rax
movslq -0x31c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x320(%rbp), %rcx
cvttsd2si (%rax,%rcx,8), %eax
movb %al, %dl
movq -0x2a8(%rbp), %rax
movslq -0x31c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x320(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0x320(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x320(%rbp)
jmp 0x6130
jmp 0x618d
movl -0x31c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x31c(%rbp)
jmp 0x6118
movq -0x2a8(%rbp), %rax
movq %rax, -0x478(%rbp)
movl -0x280(%rbp), %eax
movl %eax, -0x470(%rbp)
movl -0x27c(%rbp), %eax
movl %eax, -0x46c(%rbp)
movq -0x2a0(%rbp), %rax
movq %rax, -0x468(%rbp)
movl -0x274(%rbp), %eax
movl %eax, -0x45c(%rbp)
leaq 0x1000(%rip), %rdx      # 0x71e8
leaq -0x340(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x6850
jmp 0x61fa
movl -0x45c(%rbp), %r8d
movq -0x468(%rbp), %rcx
movl -0x46c(%rbp), %edx
movl -0x470(%rbp), %esi
movq -0x478(%rbp), %rdi
leaq -0x340(%rbp), %r9
callq 0x4910
jmp 0x6229
leaq -0x340(%rbp), %rdi
callq 0x20e0
movl -0x280(%rbp), %eax
movl %eax, -0x344(%rbp)
movl -0x278(%rbp), %eax
movl %eax, -0x348(%rbp)
movl -0x2fc(%rbp), %eax
movl %eax, -0x34c(%rbp)
movl -0x280(%rbp), %esi
movl -0x278(%rbp), %edx
movl -0x14(%rbp), %ecx
leaq -0x2c0(%rbp), %rdi
callq 0x46e0
jmp 0x6276
movl -0x280(%rbp), %esi
movl -0x278(%rbp), %edx
movl -0x14(%rbp), %ecx
leaq -0x2c8(%rbp), %rdi
callq 0x46e0
jmp 0x6293
movl -0x280(%rbp), %esi
movl -0x278(%rbp), %edx
movl -0x14(%rbp), %ecx
leaq -0x2d0(%rbp), %rdi
callq 0x46e0
jmp 0x62b0
movl -0x280(%rbp), %eax
movl %eax, -0x480(%rbp)
movl -0x278(%rbp), %eax
movl %eax, -0x47c(%rbp)
leaq -0x370(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x20b0
jmp 0x62da
movl -0x47c(%rbp), %r8d
movl -0x480(%rbp), %ecx
movl -0x2fc(%rbp), %edx
movl -0x14(%rbp), %esi
movq %rsp, %rax
movl %esi, 0x18(%rax)
movl %edx, 0x10(%rax)
leaq -0x370(%rbp), %rdx
movq %rdx, 0x8(%rax)
leaq -0x274(%rbp), %rdx
movq %rdx, (%rax)
leaq -0x2c0(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
leaq -0x2d0(%rbp), %rdx
leaq -0x2a0(%rbp), %r9
callq 0x4a60
jmp 0x6331
leaq -0x370(%rbp), %rdi
callq 0x20e0
movq -0x2a0(%rbp), %rax
movq %rax, -0x488(%rbp)
cmpq $0x0, %rax
je 0x6362
movq -0x488(%rbp), %rdi
movl $0x1, %esi
callq 0x2190
movl $0x0, -0x374(%rbp)
movl -0x374(%rbp), %eax
cmpl -0x280(%rbp), %eax
jge 0x648e
movq -0x2a8(%rbp), %rax
movslq -0x374(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x490(%rbp)
cmpq $0x0, %rax
je 0x63ae
movq -0x490(%rbp), %rdi
movl $0x1, %esi
callq 0x2190
movq -0x2c0(%rbp), %rax
movslq -0x374(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x498(%rbp)
cmpq $0x0, %rax
je 0x63de
movq -0x498(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movq -0x2c8(%rbp), %rax
movslq -0x374(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x4a0(%rbp)
cmpq $0x0, %rax
je 0x640e
movq -0x4a0(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movq -0x2d0(%rbp), %rax
movslq -0x374(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x4a8(%rbp)
cmpq $0x0, %rax
je 0x643e
movq -0x4a8(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
jmp 0x6440
movl -0x374(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x374(%rbp)
jmp 0x636c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x340(%rbp), %rdi
callq 0x20e0
jmp 0x654a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x20e0
jmp 0x654a
movq -0x2a8(%rbp), %rax
movq %rax, -0x4b0(%rbp)
cmpq $0x0, %rax
je 0x64b3
movq -0x4b0(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movq -0x2c0(%rbp), %rax
movq %rax, -0x4b8(%rbp)
cmpq $0x0, %rax
je 0x64d8
movq -0x4b8(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movq -0x2c8(%rbp), %rax
movq %rax, -0x4c0(%rbp)
cmpq $0x0, %rax
je 0x64fd
movq -0x4c0(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movq -0x2d0(%rbp), %rax
movq %rax, -0x4c8(%rbp)
cmpq $0x0, %rax
je 0x6522
movq -0x4c8(%rbp), %rdi
movl $0x8, %esi
callq 0x2190
movl $0x0, -0x4(%rbp)
movl $0x1, -0x298(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x2070
leaq -0x40(%rbp), %rdi
callq 0x20e0
jmp 0x6561
leaq -0x260(%rbp), %rdi
callq 0x2070
leaq -0x40(%rbp), %rdi
callq 0x20e0
jmp 0x656d
movl -0x4(%rbp), %eax
addq $0x4f0, %rsp            # imm = 0x4F0
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x22f0
nopw %cs:(%rax,%rax)