// File: /workspace/github_c_makefile_star2_O1/KhronosGroup[P]dfdutils/printdfd.c
// Function: printDFD
void printDFD(uint32_t *DFD, uint32_t dataSize)
{
#define PRINT_ENUM(VALUE, TO_STRING_FN) {                        \
        int value = VALUE;                                       \
        const char* str = TO_STRING_FN(value);                   \
        if (str)                                                 \
            printf("%s", str);                                   \
        else                                                     \
            printf("%u", value);                                 \
    }

    const uint32_t sizeof_dfdTotalSize = sizeof(uint32_t);
    const uint32_t sizeof_DFDBHeader = sizeof(uint32_t) * 2;
    const uint32_t sizeof_BDFD = sizeof(uint32_t) * KHR_DF_WORD_SAMPLESTART;
    const uint32_t sizeof_BDFDSample = sizeof(uint32_t) * KHR_DF_WORD_SAMPLEWORDS;

    uint32_t dfdTotalSize = dataSize >= sizeof_dfdTotalSize ? DFD[0] : 0;
    uint32_t remainingSize = dfdTotalSize < dataSize ? dfdTotalSize : dataSize;
    if (remainingSize < sizeof_dfdTotalSize)
        return; // Invalid DFD: dfdTotalSize must be present

    uint32_t* block = DFD + 1;
    remainingSize -= sizeof_dfdTotalSize;

    printf("DFD total bytes: %u\n", dfdTotalSize);

    for (int i = 0; i < MAX_NUM_DFD_BLOCKS; ++i) { // At most only iterate MAX_NUM_DFD_BLOCKS block
        if (remainingSize < sizeof_DFDBHeader)
            break; // Invalid DFD: Missing or partial block header

        const khr_df_vendorid_e vendorID = KHR_DFDVAL(block, VENDORID);
        const khr_df_khr_descriptortype_e descriptorType = KHR_DFDVAL(block, DESCRIPTORTYPE);
        const khr_df_versionnumber_e versionNumber = KHR_DFDVAL(block, VERSIONNUMBER);
        const uint32_t blockSize = KHR_DFDVAL(block, DESCRIPTORBLOCKSIZE);

        printf("Vendor ID: ");
        PRINT_ENUM(vendorID, dfdToStringVendorID);
        printf("\nDescriptor type: ");
        PRINT_ENUM(descriptorType, dfdToStringDescriptorType);
        printf("\nVersion: ");
        PRINT_ENUM(versionNumber, dfdToStringVersionNumber);
        printf("\nDescriptor block size: %u", blockSize);
        printf("\n");

        if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT) {
            if (remainingSize < sizeof_BDFD)
                break; // Invalid DFD: Missing or partial basic DFD block

            const int model = KHR_DFDVAL(block, MODEL);

            khr_df_flags_e flags = KHR_DFDVAL(block, FLAGS);
            printf("Flags: 0x%X (", flags);
            printFlagBits(flags, dfdToStringFlagsBit);
            printf(")\nTransfer: ");
            PRINT_ENUM(KHR_DFDVAL(block, TRANSFER), dfdToStringTransferFunction);
            printf("\nPrimaries: ");
            PRINT_ENUM(KHR_DFDVAL(block, PRIMARIES), dfdToStringColorPrimaries);
            printf("\nModel: ");
            PRINT_ENUM(model, dfdToStringColorModel);
            printf("\n");

            printf("Dimensions: %u, %u, %u, %u\n",
                   KHR_DFDVAL(block, TEXELBLOCKDIMENSION0) + 1,
                   KHR_DFDVAL(block, TEXELBLOCKDIMENSION1) + 1,
                   KHR_DFDVAL(block, TEXELBLOCKDIMENSION2) + 1,
                   KHR_DFDVAL(block, TEXELBLOCKDIMENSION3) + 1);
            printf("Plane bytes: %u, %u, %u, %u, %u, %u, %u, %u\n",
                   KHR_DFDVAL(block, BYTESPLANE0),
                   KHR_DFDVAL(block, BYTESPLANE1),
                   KHR_DFDVAL(block, BYTESPLANE2),
                   KHR_DFDVAL(block, BYTESPLANE3),
                   KHR_DFDVAL(block, BYTESPLANE4),
                   KHR_DFDVAL(block, BYTESPLANE5),
                   KHR_DFDVAL(block, BYTESPLANE6),
                   KHR_DFDVAL(block, BYTESPLANE7));

            int samples = (blockSize - sizeof_BDFD) / sizeof_BDFDSample;
            if (samples > MAX_NUM_BDFD_SAMPLES)
                samples = MAX_NUM_BDFD_SAMPLES; // Too many BDFD samples
            for (int sample = 0; sample < samples; ++sample) {
                if (remainingSize < sizeof_BDFD + (sample + 1) * sizeof_BDFDSample)
                    break; // Invalid DFD: Missing or partial basic DFD sample

                khr_df_model_channels_e channelType = KHR_DFDSVAL(block, sample, CHANNELID);
                printf("Sample %u:\n", sample);

                khr_df_sample_datatype_qualifiers_e qualifiers = KHR_DFDSVAL(block, sample, QUALIFIERS);
                printf("    Qualifiers: 0x%X (", qualifiers);
                printFlagBits(qualifiers, dfdToStringSampleDatatypeQualifiers);
                printf(")\n");
                printf("    Channel Type: 0x%X", channelType);
                {
                    const char* str = dfdToStringChannelId(model, channelType);
                    if (str)
                        printf(" (%s)\n", str);
                    else
                        printf(" (%u)\n", channelType);
                }
                printf("    Length: %u bits Offset: %u\n",
                       KHR_DFDSVAL(block, sample, BITLENGTH) + 1,
                       KHR_DFDSVAL(block, sample, BITOFFSET));
                printf("    Position: %u, %u, %u, %u\n",
                       KHR_DFDSVAL(block, sample, SAMPLEPOSITION0),
                       KHR_DFDSVAL(block, sample, SAMPLEPOSITION1),
                       KHR_DFDSVAL(block, sample, SAMPLEPOSITION2),
                       KHR_DFDSVAL(block, sample, SAMPLEPOSITION3));
                printf("    Lower: 0x%08x\n    Upper: 0x%08x\n",
                       KHR_DFDSVAL(block, sample, SAMPLELOWER),
                       KHR_DFDSVAL(block, sample, SAMPLEUPPER));
            }
        } else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS) {
            // TODO: Implement DFD print for ADDITIONAL_DIMENSIONS
        } else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES) {
            // TODO: Implement DFD print for ADDITIONAL_PLANES
        } else {
            printf("Unknown block\n");
        }

        const uint32_t advance = sizeof_DFDBHeader > blockSize ? sizeof_DFDBHeader : blockSize;
        if (advance > remainingSize)
            break;
        remainingSize -= advance;
        block += advance / 4;
    }
