user: Converte this assembly snippet into its equivalent C code:

```asm
<match_colors_block>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x88,%rsp
  mov    %rdi,%rax
  mov    %rsi,%rdi
  mov    %edx,%ebp
  mov    %fs:0x28,%rdx
  mov    %rdx,0x78(%rsp)
  xor    %edx,%edx
  movzbl (%rsi),%r8d
  movzbl 0x3(%rsi),%edx
  sub    %edx,%r8d
  movzbl 0x1(%rsi),%r9d
  movzbl 0x4(%rsi),%edx
  sub    %edx,%r9d
  movzbl 0x2(%rsi),%r10d
  movzbl 0x5(%rsi),%edx
  sub    %edx,%r10d
  mov    %rax,%rdx
  lea    0x30(%rsp),%rbx
  lea    0x70(%rsp),%r11
  mov    %rbx,%rcx
L138:
  movzbl (%rdx),%eax
  imul   %r8d,%eax
  movzbl 0x1(%rdx),%esi
  imul   %r9d,%esi
  add    %esi,%eax
  movzbl 0x2(%rdx),%esi
  imul   %r10d,%esi
  add    %esi,%eax
  mov    %eax,(%rcx)
  add    $0x4,%rdx
  add    $0x4,%rcx
  cmp    %r11,%rcx
  jne    L138
  mov    %rsp,%rdx
  lea    0x10(%rsp),%rsi
L177:
  movzbl (%rdi),%eax
  imul   %r8d,%eax
  movzbl 0x1(%rdi),%ecx
  imul   %r9d,%ecx
  add    %ecx,%eax
  movzbl 0x2(%rdi),%ecx
  imul   %r10d,%ecx
  add    %ecx,%eax
  mov    %eax,(%rdx)
  add    $0x3,%rdi
  add    $0x4,%rdx
  cmp    %rsi,%rdx
  jne    L177
  mov    0xc(%rsp),%esi
  mov    %esi,%r12d
  add    0x4(%rsp),%r12d
  sar    %r12d
  mov    0x8(%rsp),%edi
  add    %edi,%esi
  sar    %esi
  add    (%rsp),%edi
  sar    %edi
  test   %ebp,%ebp
  jne    L110
  lea    0x6c(%rsp),%rdx
  mov    $0x0,%eax
  jmp    L94
L179:
  cmp    %ecx,%edi
  setg   %cl
  movzbl %cl,%ecx
  add    %ecx,%ecx
  or     %ecx,%eax
L76:
  lea    -0x4(%rdx),%rcx
  cmp    %rbx,%rdx
  je     L111
  mov    %rcx,%rdx
L94:
  shl    $0x2,%eax
  mov    (%rdx),%ecx
  cmp    %ecx,%esi
  jle    L179
  cmp    %ecx,%r12d
  setle  %cl
  movzbl %cl,%ecx
  lea    0x1(%rcx,%rcx,1),%ecx
  or     %ecx,%eax
  jmp    L76
L110:
  shl    $0x4,%r12d
  mov    %esi,%ebx
  shl    $0x4,%ebx
  shl    $0x4,%edi
  mov    %edi,%ebp
  lea    0x10(%rsp),%r13
  mov    $0x20,%edx
  mov    $0x0,%esi
  mov    %r13,%rdi
  call   <memset@plt>
  mov    $0x0,%ecx
  lea    0x30(%rsp),%rdi
  lea    0x20(%rsp),%rdx
  mov    %r13,%r8
  mov    $0x0,%eax
  jmp    L25
L173:
  cmp    %esi,%ebp
  setg   %r11b
  movzbl %r11b,%r11d
  add    %r11d,%r11d
  jmp    L124
L39:
  cmp    %esi,%ebp
  setg   %r10b
  movzbl %r10b,%r10d
  add    %r10d,%r10d
  jmp    L7
L20:
  cmp    %esi,%ebp
  setg   %r9b
  movzbl %r9b,%r9d
  add    %r9d,%r9d
  jmp    L23
L41:
  cmp    %esi,%ebp
  setg   %sil
  movzbl %sil,%esi
  add    %esi,%esi
L116:
  movslq %esi,%r11
  sub    (%rsp,%r11,4),%r10d
  mov    %r10d,0xc(%r8)
  add    $0x10,%rdi
  shl    $0x6,%esi
  or     %r9d,%esi
  shl    %cl,%esi
  or     %esi,%eax
  add    $0x8,%ecx
  mov    %rdx,%rsi
  mov    %r8,%rdx
  cmp    $0x20,%ecx
  je     L111
  mov    %rsi,%r8
L25:
  mov    (%rdi),%r10d
  mov    0x4(%rdx),%esi
  lea    (%rsi,%rsi,2),%esi
  mov    (%rdx),%r9d
  lea    (%r9,%r9,4),%r9d
  add    %r9d,%esi
  mov    %r10d,%r9d
  shl    $0x4,%r9d
  add    %r9d,%esi
  cmp    %esi,%ebx
  jle    L173
  cmp    %esi,%r12d
  setle  %r11b
  movzbl %r11b,%r11d
  lea    0x1(%r11,%r11,1),%r11d
L124:
  movslq %r11d,%rsi
  sub    (%rsp,%rsi,4),%r10d
  mov    %r10d,(%r8)
  mov    0x4(%rdi),%r9d
  mov    0x8(%rdx),%esi
  lea    (%rsi,%rsi,2),%esi
  lea    0x0(,%r10,8),%r13d
  sub    %r10d,%r13d
  add    %r13d,%esi
  mov    0x4(%rdx),%r10d
  lea    (%r10,%r10,4),%r10d
  add    %r10d,%esi
  add    (%rdx),%esi
  mov    %r9d,%r10d
  shl    $0x4,%r10d
  add    %r10d,%esi
  cmp    %esi,%ebx
  jle    L39
  cmp    %esi,%r12d
  setle  %r10b
  movzbl %r10b,%r10d
  lea    0x1(%r10,%r10,1),%r10d
L7:
  movslq %r10d,%rsi
  sub    (%rsp,%rsi,4),%r9d
  mov    %r9d,0x4(%r8)
  shl    $0x2,%r10d
  or     %r11d,%r10d
  mov    0x8(%rdi),%r11d
  mov    0xc(%rdx),%esi
  lea    (%rsi,%rsi,2),%esi
  lea    0x0(,%r9,8),%r13d
  sub    %r9d,%r13d
  add    %r13d,%esi
  mov    0x8(%rdx),%r9d
  lea    (%r9,%r9,4),%r9d
  add    %r9d,%esi
  add    0x4(%rdx),%esi
  mov    %r11d,%r9d
  shl    $0x4,%r9d
  add    %r9d,%esi
  cmp    %esi,%ebx
  jle    L20
  cmp    %esi,%r12d
  setle  %r9b
  movzbl %r9b,%r9d
  lea    0x1(%r9,%r9,1),%r9d
L23:
  movslq %r9d,%rsi
  sub    (%rsp,%rsi,4),%r11d
  mov    %r11d,0x8(%r8)
  shl    $0x4,%r9d
  or     %r10d,%r9d
  mov    0xc(%rdi),%r10d
  mov    0xc(%rdx),%esi
  lea    (%rsi,%rsi,4),%esi
  lea    0x0(,%r11,8),%r13d
  sub    %r11d,%r13d
  add    %r13d,%esi
  add    0x8(%rdx),%esi
  mov    %r10d,%r11d
  shl    $0x4,%r11d
  add    %r11d,%esi
  cmp    %esi,%ebx
  jle    L41
  cmp    %esi,%r12d
  setle  %sil
  movzbl %sil,%esi
  lea    0x1(%rsi,%rsi,1),%esi
  jmp    L116
L111:
  mov    0x78(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L152
  add    $0x88,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
L152:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
unsigned int match_colors_block(const unsigned char *block, unsigned char color[4][3], int dither) {
  unsigned int mask = 0;
  int dirb = color[0][0] - color[1][0];
  int dirg = color[0][1] - color[1][1];
  int dirr = color[0][2] - color[1][2];
  int dots[16], stops[4];
  int c0pt, halfpt, c3pt, dot;
  int i;
  for (i = 0; i < 16; ++i)
    dots[i] = block[4 * i] * dirb + block[4 * i + 1] * dirg + block[4 * i + 2] * dirr;
  for (i = 0; i < 4; ++i)
    stops[i] = color[i][0] * dirb + color[i][1] * dirg + color[i][2] * dirr;
  c0pt = (stops[1] + stops[3]) >> 1;
  halfpt = (stops[3] + stops[2]) >> 1;
  c3pt = (stops[2] + stops[0]) >> 1;
  if (!dither) {
    for (i = 15; i >= 0; --i) {
      mask <<= 2;
      dot = dots[i];
      if (dot < halfpt)
        mask |= (dot < c0pt) ? 1 : 3;
      else
        mask |= (dot < c3pt) ? 2 : 0;
    }
  } else {
    int err[8], *ep1 = err, *ep2 = err + 4, *tmp;
    int *dp = dots, y, lmask, step;
    c0pt <<= 4;
    halfpt <<= 4;
    c3pt <<= 4;
    memset(err, 0, sizeof(err));
    for (y = 0; y < 4; ++y) {
      dot = (dp[0] << 4) + (3 * ep2[1] + 5 * ep2[0]);
      if (dot < halfpt)
        step = (dot < c0pt) ? 1 : 3;
      else
        step = (dot < c3pt) ? 2 : 0;
      ep1[0] = dp[0] - stops[step];
      lmask = step;
      dot = (dp[1] << 4) + (7 * ep1[0] + 3 * ep2[2] + 5 * ep2[1] + ep2[0]);
      if (dot < halfpt)
        step = (dot < c0pt) ? 1 : 3;
      else
        step = (dot < c3pt) ? 2 : 0;
      ep1[1] = dp[1] - stops[step];
      lmask |= step << 2;
      dot = (dp[2] << 4) + (7 * ep1[1] + 3 * ep2[3] + 5 * ep2[2] + ep2[1]);
      if (dot < halfpt)
        step = (dot < c0pt) ? 1 : 3;
      else
        step = (dot < c3pt) ? 2 : 0;
      ep1[2] = dp[2] - stops[step];
      lmask |= step << 4;
      dot = (dp[3] << 4) + (7 * ep1[2] + 5 * ep2[3] + ep2[2]);
      if (dot < halfpt)
        step = (dot < c0pt) ? 1 : 3;
      else
        step = (dot < c3pt) ? 2 : 0;
      ep1[3] = dp[3] - stops[step];
      lmask |= step << 6;
      tmp = ep1;
      ep1 = ep2;
      ep2 = tmp;
      dp += 4;
      mask |= lmask << (y * 8);
    }
  }
  return (mask);
}
```