// File: rapirent[P]JPEG/decoder.c
// Function: main
int main(int argc,char* argv[])
{
    if (argc != 2  && argc != 3) {
        printf("[ERROR]:\nusage: ./decoder <input_file> [<output_file_name>]");
        exit(1);
    }
    FILE* fp;
    if ((fp = fopen(argv[1], "r")) == NULL) {
        printf("%s can't be opened\n", argv[1]);
        exit(1);
    }
    const char* fwrite = argc ==3 ? argv[2] : "image.bmp";

    byte h;
    byte l;
    bool b_SOI = false;
    bool b_EOI = false;
    init_cos_cache();
    while (fread(&h,1, 1,fp)) {
        fread(&l,1, 1,fp);
        if (h == 0xff) {
            if (!b_SOI && l == SOI) {
                b_SOI = true;
            }
            assert(b_SOI == true);
            switch(l) {
            case DQT:
                read_qt(fp);
                break;
            case SOF0:
                read_frame(fp);
                break;
            case DHT:
                read_ht(fp);
                break;
            case SOS:
                read_sos(fp);
                calculate_mcu(fp,fwrite);
                break;
            case APP0:
            case APP1:
            case APP2:
            case APP3:
            case APP4:
            case APP5:
            case APP6:
            case APP7:
            case APP8:
            case APP9:
            case APP10:
            case APP11:
            case APP12:
            case APP13:
            case APP14:
            case APP15:
                break;
            case EOI:
                b_EOI = true;
                break;
            }
        }
    }
    assert(b_EOI==true);
    return 0;
}

// Assembly:
subq $0x38, %rsp
movl $0x0, 0x34(%rsp)
movl %edi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
cmpl $0x2, 0x30(%rsp)
je 0x727b
cmpl $0x3, 0x30(%rsp)
je 0x727b
leaq 0x38e5(%rip), %rdi      # 0xab4f
movb $0x0, %al
callq 0x5030
movl $0x1, %edi
callq 0x5220
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x3852(%rip), %rsi      # 0xaadd
callq 0x5200
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
jne 0x72bc
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0x38e0(%rip), %rdi      # 0xab8b
movb $0x0, %al
callq 0x5030
movl $0x1, %edi
callq 0x5220
cmpl $0x3, 0x30(%rsp)
jne 0x72d3
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x8(%rsp)
jmp 0x72e1
leaq 0x38c5(%rip), %rax      # 0xab9f
movq %rax, 0x8(%rsp)
jmp 0x72e1
movq 0x8(%rsp), %rax
movq %rax, 0x18(%rsp)
movb $0x0, 0x15(%rsp)
movb $0x0, 0x14(%rsp)
callq 0x55d0
movq 0x20(%rsp), %rcx
leaq 0x17(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x5290
cmpq $0x0, %rax
je 0x73ff
movq 0x20(%rsp), %rcx
leaq 0x16(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x5290
movzbl 0x17(%rsp), %eax
cmpl $0xff, %eax
jne 0x73fa
testb $0x1, 0x15(%rsp)
jne 0x735a
movzbl 0x16(%rsp), %eax
cmpl $0xd8, %eax
jne 0x735a
movb $0x1, 0x15(%rsp)
movb 0x15(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x736a
jmp 0x7389
leaq 0x3838(%rip), %rdi      # 0xaba9
leaq 0x3780(%rip), %rsi      # 0xaaf8
movl $0x1a1, %edx            # imm = 0x1A1
leaq 0x3833(%rip), %rcx      # 0xabb7
callq 0x50e0
movzbl 0x16(%rsp), %eax
addl $0xffffff40, %eax       # imm = 0xFFFFFF40
movl %eax, %ecx
movq %rcx, (%rsp)
subl $0x2f, %eax
ja 0x73f8
movq (%rsp), %rax
leaq 0x2caf(%rip), %rcx      # 0xa058
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x20(%rsp), %rdi
callq 0x5630
jmp 0x73f8
movq 0x20(%rsp), %rdi
callq 0x5750
jmp 0x73f8
movq 0x20(%rsp), %rdi
callq 0x5960
jmp 0x73f8
movq 0x20(%rsp), %rdi
callq 0x5b80
movq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0x6690
jmp 0x73f8
jmp 0x73f8
movb $0x1, 0x14(%rsp)
jmp 0x73fa
jmp 0x72fa
movb 0x14(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x740f
jmp 0x742e
leaq 0x37b8(%rip), %rdi      # 0xabce
leaq 0x36db(%rip), %rsi      # 0xaaf8
movl $0x1c7, %edx            # imm = 0x1C7
leaq 0x378e(%rip), %rcx      # 0xabb7
callq 0x50e0
xorl %eax, %eax
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)
nop