// File: mikeakohn[P]cloudtari/build/../src/TelevisionVNC.cxx
// Function: TelevisionVNC::send_image_diff()
int TelevisionVNC::send_image_diff()
{
  int line_mismatch_count = 0;
  int old_page = image_page ^ 1;
  int mismatch_start = 0;
  bool in_mismatch = false;
  int diff_ptr = sizeof(FramebufferUpdate);
  FramebufferUpdate *frame_buffer_update = (FramebufferUpdate *)diff_buffer;

  memset(frame_buffer_update, 0, sizeof(FramebufferUpdate));

  for (int y = 0; y < height; y += 2)
  {
    int line = y * width;
    bool is_mismatch = false;

    for (int x = 0; x < width; x += 3)
    {
      is_mismatch =
        image_packet[image_page]->data[line + x] !=
        image_packet[old_page]->data[line + x];

      if (is_mismatch)
      {
        line_mismatch_count++;

        if (line_mismatch_count > height / 6) { return send_image_full(); }
        if (!in_mismatch) { mismatch_start = y; in_mismatch = true; }

        break;
      }
    }

    // If mismatch flag is set and this is the last line in the image or
    // no longer in a mismatch.
    if (in_mismatch)
    {
      if (y == height - 2 || is_mismatch == false)
      {
        frame_buffer_update->number_of_rectangles++;

        UpdateRectangle *update_rectangle =
          (UpdateRectangle *)(diff_buffer + diff_ptr);

        int copy_height = y - mismatch_start;

        if (y == height - 2)
        {
          copy_height = height - mismatch_start;
        }

        update_rectangle->x = htons(0);
        update_rectangle->y = htons(mismatch_start);
        update_rectangle->width = htons(width);
        update_rectangle->height = htons(copy_height);
        update_rectangle->encoding_type = htons(0);

        diff_ptr += sizeof(UpdateRectangle);

        int copy_size = width * copy_height * 4;

        if (diff_ptr + copy_size > diff_buffer_length)
        {
          return send_image_full();
        }

        memcpy(
          diff_buffer + diff_ptr,
          &image_packet[image_page]->data[mismatch_start * width],
          copy_size);

        diff_ptr += copy_size;

        in_mismatch = false;
      }
    }
  }

  if (line_mismatch_count == 0) { return 0; }

  frame_buffer_update->number_of_rectangles =
    htons(frame_buffer_update->number_of_rectangles);

  if (net_send(diff_buffer, diff_ptr) != diff_ptr)
  {
    printf("Error: Send packet %s:%d\n", __FILE__, __LINE__);
    return -1;
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x0, -0x14(%rbp)
movl 0x48(%rax), %ecx
xorl $0x1, %ecx
movl %ecx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movb $0x0, -0x1d(%rbp)
movl $0x4, -0x24(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x4, %edx
callq 0x4170
movl $0x0, -0x34(%rbp)
movq -0x58(%rbp), %rcx
movl -0x34(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0xde3c
movq -0x58(%rbp), %rcx
movl -0x34(%rbp), %eax
imull 0x8(%rcx), %eax
movl %eax, -0x38(%rbp)
movb $0x0, -0x39(%rbp)
movl $0x0, -0x40(%rbp)
movq -0x58(%rbp), %rcx
movl -0x40(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0xdcd6
movq -0x58(%rbp), %rcx
movslq 0x48(%rcx), %rax
movq 0x38(%rcx,%rax,8), %rax
movl -0x38(%rbp), %edx
addl -0x40(%rbp), %edx
movslq %edx, %rdx
movl 0x10(%rax,%rdx,4), %eax
movslq -0x18(%rbp), %rdx
movq 0x38(%rcx,%rdx,8), %rcx
movl -0x38(%rbp), %edx
addl -0x40(%rbp), %edx
movslq %edx, %rdx
cmpl 0x10(%rcx,%rdx,4), %eax
setne %al
andb $0x1, %al
movb %al, -0x39(%rbp)
testb $0x1, -0x39(%rbp)
je 0xdcc6
movq -0x58(%rbp), %rax
movl -0x14(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x14(%rbp)
movl -0x14(%rbp), %ecx
movl %ecx, -0x5c(%rbp)
movl 0xc(%rax), %eax
movl $0x6, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x5c(%rbp), %eax
cmpl %ecx, %eax
jle 0xdcb4
movq -0x58(%rbp), %rdi
callq 0xe8c0
movl %eax, -0x4(%rbp)
jmp 0xdea9
testb $0x1, -0x1d(%rbp)
jne 0xdcc4
movl -0x34(%rbp), %eax
movl %eax, -0x1c(%rbp)
movb $0x1, -0x1d(%rbp)
jmp 0xdcd6
jmp 0xdcc8
movl -0x40(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x40(%rbp)
jmp 0xdc2e
testb $0x1, -0x1d(%rbp)
je 0xde2c
movq -0x58(%rbp), %rcx
movl -0x34(%rbp), %eax
movl 0xc(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
je 0xdd02
movb -0x39(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xde2a
movq -0x58(%rbp), %rcx
movq -0x30(%rbp), %rax
movw 0x2(%rax), %dx
addw $0x1, %dx
movw %dx, 0x2(%rax)
movq 0x50(%rcx), %rax
movslq -0x24(%rbp), %rdx
addq %rdx, %rax
movq %rax, -0x48(%rbp)
movl -0x34(%rbp), %eax
subl -0x1c(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x34(%rbp), %eax
movl 0xc(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jne 0xdd48
movq -0x58(%rbp), %rax
movl 0xc(%rax), %eax
subl -0x1c(%rbp), %eax
movl %eax, -0x4c(%rbp)
xorl %edi, %edi
callq 0x4070
movw %ax, %cx
movq -0x48(%rbp), %rax
movw %cx, (%rax)
movl -0x1c(%rbp), %eax
movzwl %ax, %edi
callq 0x4070
movw %ax, %dx
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rcx
movw %dx, 0x2(%rcx)
movl 0x8(%rax), %eax
movzwl %ax, %edi
callq 0x4070
movw %ax, %cx
movq -0x48(%rbp), %rax
movw %cx, 0x4(%rax)
movl -0x4c(%rbp), %eax
movzwl %ax, %edi
callq 0x4070
movw %ax, %cx
movq -0x48(%rbp), %rax
movw %cx, 0x6(%rax)
xorl %edi, %edi
callq 0x4070
movq -0x58(%rbp), %rcx
movzwl %ax, %edx
movq -0x48(%rbp), %rax
movl %edx, 0x8(%rax)
movslq -0x24(%rbp), %rax
addq $0xc, %rax
movl %eax, -0x24(%rbp)
movl 0x8(%rcx), %eax
imull -0x4c(%rbp), %eax
shll $0x2, %eax
movl %eax, -0x50(%rbp)
movl -0x24(%rbp), %eax
addl -0x50(%rbp), %eax
cmpl 0x58(%rcx), %eax
jle 0xdde8
movq -0x58(%rbp), %rdi
callq 0xe8c0
movl %eax, -0x4(%rbp)
jmp 0xdea9
movq -0x58(%rbp), %rcx
movq 0x50(%rcx), %rdi
movslq -0x24(%rbp), %rax
addq %rax, %rdi
movslq 0x48(%rcx), %rax
movq 0x38(%rcx,%rax,8), %rsi
addq $0x10, %rsi
movl -0x1c(%rbp), %eax
imull 0x8(%rcx), %eax
cltq
shlq $0x2, %rax
addq %rax, %rsi
movslq -0x50(%rbp), %rdx
callq 0x41f0
movl -0x50(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movb $0x0, -0x1d(%rbp)
jmp 0xde2c
jmp 0xde2e
movl -0x34(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x34(%rbp)
jmp 0xdc05
cmpl $0x0, -0x14(%rbp)
jne 0xde4b
movl $0x0, -0x4(%rbp)
jmp 0xdea9
movq -0x30(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x4070
movw %ax, %dx
movq -0x58(%rbp), %rax
movq -0x30(%rbp), %rcx
movw %dx, 0x2(%rcx)
movq %rax, %rdi
addq $0x20, %rdi
movq 0x50(%rax), %rsi
movl -0x24(%rbp), %edx
callq 0x9ba0
cmpl -0x24(%rbp), %eax
je 0xdea2
leaq 0x2705(%rip), %rdi      # 0x1058b
leaq 0x2718(%rip), %rsi      # 0x105a5
movl $0x1d8, %edx            # imm = 0x1D8
movb $0x0, %al
callq 0x4050
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xdea9
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)