// File: leobru[P]ACPUfont/averager.cc
// Function: Picture::find_knee(bool) const
int find_knee(bool upper) const {
        vector<int> pixels = *this;
        if (upper) {
            std::sort(pixels.begin(), pixels.end(), std::greater<int>());
        } else {
            std::sort(pixels.begin(), pixels.end());
        }
        // The background/flush color ends where the normalized histogram derivative
        // is greater than 1 for the first time. 
        int totpix = pixels.size();
        int range = std::abs(pixels.back()-pixels.front());
        int grouplen = totpix/(range+1);
        // We've found the knee when the mean of the current group differs
        // from the mean of the previous group by more than weight.
        double prev = std::accumulate(pixels.begin(), pixels.begin()+grouplen, 0)/(double)grouplen;
        for (int i = 1; i < range; ++i) {
            double cur = std::accumulate(pixels.begin()+i*grouplen, pixels.begin()+(i+1)*grouplen, 0)/(double)grouplen;
            if (upper ? cur < prev-weight : cur > prev+weight) {
                 return prev;
            }
            cur = prev;
        }
        // Nothing interesting found, return the median
        return pixels[totpix/2];
    }

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movb %sil, %al
movq %rdi, 0xf8(%rsp)
andb $0x1, %al
movb %al, 0xf7(%rsp)
movq 0xf8(%rsp), %rsi
movq %rsi, 0x30(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x4740
testb $0x1, 0xf7(%rsp)
je 0x2aea
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x4880
movq 0x28(%rsp), %rdi
movq %rax, 0xd0(%rsp)
callq 0x48b0
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
movq 0xc8(%rsp), %rsi
callq 0x4840
jmp 0x2ac2
jmp 0x2b2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x45d0
jmp 0x2d85
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x4880
movq 0x20(%rsp), %rdi
movq %rax, 0xa8(%rsp)
callq 0x48b0
movq %rax, 0xa0(%rsp)
movq 0xa8(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x48e0
jmp 0x2b2d
jmp 0x2b2f
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x3b90
movq 0x10(%rsp), %rdi
movl %eax, 0x9c(%rsp)
callq 0x4920
movq 0x10(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0xc(%rsp)
callq 0x4960
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl 0xc(%rsp), %eax
movl (%rcx), %ecx
subl %ecx, %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x98(%rsp)
movl 0x9c(%rsp), %eax
movl 0x98(%rsp), %ecx
incl %ecx
cltd
idivl %ecx
movl %eax, 0x94(%rsp)
callq 0x4880
movq 0x10(%rsp), %rdi
movq %rax, 0x80(%rsp)
callq 0x4880
movq %rax, 0x70(%rsp)
movslq 0x94(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0x49f0
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
movq 0x78(%rsp), %rsi
xorl %edx, %edx
callq 0x4990
movl %eax, 0x1c(%rsp)
jmp 0x2be7
movl 0x1c(%rsp), %eax
cvtsi2sd %eax, %xmm0
cvtsi2sdl 0x94(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x88(%rsp)
movl $0x1, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x98(%rsp), %eax
jge 0x2d39
leaq 0xd8(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x4880
movq %rax, 0x50(%rsp)
movl 0x6c(%rsp), %eax
movl 0x94(%rsp), %ecx
imull %ecx, %eax
movslq %eax, %rsi
leaq 0x50(%rsp), %rdi
callq 0x49f0
movq (%rsp), %rdi
movq %rax, 0x58(%rsp)
callq 0x4880
movq %rax, 0x40(%rsp)
movl 0x6c(%rsp), %eax
incl %eax
movl 0x94(%rsp), %ecx
imull %ecx, %eax
movslq %eax, %rsi
leaq 0x40(%rsp), %rdi
callq 0x49f0
movq %rax, 0x48(%rsp)
movq 0x58(%rsp), %rdi
movq 0x48(%rsp), %rsi
xorl %edx, %edx
callq 0x4990
movl %eax, 0x8(%rsp)
jmp 0x2c9b
movl 0x8(%rsp), %eax
cvtsi2sd %eax, %xmm0
cvtsi2sdl 0x94(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
testb $0x1, 0xf7(%rsp)
je 0x2ce1
movq 0x30(%rsp), %rax
movsd 0x60(%rsp), %xmm1
movsd 0x88(%rsp), %xmm0
subsd 0x18(%rax), %xmm0
ucomisd %xmm1, %xmm0
ja 0x2d00
jmp 0x2d1a
movq 0x30(%rsp), %rax
movsd 0x60(%rsp), %xmm0
movsd 0x88(%rsp), %xmm1
addsd 0x18(%rax), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2d1a
cvttsd2si 0x88(%rsp), %eax
movl %eax, 0x104(%rsp)
movl $0x1, 0x3c(%rsp)
jmp 0x2d69
movsd 0x88(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x2c0d
movl 0x9c(%rsp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movslq %eax, %rsi
leaq 0xd8(%rsp), %rdi
callq 0x43f0
movl (%rax), %eax
movl %eax, 0x104(%rsp)
movl $0x1, 0x3c(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x45d0
movl 0x104(%rsp), %eax
addq $0x108, %rsp            # imm = 0x108
retq
movq 0xb8(%rsp), %rdi
callq 0x11b0
nopw %cs:(%rax,%rax)
nopl (%rax)