// File: /workspace/github_cpp_makefile_star2_O3/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r8, %r14
movl %ecx, %ebx
movq %rdx, 0x30(%rsp)
movq %rsi, %rdx
movq %rdi, %rsi
leaq 0x18(%rsp), %r13
movq $0x0, (%r13)
leaq 0x28(%rsp), %r12
movq %r12, %rdi
movl $0x803, %ecx            # imm = 0x803
movq %r13, %r8
callq 0x11f4c
movq (%r12), %r12
testq %r12, %r12
setne %cl
movq (%r13), %rax
testq %rax, %rax
setne %bpl
andb %cl, %bpl
cmpb $0x1, %bpl
jne 0x11ef0
testl %ebx, %ebx
setg %cl
cmpl %ebx, %eax
setg %al
andb %cl, %al
cmpb $0x1, %al
jne 0x11d70
movl %ebx, %eax
movq %rax, 0x18(%rsp)
movb %bpl, 0xf(%rsp)
movl 0x8(%r12), %ebx
movl 0xc(%r12), %edx
movl $0xffffff, %eax         # imm = 0xFFFFFF
movl %ebx, %ecx
andl %eax, %ecx
bswapl %ecx
sarl $0x18, %ebx
orl %ecx, %ebx
andl %edx, %eax
bswapl %eax
sarl $0x18, %edx
orl %eax, %edx
movslq %ebx, %rsi
movl %edx, 0x10(%rsp)
movslq %edx, %rdx
leaq 0x38(%rsp), %rdi
callq 0x197fe
cmpq $0x0, 0x18(%rsp)
je 0x11edc
movl 0x10(%rsp), %eax
imull %ebx, %eax
movl %eax, 0x10(%rsp)
testq %r14, %r14
js 0x11dcf
cvtsi2ss %r14, %xmm0
jmp 0x11de7
movq %r14, %rax
shrq %rax
movl %r14d, %ecx
andl $0x1, %ecx
orq %rax, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
addq $0x10, %r12
movl 0x10(%rsp), %r15d
xorl %ebx, %ebx
leaq 0x60(%rsp), %r13
movl $0x0, 0x24(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0x24(%rsp), %rsi
callq 0x1a96a
cmpl $0x0, 0x10(%rsp)
je 0x11e64
movq 0x48(%rsp), %rcx
xorl %eax, %eax
movzbl (%r12,%rax), %edx
xorps %xmm1, %xmm1
cvtsi2ss %edx, %xmm1
movaps %xmm1, %xmm0
divss 0x281cf(%rip), %xmm0    # 0x3a008
testq %r14, %r14
je 0x11e54
movss 0x14(%rsp), %xmm0
cmpltss %xmm1, %xmm0
movss 0x281bb(%rip), %xmm1    # 0x3a00c
andps %xmm1, %xmm0
movss %xmm0, (%rcx,%rax,4)
incq %rax
cmpq %rax, %r15
jne 0x11e22
addq %rax, %r12
leaq 0x78(%rsp), %rdi
callq 0xbb7c
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rbp
movq %rax, 0x60(%rsp)
movq %rbp, 0x68(%rsp)
imulq %rax, %rbp
movq %rbp, %rax
shrq $0x3e, %rax
shlq $0x2, %rbp
negq %rax
movl $0x0, %edi
sbbq %rdi, %rdi
orq %rbp, %rdi
callq 0x9030
movq %rax, 0x70(%rsp)
movq 0x48(%rsp), %rsi
movq %rax, %rdi
movq %rbp, %rdx
callq 0x92b0
movq 0x30(%rsp), %rdi
movq %r13, %rsi
callq 0x12204
movq %r13, %rdi
callq 0x19a36
incq %rbx
cmpq 0x18(%rsp), %rbx
jne 0x11dfd
leaq 0x38(%rsp), %rdi
callq 0x19a36
movq 0x28(%rsp), %r12
movb 0xf(%rsp), %bpl
testq %r12, %r12
je 0x11efd
movq %r12, %rdi
callq 0x9420
movl %ebp, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x11f34
jmp 0x11f27
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x19a36
jmp 0x11f2a
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x19a36
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x11f43
callq 0x9420
movq %rbx, %rdi
callq 0x95d0
nop