// File: OpenFirework[P]MyJPEG_Decoder/./jpeg/jpeg_decoder.cpp
// Function: MyJPEG::jpegDecoder::readinfo(unsigned char*&, unsigned char*&, int&, int&)
int MyJPEG::jpegDecoder::readinfo(byte *&jpegdata, byte *&bgrdata, int &imgwidth, int &imgheidht) {
    init_c();
    init_cos_cache();
    unsigned char start;
    unsigned short two;
    memcpy(&start, jpegdata++, 1);
    if(start == 0xFF) {
        memcpy(&start, jpegdata++, 1);
        if(start == 0xD8) {          //jpeg文件开头标识符：0XFFD8
            std::cout<<"This is a jpeg file and open success!\n";
        }
        else {
            std::cout<<"This is not a jpeg file, decode failed!\n";
        } 
    }

    memcpy(&start, jpegdata++, 1);
    while(start == 0xFF) {
        memcpy(&start, jpegdata++, 1);
        switch (start) {
            case 0xE0:
            case 0xE1:
            case 0xE2:
            case 0xE3:
            case 0xE4:
            case 0xE5:
            case 0xE6:
            case 0xE7:
            case 0xE8:
            case 0xE9:
            case 0xEA:
            case 0xEB:
            case 0xEC:
            case 0xED:
            case 0xEE:
            case 0xEF:
                readAPP0(jpegdata);
                break;
            case 0xFE:
                readCOM(jpegdata);
                break;
            case 0xDB:
                readDQT(jpegdata);
                break;
            case 0xC0:
                readSOF0(jpegdata);
                imgwidth = image.width;
                imgheidht = image.height;
                break;
            case 0xC4:
                reaDHT(jpegdata);
                break;
            case 0xDA:
                readSOS(jpegdata);
                decodeMCU(jpegdata, bgrdata);
                break;
            default:
            break;
        }
        memcpy(&start, jpegdata++, 1);
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
callq 0x2570
callq 0x2620
movq -0x10(%rbp), %rcx
movq (%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movb (%rax), %al
movb %al, -0x29(%rbp)
movzbl -0x29(%rbp), %eax
cmpl $0xff, %eax
jne 0x2712
movq -0x10(%rbp), %rcx
movq (%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movb (%rax), %al
movb %al, -0x29(%rbp)
movzbl -0x29(%rbp), %eax
cmpl $0xd8, %eax
jne 0x26fd
movq 0x88e1(%rip), %rdi      # 0xafd0
leaq 0x5a5e(%rip), %rsi      # 0x8154
callq 0x2130
jmp 0x2710
movq 0x88cc(%rip), %rdi      # 0xafd0
leaq 0x5a70(%rip), %rsi      # 0x817b
callq 0x2130
jmp 0x2712
movq -0x10(%rbp), %rcx
movq (%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movb (%rax), %al
movb %al, -0x29(%rbp)
movzbl -0x29(%rbp), %eax
cmpl $0xff, %eax
jne 0x27f8
movq -0x10(%rbp), %rcx
movq (%rcx), %rax
movq %rax, %rdx
incq %rdx
movq %rdx, (%rcx)
movb (%rax), %al
movb %al, -0x29(%rbp)
movzbl -0x29(%rbp), %eax
addl $0xffffff40, %eax       # imm = 0xFFFFFF40
movl %eax, %ecx
movq %rcx, -0x38(%rbp)
subl $0x3e, %eax
ja 0x27db
movq -0x38(%rbp), %rax
leaq 0x58ed(%rip), %rcx      # 0x8058
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
callq 0x2800
jmp 0x27dd
movq -0x10(%rbp), %rdi
callq 0x2a90
jmp 0x27dd
movq -0x10(%rbp), %rdi
callq 0x2ba0
jmp 0x27dd
movq -0x10(%rbp), %rdi
callq 0x2dd0
movl 0x9928(%rip), %ecx      # 0xc0cc
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movl 0x9918(%rip), %ecx      # 0xc0c8
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
jmp 0x27dd
movq -0x10(%rbp), %rdi
callq 0x3230
jmp 0x27dd
movq -0x10(%rbp), %rdi
callq 0x34f0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x3760
jmp 0x27dd
jmp 0x27dd
movq -0x10(%rbp), %rcx
movq (%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, (%rcx)
movb (%rax), %al
movb %al, -0x29(%rbp)
jmp 0x2728
xorl %eax, %eax
addq $0x40, %rsp
popq %rbp
retq