// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movl %edx, -0x54(%rbp)
movq %rdi, -0x90(%rbp)
xorl %eax, %eax
leaq -0xa8(%rbp), %r13
movl %eax, (%r13)
leaq -0xa4(%rbp), %r12
movl %eax, (%r12)
movq $0x0, -0x40(%rbp)
movl %eax, 0x161f8(%rip)     # 0x28410
movq (%rsi), %rdi
leaq -0x60(%rbp), %rcx
movq %r13, %rsi
movq %r12, %rdx
movl $0x3, %r8d
callq 0xff98
movq %rax, -0x48(%rbp)
movl (%r13), %ebx
movl (%r12), %r15d
movl %r15d, %r14d
imull %ebx, %r14d
movslq %r14d, %r12
movq %r12, %rdi
callq 0x8040
movq %rax, -0x80(%rbp)
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x81d0
movq %rsp, -0x88(%rbp)
leal 0x7(%rbx), %eax
leal 0xe(%rbx), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x3, %ecx
cmpl $0x179, %ebx            # imm = 0x179
movl $0x30, %eax
cmovll %ecx, %eax
movq %rax, -0x68(%rbp)
imull %r15d, %eax
leaq 0xf(%rax), %rcx
andq $-0x10, %rcx
movq %rsp, %rdi
subq %rcx, %rdi
movq %rdi, %rsp
movslq %eax, %rdx
movq %rdi, -0x70(%rbp)
xorl %esi, %esi
callq 0x81d0
movq %rbx, -0x50(%rbp)
testl %ebx, %ebx
jle 0x124c9
movq -0x68(%rbp), %rcx
leal (,%rcx,8), %eax
movl %eax, -0x5c(%rbp)
movq -0x50(%rbp), %rax
leal (%rax,%rax), %edx
movl %edx, -0x34(%rbp)
movl %ecx, %ecx
movq %rcx, -0x98(%rbp)
movl $0x2, -0x30(%rbp)
movl %eax, -0x2c(%rbp)
movq %r15, -0x78(%rbp)
movl %r14d, -0x38(%rbp)
testl %r15d, %r15d
jle 0x124a8
movq -0x40(%rbp), %rax
movq %rax, %rbx
shrq $0x3, %rbx
addq -0x70(%rbp), %rbx
notl %eax
andl $0x7, %eax
movl %eax, -0x58(%rbp)
movq -0x78(%rbp), %rdx
movl -0x30(%rbp), %eax
movl %eax, %r15d
movl -0x2c(%rbp), %eax
movl %eax, %r12d
movl -0x34(%rbp), %r13d
movq %rdx, -0xa0(%rbp)
movl -0x60(%rbp), %ecx
leal -0x2(%r15), %r14d
movl %ecx, %eax
imull %r14d, %eax
leal -0x1(%rcx), %edx
cmpl $0x1, %edx
ja 0x1234b
cltq
movq -0x48(%rbp), %rcx
movzbl (%rcx,%rax), %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
jmp 0x123b0
addl $-0x3, %ecx
xorps %xmm0, %xmm0
cmpl $0x1, %ecx
ja 0x123b0
cltq
movq -0x48(%rbp), %rdx
movzbl (%rdx,%rax), %ecx
xorps %xmm1, %xmm1
cvtsi2ss %ecx, %xmm1
movzbl 0x1(%rdx,%rax), %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
mulss 0xf545(%rip), %xmm0     # 0x218c0
mulss 0xf541(%rip), %xmm1     # 0x218c4
addss %xmm0, %xmm1
movzbl 0x2(%rdx,%rax), %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
mulss 0xf52d(%rip), %xmm0     # 0x218c8
addss %xmm1, %xmm0
ucomiss 0xf512(%rip), %xmm0     # 0x218b8
jbe 0x123b0
movss 0xf508(%rip), %xmm0     # 0x218b8
ucomiss 0xf515(%rip), %xmm0     # 0x218cc
jb 0x123bf
sqrtss %xmm0, %xmm0
jmp 0x123c4
callq 0x8630
cvtss2sd %xmm0, %xmm0
mulsd 0xfa90(%rip), %xmm0     # 0x21e60
cvtsd2ss %xmm0, %xmm0
movss 0xf4dc(%rip), %xmm1     # 0x218b8
minss %xmm0, %xmm1
xorps %xmm0, %xmm0
maxss %xmm1, %xmm0
callq 0x8150
movss 0xf4c4(%rip), %xmm1     # 0x218b8
subss %xmm0, %xmm1
cvttss2si %xmm1, %eax
movslq %r14d, %rcx
movq -0x80(%rbp), %rdi
movzbl (%rdi,%rcx), %edx
addl %eax, %edx
movl -0x5c(%rbp), %eax
cmpl %eax, -0x40(%rbp)
jae 0x1242c
xorl %eax, %eax
movl -0x54(%rbp), %ecx
cmpl %ecx, %edx
setge %al
movl $0x0, %esi
cmovgel %ecx, %esi
movl -0x58(%rbp), %ecx
shll %cl, %eax
subl %esi, %edx
addb %al, (%rbx)
movl -0x38(%rbp), %r14d
leal 0x7(%rdx), %eax
testl %edx, %edx
cmovnsl %edx, %eax
sarl $0x3, %eax
leal -0x1(%r15), %ecx
cmpl %r14d, %ecx
jge 0x1244a
movslq %ecx, %rcx
addb %al, (%rdi,%rcx)
cmpl %r14d, %r15d
jge 0x12455
movslq %r15d, %rcx
addb %al, (%rdi,%rcx)
movslq %r12d, %rcx
cmpl %r14d, %r12d
jg 0x12461
addb %al, -0x1(%rdi,%rcx)
cmpl %r14d, %r12d
jge 0x12469
addb %al, (%rdi,%rcx)
leal 0x1(%r12), %ecx
cmpl %r14d, %ecx
jge 0x12479
movslq %ecx, %rcx
addb %al, (%rdi,%rcx)
cmpl %r14d, %r13d
movq -0xa0(%rbp), %rdx
jge 0x1248b
movslq %r13d, %rcx
addb %al, (%rdi,%rcx)
movq -0x50(%rbp), %rax
addl %eax, %r13d
addl %eax, %r12d
addl %eax, %r15d
addq -0x98(%rbp), %rbx
decq %rdx
jne 0x1231c
movq -0x40(%rbp), %rax
incq %rax
incl -0x34(%rbp)
incl -0x2c(%rbp)
incl -0x30(%rbp)
movq %rax, -0x40(%rbp)
cmpl -0x50(%rbp), %eax
movq -0x78(%rbp), %r15
jne 0x122e8
testl %r15d, %r15d
movq -0x90(%rbp), %r14
movq -0x68(%rbp), %r12
movq -0x70(%rbp), %r13
jle 0x124f6
movslq %r12d, %rbx
movq %r14, %rdi
movq %r13, %rsi
movl %r12d, %edx
callq 0x12524
addq %rbx, %r13
decq %r15
jne 0x124e0
movq -0x80(%rbp), %rdi
callq 0x8420
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x1250d
callq 0x8420
movq -0x88(%rbp), %rsp
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop