// File: cloudinary[P]fuif/transform/2dmatch.h
// Function: find_good_match(Image&, int, int, int, int, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>&)
pixel_type find_good_match(Image &img, int c0, int cn, int x, int y, offsets &ot) {
    int max_count=100;   // this is the minimal match size (number of nontrivial matching pixels) to consider
    int best_z=0;
    int w = img.channel[c0].w;
    int h = img.channel[c0].h;
    for (int z=1; z<ot.size(); z++) {
            if (!matches(img,c0,cn,x,y,z,ot,true)) continue;
            int count=0;
            int yy=0;
            for (; y+yy<h; yy++) {
                int xl=0;
                for (; x+xl>=0; xl--) {
                    // if it matches                              // and if it's a nontrivial pixel (not equal to its left neighbor)
                    if (matches(img,c0,cn,x+xl,y+yy,z,ot,true)) { if (!matches(img,c0,cn,x+xl,y+yy,1,ot,true)) count++; }       // then count it
                    else break;
                }
                xl++;
                int xr=1;
                for (; x+xr<w; xr++) {
                    if (matches(img,c0,cn,x+xr,y+yy,z,ot,true)) { if (!matches(img,c0,cn,x+xl,y+yy,1,ot,true)) count++; }
                    else break;
                }
                xr--;
                if (!xl && !xr) break;
                if (xr-xl < 8) break; // minimum 8 pixels wide
            }
            if (yy < 7) break; //minimum 8 pixels high
            if (count>max_count) { max_count=count; best_z=z; }
    }
    if (best_z) v_printf(6,"Found good match at %i,%i with offset %i (x+=%i,y+=%i) and count %i\n",x,y,best_z,ot[best_z].first,ot[best_z].second,max_count);
    return best_z;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movl %esi, 0x6c(%rsp)
movl %edx, 0x68(%rsp)
movl %ecx, 0x64(%rsp)
movl %r8d, 0x60(%rsp)
movq %r9, 0x58(%rsp)
movl $0x64, 0x54(%rsp)
movl $0x0, 0x50(%rsp)
movq 0x70(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x4ba0
movl 0x18(%rax), %eax
movl %eax, 0x4c(%rsp)
movq 0x70(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x4ba0
movl 0x1c(%rax), %eax
movl %eax, 0x48(%rsp)
movl $0x1, 0x44(%rsp)
movslq 0x44(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x58(%rsp), %rdi
callq 0x13400
movq %rax, %rcx
movq 0x28(%rsp), %rax
cmpq %rcx, %rax
jae 0xf443
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
movl 0x64(%rsp), %ecx
movl 0x60(%rsp), %r8d
movl 0x44(%rsp), %r9d
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
movl $0x1, 0x8(%rsp)
callq 0xef00
testb $0x1, %al
jne 0xf232
jmp 0xf433
movl $0x0, 0x40(%rsp)
movl $0x0, 0x3c(%rsp)
movl 0x60(%rsp), %eax
addl 0x3c(%rsp), %eax
cmpl 0x48(%rsp), %eax
jge 0xf40e
movl $0x0, 0x38(%rsp)
movl 0x64(%rsp), %eax
addl 0x38(%rsp), %eax
cmpl $0x0, %eax
jl 0xf30d
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
movl 0x64(%rsp), %ecx
addl 0x38(%rsp), %ecx
movl 0x60(%rsp), %r8d
addl 0x3c(%rsp), %r8d
movl 0x44(%rsp), %r9d
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
movl $0x1, 0x8(%rsp)
callq 0xef00
testb $0x1, %al
jne 0xf2ad
jmp 0xf2f9
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
movl 0x64(%rsp), %ecx
addl 0x38(%rsp), %ecx
movl 0x60(%rsp), %r8d
addl 0x3c(%rsp), %r8d
movq 0x58(%rsp), %rax
movl $0x1, %r9d
movq %rax, (%rsp)
movl $0x1, 0x8(%rsp)
callq 0xef00
testb $0x1, %al
jne 0xf2f7
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0xf2fb
jmp 0xf30d
jmp 0xf2fd
movl 0x38(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0xf25c
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
movl $0x1, 0x34(%rsp)
movl 0x64(%rsp), %eax
addl 0x34(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jge 0xf3d2
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
movl 0x64(%rsp), %ecx
addl 0x34(%rsp), %ecx
movl 0x60(%rsp), %r8d
addl 0x3c(%rsp), %r8d
movl 0x44(%rsp), %r9d
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
movl $0x1, 0x8(%rsp)
callq 0xef00
testb $0x1, %al
jne 0xf372
jmp 0xf3be
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
movl 0x64(%rsp), %ecx
addl 0x38(%rsp), %ecx
movl 0x60(%rsp), %r8d
addl 0x3c(%rsp), %r8d
movq 0x58(%rsp), %rax
movl $0x1, %r9d
movq %rax, (%rsp)
movl $0x1, 0x8(%rsp)
callq 0xef00
testb $0x1, %al
jne 0xf3bc
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0xf3c0
jmp 0xf3d2
jmp 0xf3c2
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0xf320
movl 0x34(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x34(%rsp)
cmpl $0x0, 0x38(%rsp)
jne 0xf3ed
cmpl $0x0, 0x34(%rsp)
jne 0xf3ed
jmp 0xf40e
movl 0x34(%rsp), %eax
subl 0x38(%rsp), %eax
cmpl $0x8, %eax
jge 0xf3fc
jmp 0xf40e
jmp 0xf3fe
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0xf242
cmpl $0x7, 0x3c(%rsp)
jge 0xf417
jmp 0xf443
movl 0x40(%rsp), %eax
cmpl 0x54(%rsp), %eax
jle 0xf431
movl 0x40(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x50(%rsp)
jmp 0xf433
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0xf1d3
cmpl $0x0, 0x50(%rsp)
je 0xf4bb
movl 0x64(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x50(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0x58(%rsp), %rdi
movslq 0x50(%rsp), %rsi
callq 0x13420
movl (%rax), %eax
movl %eax, 0x24(%rsp)
movq 0x58(%rsp), %rdi
movslq 0x50(%rsp), %rsi
callq 0x13420
movl 0x18(%rsp), %edx
movl 0x1c(%rsp), %ecx
movl 0x20(%rsp), %r8d
movl 0x24(%rsp), %r9d
movl 0x4(%rax), %r10d
movl 0x54(%rsp), %eax
movl $0x6, %edi
leaq 0x378fc(%rip), %rsi     # 0x46da8
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x3a770
movl 0x50(%rsp), %eax
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)