// File: /workspace/github_cpp_makefile_star2_O1/qhan1028[P]JPEG-Decoder/jpeg-decoder.cpp
// Function: main
int main(int argc, char* argv[]) {
    if (argc < 2) {
        cout << "[Error] usage: ./jpeg-decoder [filename].jpg" << endl;
        return -1;
    }

    /* parse filename */
    string filename;
    for (int i = 0; i < argc; i++) {
        if (strcmp(argv[i], "--debug") == 0)
            debug = true;
        else
            filename = argv[i];
    }

    /* open jpeg */
    ifstream jpegfile;
    jpegfile.open(filename, ifstream::binary);
    if (!jpegfile.is_open()) {
        cout << "[Error] fail to open file: " << filename << endl;
        return -2;
    }

    /* read first tag */
    if (process_SOI(jpegfile))
        return -3;

    /* initialize */
    qtable_t qtable = init_qtable();
    sof_t sof;
    htable_t* htable = init_htable();
    sos_t sos;
    image_t rgb;

    char c1, c2;
    bool eoi = false; // end of image

    while(!eoi) {
        jpegfile.read(&c1, 1);
        jpegfile.read(&c2, 1);

        if (to_uint(c1) == TAG && to_uint(c2) != TAG) {

            unsigned int opt = to_uint(c2);

            switch(opt) {
                case DQT:
                    process_DQT(jpegfile, qtable);
                    break;
                
                case SOF0:
                    process_SOF0(jpegfile, sof);
                    break;
                
                case DHT:
                    process_DHT(jpegfile, htable);
                    break;
                
                case SOS:
                    process_SOS(jpegfile, sos);
                    if (debug) {
                        print_DQT(qtable);
                        print_SOF(sof);
                        print_DHT(htable);
                        print_SOS(sos);
                    }
                    rgb = process_scan(jpegfile, qtable, sof, htable, sos);
                    break;
                
                case EOI:
                    process_EOI(eoi);
                    break;
                
                default:
                    process_other(jpegfile, opt);
            }
        }
    }

    jpegfile.close();

    /* output bitmap */
    to_bitmap(filename, rgb, sof);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x298, %rsp            # imm = 0x298
cmpl $0x1, %edi
jg 0x4bc5
movq 0x4450(%rip), %rbx      # 0x8fd0
leaq 0x178f(%rip), %rsi      # 0x6316
movl $0x2c, %edx
movq %rbx, %rdi
callq 0x2210
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x4e86
movq %rsi, %rbx
leaq -0x48(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movl %edi, %r15d
xorl %r14d, %r14d
movq (%rbx,%r14,8), %r12
movq %r12, %rdi
leaq 0x1754(%rip), %rsi      # 0x6343
callq 0x2260
testl %eax, %eax
je 0x4c1a
movq -0x50(%rbp), %r13
movq %r12, %rdi
callq 0x20e0
leaq -0x58(%rbp), %rdi
xorl %esi, %esi
movq %r13, %rdx
movq %r12, %rcx
movq %rax, %r8
callq 0x22b0
jmp 0x4c21
movb $0x1, 0x45d9(%rip)      # 0x91fa
incq %r14
cmpq %r14, %r15
jne 0x4be1
leaq -0x2c0(%rbp), %rdi
callq 0x2200
leaq -0x2c0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x4, %edx
callq 0x2180
leaq -0x248(%rbp), %rdi
callq 0x2080
testb %al, %al
je 0x4dc0
leaq -0x2c0(%rbp), %rdi
callq 0x2984
movl $0xfffffffd, %ebx       # imm = 0xFFFFFFFD
testb %al, %al
jne 0x4e68
callq 0x2a39
movq %rax, -0x38(%rbp)
callq 0x318a
movq %rax, %r14
leaq -0x29(%rbp), %rax
movb $0x0, (%rax)
leaq -0x2c0(%rbp), %r12
leaq -0x2b(%rbp), %r13
leaq -0x2a(%rbp), %r15
movl $0x1, %edx
movq %r12, %rdi
movq %r13, %rsi
callq 0x2220
movl $0x1, %edx
movq %r12, %rdi
movq %r15, %rsi
callq 0x2220
cmpb $-0x1, -0x2b(%rbp)
je 0x4ccf
cmpb $0x1, -0x29(%rbp)
jne 0x4c9e
jmp 0x4e1d
movzbl -0x2a(%rbp), %esi
cmpl $0xd9, %esi
jg 0x4d02
cmpl $0xc0, %esi
je 0x4d28
cmpl $0xc4, %esi
je 0x4d9f
cmpl $0xd9, %esi
jne 0x4d1e
leaq -0x29(%rbp), %rdi
callq 0x4a06
jmp 0x4cc4
cmpl $0xda, %esi
je 0x4d39
cmpl $0xdb, %esi
je 0x4daf
cmpl $0xff, %esi
je 0x4cc4
movq %r12, %rdi
callq 0x4a65
jmp 0x4cc4
movq %r12, %rdi
leaq -0x98(%rbp), %rsi
callq 0x2f6d
jmp 0x4cc4
movq %r12, %rdi
leaq -0xb8(%rbp), %rsi
callq 0x377a
cmpb $0x1, 0x44ab(%rip)      # 0x91fa
jne 0x4d7a
movq -0x38(%rbp), %rdi
callq 0x2a6f
leaq -0x98(%rbp), %rdi
callq 0x2cee
movq %r14, %rdi
callq 0x31d9
leaq -0xb8(%rbp), %rdi
callq 0x34e2
movq %r12, %rdi
movq -0x38(%rbp), %rsi
leaq -0x98(%rbp), %rdx
movq %r14, %rcx
leaq -0xb8(%rbp), %r8
callq 0x3c4f
movq %rax, %rbx
jmp 0x4cc4
movq %r12, %rdi
movq %r14, %rsi
callq 0x330f
jmp 0x4cc4
movq %r12, %rdi
movq -0x38(%rbp), %rsi
callq 0x2bd3
jmp 0x4cc4
movq 0x4209(%rip), %rdi      # 0x8fd0
leaq 0x157d(%rip), %rsi      # 0x634b
movl $0x1b, %edx
callq 0x2210
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x41e9(%rip), %rdi      # 0x8fd0
callq 0x2210
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movl $0xfffffffe, %ebx       # imm = 0xFFFFFFFE
movq %rax, %rdi
callq 0x2120
jmp 0x4e68
leaq -0x2c0(%rbp), %rdi
callq 0x2070
leaq -0x68(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
addq %rsi, %rdx
leaq -0x78(%rbp), %rdi
callq 0x553a
leaq -0x78(%rbp), %rdi
leaq -0x98(%rbp), %rdx
movq %rbx, %rsi
callq 0x3a7f
movq -0x78(%rbp), %rdi
cmpq %r14, %rdi
je 0x4e66
callq 0x21a0
xorl %ebx, %ebx
leaq -0x2c0(%rbp), %rdi
callq 0x2090
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x4e86
callq 0x21a0
movl %ebx, %eax
addq $0x298, %rsp            # imm = 0x298
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x78(%rbp), %rdi
cmpq %r14, %rdi
je 0x4ebc
callq 0x21a0
jmp 0x4ebc
jmp 0x4eb9
jmp 0x4eb9
jmp 0x4eb9
jmp 0x4eca
jmp 0x4eb9
jmp 0x4eb9
movq %rax, %rbx
leaq -0x2c0(%rbp), %rdi
callq 0x2090
jmp 0x4ecd
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x4edf
callq 0x21a0
movq %rbx, %rdi
callq 0x22f0
nop