// File: btbujiangjun[P]abcdl/include/utils/MnistHelper.h
// Function: abcdl::utils::MnistHelper<float>::read_image(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, abcdl::algebra::Matrix<float>*, int, unsigned long)
bool MnistHelper<T>::read_image(const std::string& image_file,
                                abcdl::algebra::Matrix<T>* out_mat,
                                const int limit,
                                const size_t threshold){

    size_t count = 0;
    auto image_buffer = read_mnist_file(image_file, 0x803, &count);

    if(!image_buffer || count == 0){
        return false;
    }

    if( limit > 0 && limit < (int)count){
        count = limit;
    }

    //read image data
    auto rows = read_header(image_buffer, 2);
    auto cols = read_header(image_buffer, 3);

    auto image_data_buffer = reinterpret_cast<unsigned char*>(image_buffer.get() + 16);

    size_t size = count * rows * cols;
    T* data = new T[size];
    for(size_t i = 0; i < size; i++){
        if(threshold > 0){
            data[i] = static_cast<T>(*image_data_buffer++) > threshold ? 1 : 0;
        }else{
            data[i] = static_cast<T>(*image_data_buffer++) / 255;
        }
    }

    out_mat->set_shallow_data(data, count, rows * cols);

    return true;
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0x98(%rsp)
movq %rsi, 0x90(%rsp)
movq %rdx, 0x88(%rsp)
movl %ecx, 0x84(%rsp)
movq %r8, 0x78(%rsp)
movq 0x98(%rsp), %rsi
movq %rsi, 0x20(%rsp)
movq $0x0, 0x70(%rsp)
movq 0x90(%rsp), %rdx
leaq 0x68(%rsp), %rdi
movl $0x803, %ecx            # imm = 0x803
leaq 0x70(%rsp), %r8
callq 0x18db0
leaq 0x68(%rsp), %rdi
callq 0x192c0
testb $0x1, %al
jne 0x26b4d
jmp 0x26b55
cmpq $0x0, 0x70(%rsp)
jne 0x26b6a
movb $0x0, 0xa7(%rsp)
movl $0x1, 0x64(%rsp)
jmp 0x26d6f
cmpl $0x0, 0x84(%rsp)
jle 0x26b91
movl 0x84(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl %ecx, %eax
jge 0x26b91
movslq 0x84(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x20(%rsp), %rdi
leaq 0x68(%rsp), %rsi
movq %rsi, 0x10(%rsp)
movl $0x2, %edx
callq 0x192e0
movq 0x20(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl %eax, 0x60(%rsp)
movl $0x3, %edx
callq 0x192e0
movq 0x10(%rsp), %rdi
movl %eax, 0x5c(%rsp)
callq 0x19350
addq $0x10, %rax
movq %rax, 0x50(%rsp)
movq 0x70(%rsp), %rax
movslq 0x60(%rsp), %rcx
imulq %rcx, %rax
movslq 0x5c(%rsp), %rcx
imulq %rcx, %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x9030
movq %rax, 0x18(%rsp)
jmp 0x26c1c
movq 0x18(%rsp), %rax
movq %rax, 0x40(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x48(%rsp), %rax
jae 0x26d38
cmpq $0x0, 0x78(%rsp)
jbe 0x26cf1
movq 0x50(%rsp), %rax
movq %rax, %rcx
incq %rcx
movq %rcx, 0x50(%rsp)
movzbl (%rax), %eax
cvtsi2ss %eax, %xmm0
movss %xmm0, 0x4(%rsp)
movq 0x78(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x8(%rsp)
testq %rax, %rax
movss %xmm0, 0xc(%rsp)
js 0x26ca6
movss 0x8(%rsp), %xmm0
movss %xmm0, 0xc(%rsp)
movss 0x4(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
xorl %eax, %eax
movl $0x1, %ecx
ucomiss %xmm1, %xmm0
cmoval %ecx, %eax
cvtsi2ss %eax, %xmm0
movq 0x40(%rsp), %rax
movq 0x28(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
jmp 0x26d23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x19470
jmp 0x26d8a
movq 0x50(%rsp), %rax
movq %rax, %rcx
incq %rcx
movq %rcx, 0x50(%rsp)
movzbl (%rax), %eax
cvtsi2ss %eax, %xmm0
movss 0x67300(%rip), %xmm1    # 0x8e010
divss %xmm1, %xmm0
movq 0x40(%rsp), %rax
movq 0x28(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
jmp 0x26d25
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0x26c2f
movq 0x88(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x70(%rsp), %rdx
movl 0x60(%rsp), %eax
movl 0x5c(%rsp), %ecx
imull %ecx, %eax
movslq %eax, %rcx
callq 0x34360
jmp 0x26d5f
movb $0x1, 0xa7(%rsp)
movl $0x1, 0x64(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x19470
movb 0xa7(%rsp), %al
andb $0x1, %al
addq $0xa8, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0x9700
nopw %cs:(%rax,%rax)
nop