user: Please show me the C implementation that matches the assembly code listed below:

```asm
<uudecode>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%r15
  mov    %esi,%ebp
  mov    %rdx,0x8(%rsp)
  movslq %esi,%rax
  movzbl (%rdi,%rax,1),%edi
  test   $0xdf,%dil
  je     L67
  mov    $0x0,%r14d
  jmp    L9
L48:
  movzbl (%rbx),%edi
  call   <decode_char@plt>
  mov    %eax,(%rsp)
  movzbl 0x1(%rbx),%edi
  call   <decode_char@plt>
  mov    (%rsp),%edx
  shl    $0x2,%edx
  sar    $0x4,%eax
  or     %eax,%edx
  mov    %dl,0x0(%rbp)
  movzbl 0x1(%rbx),%edi
  call   <decode_char@plt>
  mov    %eax,(%rsp)
  movzbl 0x2(%rbx),%edi
  call   <decode_char@plt>
  mov    (%rsp),%edx
  shl    $0x4,%edx
  sar    $0x2,%eax
  or     %eax,%edx
  mov    %dl,0x1(%rbp)
  movzbl 0x2(%rbx),%edi
  call   <decode_char@plt>
  mov    %eax,(%rsp)
  movzbl 0x3(%rbx),%edi
  call   <decode_char@plt>
  mov    %eax,%edx
  add    $0x3,%r14d
  mov    (%rsp),%eax
  shl    $0x6,%eax
  or     %edx,%eax
  mov    %al,0x2(%rbp)
  add    $0x4,%r13d
  sub    $0x3,%r12d
  add    $0x4,%rbx
  add    $0x3,%rbp
  test   %r12d,%r12d
  jle    L33
L34:
  cmp    $0x2,%r12d
  jg     L48
  movslq %r13d,%rbx
  movzbl (%r15,%rbx,1),%edi
  call   <decode_char@plt>
  mov    %eax,0x4(%rsp)
  lea    0x1(%r15,%rbx,1),%rbp
  movzbl 0x0(%rbp),%edi
  call   <decode_char@plt>
  lea    0x1(%r14),%esi
  mov    %esi,(%rsp)
  movslq %r14d,%rcx
  mov    0x4(%rsp),%edx
  shl    $0x2,%edx
  sar    $0x4,%eax
  or     %eax,%edx
  mov    0x8(%rsp),%rax
  mov    %dl,(%rax,%rcx,1)
  cmp    $0x2,%r12d
  jne    L25
  movzbl 0x0(%rbp),%edi
  call   <decode_char@plt>
  mov    %eax,%ebp
  movzbl 0x2(%r15,%rbx,1),%edi
  call   <decode_char@plt>
  movslq (%rsp),%rdx
  shl    $0x4,%ebp
  sar    $0x2,%eax
  or     %eax,%ebp
  mov    0x8(%rsp),%rax
  mov    %bpl,(%rax,%rdx,1)
  lea    0x2(%r14),%eax
  mov    %eax,(%rsp)
L25:
  add    $0x4,%r13d
  mov    (%rsp),%r14d
L33:
  movslq %r13d,%rax
  add    %r15,%rax
  mov    %rax,%rbx
  sub    %eax,%r13d
L2:
  lea    0x0(%r13,%rbx,1),%ebp
  mov    %rbx,%r12
  movzbl (%rbx),%edi
  call   <isblanks@plt>
  add    $0x1,%rbx
  test   %rax,%rax
  jne    L2
  movzbl (%r12),%edi
  test   $0xdf,%dil
  je     L60
L9:
  movzbl %dil,%edi
  call   <decode_char@plt>
  mov    %eax,%r12d
  lea    0x1(%rbp),%r13d
  test   %eax,%eax
  jle    L33
  movslq %r13d,%rbx
  add    %r15,%rbx
  movslq %r14d,%rbp
  add    0x8(%rsp),%rbp
  jmp    L34
L67:
  mov    $0x0,%r14d
L60:
  movslq %ebp,%rbp
  add    %rbp,%r15
L44:
  movzbl (%r15),%edi
  call   <isblanks@plt>
  add    $0x1,%r15
  test   %rax,%rax
  jne    L44
  mov    %r14d,%eax
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
int uudecode(unsigned char *input, int offset, unsigned char *output) {
  int ooffset = 0;
  while (input[offset] != 32 && input[offset] != '\0') {
    int encodedoctets;
    encodedoctets = decode_char(input[offset]);
    for (++offset; encodedoctets > 0; offset += 4, encodedoctets -= 3) {
      char ch;
      if (encodedoctets >= 3) {
        ch = decode_char(input[offset]) << 2 | decode_char(input[offset + 1]) >> 4;
        output[ooffset++] = ch;
        ch = decode_char(input[offset + 1]) << 4 | decode_char(input[offset + 2]) >> 2;
        output[ooffset++] = ch;
        ch = decode_char(input[offset + 2]) << 6 | decode_char(input[offset + 3]);
        output[ooffset++] = ch;
      } else {
        if (encodedoctets >= 1) {
          ch = decode_char(input[offset]) << 2 | decode_char(input[offset + 1]) >> 4;
          output[ooffset++] = ch;
        }
        if (encodedoctets >= 2) {
          ch = decode_char(input[offset + 1]) << 4 | decode_char(input[offset + 2]) >> 2;
          output[ooffset++] = ch;
        }
      }
    }
    while (isblanks(input[offset]))
      offset++;
  }
  while (isblanks(input[offset]))
    offset++;
  return ooffset;
}
```