// File: /workspace/github_cpp_makefile_star2_O1/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 %r12
pushq %rbx
subq $0x210, %rsp            # imm = 0x210
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x40(%rdi), %r15
movq 0x48(%rdi), %r12
movq %rsi, %rdi
callq 0x20e0
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rdx
movq %r14, %rcx
movq %rax, %r8
callq 0x2300
leaq 0x8(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movl $0x4, %edx
callq 0x23c0
movq (%r15), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x28(%rsp,%rax)
jne 0x6128
leaq 0x8(%rsp), %rdi
movl $0xe, %edx
movq %rbx, %rsi
callq 0x2280
cmpw $0x4d42, (%rbx)         # imm = 0x4D42
jne 0x6170
leaq 0xe(%rbx), %rsi
leaq 0x8(%rsp), %rdi
movl $0x28, %edx
callq 0x2280
movl 0x16(%rbx), %eax
testl %eax, %eax
jns 0x5ffd
negl %eax
movl %eax, 0x16(%rbx)
movb $0x1, 0x64(%rbx)
movl 0xa(%rbx), %esi
leaq 0x8(%rsp), %rdi
xorl %edx, %edx
callq 0x22b0
movabsq $0x2800000036, %rax     # imm = 0x2800000036
movq %rax, 0xa(%rbx)
movslq 0x12(%rbx), %r14
movslq 0x16(%rbx), %r15
imulq %r14, %r15
movq %r15, %rax
shlq $0x2, %rax
testl %r15d, %r15d
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0x2030
movq %rax, 0x38(%rbx)
movzwl 0x1c(%rbx), %ecx
testb $0x18, %cl
sete %dl
testb $0x3, %r14b
sete %sil
orb %dl, %sil
je 0x607c
imull %r15d, %ecx
leal 0x7(%rcx), %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
sarl $0x3, %edx
movslq %edx, %rdx
leaq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0x2280
jmp 0x60ee
imull %ecx, %r14d
leal 0x7(%r14), %eax
testl %r14d, %r14d
cmovnsl %r14d, %eax
sarl $0x3, %eax
leal 0x3(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
andl $-0x4, %ecx
subl %eax, %ecx
addl $0x4, %ecx
movl %ecx, 0x60(%rbx)
cmpl $0x0, 0x16(%rbx)
jle 0x60ee
xorl %ebp, %ebp
leaq 0x8(%rsp), %r14
movl 0x12(%rbx), %eax
movzwl 0x1c(%rbx), %ecx
imull %eax, %ecx
imull %ebp, %eax
movslq %eax, %rsi
shlq $0x2, %rsi
addq 0x38(%rbx), %rsi
leal 0x7(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
sarl $0x3, %eax
movslq %eax, %rdx
movq %r14, %rdi
callq 0x2280
movl 0x60(%rbx), %esi
movq %r14, %rdi
callq 0x2050
incl %ebp
cmpl 0x16(%rbx), %ebp
jl 0x60ae
movzwl 0x1c(%rbx), %eax
imull 0x12(%rbx), %eax
leal 0x7(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x3, %ecx
addl 0x60(%rbx), %ecx
imull 0x16(%rbx), %ecx
addl $0x36, %ecx
movl %ecx, 0x2(%rbx)
leaq 0x8(%rsp), %rdi
callq 0x2070
addq $0x210, %rsp            # imm = 0x210
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x3eb9(%rip), %rdi      # 0x9fe8
leaq 0x146a(%rip), %rsi      # 0x75a0
movl $0x15, %edx
callq 0x2250
movq 0x3ea1(%rip), %rdi      # 0x9fe8
movq %r14, %rsi
callq 0x2200
movq %rax, %rbx
leaq 0x133e(%rip), %rsi      # 0x7497
movl $0x1, %edx
movq %rax, %rdi
callq 0x2250
movq %rbx, %rdi
callq 0x2100
jmp 0x61b6
movq 0x3e71(%rip), %rdi      # 0x9fe8
leaq 0x1438(%rip), %rsi      # 0x75b6
movl $0x6, %edx
callq 0x2250
movq 0x3e59(%rip), %rdi      # 0x9fe8
movq %r14, %rsi
callq 0x2200
movq %rax, %rbx
leaq 0x141c(%rip), %rsi      # 0x75bd
movl $0x13, %edx
movq %rax, %rdi
callq 0x2250
movq %rbx, %rdi
callq 0x2100
movl $0x1, %edi
callq 0x2270
jmp 0x61c2
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x23a0
nop