// File: OpenFirework[P]MyJPEG_Decoder/./jpeg/jpeg_decoder.cpp
// Function: decodeMCU(unsigned char*&, unsigned char*&)
void decodeMCU(byte *&framedata, byte *&bgrdata) {
    int w = (image.width - 1) / (8*maxWidth) + 1; //水平mcu的个数
    int h = (image.height - 1) / (8*maxHeight) + 1; //垂直mcu的个数

    bmpwidth = image.width;
    bmpheight = image.height;
    bgrdata = new byte[bmpwidth*bmpheight*3];
    int bytes_per_pixel = 3;
    int bytes_per_row = bmpwidth*3;
    
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            MCU mcu = readMCU(framedata);
            mcu.decode();
            RGB **b = mcu.toRGB();
            for (int y = i*8*maxHeight; y < (i+1)*8*maxHeight; y++) {  //整个图片上的垂直坐标
                for (int x = j*8*maxWidth; x < (j+1)*8*maxWidth; x++) {  //整个图片上的水平坐标
                    int by = y - i*8*maxHeight;
                    int bx = x - j*8*maxWidth;
                    if(x < 0 || x >= bmpwidth || y < 0 || y >= bmpheight) {
                        continue;
                    } else {
                        byte *pixel;
                        pixel = bgrdata + ( y * bytes_per_row + x * bytes_per_pixel );
                        *( pixel + 2 ) = b[by][bx].R;
                        *( pixel + 1 ) = b[by][bx].G;
                        *( pixel + 0 ) = b[by][bx].B;
                    }
                }
            } // end for 

            //释放每个MCU转换RBG数据的暂存内存
            for (int i = 0; i < maxHeight*8; i++) { 
                if(b[i] != nullptr) {
                     delete[] b[i];
                }
            } 
            if(b != nullptr) {
                delete[] b;
            }
            
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2060, %rsp           # imm = 0x2060
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl 0x8953(%rip), %eax      # 0xc0cc
subl $0x1, %eax
movzbl 0x80cd(%rip), %ecx      # 0xb850
shll $0x3, %ecx
cltd
idivl %ecx
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl 0x8933(%rip), %eax      # 0xc0c8
subl $0x1, %eax
movzbl 0x80b2(%rip), %ecx      # 0xb851
shll $0x3, %ecx
cltd
idivl %ecx
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl 0x891b(%rip), %eax      # 0xc0cc
movl %eax, 0x88a9(%rip)      # 0xc060
movl 0x890b(%rip), %eax      # 0xc0c8
movl %eax, 0x88a1(%rip)      # 0xc064
movl 0x8897(%rip), %eax      # 0xc060
imull 0x8894(%rip), %eax      # 0xc064
imull $0x3, %eax, %eax
movslq %eax, %rdi
callq 0x2030
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movl $0x3, -0x1c(%rbp)
imull $0x3, 0x886d(%rip), %eax # 0xc060
movl %eax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x3ac2
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x3ab2
movq -0x8(%rbp), %rsi
leaq -0x2028(%rbp), %rdi
callq 0x46d0
leaq -0x2028(%rbp), %rdi
callq 0x4ba0
leaq -0x2028(%rbp), %rdi
callq 0x4be0
movq %rax, -0x2030(%rbp)
movl -0x24(%rbp), %eax
shll $0x3, %eax
movzbl 0x7ff9(%rip), %ecx      # 0xb851
imull %ecx, %eax
movl %eax, -0x2034(%rbp)
movl -0x2034(%rbp), %eax
movl -0x24(%rbp), %ecx
addl $0x1, %ecx
shll $0x3, %ecx
movzbl 0x7fda(%rip), %edx      # 0xb851
imull %edx, %ecx
cmpl %ecx, %eax
jge 0x3a03
movl -0x28(%rbp), %eax
shll $0x3, %eax
movzbl 0x7fc1(%rip), %ecx      # 0xb850
imull %ecx, %eax
movl %eax, -0x2038(%rbp)
movl -0x2038(%rbp), %eax
movl -0x28(%rbp), %ecx
addl $0x1, %ecx
shll $0x3, %ecx
movzbl 0x7fa2(%rip), %edx      # 0xb850
imull %edx, %ecx
cmpl %ecx, %eax
jge 0x39ed
movl -0x2034(%rbp), %eax
movl -0x24(%rbp), %ecx
shll $0x3, %ecx
movzbl 0x7f85(%rip), %edx      # 0xb851
imull %edx, %ecx
subl %ecx, %eax
movl %eax, -0x203c(%rbp)
movl -0x2038(%rbp), %eax
movl -0x28(%rbp), %ecx
shll $0x3, %ecx
movzbl 0x7f66(%rip), %edx      # 0xb850
imull %edx, %ecx
subl %ecx, %eax
movl %eax, -0x2040(%rbp)
cmpl $0x0, -0x2038(%rbp)
jl 0x3923
movl -0x2038(%rbp), %eax
cmpl 0x8756(%rip), %eax      # 0xc060
jge 0x3923
cmpl $0x0, -0x2034(%rbp)
jl 0x3923
movl -0x2034(%rbp), %eax
cmpl 0x8743(%rip), %eax      # 0xc064
jl 0x3928
jmp 0x39d9
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x2034(%rbp), %ecx
imull -0x20(%rbp), %ecx
movl -0x2038(%rbp), %edx
imull -0x1c(%rbp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x2048(%rbp)
movq -0x2030(%rbp), %rax
movslq -0x203c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2040(%rbp), %rcx
imulq $0x3, %rcx, %rcx
addq %rcx, %rax
movb (%rax), %cl
movq -0x2048(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x2030(%rbp), %rax
movslq -0x203c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2040(%rbp), %rcx
imulq $0x3, %rcx, %rcx
addq %rcx, %rax
movb 0x1(%rax), %cl
movq -0x2048(%rbp), %rax
movb %cl, 0x1(%rax)
movq -0x2030(%rbp), %rax
movslq -0x203c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2040(%rbp), %rcx
imulq $0x3, %rcx, %rcx
addq %rcx, %rax
movb 0x2(%rax), %cl
movq -0x2048(%rbp), %rax
movb %cl, (%rax)
jmp 0x39d9
movl -0x2038(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2038(%rbp)
jmp 0x3898
jmp 0x39ef
movl -0x2034(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2034(%rbp)
jmp 0x3861
movl $0x0, -0x204c(%rbp)
movl -0x204c(%rbp), %eax
movzbl 0x7e37(%rip), %ecx      # 0xb851
shll $0x3, %ecx
cmpl %ecx, %eax
jge 0x3a76
movq -0x2030(%rbp), %rax
movslq -0x204c(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x3a63
movq -0x2030(%rbp), %rax
movslq -0x204c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x2058(%rbp)
cmpq $0x0, %rax
je 0x3a61
movq -0x2058(%rbp), %rdi
callq 0x21a0
jmp 0x3a63
jmp 0x3a65
movl -0x204c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x204c(%rbp)
jmp 0x3a0d
cmpq $0x0, -0x2030(%rbp)
je 0x3aa2
movq -0x2030(%rbp), %rax
movq %rax, -0x2060(%rbp)
cmpq $0x0, %rax
je 0x3aa0
movq -0x2060(%rbp), %rdi
callq 0x21a0
jmp 0x3aa2
jmp 0x3aa4
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3810
jmp 0x3ab4
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x37fd
addq $0x2060, %rsp           # imm = 0x2060
popq %rbp
retq
nopl (%rax,%rax)