// File: btbujiangjun[P]abcdl/include/utils/MnistHelper.h
// Function: abcdl::utils::MnistHelper<float>::read_images(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, abcdl::algebra::MatrixSet<float>&, int, unsigned long)
bool MnistHelper<T>::read_images(const std::string& image_file,
                                 abcdl::algebra::MatrixSet<T>& out_matrix_set,
                                 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);

    auto size = rows * cols;
    abcdl::algebra::Matrix<T> mat(rows, cols);
    for(size_t i = 0; i != count; i++){
        mat.reset();
        T* data = mat.data();
        for(int j = 0; j != size; j++){
            if(threshold > 0){
                data[j] = static_cast<T>(*image_data_buffer++) > threshold ? 1 : 0;
            }else{
                data[j] = static_cast<T>(*image_data_buffer++) / 255;
            }
        }
        out_matrix_set.push_back(mat);
    }

    return true;
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0xf8(%rsp)
movq %rsi, 0xf0(%rsp)
movq %rdx, 0xe8(%rsp)
movl %ecx, 0xe4(%rsp)
movq %r8, 0xd8(%rsp)
movq 0xf8(%rsp), %rsi
movq %rsi, 0x28(%rsp)
movq $0x0, 0xd0(%rsp)
movq 0xf0(%rsp), %rdx
leaq 0xc8(%rsp), %rdi
movl $0x803, %ecx            # imm = 0x803
leaq 0xd0(%rsp), %r8
callq 0x18db0
leaq 0xc8(%rsp), %rdi
callq 0x192c0
testb $0x1, %al
jne 0x1893c
jmp 0x18947
cmpq $0x0, 0xd0(%rsp)
jne 0x1895f
movb $0x0, 0x107(%rsp)
movl $0x1, 0xc4(%rsp)
jmp 0x18c44
cmpl $0x0, 0xe4(%rsp)
jle 0x1898c
movl 0xe4(%rsp), %eax
movq 0xd0(%rsp), %rcx
cmpl %ecx, %eax
jge 0x1898c
movslq 0xe4(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0x28(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
movl $0x2, %edx
callq 0x192e0
movl %eax, 0x24(%rsp)
jmp 0x189a9
movq 0x28(%rsp), %rdi
movl 0x24(%rsp), %eax
movl %eax, 0xc0(%rsp)
leaq 0xc8(%rsp), %rsi
movl $0x3, %edx
callq 0x192e0
movl %eax, 0x20(%rsp)
jmp 0x189d1
movl 0x20(%rsp), %eax
movl %eax, 0xb0(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x19350
addq $0x10, %rax
movq %rax, 0xa8(%rsp)
movl 0xc0(%rsp), %eax
movl 0xb0(%rsp), %ecx
imull %ecx, %eax
movl %eax, 0xa4(%rsp)
movslq 0xc0(%rsp), %rsi
movslq 0xb0(%rsp), %rdx
leaq 0x78(%rsp), %rdi
callq 0x33a80
jmp 0x18a29
movq $0x0, 0x70(%rsp)
movq 0x70(%rsp), %rax
cmpq 0xd0(%rsp), %rax
je 0x18c19
movl $0x0, 0x6c(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x6c(%rsp), %rsi
callq 0x35570
jmp 0x18a5e
leaq 0x78(%rsp), %rdi
callq 0x19380
movq %rax, 0x18(%rsp)
jmp 0x18a6f
movq 0x18(%rsp), %rax
movq %rax, 0x60(%rsp)
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
cmpl 0xa4(%rsp), %eax
je 0x18baf
cmpq $0x0, 0xd8(%rsp)
jbe 0x18b65
movq 0xa8(%rsp), %rax
movq %rax, %rcx
incq %rcx
movq %rcx, 0xa8(%rsp)
movzbl (%rax), %eax
cvtsi2ss %eax, %xmm0
movss %xmm0, 0xc(%rsp)
movq 0xd8(%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, 0x10(%rsp)
testq %rax, %rax
movss %xmm0, 0x14(%rsp)
js 0x18b05
movss 0x10(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movss 0xc(%rsp), %xmm0
movss 0x14(%rsp), %xmm1
xorl %eax, %eax
movl $0x1, %ecx
ucomiss %xmm1, %xmm0
cmoval %ecx, %eax
cvtsi2ss %eax, %xmm0
movq 0x60(%rsp), %rax
movslq 0x5c(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
jmp 0x18b9d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
jmp 0x18c62
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
jmp 0x18c38
movq 0xa8(%rsp), %rax
movq %rax, %rcx
incq %rcx
movq %rcx, 0xa8(%rsp)
movzbl (%rax), %eax
cvtsi2ss %eax, %xmm0
movss 0x75486(%rip), %xmm1    # 0x8e010
divss %xmm1, %xmm0
movq 0x60(%rsp), %rax
movslq 0x5c(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
jmp 0x18b9f
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x18a81
movq 0xe8(%rsp), %rax
movq %rax, (%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x193b0
jmp 0x18bcc
movq (%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x19390
jmp 0x18bdc
leaq 0x30(%rsp), %rdi
callq 0x33e80
movq 0x70(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x70(%rsp)
jmp 0x18a32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x33e80
jmp 0x18c38
movb $0x1, 0x107(%rsp)
movl $0x1, 0xc4(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x33e80
jmp 0x18c44
leaq 0x78(%rsp), %rdi
callq 0x33e80
jmp 0x18c62
leaq 0xc8(%rsp), %rdi
callq 0x19470
movb 0x107(%rsp), %al
andb $0x1, %al
addq $0x108, %rsp            # imm = 0x108
retq
leaq 0xc8(%rsp), %rdi
callq 0x19470
movq 0xb8(%rsp), %rdi
callq 0x9700
nopl (%rax)