// File: iibrahimli[P]adsa_project/src/../include/bmp.hpp
// Function: BMP_image::read(char const*)
void read(const char *filename){

        filenm = filename;

        std::ifstream in(filename, std::ios::binary);

        if(!in){
            // error opening file
            std::cerr << "Unable to read file \'" << filename << "\'" << std::endl;
            exit(EXIT_FAILURE);
        }

        // read file header
        in.read((char*) &file_h, sizeof file_h);

        // if first 2 bytes don't match BM
        if(file_h.file_type != 0x4D42){
            std::cerr << "File \'" << filename << "\' is not a BMP file" << std::endl;
            exit(EXIT_FAILURE);
        }

        // read DIB header
        in.read((char*) &info_h, sizeof info_h);

        // image is stored top to bottom
        if(info_h.height < 0){
            info_h.height = abs(info_h.height);
            neg_height = true;
        }

        // seek to pixels
        in.seekg(file_h.pxl_offset, in.beg);

        // adjust the header fields for output, only save the headers and the data.
        if(info_h.bit_count == 32) {
            info_h.size = sizeof(BMP_info_header);
            file_h.pxl_offset = sizeof(BMP_file_header) + sizeof(BMP_info_header);
        } else {
            info_h.size = sizeof(BMP_info_header);
            file_h.pxl_offset = sizeof(BMP_file_header) + sizeof(BMP_info_header);
        }

        // initialize data array
        data = new pixel[info_h.width * info_h.height];

        // if bytes per pixel is not divisible by 4
        if(info_h.bit_count/8 % 4 != 0){

            // check whether we need padding
            if(info_h.width % 4 == 0){

                // width is divisible by 4 = no padding needed
                in.read((char*) data, info_h.width * info_h.height * info_h.bit_count/8);

            }
            else{
                padding = 4 - ((info_h.width * info_h.bit_count/8) % 4);

                for(int r=0; r<info_h.height; ++r){
                    // read a row
                    in.read((char*) &data[r * info_h.width], info_h.width * info_h.bit_count/8);

                    // discard padding
                    in.ignore(padding);
                }
            }

        }
        else{
            in.read((char*) data, info_h.width * info_h.height * info_h.bit_count/8);
        }

        // file size is size of headers + pixel data with padding bytes
        file_h.file_size = sizeof file_h + sizeof info_h + info_h.height * (info_h.width * info_h.bit_count/8 + padding);

    }

