// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x420, %rsp            # imm = 0x420
movq 0x458(%rsp), %r12
testq %rsi, %rsi
je 0x11b6
movq %rcx, %r14
movzbl (%rdi), %ecx
shrl $0x3, %ecx
andl $0xf, %ecx
movl %ecx, (%rdx)
leal -0x9(%rcx), %eax
cmpl $-0x8, %eax
setae %al
cmpl $0xf, %ecx
sete %dl
orb %al, %dl
jne 0x11cb
movq (%r12), %rdi
movq 0x8(%r12), %rsi
leaq 0x6e91(%rip), %rdx      # 0x803b
xorl %eax, %eax
callq 0x1030
jmp 0x1299
movq (%r12), %rdi
movq 0x8(%r12), %rsi
leaq 0x6e4e(%rip), %rdx      # 0x8014
jmp 0x1292
movq %r8, %r15
movq %rsi, %rbx
movzbl (%rdi), %eax
testb $0x4, %al
jne 0x11e4
andl $0x0, (%r9)
pushq $0x1
popq %r13
xorl %ecx, %ecx
jmp 0x1217
cmpq $0x1, %rbx
jne 0x11ff
movq (%r12), %rdi
movq 0x8(%r12), %rsi
leaq 0x6e6a(%rip), %rdx      # 0x8064
jmp 0x1292
movzbl 0x1(%rdi), %ecx
shrl $0x5, %ecx
movl %ecx, (%r9)
movzbl 0x1(%rdi), %ecx
shrl $0x3, %ecx
andl $0x3, %ecx
pushq $0x2
popq %r13
movq 0x450(%rsp), %rdx
movl %ecx, (%rdx)
testb $0x2, %al
jne 0x1230
movq %r13, (%r14)
movq %rbx, %rcx
subq %r13, %rcx
jmp 0x1275
leaq 0x20(%rsp), %rax
leaq 0x10(%rsp), %r8
movq %rax, (%r8)
movq $0x400, 0x8(%r8)        # imm = 0x400
addq %r13, %rdi
movq %rbx, %rsi
subq %r13, %rsi
leaq 0x8(%rsp), %rdx
movq %rsp, %rcx
callq 0x12ea
testl %eax, %eax
js 0x12ad
movq 0x8(%rsp), %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, %rcx
jae 0x12cb
addq (%rsp), %r13
movq %r13, (%r14)
movq %rcx, (%r15)
subq (%r14), %rbx
xorl %eax, %eax
cmpq %rbx, %rcx
jbe 0x129c
movq (%r12), %rdi
movq 0x8(%r12), %rsi
leaq 0x6eab(%rip), %rdx      # 0x813d
xorl %eax, %eax
callq 0x1030
pushq $-0x1
popq %rax
addq $0x420, %rsp            # imm = 0x420
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq (%r12), %rdi
movq 0x8(%r12), %rsi
leaq 0x6ddf(%rip), %rdx      # 0x809c
leaq 0x20(%rsp), %rcx
xorl %eax, %eax
callq 0x1030
jmp 0x1299
leaq 0x6de6(%rip), %rdi      # 0x80b8
leaq 0x6df2(%rip), %rsi      # 0x80cb
leaq 0x6df6(%rip), %rcx      # 0x80d6
movl $0x221, %edx            # imm = 0x221
callq 0x1040