// File: qhan1028[P]JPEG-Decoder/jpeg-decoder.cpp
// Function: fast_idct(short*, int, bool)
void fast_idct(int16_t* vec, int rc, bool by_row){
    const int FACTOR = 1;
    double a = PI / 16.0;

    double c1 = double(FACTOR * cos(4.0 * a));
    double c2 = double(FACTOR * sin(4.0 * a));
    double c3 = double(FACTOR * cos(a));
    double c4 = double(FACTOR * sin(a));
    double c5 = double(FACTOR * cos(2.0 * a));
    double c6 = double(FACTOR * sin(2.0 * a));
    double c7 = double(FACTOR * cos(3.0 * a));
    double c8 = double(FACTOR * sin(3.0 * a));
    double c9 = double(FACTOR * sqrt(2.0));

    int si1[8] = {4, 0, 1, 7, 2, 6, 3, 5};
    double s1[8];

    if(by_row) {
        for (int i = 0; i < 8; i++) {
            s1[i] = (double)(vec[rc * 8 + si1[i]] * 8);
        }
    } else {
        for (int i = 0; i < 8; i++) {
            s1[i] = (double)(vec[si1[i] * 8 + rc] * 8);
        }
    }

    double s2[8];
    s2[0] = (c1 * s1[0] + c2 * s1[1]) * 2.0;
    s2[1] = (c5 * s1[4] + c6 * s1[5]) * 2.0;
    s2[2] = (c1 * s1[1] - c2 * s1[0]) * 2.0;
    s2[3] = (c5 * s1[5] - c6 * s1[4]) * 2.0;
    s2[4] = (c3 * s1[2] + c4 * s1[3]) * 2.0;
    s2[5] = (c7 * s1[6] + c8 * s1[7]) * 2.0;
    s2[6] = (c3 * s1[3] - c4 * s1[2]) * 2.0;
    s2[7] = (c7 * s1[7] - c8 * s1[6]) * 2.0;

    double s3[8];
    s3[0] = (s2[4] + s2[5]) * 0.5;
    s3[1] = (s2[6] - s2[7]) * 0.5;
    s3[2] = s2[0];
    s3[3] = (s2[4] - s2[5]) * 0.5;
    s3[4] = s2[1];
    s3[5] = s2[2];
    s3[6] = s2[3];
    s3[7] = (s2[6] + s2[7]) * 0.5;

    double s4[8];
    s4[0] = s3[0];
    s4[1] = s3[1];
    s4[2] = s3[2];
    s4[3] = s3[4];
    s4[4] = s3[5];
    s4[5] = s3[3] * c9;
    s4[6] = s3[6];
    s4[7] = s3[7] * c9;

    double s5[8];
    s5[0] = (s4[2] + s4[3]) * 0.5;
    s5[1] = s4[0];
    s5[2] = (s4[4] + s4[5]) * 0.5;
    s5[3] = (s4[6] + s4[7]) * 0.5;
    s5[4] = (s4[2] - s4[3]) * 0.5;
    s5[5] = s4[1];
    s5[6] = (s4[4] - s4[5]) * 0.5;
    s5[7] = (s4[6] - s4[7]) * 0.5;

    double d[8];
    d[0] = (s5[0] + s5[1]) * 0.5;
    d[1] = (s5[2] - s5[3]) * 0.5;
    d[2] = (s5[2] + s5[3]) * 0.5;
    d[3] = (s5[4] - s5[5]) * 0.5;
    d[4] = (s5[4] + s5[5]) * 0.5;
    d[5] = (s5[6] + s5[7]) * 0.5;
    d[6] = (s5[6] - s5[7]) * 0.5;
    d[7] = (s5[0] - s5[1]) * 0.5;

    if(by_row) {
        for(int i = 0; i < 8; i++){
            if(d[i] < 0) {
                vec[rc * 8 + i] = (int16_t)((d[i] - 4) / 8);
            } else {
                vec[rc * 8 + i] = (int16_t)((d[i] + 4) / 8);
            }
        }
    }
    else {
        for(int i = 0; i < 8; i++){
            if(d[i] < 0){
                vec[i * 8 + rc] = (int16_t)((d[i] - 4) / 8);
            } else {
                vec[i * 8 + rc] = (int16_t)((d[i] + 4) / 8);
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movb %dl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
andb $0x1, %al
movb %al, -0xd(%rbp)
movl $0x1, -0x14(%rbp)
movsd 0x88a0(%rip), %xmm0     # 0xb028
movsd %xmm0, -0x20(%rbp)
movsd 0x888b(%rip), %xmm0     # 0xb020
mulsd -0x20(%rbp), %xmm0
callq 0x2360
movaps %xmm0, %xmm1
movsd 0x885e(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd 0x8865(%rip), %xmm0     # 0xb020
mulsd -0x20(%rbp), %xmm0
callq 0x2070
movaps %xmm0, %xmm1
movsd 0x8838(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movsd -0x20(%rbp), %xmm0
callq 0x2360
movaps %xmm0, %xmm1
movsd 0x881a(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x20(%rbp), %xmm0
callq 0x2070
movaps %xmm0, %xmm1
movsd 0x87fc(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rbp)
movsd 0x87f3(%rip), %xmm0     # 0xb010
mulsd -0x20(%rbp), %xmm0
callq 0x2360
movaps %xmm0, %xmm1
movsd 0x87d6(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movsd 0x87cd(%rip), %xmm0     # 0xb010
mulsd -0x20(%rbp), %xmm0
callq 0x2070
movaps %xmm0, %xmm1
movsd 0x87b0(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd 0x87af(%rip), %xmm0     # 0xb018
mulsd -0x20(%rbp), %xmm0
callq 0x2360
movaps %xmm0, %xmm1
movsd 0x878a(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd 0x8789(%rip), %xmm0     # 0xb018
mulsd -0x20(%rbp), %xmm0
callq 0x2070
movaps %xmm0, %xmm1
movsd 0x8764(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd 0x875b(%rip), %xmm0     # 0xb010
callq 0x2150
movaps %xmm0, %xmm1
movsd 0x8743(%rip), %xmm0     # 0xb008
mulsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
movq 0x880b(%rip), %rax      # 0xb0e0
movq %rax, -0x90(%rbp)
movq 0x8805(%rip), %rax      # 0xb0e8
movq %rax, -0x88(%rbp)
movq 0x87ff(%rip), %rax      # 0xb0f0
movq %rax, -0x80(%rbp)
movq 0x87fc(%rip), %rax      # 0xb0f8
movq %rax, -0x78(%rbp)
testb $0x1, -0xd(%rbp)
je 0x2962
movl $0x0, -0xd4(%rbp)
cmpl $0x8, -0xd4(%rbp)
jge 0x2960
movq -0x8(%rbp), %rax
movl -0xc(%rbp), %ecx
shll $0x3, %ecx
movslq -0xd4(%rbp), %rdx
addl -0x90(%rbp,%rdx,4), %ecx
movslq %ecx, %rcx
movswl (%rax,%rcx,2), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm0
movslq -0xd4(%rbp), %rax
movsd %xmm0, -0xd0(%rbp,%rax,8)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x2910
jmp 0x29be
movl $0x0, -0xd8(%rbp)
cmpl $0x8, -0xd8(%rbp)
jge 0x29bc
movq -0x8(%rbp), %rax
movslq -0xd8(%rbp), %rcx
movl -0x90(%rbp,%rcx,4), %ecx
shll $0x3, %ecx
addl -0xc(%rbp), %ecx
movslq %ecx, %rcx
movswl (%rax,%rcx,2), %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm0
movslq -0xd8(%rbp), %rax
movsd %xmm0, -0xd0(%rbp,%rax,8)
movl -0xd8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd8(%rbp)
jmp 0x296c
jmp 0x29be
movsd -0x28(%rbp), %xmm0
movsd -0xd0(%rbp), %xmm2
movsd -0x30(%rbp), %xmm1
mulsd -0xc8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x8628(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0x120(%rbp)
movsd -0x48(%rbp), %xmm0
movsd -0xb0(%rbp), %xmm2
movsd -0x50(%rbp), %xmm1
mulsd -0xa8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x85f2(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0x118(%rbp)
movsd -0x28(%rbp), %xmm0
movsd -0xc8(%rbp), %xmm2
movsd -0x30(%rbp), %xmm1
mulsd -0xd0(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x85a5(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0x110(%rbp)
movsd -0x48(%rbp), %xmm0
movsd -0xa8(%rbp), %xmm2
movsd -0x50(%rbp), %xmm1
mulsd -0xb0(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x8558(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0x108(%rbp)
movsd -0x38(%rbp), %xmm0
movsd -0xc0(%rbp), %xmm2
movsd -0x40(%rbp), %xmm1
mulsd -0xb8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x8522(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0x100(%rbp)
movsd -0x58(%rbp), %xmm0
movsd -0xa0(%rbp), %xmm2
movsd -0x60(%rbp), %xmm1
mulsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x84ec(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0xf8(%rbp)
movsd -0x38(%rbp), %xmm0
movsd -0xb8(%rbp), %xmm2
movsd -0x40(%rbp), %xmm1
mulsd -0xc0(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x849f(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0xf0(%rbp)
movsd -0x58(%rbp), %xmm0
movsd -0x98(%rbp), %xmm2
movsd -0x60(%rbp), %xmm1
mulsd -0xa0(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x8452(%rip), %xmm1     # 0xb010
mulsd %xmm1, %xmm0
movsd %xmm0, -0xe8(%rbp)
movsd -0x100(%rbp), %xmm0
addsd -0xf8(%rbp), %xmm0
movsd 0x844e(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x160(%rbp)
movsd -0xf0(%rbp), %xmm0
subsd -0xe8(%rbp), %xmm0
movsd 0x842a(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x158(%rbp)
movsd -0x120(%rbp), %xmm0
movsd %xmm0, -0x150(%rbp)
movsd -0x100(%rbp), %xmm0
subsd -0xf8(%rbp), %xmm0
movsd 0x83f6(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x148(%rbp)
movsd -0x118(%rbp), %xmm0
movsd %xmm0, -0x140(%rbp)
movsd -0x110(%rbp), %xmm0
movsd %xmm0, -0x138(%rbp)
movsd -0x108(%rbp), %xmm0
movsd %xmm0, -0x130(%rbp)
movsd -0xf0(%rbp), %xmm0
addsd -0xe8(%rbp), %xmm0
movsd 0x83a2(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x128(%rbp)
movsd -0x160(%rbp), %xmm0
movsd %xmm0, -0x1a0(%rbp)
movsd -0x158(%rbp), %xmm0
movsd %xmm0, -0x198(%rbp)
movsd -0x150(%rbp), %xmm0
movsd %xmm0, -0x190(%rbp)
movsd -0x140(%rbp), %xmm0
movsd %xmm0, -0x188(%rbp)
movsd -0x138(%rbp), %xmm0
movsd %xmm0, -0x180(%rbp)
movsd -0x148(%rbp), %xmm0
mulsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x178(%rbp)
movsd -0x130(%rbp), %xmm0
movsd %xmm0, -0x170(%rbp)
movsd -0x128(%rbp), %xmm0
mulsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x168(%rbp)
movsd -0x190(%rbp), %xmm0
addsd -0x188(%rbp), %xmm0
movsd 0x82f4(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1e0(%rbp)
movsd -0x1a0(%rbp), %xmm0
movsd %xmm0, -0x1d8(%rbp)
movsd -0x180(%rbp), %xmm0
addsd -0x178(%rbp), %xmm0
movsd 0x82c0(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1d0(%rbp)
movsd -0x170(%rbp), %xmm0
addsd -0x168(%rbp), %xmm0
movsd 0x829c(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1c8(%rbp)
movsd -0x190(%rbp), %xmm0
subsd -0x188(%rbp), %xmm0
movsd 0x8278(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1c0(%rbp)
movsd -0x198(%rbp), %xmm0
movsd %xmm0, -0x1b8(%rbp)
movsd -0x180(%rbp), %xmm0
subsd -0x178(%rbp), %xmm0
movsd 0x8244(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1b0(%rbp)
movsd -0x170(%rbp), %xmm0
subsd -0x168(%rbp), %xmm0
movsd 0x8220(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1a8(%rbp)
movsd -0x1e0(%rbp), %xmm0
addsd -0x1d8(%rbp), %xmm0
movsd 0x81fc(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x220(%rbp)
movsd -0x1d0(%rbp), %xmm0
subsd -0x1c8(%rbp), %xmm0
movsd 0x81d8(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x218(%rbp)
movsd -0x1d0(%rbp), %xmm0
addsd -0x1c8(%rbp), %xmm0
movsd 0x81b4(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x210(%rbp)
movsd -0x1c0(%rbp), %xmm0
subsd -0x1b8(%rbp), %xmm0
movsd 0x8190(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x208(%rbp)
movsd -0x1c0(%rbp), %xmm0
addsd -0x1b8(%rbp), %xmm0
movsd 0x816c(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x200(%rbp)
movsd -0x1b0(%rbp), %xmm0
addsd -0x1a8(%rbp), %xmm0
movsd 0x8148(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1f8(%rbp)
movsd -0x1b0(%rbp), %xmm0
subsd -0x1a8(%rbp), %xmm0
movsd 0x8124(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1f0(%rbp)
movsd -0x1e0(%rbp), %xmm0
subsd -0x1d8(%rbp), %xmm0
movsd 0x8100(%rip), %xmm1     # 0xb030
mulsd %xmm1, %xmm0
movsd %xmm0, -0x1e8(%rbp)
testb $0x1, -0xd(%rbp)
je 0x301b
movl $0x0, -0x224(%rbp)
cmpl $0x8, -0x224(%rbp)
jge 0x3016
movslq -0x224(%rbp), %rax
xorps %xmm0, %xmm0
ucomisd -0x220(%rbp,%rax,8), %xmm0
jbe 0x2fba
movslq -0x224(%rbp), %rax
movsd -0x220(%rbp,%rax,8), %xmm0
movsd 0x80b6(%rip), %xmm1     # 0xb040
addsd %xmm1, %xmm0
movsd 0x80a2(%rip), %xmm1     # 0xb038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, %dx
movq -0x8(%rbp), %rax
movl -0xc(%rbp), %ecx
shll $0x3, %ecx
addl -0x224(%rbp), %ecx
movslq %ecx, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x3000
movslq -0x224(%rbp), %rax
movsd -0x220(%rbp,%rax,8), %xmm0
movsd 0x804e(%rip), %xmm1     # 0xb020
addsd %xmm1, %xmm0
movsd 0x805a(%rip), %xmm1     # 0xb038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, %dx
movq -0x8(%rbp), %rax
movl -0xc(%rbp), %ecx
shll $0x3, %ecx
addl -0x224(%rbp), %ecx
movslq %ecx, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x3002
movl -0x224(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x224(%rbp)
jmp 0x2f50
jmp 0x30ed
movl $0x0, -0x228(%rbp)
cmpl $0x8, -0x228(%rbp)
jge 0x30eb
movslq -0x228(%rbp), %rax
xorps %xmm0, %xmm0
ucomisd -0x220(%rbp,%rax,8), %xmm0
jbe 0x308f
movslq -0x228(%rbp), %rax
movsd -0x220(%rbp,%rax,8), %xmm0
movsd 0x7fe1(%rip), %xmm1     # 0xb040
addsd %xmm1, %xmm0
movsd 0x7fcd(%rip), %xmm1     # 0xb038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, %dx
movq -0x8(%rbp), %rax
movl -0x228(%rbp), %ecx
shll $0x3, %ecx
addl -0xc(%rbp), %ecx
movslq %ecx, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x30d5
movslq -0x228(%rbp), %rax
movsd -0x220(%rbp,%rax,8), %xmm0
movsd 0x7f79(%rip), %xmm1     # 0xb020
addsd %xmm1, %xmm0
movsd 0x7f85(%rip), %xmm1     # 0xb038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, %dx
movq -0x8(%rbp), %rax
movl -0x228(%rbp), %ecx
shll $0x3, %ecx
addl -0xc(%rbp), %ecx
movslq %ecx, %rcx
movw %dx, (%rax,%rcx,2)
jmp 0x30d7
movl -0x228(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x228(%rbp)
jmp 0x3025
jmp 0x30ed
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
nopw %cs:(%rax,%rax)