// File: /workspace/github_cpp_makefile_star2_O2/misohena[P]drawstars/./image_jpeg.h
// Function: bool writeJpegFile<Image<ColorRGB<double>>>(char const*, Image<ColorRGB<double>> const&, int)
bool writeJpegFile(const char *filename, const ImageT &image, int quality)
{
    File file(filename, "wb");
    if(!file){
        return false;
    }

    ///@todo handle errors

    jpeg_compress_struct cinfo;
    jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    jpeg_stdio_dest(&cinfo, file);

    cinfo.image_width = image.width();
    cinfo.image_height = image.height();
    cinfo.input_components = 3; // number of components per pixel.
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);


    jpeg_start_compress(&cinfo, TRUE);

    std::unique_ptr<unsigned char[]> lineBytes(new unsigned char[image.width() * 3]);

    while(cinfo.next_scanline < cinfo.image_height){
        // copy scanline bytes
        unsigned char *dst = lineBytes.get();
        const typename ImageT::PixelType *src = image.at(0, cinfo.next_scanline);
        for(unsigned int x = 0; x < image.width(); ++x, ++src, dst += 3){
            using VT = typename ImageT::PixelType::ValueType;
            dst[0] = static_cast<std::uint8_t>(clamp(255*src->r, VT(0), VT(255)));
            dst[1] = static_cast<std::uint8_t>(clamp(255*src->g, VT(0), VT(255)));
            dst[2] = static_cast<std::uint8_t>(clamp(255*src->b, VT(0), VT(255)));
        }

        // write
        JSAMPROW row_pointer[1] = {lineBytes.get()};
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);

    jpeg_destroy_compress(&cinfo);

    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x310, %rsp            # imm = 0x310
movl %edx, %ebp
movq %rsi, %r14
leaq 0x4424(%rip), %rsi      # 0xc538
callq 0x4360
movq %rax, %rbx
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x82a4
leaq 0x268(%rsp), %rdi
callq 0x4070
leaq 0x20(%rsp), %rdi
movq %rax, (%rdi)
pushq $0x50
popq %rsi
movl $0x248, %edx            # imm = 0x248
callq 0x4060
movq 0x10(%rsp), %rsi
leaq 0x20(%rsp), %rdi
callq 0x44f0
movq (%r14), %rax
leaq 0x20(%rsp), %rdi
movq %rax, 0x30(%rdi)
movabsq $0x200000003, %rax      # imm = 0x200000003
movq %rax, 0x38(%rdi)
callq 0x4450
leaq 0x20(%rsp), %rdi
pushq $0x1
popq %rdx
movl %ebp, %esi
callq 0x40d0
leaq 0x20(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x4460
imull $0x3, (%r14), %edi
callq 0x4030
movq %rax, 0x8(%rsp)
movsd 0x3ebc(%rip), %xmm2     # 0xc068
xorpd %xmm3, %xmm3
leaq 0x20(%rsp), %r15
leaq 0x18(%rsp), %r12
pushq $0x1
popq %rbp
movl 0x174(%rsp), %ecx
cmpl 0x54(%rsp), %ecx
jae 0x8286
movq 0x8(%rsp), %rax
movl (%r14), %edi
imull %edi, %ecx
imulq $0x18, %rcx, %rcx
addq 0x8(%r14), %rcx
xorl %edx, %edx
xorl %esi, %esi
cmpl %edi, %esi
jae 0x825e
movsd (%rcx,%rdx,8), %xmm0
mulsd %xmm2, %xmm0
movapd %xmm2, %xmm1
minsd %xmm0, %xmm1
cmpltsd %xmm3, %xmm0
andnpd %xmm1, %xmm0
cvttsd2si %xmm0, %edi
movb %dil, (%rax,%rdx)
movsd 0x8(%rcx,%rdx,8), %xmm0
mulsd %xmm2, %xmm0
movapd %xmm2, %xmm1
minsd %xmm0, %xmm1
cmpltsd %xmm3, %xmm0
andnpd %xmm1, %xmm0
cvttsd2si %xmm0, %edi
movb %dil, 0x1(%rax,%rdx)
movsd 0x10(%rcx,%rdx,8), %xmm0
mulsd %xmm2, %xmm0
movapd %xmm2, %xmm1
minsd %xmm0, %xmm1
cmpltsd %xmm3, %xmm0
andnpd %xmm1, %xmm0
cvttsd2si %xmm0, %edi
movb %dil, 0x2(%rax,%rdx)
incl %esi
movl (%r14), %edi
addq $0x3, %rdx
jmp 0x81e5
movq 0x8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r15, %rdi
movq %r12, %rsi
movl %ebp, %edx
callq 0x4350
movsd 0x3deb(%rip), %xmm2     # 0xc068
xorpd %xmm3, %xmm3
jmp 0x81bd
leaq 0x20(%rsp), %rdi
callq 0x4330
leaq 0x20(%rsp), %rdi
callq 0x43b0
leaq 0x8(%rsp), %rdi
callq 0x94b2
testq %rbx, %rbx
setne %bl
leaq 0x10(%rsp), %rdi
callq 0x94cc
movl %ebx, %eax
addq $0x310, %rsp            # imm = 0x310
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
jmp 0x82ca
jmp 0x82cf
movq %rax, %rbx
jmp 0x82dc
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x94b2
leaq 0x10(%rsp), %rdi
callq 0x94cc
movq %rbx, %rdi
callq 0x4520