// File: /workspace/github_c_makefile_star2_O3/dwbuiten[P]obuparse/obuparse.c
// Function: obp_get_next_obu
int obp_get_next_obu(uint8_t *buf, size_t buf_size, OBPOBUType *obu_type, ptrdiff_t *offset,
                     size_t *size, int *temporal_id, int *spatial_id, OBPError *err)
{
    ptrdiff_t pos = 0;
    int obu_extension_flag;
    int obu_has_size_field;

    if (buf_size < 1) {
        snprintf(err->error, err->size, "Buffer is too small to contain an OBU.");
        return -1;
    }

    *obu_type          = (buf[pos] & 0x78) >> 3;
    obu_extension_flag = (buf[pos] & 0x04) >> 2;
    obu_has_size_field = (buf[pos] & 0x02) >> 1;
    pos++;

    if (!_obp_is_valid_obu(*obu_type)) {
        snprintf(err->error, err->size, "OBU header contains invalid OBU type: %d", *obu_type);
        return -1;
    }

    if (obu_extension_flag) {
        if (buf_size < 2) {
            snprintf(err->error, err->size, "Buffer is too small to contain an OBU extension header.");
            return -1;
        }
        *temporal_id = (buf[pos] & 0xE0) >> 5;
        *spatial_id  = (buf[pos] & 0x18) >> 3;
        pos++;
    } else {
        *temporal_id = 0;
        *spatial_id  = 0;
    }

    if (obu_has_size_field) {
        char err_buf[1024];
        uint64_t value;
        ptrdiff_t consumed;
        OBPError error = { &err_buf[0], 1024 };

        int ret      = _obp_leb128(buf + pos, buf_size - (size_t) pos, &value, &consumed, &error);
        if (ret < 0) {
            snprintf(err->error, err->size, "Failed to read OBU size: %s", &error.error[0]);
            return -1;
        }

        assert(value < UINT32_MAX);

        *offset = (ptrdiff_t) pos + consumed;
        *size   = (size_t) value;
    } else {
        *offset = (ptrdiff_t) pos;
        *size   = buf_size - (size_t) pos;
    }

    if (*size > buf_size - (size_t) *offset) {
        snprintf(err->error, err->size, "Invalid OBU size: larger than remaining buffer.");
        return -1;
    }

    return 0;
}

// Assembly:
pushq %rbx
subq $0x400, %rsp            # imm = 0x400
movq 0x418(%rsp), %r10
testq %rsi, %rsi
je 0x11ab
movq %rcx, %rax
movzbl (%rdi), %ecx
shrl $0x3, %ecx
andl $0xf, %ecx
movl %ecx, (%rdx)
leal -0x9(%rcx), %edx
cmpl $-0x8, %edx
setae %dl
cmpl $0xf, %ecx
sete %r11b
orb %dl, %r11b
jne 0x11ce
movq (%r10), %rdi
movq 0x8(%r10), %rsi
leaq 0x6ee5(%rip), %rdx      # 0x8087
xorl %eax, %eax
callq 0x1030
jmp 0x11c0
movq (%r10), %rdi
movq 0x8(%r10), %rsi
leaq 0x6ea7(%rip), %rdx      # 0x8060
xorl %eax, %eax
callq 0x1030
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x400, %rsp            # imm = 0x400
popq %rbx
retq
movzbl (%rdi), %ecx
testb $0x4, %cl
jne 0x11e7
movl $0x0, (%r9)
movl $0x1, %edx
xorl %r9d, %r9d
jmp 0x1219
cmpq $0x1, %rsi
jne 0x11fd
movq (%r10), %rdi
movq 0x8(%r10), %rsi
leaq 0x6eb5(%rip), %rdx      # 0x80b0
jmp 0x11b9
movzbl 0x1(%rdi), %edx
shrl $0x5, %edx
movl %edx, (%r9)
movzbl 0x1(%rdi), %r9d
shrl $0x3, %r9d
andl $0x3, %r9d
movl $0x2, %edx
movq 0x410(%rsp), %r11
movl %r9d, (%r11)
testb $0x2, %cl
jne 0x1234
movq %rdx, (%rax)
movq %rsi, %r9
subq %rdx, %r9
jmp 0x1271
xorl %ecx, %ecx
xorl %r9d, %r9d
cmpq %rdx, %rsi
je 0x1295
movzbl (%rdi,%rdx), %r11d
movl %r11d, %ebx
andl $0x7f, %ebx
shlq %cl, %rbx
orq %rbx, %r9
incq %rdx
testb %r11b, %r11b
jns 0x1264
leaq 0x7(%rcx), %r11
cmpq $0x31, %rcx
movq %r11, %rcx
jne 0x1239
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %r9
jae 0x12d5
movq %rdx, (%rax)
movq %r9, (%r8)
subq (%rax), %rsi
xorl %eax, %eax
cmpq %rsi, %r9
jbe 0x11c5
movq (%r10), %rdi
movq 0x8(%r10), %rsi
leaq 0x6ef9(%rip), %rdx      # 0x8189
jmp 0x11b9
movups 0x7223(%rip), %xmm0     # 0x84bf
movq %rsp, %rcx
movaps %xmm0, 0x10(%rcx)
movups 0x7205(%rip), %xmm0     # 0x84af
movaps %xmm0, (%rcx)
movabsq $0x2e65756c617620, %rax # imm = 0x2E65756C617620
movq %rax, 0x1f(%rcx)
movq (%r10), %rdi
movq 0x8(%r10), %rsi
leaq 0x6e1f(%rip), %rdx      # 0x80e8
xorl %eax, %eax
callq 0x1030
jmp 0x11c0
leaq 0x6e28(%rip), %rdi      # 0x8104
leaq 0x6e34(%rip), %rsi      # 0x8117
leaq 0x6e38(%rip), %rcx      # 0x8122
movl $0x221, %edx            # imm = 0x221
callq 0x1040