// File: /workspace/github_cpp_makefile_star2_O3/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 $0x2a8, %rsp            # imm = 0x2A8
cmpl $0x1, %edi
jg 0x4b3f
movq 0x44d6(%rip), %rbx      # 0x8fd0
leaq 0x1815(%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 0x4e0b
movq %rsi, %rbx
leaq -0x50(%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 0x17da(%rip), %rsi      # 0x6343
callq 0x2260
testl %eax, %eax
je 0x4b94
movq -0x58(%rbp), %r13
movq %r12, %rdi
callq 0x20e0
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
movq %r13, %rdx
movq %r12, %rcx
movq %rax, %r8
callq 0x22b0
jmp 0x4b9b
movb $0x1, 0x465f(%rip)      # 0x91fa
incq %r14
cmpq %r14, %r15
jne 0x4b5b
leaq -0x2c8(%rbp), %rdi
callq 0x2200
leaq -0x2c8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x4, %edx
callq 0x2180
leaq -0x250(%rbp), %rdi
callq 0x2080
testb %al, %al
je 0x4d45
leaq -0x2c8(%rbp), %rdi
callq 0x2983
movl $0xfffffffd, %ebx       # imm = 0xFFFFFFFD
testb %al, %al
jne 0x4ded
callq 0x2a38
movq %rax, -0x40(%rbp)
callq 0x318a
movq %rax, -0x38(%rbp)
leaq -0x29(%rbp), %rax
movb $0x0, (%rax)
xorl %r14d, %r14d
leaq -0x2c8(%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 0x4c4d
testb $0x1, %r14b
je 0x4c1c
jmp 0x4da2
movzbl -0x2a(%rbp), %esi
cmpl $0xd9, %esi
jg 0x4c84
cmpl $0xc0, %esi
je 0x4caa
cmpl $0xc4, %esi
je 0x4d23
cmpl $0xd9, %esi
jne 0x4ca0
leaq -0x29(%rbp), %rdi
callq 0x4980
movb -0x29(%rbp), %r14b
jmp 0x4c42
cmpl $0xda, %esi
je 0x4cbb
cmpl $0xdb, %esi
je 0x4d34
cmpl $0xff, %esi
je 0x4c42
movq %r12, %rdi
callq 0x49df
jmp 0x4c42
movq %r12, %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2f6c
jmp 0x4c42
movq %r12, %rdi
leaq -0xc0(%rbp), %rsi
callq 0x3762
cmpb $0x1, 0x4529(%rip)      # 0x91fa
jne 0x4cfd
movq -0x40(%rbp), %rdi
callq 0x2a6e
leaq -0xa0(%rbp), %rdi
callq 0x2ced
movq -0x38(%rbp), %rdi
callq 0x31d9
leaq -0xc0(%rbp), %rdi
callq 0x34ca
movq %r12, %rdi
movq -0x40(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
movq -0x38(%rbp), %rcx
leaq -0xc0(%rbp), %r8
callq 0x3c45
movq %rax, %rbx
jmp 0x4c42
movq %r12, %rdi
movq -0x38(%rbp), %rsi
callq 0x330f
jmp 0x4c42
movq %r12, %rdi
movq -0x40(%rbp), %rsi
callq 0x2bd2
jmp 0x4c42
movq 0x4284(%rip), %rdi      # 0x8fd0
leaq 0x15f8(%rip), %rsi      # 0x634b
movl $0x1b, %edx
callq 0x2210
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
movq 0x4264(%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 0x4ded
leaq -0x2c8(%rbp), %rdi
callq 0x2070
leaq -0x70(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
addq %rsi, %rdx
leaq -0x80(%rbp), %rdi
callq 0x54ae
leaq -0x80(%rbp), %rdi
leaq -0xa0(%rbp), %rdx
movq %rbx, %rsi
callq 0x3a68
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x4deb
callq 0x21a0
xorl %ebx, %ebx
leaq -0x2c8(%rbp), %rdi
callq 0x2090
movq -0x60(%rbp), %rdi
leaq -0x50(%rbp), %rax
cmpq %rax, %rdi
je 0x4e0b
callq 0x21a0
movl %ebx, %eax
addq $0x2a8, %rsp            # imm = 0x2A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x4e41
callq 0x21a0
jmp 0x4e41
jmp 0x4e3e
jmp 0x4e3e
jmp 0x4e3e
jmp 0x4e4f
jmp 0x4e3e
jmp 0x4e3e
movq %rax, %rbx
leaq -0x2c8(%rbp), %rdi
callq 0x2090
jmp 0x4e52
movq %rax, %rbx
movq -0x60(%rbp), %rdi
leaq -0x50(%rbp), %rax
cmpq %rax, %rdi
je 0x4e64
callq 0x21a0
movq %rbx, %rdi
callq 0x22f0