// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x208, %rsp            # imm = 0x208
movq %rsi, %r14
movq %rdi, %rbx
addq $0x40, %rdi
callq 0x23c0
movq %rsp, %r15
pushq $0x4
popq %rbp
movq %r15, %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x23a0
movq (%r15), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x20(%rsp,%rax)
jne 0x519d
movq %rsp, %rdi
pushq $0xe
popq %rdx
movq %rbx, %rsi
callq 0x2240
cmpw $0x4d42, (%rbx)         # imm = 0x4D42
jne 0x51d4
leaq 0xe(%rbx), %rsi
movq %rsp, %rdi
pushq $0x28
popq %rdx
callq 0x2240
movl 0x16(%rbx), %eax
testl %eax, %eax
jns 0x509b
negl %eax
movl %eax, 0x16(%rbx)
movb $0x1, 0x64(%rbx)
movl 0xa(%rbx), %esi
movq %rsp, %rdi
xorl %edx, %edx
callq 0x2280
movabsq $0x2800000036, %rax     # imm = 0x2800000036
movq %rax, 0xa(%rbx)
movl 0x12(%rbx), %r14d
movl 0x16(%rbx), %r13d
movl %r13d, %r15d
imull %r14d, %r15d
movslq %r15d, %rax
leaq (,%rax,4), %rcx
testl %eax, %eax
pushq $-0x1
popq %rdi
cmovnsq %rcx, %rdi
callq 0x2030
movq %rax, %rsi
movq %rax, 0x38(%rbx)
movzwl 0x1c(%rbx), %eax
testb $0x18, %al
sete %cl
testb $0x3, %r14b
sete %dl
orb %cl, %dl
pushq $0x8
popq %r12
je 0x5146
imull %eax, %r15d
movl %r15d, %eax
cltd
idivl %r12d
movslq %eax, %rdx
movq %rsp, %rdi
callq 0x2240
movzwl 0x1c(%rbx), %eax
imull 0x12(%rbx), %eax
cltd
idivl %r12d
addl 0x60(%rbx), %eax
imull 0x16(%rbx), %eax
addl $0x36, %eax
movl %eax, 0x2(%rbx)
movq %rsp, %rdi
callq 0x2070
addq $0x208, %rsp            # imm = 0x208
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
imull %eax, %r14d
movl %r14d, %eax
cltd
idivl %r12d
cltd
idivl %ebp
subl %edx, %ebp
movl %ebp, 0x60(%rbx)
xorl %ebp, %ebp
movq %rsp, %r14
cmpl %r13d, %ebp
jge 0x5113
movl 0x12(%rbx), %ecx
movzwl 0x1c(%rbx), %eax
imull %ecx, %eax
imull %ebp, %ecx
movslq %ecx, %rsi
shlq $0x2, %rsi
addq 0x38(%rbx), %rsi
cltd
idivl %r12d
movslq %eax, %rdx
movq %r14, %rdi
callq 0x2240
movl 0x60(%rbx), %esi
movq %r14, %rdi
callq 0x2040
incl %ebp
movl 0x16(%rbx), %r13d
jmp 0x515e
movq 0x4e44(%rip), %rdi      # 0x9fe8
leaq 0x13f5(%rip), %rsi      # 0x65a0
callq 0x21e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x21e0
leaq 0x12d5(%rip), %rsi      # 0x6497
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x2100
jmp 0x5209
movq 0x4e0d(%rip), %rdi      # 0x9fe8
leaq 0x13d4(%rip), %rsi      # 0x65b6
callq 0x21e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x21e0
leaq 0x13c4(%rip), %rsi      # 0x65bd
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x2100
pushq $0x1
popq %rdi
callq 0x2230
jmp 0x5213
movq %rax, %rbx
movq %rsp, %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x2380