// File: /workspace/github_c_makefile_star2_O0/erik[P]gamut/rotate.c
// Function: rotate
int rotate(double angle)
{
    uint32_t inw, inh;
    pixel_t* image = NULL;

    read_header(&inw, &inh);

    if (!(image = calloc(inw * inh, sizeof(pixel_t)))) {
        perror("couldn't allocate memory");
        return 1;
    }

    read_image(image, inw, inh);

    const double rad = angle / 180.0 * M_PI;

    // calculate output dimensions
    int outw, outh;
    {
        const double S = sin(rad);
        const double C = cos(rad);
        double a = inw / 2 * C;
        double b = inh / 2 * S;
        outw = round(MAX(MAX(-a + b, a + b), MAX(-a - b, a - b))) * 2.0;
        double c = inh / 2 * C;
        double d = inw / 2 * S;
        outh = round(MAX(MAX(-c + d, c + d), MAX(-c - d, c - d))) * 2.0;
    }

    write_header(outw, outh);

    const double S = sin(-rad);
    const double C = cos(-rad);
    for (int outy = 0; outy < outh; outy++) {
        for (int outx = 0; outx < outw; outx++) {
            double cox = outx - outw / 2 + 1;
            double coy = outy - outh / 2 + 1;
            // rotate back to find input image coordinates
            double inx = cox * C - coy * S + inw / 2;
            double iny = coy * C + cox * S + inh / 2;
            // separate base coordinates and interpolation factors
            double basex, basey;
            double tx = modf(inx, &basex);
            double ty = modf(iny, &basey);
            int signx = SIGN(tx), signy = SIGN(ty);
            // bilinear interpolation
            pixel_t pixel = interpolate(
                interpolate(
                    sampleat(image, basex, basey, inw, inh),
                    sampleat(image, basex + signx, basey, inw, inh),
                    fabs(tx)),
                interpolate(
                    sampleat(image, basex, basey + signy, inw, inh),
                    sampleat(image, basex + signx, basey + signy, inw, inh),
                    fabs(tx)),
                fabs(ty));
            write_pixel(&pixel);
        }
   }
   return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movsd %xmm0, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
leaq -0x14(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x1c90
movl -0x14(%rbp), %eax
imull -0x18(%rbp), %eax
movl %eax, %eax
movl %eax, %edi
movl $0x8, %esi
callq 0x10c0
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
jne 0x142c
leaq 0x1c25(%rip), %rdi      # 0x3040
callq 0x10e0
movl $0x1, -0x4(%rbp)
jmp 0x1c75
movq -0x20(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
callq 0x1d60
movsd -0x10(%rbp), %xmm0
movsd 0x1bc8(%rip), %xmm1     # 0x3010
divsd %xmm1, %xmm0
movsd 0x1bc4(%rip), %xmm1     # 0x3018
mulsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x10f0
movsd %xmm0, -0x38(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x10b0
movsd %xmm0, -0x40(%rbp)
movl -0x14(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm0
movsd -0x40(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
movl -0x18(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm0
mulsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x50(%rbp), %xmm0
movsd -0x48(%rbp), %xmm1
addsd -0x50(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1501
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x100(%rbp)
jmp 0x1513
movsd -0x48(%rbp), %xmm0
addsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x100(%rbp)
movsd -0x100(%rbp), %xmm0
movsd %xmm0, -0x108(%rbp)
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x50(%rbp), %xmm0
movsd -0x48(%rbp), %xmm1
subsd -0x50(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x157f
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x110(%rbp)
jmp 0x1591
movsd -0x48(%rbp), %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x110(%rbp)
movsd -0x108(%rbp), %xmm0
movsd -0x110(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x162b
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x50(%rbp), %xmm0
movsd -0x48(%rbp), %xmm1
addsd -0x50(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1607
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x118(%rbp)
jmp 0x1619
movsd -0x48(%rbp), %xmm0
addsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x118(%rbp)
movsd -0x118(%rbp), %xmm0
movsd %xmm0, -0x120(%rbp)
jmp 0x16a9
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x50(%rbp), %xmm0
movsd -0x48(%rbp), %xmm1
subsd -0x50(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1687
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x128(%rbp)
jmp 0x1699
movsd -0x48(%rbp), %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x128(%rbp)
movsd -0x128(%rbp), %xmm0
movsd %xmm0, -0x120(%rbp)
movsd -0x120(%rbp), %xmm0
callq 0x1030
addsd %xmm0, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x2c(%rbp)
movl -0x18(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm0
movsd -0x40(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movl -0x14(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm0
mulsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x60(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
addsd -0x60(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1747
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x130(%rbp)
jmp 0x1759
movsd -0x58(%rbp), %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x130(%rbp)
movsd -0x130(%rbp), %xmm0
movsd %xmm0, -0x138(%rbp)
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x60(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
subsd -0x60(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x17c5
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x140(%rbp)
jmp 0x17d7
movsd -0x58(%rbp), %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x140(%rbp)
movsd -0x138(%rbp), %xmm0
movsd -0x140(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1871
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x60(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
addsd -0x60(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x184d
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x148(%rbp)
jmp 0x185f
movsd -0x58(%rbp), %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x148(%rbp)
movsd -0x148(%rbp), %xmm0
movsd %xmm0, -0x150(%rbp)
jmp 0x18ef
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x60(%rbp), %xmm0
movsd -0x58(%rbp), %xmm1
subsd -0x60(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x18cd
movsd -0x58(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x158(%rbp)
jmp 0x18df
movsd -0x58(%rbp), %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x158(%rbp)
movsd -0x158(%rbp), %xmm0
movsd %xmm0, -0x150(%rbp)
movsd -0x150(%rbp), %xmm0
callq 0x1030
movsd 0x171c(%rip), %xmm1     # 0x3020
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %edi
movl -0x30(%rbp), %esi
callq 0x1e40
movsd -0x28(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x10f0
movsd %xmm0, -0x68(%rbp)
movsd -0x28(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x10b0
movsd %xmm0, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x1c6e
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x1c5e
movl -0x78(%rbp), %ecx
movl -0x2c(%rbp), %edx
movl %edx, %eax
shrl $0x1f, %eax
addl %eax, %edx
sarl %edx
movl %ecx, %eax
negl %edx
movl %edx, %ecx
leal 0x1(%rax,%rcx), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x74(%rbp), %ecx
movl -0x30(%rbp), %edx
movl %edx, %eax
shrl $0x1f, %eax
addl %eax, %edx
sarl %edx
movl %ecx, %eax
negl %edx
movl %edx, %ecx
leal 0x1(%rax,%rcx), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x80(%rbp), %xmm0
movsd -0x70(%rbp), %xmm2
movsd -0x88(%rbp), %xmm1
movsd -0x68(%rbp), %xmm3
mulsd %xmm3, %xmm1
mulsd %xmm2, %xmm0
subsd %xmm1, %xmm0
movl -0x14(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x88(%rbp), %xmm0
movsd -0x70(%rbp), %xmm2
movsd -0x80(%rbp), %xmm1
movsd -0x68(%rbp), %xmm3
mulsd %xmm3, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movl -0x18(%rbp), %eax
shrl %eax
cvtsi2sd %eax, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x90(%rbp), %xmm0
leaq -0xa0(%rbp), %rdi
callq 0x1070
movsd %xmm0, -0xb0(%rbp)
movsd -0x98(%rbp), %xmm0
leaq -0xa8(%rbp), %rdi
callq 0x1070
movsd %xmm0, -0xb8(%rbp)
movsd -0xb0(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
seta %al
andb $0x1, %al
movzbl %al, %eax
xorps %xmm0, %xmm0
ucomisd -0xb0(%rbp), %xmm0
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
subl %ecx, %eax
movl %eax, -0xbc(%rbp)
movsd -0xb8(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
seta %al
andb $0x1, %al
movzbl %al, %eax
xorps %xmm0, %xmm0
ucomisd -0xb8(%rbp), %xmm0
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
subl %ecx, %eax
movl %eax, -0xc0(%rbp)
movq -0x20(%rbp), %rdi
cvttsd2si -0xa0(%rbp), %esi
cvttsd2si -0xa8(%rbp), %edx
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %r8d
callq 0x1230
movq %rax, -0xd8(%rbp)
movq -0x20(%rbp), %rdi
movsd -0xa0(%rbp), %xmm0
cvtsi2sdl -0xbc(%rbp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %esi
cvttsd2si -0xa8(%rbp), %edx
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %r8d
callq 0x1230
movq %rax, -0xe0(%rbp)
movsd -0xb0(%rbp), %xmm0
movaps 0x14e2(%rip), %xmm1     # 0x3030
pand %xmm1, %xmm0
movq -0xd8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
callq 0x12e0
movq %rax, -0xd0(%rbp)
movq -0x20(%rbp), %rdi
cvttsd2si -0xa0(%rbp), %esi
movsd -0xa8(%rbp), %xmm0
cvtsi2sdl -0xc0(%rbp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %edx
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %r8d
callq 0x1230
movq %rax, -0xf0(%rbp)
movq -0x20(%rbp), %rdi
movsd -0xa0(%rbp), %xmm0
cvtsi2sdl -0xbc(%rbp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %esi
movsd -0xa8(%rbp), %xmm0
cvtsi2sdl -0xc0(%rbp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %edx
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %r8d
callq 0x1230
movq %rax, -0xf8(%rbp)
movsd -0xb0(%rbp), %xmm0
movaps 0x1437(%rip), %xmm1     # 0x3030
pand %xmm1, %xmm0
movq -0xf0(%rbp), %rdi
movq -0xf8(%rbp), %rsi
callq 0x12e0
movq %rax, -0xe8(%rbp)
movsd -0xb8(%rbp), %xmm0
movaps 0x140a(%rip), %xmm1     # 0x3030
pand %xmm1, %xmm0
movq -0xd0(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0x12e0
movq %rax, -0xc8(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x1ee0
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x1980
jmp 0x1c60
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x196d
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
nopw %cs:(%rax,%rax)