// Assembly:
subq $0x278, %rsp            # imm = 0x278
movq %rdi, 0x270(%rsp)
movq %rsi, 0x268(%rsp)
movq 0x270(%rsp), %rdi
movq %rdi, 0x40(%rsp)
movq 0x268(%rsp), %rsi
addq $0x40, %rdi
callq 0x3370
movq 0x268(%rsp), %rsi
leaq 0x60(%rsp), %rdi
movl $0x4, %edx
callq 0x3490
movq 0x60(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x60(%rsp,%rax), %rdi
callq 0x3130
movb %al, 0x4f(%rsp)
jmp 0x9775
movb 0x4f(%rsp), %al
testb $0x1, %al
jne 0x9782
jmp 0x9807
movq 0xa85f(%rip), %rdi      # 0x13fe8
leaq 0x4e10(%rip), %rsi      # 0xe5a0
callq 0x3250
movq %rax, 0x38(%rsp)
jmp 0x979c
movq 0x38(%rsp), %rdi
movq 0x268(%rsp), %rsi
callq 0x3250
movq %rax, 0x30(%rsp)
jmp 0x97b5
movq 0x30(%rsp), %rdi
leaq 0x4cd6(%rip), %rsi      # 0xe497
callq 0x3250
movq %rax, 0x28(%rsp)
jmp 0x97cd
movq 0x28(%rsp), %rdi
movq 0xa7cf(%rip), %rsi      # 0x13fa8
callq 0x3280
jmp 0x97e0
movl $0x1, %edi
callq 0x3300
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x58(%rsp)
movl %eax, 0x54(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x30c0
jmp 0x9aec
movq 0x40(%rsp), %rsi
leaq 0x60(%rsp), %rdi
movl $0xe, %edx
callq 0x3320
jmp 0x981d
movq 0x40(%rsp), %rax
movzwl (%rax), %eax
cmpl $0x4d42, %eax           # imm = 0x4D42
je 0x9894
movq 0xa7b5(%rip), %rdi      # 0x13fe8
leaq 0x4d7c(%rip), %rsi      # 0xe5b6
callq 0x3250
movq %rax, 0x20(%rsp)
jmp 0x9846
movq 0x20(%rsp), %rdi
movq 0x268(%rsp), %rsi
callq 0x3250
movq %rax, 0x18(%rsp)
jmp 0x985f
movq 0x18(%rsp), %rdi
leaq 0x4d52(%rip), %rsi      # 0xe5bd
callq 0x3250
movq %rax, 0x10(%rsp)
jmp 0x9877
movq 0x10(%rsp), %rdi
movq 0xa725(%rip), %rsi      # 0x13fa8
callq 0x3280
jmp 0x988a
movl $0x1, %edi
callq 0x3300
movq 0x40(%rsp), %rsi
addq $0xe, %rsi
leaq 0x60(%rsp), %rdi
movl $0x28, %edx
callq 0x3320
jmp 0x98ae
movq 0x40(%rsp), %rax
cmpl $0x0, 0x16(%rax)
jge 0x98cf
movq 0x40(%rsp), %rax
movl 0x16(%rax), %ecx
movl %ecx, %edx
negl %edx
cmovnsl %edx, %ecx
movl %ecx, 0x16(%rax)
movb $0x1, 0x64(%rax)
movq 0x40(%rsp), %rax
movl 0xa(%rax), %eax
movl %eax, %esi
leaq 0x60(%rsp), %rdi
xorl %edx, %edx
callq 0x3360
jmp 0x98e7
movq 0x40(%rsp), %rax
movzwl 0x1c(%rax), %eax
cmpl $0x20, %eax
jne 0x990a
movq 0x40(%rsp), %rax
movl $0x28, 0xe(%rax)
movl $0x36, 0xa(%rax)
jmp 0x991d
movq 0x40(%rsp), %rax
movl $0x28, 0xe(%rax)
movl $0x36, 0xa(%rax)
movq 0x40(%rsp), %rcx
movl 0x12(%rcx), %eax
movl 0x16(%rcx), %ecx
imull %ecx, %eax
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x8(%rsp)
jmp 0x994f
movq 0x40(%rsp), %rax
movq 0x8(%rsp), %rcx
movq %rcx, 0x38(%rax)
movzwl 0x1c(%rax), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
je 0x9a73
movq 0x40(%rsp), %rax
movl 0x12(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x99c9
movq 0x40(%rsp), %rcx
movq 0x38(%rcx), %rsi
movl 0x12(%rcx), %eax
movl 0x16(%rcx), %edx
imull %edx, %eax
movzwl 0x1c(%rcx), %ecx
imull %ecx, %eax
movl %eax, %ecx
addl $0x7, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
sarl $0x3, %eax
movslq %eax, %rdx
leaq 0x60(%rsp), %rdi
callq 0x3320
jmp 0x99c4
jmp 0x9a71
movq 0x40(%rsp), %rcx
movl 0x12(%rcx), %eax
movzwl 0x1c(%rcx), %ecx
imull %ecx, %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl $0x4, %ecx
cltd
idivl %ecx
movq 0x40(%rsp), %rax
movl $0x4, %ecx
subl %edx, %ecx
movl %ecx, 0x60(%rax)
movl $0x0, 0x50(%rsp)
movq 0x40(%rsp), %rcx
movl 0x50(%rsp), %eax
cmpl 0x16(%rcx), %eax
jge 0x9a6f
movq 0x40(%rsp), %rcx
movq 0x38(%rcx), %rdx
movl 0x50(%rsp), %esi
movl 0x12(%rcx), %eax
imull %eax, %esi
movslq %esi, %rsi
leaq (%rdx,%rsi,4), %rsi
movzwl 0x1c(%rcx), %ecx
imull %ecx, %eax
movl %eax, %ecx
addl $0x7, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
sarl $0x3, %eax
movslq %eax, %rdx
leaq 0x60(%rsp), %rdi
callq 0x3320
jmp 0x9a4a
movq 0x40(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, %esi
leaq 0x60(%rsp), %rdi
callq 0x3050
jmp 0x9a60
jmp 0x9a62
movl 0x50(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x50(%rsp)
jmp 0x99ff
jmp 0x9a71
jmp 0x9aaa
movq 0x40(%rsp), %rcx
movq 0x38(%rcx), %rsi
movl 0x12(%rcx), %eax
movl 0x16(%rcx), %edx
imull %edx, %eax
movzwl 0x1c(%rcx), %ecx
imull %ecx, %eax
movl %eax, %ecx
addl $0x7, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
sarl $0x3, %eax
movslq %eax, %rdx
leaq 0x60(%rsp), %rdi
callq 0x3320
jmp 0x9aa8
jmp 0x9aaa
movq 0x40(%rsp), %rdx
movl 0x16(%rdx), %ecx
movl 0x12(%rdx), %eax
movzwl 0x1c(%rdx), %edx
imull %edx, %eax
movl $0x8, %esi
cltd
idivl %esi
movl %eax, %edx
movq 0x40(%rsp), %rax
addl 0x60(%rax), %edx
imull %edx, %ecx
movl %ecx, %ecx
addq $0x36, %rcx
movl %ecx, 0x2(%rax)
leaq 0x60(%rsp), %rdi
callq 0x30c0
addq $0x278, %rsp            # imm = 0x278
retq
movq 0x58(%rsp), %rdi
callq 0x3460
nopw %cs:(%rax,%rax)