// File: matthewarcus[P]mmps/combine.cpp
// Function: main
int main(int argc, char* argv[])
{
  Image image1;
  Image image2;
  const char* file1;
  const char* file2;
  const char* outfilename = NULL;
  Rgb background = black;
  int width;
  int height;
  double fuzz = 2.0;

  char *progname = argv[0];
  argc--;argv++;
  OptSpec *optspecs [] = {
    // General options
    new RgbSpec ("-bg", background),
    new DoubleSpec ("-fuzz", fuzz),
    new StringSpec ("-out", outfilename),
    NULL // Finish up
  };

  while (argc > 0) {
    int result = OptSpec::ReadOpts(argc, argv, optspecs);
    if (result != 1) {
      break;
    }
    argc--; argv++;
  }
  
  if (argc < 2) {
    error(usage, progname);
  }
  file1 = argv[0];
  file2 = argv[1];
  image1.Read(file1);
  image2.Read(file2);

  width = image1.Width();
  height = image1.Height();
  if (image2.Width() != width || image2.Height() != height) {
    error("Images must have same dimensions");
  }
  Image outImage(width, height);
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      Rgb rgb1;
      Rgb rgb2;
      Rgb out;
      image1.GetRgb(col,row,rgb1);
      image2.GetRgb(col,row,rgb2);
      if (rgb1.Match(background,fuzz)) {
	out = rgb2;
      } else if (rgb2.Match(background, fuzz)) {
	out = rgb1;
      } else {
#if 0
	// Average the rgb values, this produces alarming discontinuities
	out.r = (rgb1.r + rgb2.r)/2;
	out.g = (rgb1.g + rgb2.g)/2;
	out.b = (rgb1.b + rgb2.b)/2;
#endif
	// But taking the maximum of the rgb values is smooth
	out.r = max(rgb1.r,rgb2.r);
	out.g = max(rgb1.g,rgb2.g);
	out.b = max(rgb1.b,rgb2.b);

      }
      outImage.SetRgb(col,row,out);
    }
 }
  outImage.Write(outfilename);
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
xorl %eax, %eax
movl %eax, %edx
movq %rdx, -0x138(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdx, %rsi
callq 0x11c00
movq -0x138(%rbp), %rdx
leaq -0x70(%rbp), %rdi
movq %rdx, %rsi
callq 0x11c00
jmp 0x5b55
movq $0x0, -0x98(%rbp)
movb 0x166f5(%rip), %al      # 0x1c25b
movb %al, -0x9a(%rbp)
movw 0x166e6(%rip), %ax      # 0x1c259
movw %ax, -0x9c(%rbp)
movabsq $0x4000000000000000, %rax # imm = 0x4000000000000000
movq %rax, -0xb0(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb8(%rbp)
movl -0x8(%rbp), %eax
decl %eax
movl %eax, -0x8(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x10(%rbp)
movl $0x18, %edi
callq 0x52a0
movq %rax, -0x140(%rbp)
jmp 0x5bc0
movq -0x140(%rbp), %rdi
leaq 0xe458(%rip), %rsi      # 0x14026
leaq -0x9c(%rbp), %rdx
callq 0x6160
jmp 0x5bdc
movq -0x140(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rax
movq %rax, -0x150(%rbp)
movl $0x20, %edi
callq 0x52a0
movq %rax, -0x148(%rbp)
jmp 0x5c0b
movq -0x148(%rbp), %rdi
leaq 0xe411(%rip), %rsi      # 0x1402a
leaq -0xb0(%rbp), %rdx
movsd 0xe3e0(%rip), %xmm0     # 0x14008
callq 0xefb0
jmp 0x5c2f
movq -0x150(%rbp), %rax
movq -0x148(%rbp), %rcx
movq %rcx, (%rax)
leaq -0xd0(%rbp), %rax
movq %rax, -0x160(%rbp)
movl $0x18, %edi
callq 0x52a0
movq %rax, -0x158(%rbp)
jmp 0x5c61
movq -0x158(%rbp), %rdi
leaq 0xe3c1(%rip), %rsi      # 0x14030
leaq -0x98(%rbp), %rdx
callq 0xeda0
jmp 0x5c7d
movq -0x160(%rbp), %rax
movq -0x158(%rbp), %rcx
movq %rcx, (%rax)
movq $0x0, -0xc8(%rbp)
cmpl $0x0, -0x8(%rbp)
jle 0x5d7f
leaq -0x8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
leaq -0xe0(%rbp), %rdx
callq 0xec80
movl %eax, -0x164(%rbp)
jmp 0x5cbf
movl -0x164(%rbp), %eax
movl %eax, -0xe4(%rbp)
cmpl $0x1, -0xe4(%rbp)
je 0x5d65
jmp 0x5d7f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x6114
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x610b
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
movl $0x18, %esi
callq 0x52b0
jmp 0x610b
movq -0x148(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
movl $0x20, %esi
callq 0x52b0
jmp 0x610b
movq -0x158(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
movl $0x18, %esi
callq 0x52b0
jmp 0x610b
movl -0x8(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x10(%rbp)
jmp 0x5c99
cmpl $0x2, -0x8(%rbp)
jge 0x5d9c
movq 0x164bc(%rip), %rdi     # 0x1c248
movq -0xb8(%rbp), %rsi
callq 0x61b0
jmp 0x5d9a
jmp 0x5d9c
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rsi
leaq -0x40(%rbp), %rdi
xorl %edx, %edx
callq 0x11f50
jmp 0x5dcd
movq -0x90(%rbp), %rsi
leaq -0x70(%rbp), %rdi
xorl %edx, %edx
callq 0x11f50
jmp 0x5de1
leaq -0x40(%rbp), %rdi
callq 0x6200
movq %rax, -0x170(%rbp)
jmp 0x5df3
movq -0x170(%rbp), %rax
movl %eax, -0xa0(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x6220
movq %rax, -0x178(%rbp)
jmp 0x5e12
movq -0x178(%rbp), %rax
movl %eax, -0xa4(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x6200
movq %rax, -0x180(%rbp)
jmp 0x5e31
movq -0x180(%rbp), %rax
movslq -0xa0(%rbp), %rcx
cmpq %rcx, %rax
jne 0x5e69
leaq -0x70(%rbp), %rdi
callq 0x6220
movq %rax, -0x188(%rbp)
jmp 0x5e56
movq -0x188(%rbp), %rax
movslq -0xa4(%rbp), %rcx
cmpq %rcx, %rax
je 0x5e79
leaq 0xe1c5(%rip), %rdi      # 0x14035
callq 0xebd0
jmp 0x5e77
jmp 0x5e79
movslq -0xa0(%rbp), %rsi
movslq -0xa4(%rbp), %rdx
leaq -0x118(%rbp), %rdi
callq 0x11c00
jmp 0x5e95
movl $0x0, -0x11c(%rbp)
movl -0x11c(%rbp), %eax
cmpl -0xa4(%rbp), %eax
jge 0x60c5
movl $0x0, -0x120(%rbp)
movl -0x120(%rbp), %eax
cmpl -0xa0(%rbp), %eax
jge 0x60af
leaq -0x123(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x6130
jmp 0x5ee1
leaq -0x126(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x6130
jmp 0x5ef5
leaq -0x129(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x6130
jmp 0x5f09
movslq -0x120(%rbp), %rsi
movslq -0x11c(%rbp), %rdx
leaq -0x40(%rbp), %rdi
leaq -0x123(%rbp), %rcx
callq 0x6240
jmp 0x5f29
movslq -0x120(%rbp), %rsi
movslq -0x11c(%rbp), %rdx
leaq -0x70(%rbp), %rdi
leaq -0x126(%rbp), %rcx
callq 0x6240
jmp 0x5f49
movsd -0xb0(%rbp), %xmm0
leaq -0x123(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0x11a60
movb %al, -0x189(%rbp)
jmp 0x5f6c
movb -0x189(%rbp), %al
testb $0x1, %al
jne 0x5f78
jmp 0x5fb4
movw -0x126(%rbp), %ax
movw %ax, -0x129(%rbp)
movb -0x124(%rbp), %al
movb %al, -0x127(%rbp)
jmp 0x6076
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x11cc0
jmp 0x610b
movsd -0xb0(%rbp), %xmm0
leaq -0x126(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0x11a60
movb %al, -0x18a(%rbp)
jmp 0x5fd7
movb -0x18a(%rbp), %al
testb $0x1, %al
jne 0x5fe3
jmp 0x5fff
movw -0x123(%rbp), %ax
movw %ax, -0x129(%rbp)
movb -0x121(%rbp), %al
movb %al, -0x127(%rbp)
jmp 0x6074
movzbl -0x123(%rbp), %edi
movzbl -0x126(%rbp), %esi
callq 0x6280
movb %al, -0x18b(%rbp)
jmp 0x601a
movb -0x18b(%rbp), %al
movb %al, -0x129(%rbp)
movzbl -0x122(%rbp), %edi
movzbl -0x125(%rbp), %esi
callq 0x6280
movb %al, -0x18c(%rbp)
jmp 0x6041
movb -0x18c(%rbp), %al
movb %al, -0x128(%rbp)
movzbl -0x121(%rbp), %edi
movzbl -0x124(%rbp), %esi
callq 0x6280
movb %al, -0x18d(%rbp)
jmp 0x6068
movb -0x18d(%rbp), %al
movb %al, -0x127(%rbp)
jmp 0x6076
movslq -0x120(%rbp), %rsi
movslq -0x11c(%rbp), %rdx
leaq -0x118(%rbp), %rdi
leaq -0x129(%rbp), %rcx
callq 0x62b0
jmp 0x6099
jmp 0x609b
movl -0x120(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x120(%rbp)
jmp 0x5ebb
jmp 0x60b1
movl -0x11c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x11c(%rbp)
jmp 0x5e9f
movq -0x98(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0x122f0
jmp 0x60da
movl $0x0, -0x4(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x11cc0
leaq -0x70(%rbp), %rdi
callq 0x11cc0
leaq -0x40(%rbp), %rdi
callq 0x11cc0
movl -0x4(%rbp), %eax
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
leaq -0x70(%rbp), %rdi
callq 0x11cc0
leaq -0x40(%rbp), %rdi
callq 0x11cc0
movq -0x78(%rbp), %rdi
callq 0x53f0
nopw %cs:(%rax,%rax)