// File: cloudinary[P]fuif/transform/2dmatch.h
// Function: inv_match(Image&, std::vector<int, std::allocator<int>>)
bool inv_match(Image &input, std::vector<int> parameters) {
    if (input.nb_meta_channels < 1) {
        e_printf("Error: match transform without match.\n");
        return false;
    }
    if (!parameters.size()) default_match_parameters(parameters,input);
    if (parameters.size() < 3) {
        e_printf("Error: match transform with incorrect parameters.\n");
        return false;
    }
    const Channel &m = input.channel[0];
    int c0 = input.nb_meta_channels + parameters[0];
    int cn = input.nb_meta_channels + parameters[1];
    if (c0 >= input.channel.size() || cn >= input.channel.size()) {
        e_printf("Error: match transform with incorrect parameters.\n");
        return false;
    }
    bool softmatch = parameters[2];
    int w = input.channel[c0].w;
    int h = input.channel[c0].h;


    if (m.q == 1) {
        offsets offsets_table(m.maxval + 1);
        make_offsets_table(offsets_table);
        if (softmatch)
        for (int y=0; y<h; y++) {
          for (int x=0; x<w; x++) {
            pixel_type z = m.value(y,x);
            if (z) {
                offset o = offsets_table[z];
                for (int c=c0; c<=cn; c++)
                    input.channel[c].value(y,x) += input.channel[c].value(y+o.second, x+o.first);
            }
          }
        }
        else
        for (int y=0; y<h; y++) {
          for (int x=0; x<w; x++) {
            pixel_type z = m.value(y,x);
            if (z) {
                offset o = offsets_table[z];
                for (int c=c0; c<=cn; c++)
                    input.channel[c].value(y,x) = input.channel[c].value(y+o.second, x+o.first);
            }
          }
        }
    } else {
        int fh = h/input.nb_frames;
        int offsetcode = 2*fh*fh + (fh&1); // this simple formula corresponds to the code to go exactly one frame up
        if (m.q == offsetcode) {
            // this is the special case where we are matching with corresponding pixels from previous frames; optimize it a bit...
            if (softmatch)
            for (int y=0; y<h; y++) {
              for (int x=0; x<w; x++) {
                pixel_type z = m.value(y,x);
                if (z) {
                    for (int c=c0; c<=cn; c++)
                        input.channel[c].value(y,x) += input.channel[c].value(y-z*fh, x);
                }
              }
            }
            else
            for (int y=0; y<h; y++) {
              for (int x=0; x<w; x++) {
                pixel_type z = m.value(y,x);
                if (z) {
                    for (int c=c0; c<=cn; c++)
                        input.channel[c].value(y,x) = input.channel[c].value(y-z*fh, x);
                }
              }
            }
        } else {
            e_printf("Error: match transform with unexpected quantization factor. Not implemented.\n");
            return false;
        }
    }
    input.nb_meta_channels--;
    input.channel.erase(input.channel.begin(),input.channel.begin()+1);
    return true;
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rsi, 0x70(%rsp)
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
movq 0x158(%rsp), %rax
cmpl $0x1, 0x6c(%rax)
jge 0xe325
leaq 0x389ef(%rip), %rdi     # 0x46d00
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x167(%rsp)
jmp 0xec9d
movq 0x70(%rsp), %rdi
callq 0x4d50
cmpq $0x0, %rax
jne 0xe347
movq 0x70(%rsp), %rdi
movq 0x158(%rsp), %rsi
callq 0xe260
movq 0x70(%rsp), %rdi
callq 0x4d50
cmpq $0x3, %rax
jae 0xe372
leaq 0x389c9(%rip), %rdi     # 0x46d27
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x167(%rsp)
jmp 0xec9d
movq 0x158(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4ba0
movq 0x70(%rsp), %rdi
movq %rax, 0x148(%rsp)
movq 0x158(%rsp), %rax
movl 0x6c(%rax), %eax
movl %eax, 0x60(%rsp)
xorl %eax, %eax
movl %eax, %esi
callq 0x12190
movq 0x70(%rsp), %rdi
movq %rax, %rcx
movl 0x60(%rsp), %eax
addl (%rcx), %eax
movl %eax, 0x144(%rsp)
movq 0x158(%rsp), %rax
movl 0x6c(%rax), %eax
movl %eax, 0x64(%rsp)
movl $0x1, %esi
callq 0x12190
movq %rax, %rcx
movl 0x64(%rsp), %eax
addl (%rcx), %eax
movl %eax, 0x140(%rsp)
movslq 0x144(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x158(%rsp), %rdi
callq 0x4b80
movq %rax, %rcx
movq 0x68(%rsp), %rax
cmpq %rcx, %rax
jae 0xe434
movslq 0x140(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x158(%rsp), %rdi
callq 0x4b80
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
jb 0xe44f
leaq 0x388ec(%rip), %rdi     # 0x46d27
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x167(%rsp)
jmp 0xec9d
movq 0x70(%rsp), %rdi
movl $0x2, %esi
callq 0x12190
cmpl $0x0, (%rax)
setne %al
andb $0x1, %al
movb %al, 0x13f(%rsp)
movq 0x158(%rsp), %rdi
movslq 0x144(%rsp), %rsi
callq 0x4ba0
movl 0x18(%rax), %eax
movl %eax, 0x138(%rsp)
movq 0x158(%rsp), %rdi
movslq 0x144(%rsp), %rsi
callq 0x4ba0
movl 0x1c(%rax), %eax
movl %eax, 0x134(%rsp)
movq 0x148(%rsp), %rax
cmpl $0x1, 0x28(%rax)
jne 0xe8bb
movq 0x148(%rsp), %rax
movswl 0x22(%rax), %eax
incl %eax
cltq
movq %rax, 0x48(%rsp)
leaq 0x117(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x13440
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdx
leaq 0x118(%rsp), %rdi
callq 0x13450
jmp 0xe4fd
leaq 0x117(%rsp), %rdi
callq 0x134d0
leaq 0x118(%rsp), %rdi
callq 0xe1d0
testb $0x1, 0x13f(%rsp)
je 0xe710
movl $0x0, 0x100(%rsp)
movl 0x100(%rsp), %eax
cmpl 0x134(%rsp), %eax
jge 0xe70b
movl $0x0, 0xfc(%rsp)
movl 0xfc(%rsp), %eax
cmpl 0x138(%rsp), %eax
jge 0xe6f3
movq 0x148(%rsp), %rdi
movl 0x100(%rsp), %esi
movl 0xfc(%rsp), %edx
callq 0x12ba0
movw %ax, 0x46(%rsp)
jmp 0xe585
movw 0x46(%rsp), %ax
movw %ax, 0xfa(%rsp)
cmpw $0x0, 0xfa(%rsp)
je 0xe6db
movswq 0xfa(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x13420
movq (%rax), %rax
movq %rax, 0xf0(%rsp)
movl 0x144(%rsp), %eax
movl %eax, 0xec(%rsp)
movl 0xec(%rsp), %eax
cmpl 0x140(%rsp), %eax
jg 0xe6d9
movq 0x158(%rsp), %rdi
movslq 0xec(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0x100(%rsp), %esi
movl 0xf0(%rsp), %eax
movl 0xf4(%rsp), %ecx
addl %ecx, %esi
movl 0xfc(%rsp), %edx
addl %eax, %edx
callq 0x12110
movq %rax, 0x38(%rsp)
jmp 0xe628
movq 0x38(%rsp), %rax
movswl (%rax), %eax
movl %eax, 0x2c(%rsp)
movq 0x158(%rsp), %rdi
movslq 0xec(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0x100(%rsp), %esi
movl 0xfc(%rsp), %edx
callq 0x12110
movq %rax, 0x30(%rsp)
jmp 0xe666
movq 0x30(%rsp), %rax
movl 0x2c(%rsp), %edx
movswl (%rax), %ecx
addl %edx, %ecx
movw %cx, (%rax)
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0xe5d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x117(%rsp), %rdi
callq 0x134d0
jmp 0xecae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x134e0
jmp 0xecae
jmp 0xe6db
jmp 0xe6dd
movl 0xfc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xfc(%rsp)
jmp 0xe54f
jmp 0xe6f5
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0xe530
jmp 0xe8a9
movl $0x0, 0xe8(%rsp)
movl 0xe8(%rsp), %eax
cmpl 0x134(%rsp), %eax
jge 0xe8a7
movl $0x0, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
cmpl 0x138(%rsp), %eax
jge 0xe88f
movq 0x148(%rsp), %rdi
movl 0xe8(%rsp), %esi
movl 0xe4(%rsp), %edx
callq 0x12ba0
movw %ax, 0x2a(%rsp)
jmp 0xe770
movw 0x2a(%rsp), %ax
movw %ax, 0xe2(%rsp)
cmpw $0x0, 0xe2(%rsp)
je 0xe877
movswq 0xe2(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x13420
movq (%rax), %rax
movq %rax, 0xd8(%rsp)
movl 0x144(%rsp), %eax
movl %eax, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
cmpl 0x140(%rsp), %eax
jg 0xe875
movq 0x158(%rsp), %rdi
movslq 0xd4(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xe8(%rsp), %esi
movl 0xd8(%rsp), %eax
movl 0xdc(%rsp), %ecx
addl %ecx, %esi
movl 0xe4(%rsp), %edx
addl %eax, %edx
callq 0x12110
movq %rax, 0x20(%rsp)
jmp 0xe813
movq 0x20(%rsp), %rax
movw (%rax), %ax
movw %ax, 0x16(%rsp)
movq 0x158(%rsp), %rdi
movslq 0xd4(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xe8(%rsp), %esi
movl 0xe4(%rsp), %edx
callq 0x12110
movq %rax, 0x18(%rsp)
jmp 0xe852
movq 0x18(%rsp), %rax
movw 0x16(%rsp), %cx
movw %cx, (%rax)
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0xe7bb
jmp 0xe877
jmp 0xe879
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0xe73a
jmp 0xe891
movl 0xe8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe8(%rsp)
jmp 0xe71b
jmp 0xe8a9
leaq 0x118(%rsp), %rdi
callq 0x134e0
jmp 0xebec
movl 0x134(%rsp), %eax
movq 0x158(%rsp), %rcx
cltd
idivl 0x38(%rcx)
movl %eax, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
shll %eax
imull 0xd0(%rsp), %eax
movl 0xd0(%rsp), %ecx
andl $0x1, %ecx
addl %ecx, %eax
movl %eax, 0xcc(%rsp)
movq 0x148(%rsp), %rax
movl 0x28(%rax), %eax
cmpl 0xcc(%rsp), %eax
jne 0xebcf
testb $0x1, 0x13f(%rsp)
je 0xea79
movl $0x0, 0xc8(%rsp)
movl 0xc8(%rsp), %eax
cmpl 0x134(%rsp), %eax
jge 0xea74
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
cmpl 0x138(%rsp), %eax
jge 0xea5c
movq 0x148(%rsp), %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %edx
callq 0x12ba0
movw %ax, 0xc2(%rsp)
cmpw $0x0, 0xc2(%rsp)
je 0xea44
movl 0x144(%rsp), %eax
movl %eax, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
cmpl 0x140(%rsp), %eax
jg 0xea42
movq 0x158(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xc8(%rsp), %esi
movswl 0xc2(%rsp), %eax
imull 0xd0(%rsp), %eax
subl %eax, %esi
movl 0xc4(%rsp), %edx
callq 0x12110
movswl (%rax), %eax
movl %eax, 0x10(%rsp)
movq 0x158(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xc8(%rsp), %esi
movl 0xc4(%rsp), %edx
callq 0x12110
movl 0x10(%rsp), %edx
movswl (%rax), %ecx
addl %edx, %ecx
movw %cx, (%rax)
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0xe99d
jmp 0xea44
jmp 0xea46
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0xe949
jmp 0xea5e
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0xe92a
jmp 0xebcd
movl $0x0, 0xb8(%rsp)
movl 0xb8(%rsp), %eax
cmpl 0x134(%rsp), %eax
jge 0xebcb
movl $0x0, 0xb4(%rsp)
movl 0xb4(%rsp), %eax
cmpl 0x138(%rsp), %eax
jge 0xebb3
movq 0x148(%rsp), %rdi
movl 0xb8(%rsp), %esi
movl 0xb4(%rsp), %edx
callq 0x12ba0
movw %ax, 0xb2(%rsp)
cmpw $0x0, 0xb2(%rsp)
je 0xeb9b
movl 0x144(%rsp), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0x140(%rsp), %eax
jg 0xeb99
movq 0x158(%rsp), %rdi
movslq 0xac(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xb8(%rsp), %esi
movswl 0xb2(%rsp), %eax
imull 0xd0(%rsp), %eax
subl %eax, %esi
movl 0xb4(%rsp), %edx
callq 0x12110
movw (%rax), %ax
movw %ax, 0xe(%rsp)
movq 0x158(%rsp), %rdi
movslq 0xac(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xb8(%rsp), %esi
movl 0xb4(%rsp), %edx
callq 0x12110
movw 0xe(%rsp), %cx
movw %cx, (%rax)
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0xeaf7
jmp 0xeb9b
jmp 0xeb9d
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0xeaa3
jmp 0xebb5
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0xea84
jmp 0xebcd
jmp 0xebea
leaq 0x38184(%rip), %rdi     # 0x46d5a
movb $0x0, %al
callq 0x3a670
movb $0x0, 0x167(%rsp)
jmp 0xec9d
jmp 0xebec
movq 0x158(%rsp), %rax
movl 0x6c(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x6c(%rax)
movq 0x158(%rsp), %rax
movq %rax, (%rsp)
movq 0x158(%rsp), %rdi
callq 0x127d0
movq %rax, 0x98(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x12840
movq 0x158(%rsp), %rdi
callq 0x127d0
movq %rax, 0x80(%rsp)
leaq 0x80(%rsp), %rdi
movl $0x1, %esi
callq 0x12800
movq %rax, 0x88(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x12840
movq (%rsp), %rdi
movq 0xa0(%rsp), %rsi
movq 0x90(%rsp), %rdx
callq 0x12730
movq %rax, 0x78(%rsp)
movb $0x1, 0x167(%rsp)
movb 0x167(%rsp), %al
andb $0x1, %al
addq $0x168, %rsp            # imm = 0x168
retq
movq 0x108(%rsp), %rdi
callq 0x36a0
nopl (%rax,%rax)