// File: /workspace/github_c_makefile_star2_O0/patriciogonzalezvivo[P]tprint/src/thermalPrinter.cpp
// Function: ThermalPrinter::printImg(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int)
void ThermalPrinter::printImg(const std::string& _path, int _threshold){
    int width = 0;
    int height = 0;
    int comp;

    stbi_set_flip_vertically_on_load(false);
    unsigned char* pixels = stbi_load(_path.c_str(), &width, &height, &comp, STBI_rgb);
    
    int GrayArrayLength = width * height;
    unsigned char * GrayArray = new unsigned char[GrayArrayLength];
    memset(GrayArray,0x00,GrayArrayLength);
    
    int rowBytes        = (width + 7) / 8;                  // Round up to next byte boundary
    int rowBytesClipped = (rowBytes >= 48) ? 48 : rowBytes; // 384 pixels max width
    
    int totalBytes = rowBytesClipped*height;
    uint8_t data[totalBytes];
    memset(data,0x00,totalBytes);
    
    for (int x = 0; x < width;x++) {
        for (int y = 0; y < height; y++) {
            int index = (y*width)*comp+x*comp;

            float brightTemp = 0.0;
            if (comp == 1 || comp == 2){
                brightTemp = pixels[index];
            } else if (comp == 3 || comp == 4 ){
                brightTemp =    0.212655f * (float)pixels[index] + 
                                0.715158f * (float)pixels[index+1] + 
                                0.072187f * (float)pixels[index+2];
                if(brightTemp>255) brightTemp = 255;
            } 
            
            // Brightness correction curve:
            brightTemp =  sqrt(255) * sqrt (brightTemp);
            if (brightTemp > 255) brightTemp = 255;
            if (brightTemp < 0) brightTemp = 0;
            
            int darkness = 255 - floor(brightTemp);
            
            int idx = y*width + x;
            darkness += GrayArray[idx];
            
            if(x<rowBytesClipped*8){
                
                uint8_t pixel;
                if( darkness >= _threshold){
                    darkness -= _threshold;
                    pixel = 0x01;
                } else {
                    pixel = 0x00;
                }
                
                data[y*rowBytesClipped+x/8] += (pixel&0x01)<<(7-x%8);
            }
            
            int darkn8 = round(darkness / 8);
            
            // Atkinson dithering algorithm:  http://verlagmartinkoch.at/software/dither/index.html
            // Distribute error as follows:
            //     [ ]  1/8  1/8
            //1/8  1/8  1/8
            //     1/8
            
            if ((idx + 1) < GrayArrayLength)
                GrayArray[idx + 1] += darkn8;
            if ((idx + 2) < GrayArrayLength)
                GrayArray[idx + 2] += darkn8;
            if ((idx + width - 1) < GrayArrayLength)
                GrayArray[idx + width - 1] += darkn8;
            if ((idx + width) < GrayArrayLength)
                GrayArray[idx + width] += darkn8;
            if ((idx + width + 1) < GrayArrayLength)
                GrayArray[idx + width + 1 ] += darkn8;
            if ((idx + 2 * width) < GrayArrayLength)
                GrayArray[idx + 2 * width] += darkn8;
        }
    }
    
    for (int y=0; y<height; y++) {
        writeBytesRow(&data[y*rowBytesClipped],rowBytesClipped);
    }

    delete []GrayArray;
    delete []pixels;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movl $0x0, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
xorl %edi, %edi
callq 0x1a0b0
movq -0x10(%rbp), %rdi
callq 0xd170
movq %rax, %rdi
leaq -0x18(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
leaq -0x20(%rbp), %rcx
movl $0x3, %r8d
callq 0x1a0c0
movq %rax, -0x28(%rbp)
movl -0x18(%rbp), %eax
imull -0x1c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movslq -0x2c(%rbp), %rdi
callq 0xd040
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movslq -0x2c(%rbp), %rdx
xorl %esi, %esi
callq 0xd200
movl -0x18(%rbp), %eax
addl $0x7, %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, -0x3c(%rbp)
cmpl $0x30, -0x3c(%rbp)
jl 0x1c1f7
movl $0x30, %eax
movl %eax, -0x8c(%rbp)
jmp 0x1c200
movl -0x3c(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
movl -0x1c(%rbp), %ecx
imull %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq %rsp, %rcx
movq %rcx, -0x50(%rbp)
movq %rax, %rcx
addq $0xf, %rcx
andq $-0x10, %rcx
movq %rsp, %rdi
subq %rcx, %rdi
movq %rdi, -0x98(%rbp)
movq %rdi, %rsp
movq %rax, -0x58(%rbp)
movslq -0x44(%rbp), %rdx
xorl %esi, %esi
callq 0xd200
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1c570
movl $0x0, -0x60(%rbp)
movl -0x60(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x1c560
movl -0x60(%rbp), %eax
imull -0x18(%rbp), %eax
imull -0x20(%rbp), %eax
movl -0x5c(%rbp), %ecx
imull -0x20(%rbp), %ecx
addl %ecx, %eax
movl %eax, -0x64(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x68(%rbp)
cmpl $0x1, -0x20(%rbp)
je 0x1c29a
cmpl $0x2, -0x20(%rbp)
jne 0x1c2b4
movq -0x28(%rbp), %rax
movslq -0x64(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cvtsi2ss %eax, %xmm0
movss %xmm0, -0x68(%rbp)
jmp 0x1c336
cmpl $0x3, -0x20(%rbp)
je 0x1c2c0
cmpl $0x4, -0x20(%rbp)
jne 0x1c334
movq -0x28(%rbp), %rax
movslq -0x64(%rbp), %rcx
movzbl (%rax,%rcx), %edx
cvtsi2ss %edx, %xmm1
movzbl 0x1(%rax,%rcx), %edx
cvtsi2ss %edx, %xmm0
movss 0x1159f(%rip), %xmm2    # 0x2d880
mulss %xmm2, %xmm0
movss 0x11597(%rip), %xmm2    # 0x2d884
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movzbl 0x2(%rax,%rcx), %eax
cvtsi2ss %eax, %xmm0
movss 0x11576(%rip), %xmm2    # 0x2d87c
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x68(%rbp)
movss -0x68(%rbp), %xmm0
movss 0x11558(%rip), %xmm1    # 0x2d878
ucomiss %xmm1, %xmm0
jbe 0x1c332
movss 0x1154b(%rip), %xmm0    # 0x2d878
movss %xmm0, -0x68(%rbp)
jmp 0x1c334
jmp 0x1c336
movl $0xff, %edi
callq 0x2cb30
movsd %xmm0, -0xa0(%rbp)
movss -0x68(%rbp), %xmm0
callq 0x2cb50
movaps %xmm0, %xmm1
movsd -0xa0(%rbp), %xmm0
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x68(%rbp)
movss -0x68(%rbp), %xmm0
movss 0x114fd(%rip), %xmm1    # 0x2d878
ucomiss %xmm1, %xmm0
jbe 0x1c38d
movss 0x114f0(%rip), %xmm0    # 0x2d878
movss %xmm0, -0x68(%rbp)
xorps %xmm0, %xmm0
ucomiss -0x68(%rbp), %xmm0
jbe 0x1c39e
xorps %xmm0, %xmm0
movss %xmm0, -0x68(%rbp)
movss -0x68(%rbp), %xmm0
callq 0x2cb70
movaps %xmm0, %xmm1
movss 0x114c5(%rip), %xmm0    # 0x2d878
subss %xmm1, %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x6c(%rbp)
movl -0x60(%rbp), %eax
imull -0x18(%rbp), %eax
addl -0x5c(%rbp), %eax
movl %eax, -0x70(%rbp)
movq -0x38(%rbp), %rax
movslq -0x70(%rbp), %rcx
movzbl (%rax,%rcx), %eax
addl -0x6c(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x5c(%rbp), %eax
movl -0x40(%rbp), %ecx
shll $0x3, %ecx
cmpl %ecx, %eax
jge 0x1c44b
movl -0x6c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jl 0x1c403
movl -0x14(%rbp), %ecx
movl -0x6c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x6c(%rbp)
movb $0x1, -0x71(%rbp)
jmp 0x1c407
movb $0x0, -0x71(%rbp)
movzbl -0x71(%rbp), %esi
andl $0x1, %esi
movl -0x5c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl $0x7, %ecx
subl %edx, %ecx
shll %cl, %esi
movl -0x60(%rbp), %ecx
imull -0x40(%rbp), %ecx
movl -0x5c(%rbp), %eax
movl $0x8, %edi
cltd
idivl %edi
movl %eax, %edx
movq -0x98(%rbp), %rax
addl %edx, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x6c(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %edi
callq 0x2cb90
cvttsd2si %xmm0, %eax
movl %eax, -0x78(%rbp)
movl -0x70(%rbp), %eax
addl $0x1, %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c488
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x70(%rbp), %eax
addl $0x2, %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c4ac
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x70(%rbp), %eax
addl -0x18(%rbp), %eax
subl $0x1, %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c4d6
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
addl -0x18(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x70(%rbp), %eax
addl -0x18(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c4fa
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
addl -0x18(%rbp), %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x70(%rbp), %eax
addl -0x18(%rbp), %eax
addl $0x1, %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c524
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
addl -0x18(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0x70(%rbp), %eax
movl -0x18(%rbp), %ecx
shll %ecx
addl %ecx, %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c550
movl -0x78(%rbp), %esi
movq -0x38(%rbp), %rax
movl -0x70(%rbp), %ecx
movl -0x18(%rbp), %edx
shll %edx
addl %edx, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movb %dl, (%rax,%rcx)
jmp 0x1c552
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x1c263
jmp 0x1c562
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1c250
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x1c5ac
movq -0x88(%rbp), %rdi
movq -0x98(%rbp), %rsi
movl -0x7c(%rbp), %eax
imull -0x40(%rbp), %eax
cltq
addq %rax, %rsi
movl -0x40(%rbp), %edx
callq 0x1c600
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x1c577
movq -0x38(%rbp), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x1c5c9
movq -0xa8(%rbp), %rdi
callq 0xd540
movq -0x28(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, %rax
je 0x1c5e6
movq -0xb0(%rbp), %rdi
callq 0xd540
movq -0x50(%rbp), %rax
movq %rax, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)