// File: leobru[P]ACPUfont/averager.cc
// Function: main
int main(int argc, char**argv) {
    // Take at least 2 files, mean mode (default) or spanning tree mode.
    bool spanning = false;
    bool contrastMean = false;
    int opt;
    static const char usage[] =
        "Usage: %s [-s] [-t] [-mF] [-dN] file1 file2 ...\n\
	-s - use spanning tree combining (default - adding to the mean)\n\
	-c - contrast the mean in the default mode\n\
	-mF - use power F of the pixel count when computing MSE, default 2.0\n\
	-dN - decontrast while adding samples, N=threshold, 0: automatic selection, nondigit: 128\n";

    while ((opt = getopt(argc, argv, "scd:m:")) != -1) {
        switch (opt) {
        case 's':
            spanning = true;
            break;
        case 'c':
            contrastMean = true;
            break;
        case 'd':
            Picture::decontrast = isdigit(*optarg) ? atoi(optarg) : 128;
            break;
        case 'm':
            Picture::msepower = atof(optarg);
            if (Picture::msepower != 0.0)
                break;
        default: /* '?' */
            fprintf(stderr, usage, argv[0]);
            exit(1);
        }
    }
    if (argc - optind < 2) {
        fprintf(stderr, usage, argv[0]);
        exit(1);
    }

    vector<Picture> pics;
    for (int arg = optind; arg < argc; ++arg) {
        pics.push_back(Picture(argv[arg]));
        if (pics.back().height != pics.front().height || pics.back().width != pics.front().width) {
            fprintf(stderr, "Files must have same dimensions, got %dx%d and %dx%d\n",
                    pics.front().width, pics.front().height, pics.back().width, pics.back().height);
            exit(1);
        }
    }
    
    if (spanning) {
        averageSpanningTree(pics);
    } else {
    averageToMean(pics, contrastMean);
    }
}

// Assembly:
subq $0x98, %rsp
movl $0x0, 0x94(%rsp)
movl %edi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movb $0x0, 0x87(%rsp)
movb $0x0, 0x86(%rsp)
movl 0x90(%rsp), %edi
movq 0x88(%rsp), %rsi
leaq 0xb0f2(%rip), %rdx      # 0xd1e9
callq 0x1040
movl %eax, 0x80(%rsp)
cmpl $-0x1, %eax
je 0x21fa
movl 0x80(%rsp), %eax
addl $-0x63, %eax
movl %eax, %ecx
movq %rcx, 0x20(%rsp)
subl $0x10, %eax
ja 0x21c8
movq 0x20(%rsp), %rax
leaq 0xaf0e(%rip), %rcx      # 0xd040
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, 0x87(%rsp)
jmp 0x21f5
movb $0x1, 0x86(%rsp)
jmp 0x21f5
movq 0xfe64(%rip), %rax      # 0x11fc0
movq (%rax), %rax
movsbl (%rax), %edi
callq 0x10c0
cmpl $0x0, %eax
je 0x2181
movq 0xfe4d(%rip), %rax      # 0x11fc0
movq (%rax), %rdi
callq 0x1170
movl %eax, 0x1c(%rsp)
jmp 0x218c
movl $0x80, %eax
movl %eax, 0x1c(%rsp)
jmp 0x218c
movl 0x1c(%rsp), %eax
movl %eax, 0xff6a(%rip)      # 0x12100
jmp 0x21f5
movq 0xfe21(%rip), %rax      # 0x11fc0
movq (%rax), %rdi
callq 0x1120
movsd %xmm0, 0xff59(%rip)     # 0x12108
movsd 0xff51(%rip), %xmm0     # 0x12108
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x21c4
jp 0x21c4
jmp 0x21c6
jmp 0x21f5
jmp 0x21c8
movq 0xfe01(%rip), %rax      # 0x11fd0
movq (%rax), %rdi
movq 0x88(%rsp), %rax
movq (%rax), %rdx
leaq 0xaeac(%rip), %rsi      # 0xd090
movb $0x0, %al
callq 0x1140
movl $0x1, %edi
callq 0x1110
jmp 0x20e1
movl 0x90(%rsp), %eax
movq 0xfdd0(%rip), %rcx      # 0x11fd8
subl (%rcx), %eax
cmpl $0x2, %eax
jge 0x223c
movq 0xfdba(%rip), %rax      # 0x11fd0
movq (%rax), %rdi
movq 0x88(%rsp), %rax
movq (%rax), %rdx
leaq 0xae65(%rip), %rsi      # 0xd090
movb $0x0, %al
callq 0x1140
movl $0x1, %edi
callq 0x1110
leaq 0x68(%rsp), %rdi
callq 0x38a0
movq 0xfd8b(%rip), %rax      # 0x11fd8
movl (%rax), %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
cmpl 0x90(%rsp), %eax
jge 0x23a2
movq 0x88(%rsp), %rax
movslq 0x64(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x38(%rsp), %rdi
callq 0x38e0
jmp 0x2281
leaq 0x68(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x38b0
jmp 0x2292
leaq 0x38(%rsp), %rdi
callq 0x2840
leaq 0x68(%rsp), %rdi
callq 0x3800
movl 0x24(%rax), %eax
movl %eax, 0x18(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x2400
movq %rax, %rcx
movl 0x18(%rsp), %eax
cmpl 0x24(%rcx), %eax
jne 0x22ee
leaq 0x68(%rsp), %rdi
callq 0x3800
movl 0x20(%rax), %eax
movl %eax, 0x14(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x2400
movq %rax, %rcx
movl 0x14(%rsp), %eax
cmpl 0x20(%rcx), %eax
je 0x2390
movq 0xfcdb(%rip), %rax      # 0x11fd0
movq (%rax), %rax
movq %rax, (%rsp)
leaq 0x68(%rsp), %rdi
callq 0x2400
movl 0x20(%rax), %eax
movl %eax, 0x8(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x2400
movl 0x24(%rax), %eax
movl %eax, 0xc(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x3800
movl 0x20(%rax), %eax
movl %eax, 0x10(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x3800
movq (%rsp), %rdi
movl 0x8(%rsp), %edx
movl 0xc(%rsp), %ecx
movl 0x10(%rsp), %r8d
movl 0x24(%rax), %r9d
leaq 0xae9b(%rip), %rsi      # 0xd1f0
movb $0x0, %al
callq 0x1140
movl $0x1, %edi
callq 0x1110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x30(%rsp)
movl %eax, 0x2c(%rsp)
jmp 0x23ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x30(%rsp)
movl %eax, 0x2c(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x2840
jmp 0x23ec
jmp 0x2392
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x2253
testb $0x1, 0x87(%rsp)
je 0x23ba
leaq 0x68(%rsp), %rdi
callq 0x18f0
jmp 0x23b8
jmp 0x23d3
movzbl 0x86(%rsp), %esi
andl $0x1, %esi
leaq 0x68(%rsp), %rdi
callq 0x1320
jmp 0x23d1
jmp 0x23d3
leaq 0x68(%rsp), %rdi
callq 0x3b30
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
leaq 0x68(%rsp), %rdi
callq 0x3b30
movq 0x30(%rsp), %rdi
callq 0x11b0