#undef PRINT_ENUM
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, %r15d
movq %rdi, %rbp
xorl %esi, %esi
cmpl $0x4, %r15d
jb 0x2f67
movl (%rbp), %esi
cmpl %r15d, %esi
cmovbl %esi, %r15d
cmpl $0x4, %r15d
jb 0x2f8c
addl $-0x4, %r15d
leaq 0x3a37(%rip), %rdi      # 0x69b6
xorl %eax, %eax
callq 0x1050
cmpl $0x8, %r15d
jae 0x2f9b
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0x4, %rbp
leaq 0x2736(%rip), %r12      # 0x56dc
xorl %eax, %eax
movl %eax, 0x1c(%rsp)
movq %rbp, %rax
movl (%rbp), %ebp
movq %rax, 0x8(%rsp)
movl 0x4(%rax), %eax
movq %rax, 0x10(%rsp)
leaq 0x3a05(%rip), %rdi      # 0x69cb
xorl %eax, %eax
callq 0x1050
movl %ebp, %r13d
andl $0x1ffff, %r13d         # imm = 0x1FFFF
je 0x2fec
leaq 0x3a2d(%rip), %rdi      # 0x6a0d
movl %r13d, %esi
xorl %eax, %eax
callq 0x1050
jmp 0x3001
leaq 0x3d0a(%rip), %rdi      # 0x6cfd
leaq 0x27f2(%rip), %rsi      # 0x57ec
xorl %eax, %eax
callq 0x1050
movl %ebp, %ebx
shrl $0x11, %ebx
xorl %r14d, %r14d
leaq 0x39c7(%rip), %rdi      # 0x69d7
xorl %eax, %eax
callq 0x1050
leaq 0x27e6(%rip), %rsi      # 0x5804
testl %ebx, %ebx
je 0x304f
cmpl $0x6002, %ebx           # imm = 0x6002
je 0x303e
cmpl $0x6001, %ebx           # imm = 0x6001
jne 0x304a
xorl %r14d, %r14d
leaq 0x27ee(%rip), %rsi      # 0x582a
jmp 0x304f
xorl %r14d, %r14d
leaq 0x280e(%rip), %rsi      # 0x5856
jmp 0x304f
movb $0x1, %r14b
xorl %esi, %esi
testb %r14b, %r14b
je 0x3066
leaq 0x39b2(%rip), %rdi      # 0x6a0d
movl %ebx, %esi
xorl %eax, %eax
callq 0x1050
jmp 0x3074
leaq 0x3c90(%rip), %rdi      # 0x6cfd
xorl %eax, %eax
callq 0x1050
xorl %r14d, %r14d
leaq 0x396c(%rip), %rdi      # 0x69ea
xorl %eax, %eax
callq 0x1050
leaq 0x27fa(%rip), %rsi      # 0x5886
movq 0x10(%rsp), %rcx
testw %cx, %cx
je 0x30c0
movzwl %cx, %eax
cmpl $0x2, %eax
je 0x30af
cmpl $0x1, %eax
jne 0x30bb
xorl %r14d, %r14d
leaq 0x27f2(%rip), %rsi      # 0x589f
jmp 0x30c0
xorl %r14d, %r14d
leaq 0x27ff(%rip), %rsi      # 0x58b8
jmp 0x30c0
movb $0x1, %r14b
xorl %esi, %esi
testb %r14b, %r14b
je 0x30db
movzwl %cx, %esi
leaq 0x393e(%rip), %rdi      # 0x6a0d
xorl %eax, %eax
movq %rcx, %r14
callq 0x1050
jmp 0x30ec
leaq 0x3c1b(%rip), %rdi      # 0x6cfd
xorl %eax, %eax
movq %rcx, %r14
callq 0x1050
shrl $0x10, %r14d
leaq 0x38fe(%rip), %rdi      # 0x69f5
movq %r14, 0x10(%rsp)
movl %r14d, %esi
xorl %eax, %eax
callq 0x1050
movl $0xa, %edi
callq 0x1030
testl %ebp, %ebp
je 0x3149
movl %r15d, 0x4(%rsp)
testl %r13d, %r13d
sete %al
addl $0xffff9fff, %ebx       # imm = 0xFFFF9FFF
cmpl $0x2, %ebx
setb %cl
testb %cl, %al
movq 0x8(%rsp), %rbp
jne 0x355c
leaq 0x3cc3(%rip), %rdi      # 0x6e02
callq 0x1040
jmp 0x355c
xorl %ebx, %ebx
cmpl $0x18, %r15d
movq 0x8(%rsp), %rbp
jb 0x358f
movl %r15d, 0x4(%rsp)
movl 0x8(%rbp), %r15d
movl %r15d, %ebp
shrl $0x18, %ebp
leaq 0x38a0(%rip), %rdi      # 0x6a10
movl %ebp, %esi
xorl %eax, %eax
callq 0x1050
movb $0x1, %r14b
movl $0x1, %edx
movl %ebx, %ecx
shll %cl, %edx
testb $0x1, %r14b
leaq 0x3c52(%rip), %rsi      # 0x6de2
leaq 0x3933(%rip), %rax      # 0x6aca
cmovneq %rax, %rsi
testl %ebx, %ebx
je 0x31b6
testl %ebp, %edx
je 0x31db
xorl %r14d, %r14d
leaq 0x3a20(%rip), %rdi      # 0x6bcd
xorl %eax, %eax
callq 0x1050
jmp 0x31db
testl %ebp, %edx
leaq 0x2712(%rip), %rdx      # 0x58d1
leaq 0x272b(%rip), %rax      # 0x58f1
cmoveq %rax, %rdx
xorl %r14d, %r14d
leaq 0x3c11(%rip), %rdi      # 0x6de5
xorl %eax, %eax
callq 0x1050
incl %ebx
cmpl $0x20, %ebx
jne 0x317c
leaq 0x3835(%rip), %rdi      # 0x6a1e
xorl %eax, %eax
callq 0x1050
movq 0x8(%rsp), %rbp
movzbl 0xa(%rbp), %ebx
movl %ebx, %edi
callq 0x2811
testq %rax, %rax
je 0x3218
leaq 0x3af1(%rip), %rdi      # 0x6cfd
movq %rax, %rsi
xorl %eax, %eax
callq 0x1050
jmp 0x3228
leaq 0x37ee(%rip), %rdi      # 0x6a0d
movl %ebx, %esi
xorl %eax, %eax
callq 0x1050
leaq 0x37fc(%rip), %rdi      # 0x6a2b
xorl %eax, %eax
callq 0x1050
movzbl 0x9(%rbp), %ebx
movl %ebx, %edi
callq 0x282a
testq %rax, %rax
je 0x3259
leaq 0x3ab0(%rip), %rdi      # 0x6cfd
movq %rax, %rsi
xorl %eax, %eax
callq 0x1050
jmp 0x3269
leaq 0x37ad(%rip), %rdi      # 0x6a0d
movl %ebx, %esi
xorl %eax, %eax
callq 0x1050
movzbl %r15b, %ebx
leaq 0x37c4(%rip), %rdi      # 0x6a38
xorl %eax, %eax
callq 0x1050
movl %ebx, %edi
callq 0x2843
testq %rax, %rax
movl %ebx, 0x18(%rsp)
je 0x329e
leaq 0x3a6b(%rip), %rdi      # 0x6cfd
movq %rax, %rsi
xorl %eax, %eax
callq 0x1050
jmp 0x32ae
leaq 0x3768(%rip), %rdi      # 0x6a0d
movl %ebx, %esi
xorl %eax, %eax
callq 0x1050
movl $0xa, %edi
callq 0x1030
movl 0xc(%rbp), %r8d
movl %r8d, %esi
movl $0xff, %r14d
andl %r14d, %esi
incl %esi
movl %r8d, %edx
shrl $0x8, %edx
andl %r14d, %edx
incl %edx
movl %r8d, %ecx
shrl $0x10, %ecx
andl %r14d, %ecx
incl %ecx
shrl $0x18, %r8d
incl %r8d
leaq 0x3753(%rip), %rdi      # 0x6a41
xorl %eax, %eax
callq 0x1050
movl 0x10(%rbp), %r8d
movl 0x14(%rbp), %r10d
movl %r8d, %esi
andl %r14d, %esi
movl %r8d, %edx
shrl $0x8, %edx
andl %r14d, %edx
movl %r8d, %ecx
shrl $0x10, %ecx
andl %r14d, %ecx
shrl $0x18, %r8d
movl %r10d, %r9d
andl %r14d, %r9d
movl %r10d, %r11d
shrl $0x8, %r11d
andl %r14d, %r11d
movl %r10d, %ebx
shrl $0x10, %ebx
andl %r14d, %ebx
shrl $0x18, %r10d
subq $0x8, %rsp
leaq 0x371c(%rip), %rdi      # 0x6a5d
xorl %eax, %eax
pushq %r10
pushq %rbx
pushq %r11
callq 0x1050
addq $0x20, %rsp
movq 0x10(%rsp), %rax
leal -0x18(%rax), %ecx
cmpl $0x10, %ecx
jb 0x355c
shrl $0x4, %ecx
cmpl $0x10, %ecx
movl $0x10, %eax
cmovael %eax, %ecx
movl 0x4(%rsp), %eax
movq %rax, 0x28(%rsp)
cmpl $0x1, %ecx
adcl $0x0, %ecx
movq %rcx, 0x20(%rsp)
xorl %esi, %esi
leaq 0x1(%rsi), %r15
movq %r15, %rax
shlq $0x4, %rax
addq $0x18, %rax
cmpq 0x28(%rsp), %rax
ja 0x355c
leaq (,%rsi,4), %rax
movq %rax, 0x30(%rsp)
movq %rsi, %r14
shlq $0x4, %r14
movzbl 0x1b(%r14,%rbp), %r13d
xorl %ebx, %ebx
leaq 0x36c7(%rip), %rdi      # 0x6a8a
xorl %eax, %eax
callq 0x1050
movzbl 0x1b(%r14,%rbp), %ebp
andl $-0x10, %ebp
leaq 0x36bc(%rip), %rdi      # 0x6a96
movl %ebp, %esi
xorl %eax, %eax
callq 0x1050
movb $0x1, %r14b
movl $0x1, %edx
movl %ebx, %ecx
shll %cl, %edx
testb $0x1, %r14b
leaq 0x39e8(%rip), %rsi      # 0x6de2
leaq 0x36c9(%rip), %rax      # 0x6aca
cmovneq %rax, %rsi
btl %ebx, %ebp
jae 0x3429
leal -0x10(%rdx), %eax
roll $0x1c, %eax
cmpl $0x7, %eax
ja 0x3429
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
xorl %ecx, %ecx
leaq 0x2a1b(%rip), %rax      # 0x5e42
jmp 0x344e
movb $0x1, %cl
xorl %eax, %eax
jmp 0x344e
xorl %ecx, %ecx
leaq 0x2a48(%rip), %rax      # 0x5e80
jmp 0x344e
xorl %ecx, %ecx
leaq 0x2a1d(%rip), %rax      # 0x5e60
jmp 0x344e
xorl %ecx, %ecx
leaq 0x2a50(%rip), %rax      # 0x5e9e
testb %cl, %cl
je 0x3469
testl %ebp, %edx
je 0x347d
xorl %r14d, %r14d
leaq 0x376d(%rip), %rdi      # 0x6bcd
xorl %eax, %eax
callq 0x1050
jmp 0x347d
xorl %r14d, %r14d
leaq 0x3972(%rip), %rdi      # 0x6de5
movq %rax, %rdx
xorl %eax, %eax
callq 0x1050
incl %ebx
cmpl $0x20, %ebx
jne 0x33e6
andl $0xf, %r13d
leaq 0x1f27(%rip), %rdi      # 0x53ba
callq 0x1040
leaq 0x360e(%rip), %rdi      # 0x6aad
movl %r13d, %esi
xorl %eax, %eax
callq 0x1050
movl 0x18(%rsp), %edi
movl %r13d, %esi
callq 0x29ad
testq %rax, %rax
je 0x34cd
leaq 0x3603(%rip), %rdi      # 0x6ac4
movq %rax, %rsi
xorl %eax, %eax
callq 0x1050
jmp 0x34de
leaq 0x35f7(%rip), %rdi      # 0x6acb
movl %r13d, %esi
xorl %eax, %eax
callq 0x1050
movq 0x8(%rsp), %rbp
movq 0x30(%rsp), %r14
movl 0x18(%rbp,%r14,4), %esi
movzwl %si, %edx
shrl $0x10, %esi
movl $0xff, %ebx
andl %ebx, %esi
incl %esi
leaq 0x35cf(%rip), %rdi      # 0x6ad2
xorl %eax, %eax
callq 0x1050
movl 0x1c(%rbp,%r14,4), %r8d
movl %r8d, %esi
andl %ebx, %esi
movl %r8d, %edx
shrl $0x8, %edx
andl %ebx, %edx
movl %r8d, %ecx
shrl $0x10, %ecx
andl %ebx, %ecx
shrl $0x18, %r8d
leaq 0x35c3(%rip), %rdi      # 0x6af2
xorl %eax, %eax
callq 0x1050
movl 0x20(%rbp,%r14,4), %esi
movl 0x24(%rbp,%r14,4), %edx
leaq 0x35c9(%rip), %rdi      # 0x6b10
xorl %eax, %eax
callq 0x1050
movq %r15, %rsi
cmpq 0x20(%rsp), %r15
jne 0x3386
movq 0x10(%rsp), %rdx
cmpl $0x9, %edx
movl $0x8, %eax
cmovbl %eax, %edx
movl %edx, %eax
shrl $0x2, %eax
movl 0x4(%rsp), %r15d
cmpl %r15d, %edx
setbe %bl
movl $0x0, %ecx
cmoval %ecx, %eax
leaq (%rbp,%rax,4), %rbp
cmoval %ecx, %edx
subl %edx, %r15d
testb %bl, %bl
movl 0x1c(%rsp), %eax
je 0x2f8c
cmpl $0x8, %eax
ja 0x2f8c
incl %eax
cmpl $0x8, %r15d
jae 0x2fa8
jmp 0x2f8c