// File: cloudinary[P]fuif/transform/permute.h
// Function: inv_permute(Image&, std::vector<int, std::allocator<int>> const&)
bool inv_permute(Image &input, const std::vector<int> &parameters) {
    Image tmp=input;
    bool use_channel = (parameters.size()==0);
    int perm_length;
    if (use_channel) perm_length = input.channel[0].w;
    else perm_length = parameters.size();

    v_printf(5,"Permutation: ");
    for (int i=0; i<perm_length; i++) {
        int c;
        if (use_channel) c = input.channel[0].value(0,i);
        else c = parameters[i];
        // permutation sanity is already checked in meta-step, so no need to double check
        input.channel[input.nb_meta_channels+i] = tmp.channel[tmp.nb_meta_channels+c];
        v_printf(5,"[%i <- %i] ",i,c);
    }
    if (use_channel) {
     input.nb_meta_channels--;
     input.channel.erase(input.channel.begin(),input.channel.begin()+1);
     assert(input.channel[0].w == input.channel.size() - input.nb_meta_channels);
    }
    v_printf(5,"\n");
    return true;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq 0x130(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x12880
movq 0x128(%rsp), %rdi
callq 0x4d50
cmpq $0x0, %rax
sete %al
andb $0x1, %al
movb %al, 0x77(%rsp)
testb $0x1, 0x77(%rsp)
je 0x10834
movq 0x130(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4ba0
movl 0x18(%rax), %eax
movl %eax, 0x70(%rsp)
jmp 0x10845
movq 0x128(%rsp), %rdi
callq 0x4d50
movl %eax, 0x70(%rsp)
leaq 0x3669c(%rip), %rsi     # 0x46ee8
xorl %eax, %eax
movl $0x5, %edi
callq 0x3a770
jmp 0x1085a
movl $0x0, 0x60(%rsp)
movl 0x60(%rsp), %eax
cmpl 0x70(%rsp), %eax
jge 0x1095c
testb $0x1, 0x77(%rsp)
je 0x108ce
movq 0x130(%rsp), %rdi
xorl %eax, %eax
movl %eax, 0x1c(%rsp)
movl %eax, %esi
callq 0x4ba0
movl 0x1c(%rsp), %esi
movq %rax, %rdi
movl 0x60(%rsp), %edx
callq 0x12110
movq %rax, 0x20(%rsp)
jmp 0x108a3
movq 0x20(%rsp), %rax
movswl (%rax), %eax
movl %eax, 0x5c(%rsp)
jmp 0x108e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x68(%rsp)
movl %eax, 0x64(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x12ab0
jmp 0x10a20
movq 0x128(%rsp), %rdi
movslq 0x60(%rsp), %rsi
callq 0x13560
movl (%rax), %eax
movl %eax, 0x5c(%rsp)
movl 0xe4(%rsp), %eax
movl 0x5c(%rsp), %ecx
addl %ecx, %eax
movslq %eax, %rsi
leaq 0x78(%rsp), %rdi
callq 0x4ba0
movq %rax, 0x10(%rsp)
movq 0x130(%rsp), %rdi
movl 0x6c(%rdi), %eax
movl 0x60(%rsp), %ecx
addl %ecx, %eax
movslq %eax, %rsi
callq 0x4ba0
movq 0x10(%rsp), %rsi
movq %rax, %rdi
callq 0x12390
jmp 0x1092d
movl 0x60(%rsp), %edx
movl 0x5c(%rsp), %ecx
leaq 0x365ba(%rip), %rsi     # 0x46ef6
xorl %eax, %eax
movl $0x5, %edi
callq 0x3a770
jmp 0x1094a
jmp 0x1094c
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x10862
testb $0x1, 0x77(%rsp)
je 0x109f5
movq 0x130(%rsp), %rax
movl 0x6c(%rax), %ecx
decl %ecx
movl %ecx, 0x6c(%rax)
movq 0x130(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x127d0
movq %rax, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x12840
movq 0x130(%rsp), %rdi
callq 0x127d0
movq %rax, 0x30(%rsp)
leaq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x12800
movq %rax, 0x38(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x12840
movq (%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x40(%rsp), %rdx
callq 0x12730
movq %rax, 0x8(%rsp)
jmp 0x109eb
movq 0x8(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x37eb1(%rip), %rsi     # 0x488ad
xorl %eax, %eax
movl $0x5, %edi
callq 0x3a770
jmp 0x10a0a
leaq 0x78(%rsp), %rdi
callq 0x12ab0
movb $0x1, %al
andb $0x1, %al
addq $0x138, %rsp            # imm = 0x138
retq
movq 0x68(%rsp), %rdi
callq 0x36a0
nopw (%rax,%rax)