user: Translate the below assembly code into C programming language:

```asm
<horizontal_line_3_5_scale_c64>:
  endbr64
  push   %r15
  push   %r14
  mov    %rdi,%r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdx,%rbx
  sub    $0x18,%rsp
  sub    $0x3,%esi
  mov    %esi,0xc(%rsp)
  je     L1
  xor    %edx,%edx
  nopw   0x0(%rax,%rax,1)
L11:
  mov    %r14,%rdi
  mov    %edx,0x8(%rsp)
  add    $0x3,%r14
  add    $0x5,%rbx
  call   <_mem4@plt>
  mov    %eax,%ebp
  mov    %eax,%edi
  call   <_unpklu4@plt>
  mov    $0x8,%esi
  mov    %ebp,%edi
  mov    %eax,%r15d
  call   <_rotl@plt>
  mov    %eax,%edi
  call   <_unpkhu4@plt>
  mov    %ebp,%edi
  mov    %eax,%r12d
  call   <_unpkhu4@plt>
  mov    %bpl,-0x5(%rbx)
  mov    $0x9a006600,%esi
  mov    %r15d,%edi
  mov    %eax,%r13d
  call   <_dotprsu2@plt>
  mov    $0x3300cd00,%esi
  mov    %r12d,%edi
  mov    %al,-0x4(%rbx)
  call   <_dotprsu2@plt>
  mov    $0xcd003300,%esi
  mov    %r12d,%edi
  mov    %al,-0x3(%rbx)
  call   <_dotprsu2@plt>
  mov    $0x66009a00,%esi
  mov    %r13d,%edi
  mov    %al,-0x2(%rbx)
  call   <_dotprsu2@plt>
  mov    0x8(%rsp),%edx
  mov    %al,-0x1(%rbx)
  add    $0x3,%edx
  cmp    0xc(%rsp),%edx
  jb     L11
L1:
  mov    %r14,%rdi
  call   <_mem4@plt>
  mov    %eax,%ebp
  mov    %eax,%edi
  call   <_unpklu4@plt>
  mov    $0x8,%esi
  mov    %ebp,%edi
  mov    %eax,%r14d
  call   <_rotl@plt>
  mov    %eax,%edi
  call   <_unpkhu4@plt>
  mov    %ebp,%edi
  mov    %eax,%r12d
  call   <_unpkhu4@plt>
  mov    %bpl,(%rbx)
  mov    %r14d,%edi
  mov    $0x9a006600,%esi
  mov    %eax,%r13d
  call   <_dotprsu2@plt>
  mov    %r12d,%edi
  mov    $0x3300cd00,%esi
  mov    %al,0x1(%rbx)
  call   <_dotprsu2@plt>
  mov    %r12d,%edi
  mov    $0xcd003300,%esi
  mov    %al,0x2(%rbx)
  call   <_dotprsu2@plt>
  mov    %r13b,0x4(%rbx)
  mov    %al,0x3(%rbx)
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void horizontal_line_3_5_scale_c64(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) {
  unsigned int i;
  unsigned int ba, cb, dc;
  unsigned int src_current;
  unsigned char *restrict des = dest;
  unsigned char *restrict src = (unsigned char *)source;
  unsigned int const_51_205, const_102_154, const_205_51, const_154_102;
  (void)dest_width;
  const_51_205 = 0x3300CD00;
  const_205_51 = 0xCD003300;
  const_102_154 = 0x66009A00;
  const_154_102 = 0x9A006600;
  for (i = 0; i < source_width - 3; i += 3) {
    src_current = _mem4(src);
    ba = _unpklu4(src_current);
    cb = _unpkhu4(_rotl(src_current, 8));
    dc = _unpkhu4(src_current);
    des[0] = src_current & 0xff;
    des[1] = _dotprsu2(ba, const_154_102);
    des[2] = _dotprsu2(cb, const_51_205);
    des[3] = _dotprsu2(cb, const_205_51);
    des[4] = _dotprsu2(dc, const_102_154);
    src += 3;
    des += 5;
  }
  src_current = _mem4(src);
  ba = _unpklu4(src_current);
  cb = _unpkhu4(_rotl(src_current, 8));
  dc = _unpkhu4(src_current);
  des[0] = src_current & 0xff;
  des[1] = _dotprsu2(ba, const_154_102);
  des[2] = _dotprsu2(cb, const_51_205);
  des[3] = _dotprsu2(cb, const_205_51);
  des[4] = dc & 0xff;
}
```