// File: dannye[P]jed/src/encoder.cpp
// Function: writeJPG(BMPImage const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void writeJPG(const BMPImage& image, const std::string& filename) {
    std::vector<byte> huffmanData = encodeHuffmanData(image);
    if (huffmanData.size() == 0) {
        return;
    }

    // open file
    std::cout << "Writing " << filename << "...\n";
    std::ofstream outFile(filename, std::ios::out | std::ios::binary);
    if (!outFile.is_open()) {
        std::cout << "Error - Error opening output file\n";
        return;
    }

    // SOI
    outFile.put(0xFF);
    outFile.put(SOI);

    // APP0
    writeAPP0(outFile);

    // DQT
    writeQuantizationTable(outFile, 0, qTableY100);
    writeQuantizationTable(outFile, 1, qTableCbCr100);

    // SOF
    writeStartOfFrame(outFile, image);

    // DHT
    writeHuffmanTable(outFile, 0, 0, hDCTableY);
    writeHuffmanTable(outFile, 0, 1, hDCTableCbCr);
    writeHuffmanTable(outFile, 1, 0, hACTableY);
    writeHuffmanTable(outFile, 1, 1, hACTableCbCr);

    // SOS
    writeStartOfScan(outFile);

    // ECS
    outFile.write((char*)&huffmanData[0], huffmanData.size());

    // EOI
    outFile.put(0xFF);
    outFile.put(EOI);

    outFile.close();
}

// Assembly:
subq $0x278, %rsp            # imm = 0x278
movq %rdi, 0x270(%rsp)
movq %rsi, 0x268(%rsp)
movq 0x270(%rsp), %rsi
leaq 0x250(%rsp), %rdi
callq 0x44c0
leaq 0x250(%rsp), %rdi
callq 0x5490
cmpq $0x0, %rax
jne 0x4c1f
movl $0x1, 0x24c(%rsp)
jmp 0x4e71
movq 0x53aa(%rip), %rdi      # 0x9fd0
leaq 0x25e0(%rip), %rsi      # 0x720d
callq 0x2130
movq %rax, 0x30(%rsp)
jmp 0x4c39
movq 0x30(%rsp), %rdi
movq 0x268(%rsp), %rsi
callq 0x2120
movq %rax, 0x28(%rsp)
jmp 0x4c52
movq 0x28(%rsp), %rdi
leaq 0x243b(%rip), %rsi      # 0x7099
callq 0x2130
jmp 0x4c65
movq 0x268(%rsp), %rax
movq %rax, 0x18(%rsp)
movl $0x10, %edi
movl $0x4, %esi
callq 0x51e0
movl %eax, 0x24(%rsp)
jmp 0x4c87
movl 0x24(%rsp), %edx
movq 0x18(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0x2280
jmp 0x4c9c
leaq 0x38(%rsp), %rdi
callq 0x20e0
movb %al, 0x17(%rsp)
jmp 0x4cac
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x4d17
jmp 0x4cb6
movq 0x5313(%rip), %rdi      # 0x9fd0
leaq 0x2552(%rip), %rsi      # 0x7216
callq 0x2130
jmp 0x4ccb
movl $0x1, 0x24c(%rsp)
jmp 0x4e67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x4e86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x21d0
jmp 0x4e86
leaq 0x38(%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x2030
jmp 0x4d28
leaq 0x38(%rsp), %rdi
movl $0xffffffd8, %esi       # imm = 0xFFFFFFD8
callq 0x2030
jmp 0x4d39
leaq 0x38(%rsp), %rdi
callq 0x4b00
jmp 0x4d45
leaq 0x2574(%rip), %rdx      # 0x72c0
leaq 0x38(%rsp), %rdi
xorl %esi, %esi
callq 0x4790
jmp 0x4d5a
leaq 0x2663(%rip), %rdx      # 0x73c4
leaq 0x38(%rsp), %rdi
movl $0x1, %esi
callq 0x4790
jmp 0x4d72
movq 0x270(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0x4830
jmp 0x4d86
leaq 0x53cb(%rip), %rcx      # 0xa158
leaq 0x38(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x4910
jmp 0x4d9d
leaq 0x573c(%rip), %rcx      # 0xa4e0
leaq 0x38(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x4910
jmp 0x4db7
leaq 0x5aaa(%rip), %rcx      # 0xa868
leaq 0x38(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x4910
jmp 0x4dd1
leaq 0x5e18(%rip), %rcx      # 0xabf0
leaq 0x38(%rsp), %rdi
movl $0x1, %edx
movl %edx, %esi
callq 0x4910
jmp 0x4deb
leaq 0x38(%rsp), %rdi
callq 0x4a40
jmp 0x4df7
xorl %eax, %eax
movl %eax, %esi
leaq 0x250(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x54b0
movq (%rsp), %rdi
movq %rax, 0x8(%rsp)
callq 0x5490
movq 0x8(%rsp), %rsi
movq %rax, %rdx
leaq 0x38(%rsp), %rdi
callq 0x21a0
jmp 0x4e2e
leaq 0x38(%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x2030
jmp 0x4e3f
leaq 0x38(%rsp), %rdi
movl $0xffffffd9, %esi       # imm = 0xFFFFFFD9
callq 0x2030
jmp 0x4e50
leaq 0x38(%rsp), %rdi
callq 0x21c0
jmp 0x4e5c
movl $0x0, 0x24c(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x21d0
leaq 0x250(%rsp), %rdi
callq 0x5430
addq $0x278, %rsp            # imm = 0x278
retq
leaq 0x250(%rsp), %rdi
callq 0x5430
movq 0x240(%rsp), %rdi
callq 0x2230