// File: /workspace/github_c_makefile_star2_O0/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:
subq $0xe8, %rsp
movq %rdi, 0xe0(%rsp)
movl %esi, 0xdc(%rsp)
movl $0x4, 0xd8(%rsp)
movl $0x8, 0xd4(%rsp)
movl $0x18, 0xd0(%rsp)
movl $0x10, 0xcc(%rsp)
cmpl $0x4, 0xdc(%rsp)
jb 0x512c
movq 0xe0(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
jmp 0x5134
xorl %eax, %eax
movl %eax, 0x20(%rsp)
jmp 0x5134
movl 0x20(%rsp), %eax
movl %eax, 0xc8(%rsp)
movl 0xc8(%rsp), %eax
cmpl 0xdc(%rsp), %eax
jae 0x515c
movl 0xc8(%rsp), %eax
movl %eax, 0x1c(%rsp)
jmp 0x5167
movl 0xdc(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
movl %eax, 0xc4(%rsp)
cmpl $0x4, 0xc4(%rsp)
jae 0x5181
jmp 0x59c8
movq 0xe0(%rsp), %rax
addq $0x4, %rax
movq %rax, 0xb8(%rsp)
movl 0xc4(%rsp), %eax
subl $0x4, %eax
movl %eax, 0xc4(%rsp)
movl 0xc8(%rsp), %esi
leaq 0x3dea(%rip), %rdi      # 0x8f9e
movb $0x0, %al
callq 0x1030
movl $0x0, 0xb4(%rsp)
cmpl $0xa, 0xb4(%rsp)
jge 0x59c8
cmpl $0x8, 0xc4(%rsp)
jae 0x51e3
jmp 0x59c8
movq 0xb8(%rsp), %rax
movl (%rax), %eax
shrl $0x0, %eax
andl $0x1ffff, %eax          # imm = 0x1FFFF
movl %eax, 0xb0(%rsp)
movq 0xb8(%rsp), %rax
movl (%rax), %eax
shrl $0x11, %eax
andl $0x7fff, %eax           # imm = 0x7FFF
movl %eax, 0xac(%rsp)
movq 0xb8(%rsp), %rax
movl 0x4(%rax), %eax
shrl $0x0, %eax
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0xa8(%rsp)
movq 0xb8(%rsp), %rax
movl 0x4(%rax), %eax
shrl $0x10, %eax
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0xa4(%rsp)
leaq 0x3d63(%rip), %rdi      # 0x8fb3
movb $0x0, %al
callq 0x1030
movl 0xb0(%rsp), %eax
movl %eax, 0xa0(%rsp)
movl 0xa0(%rsp), %edi
callq 0x3cb0
movq %rax, 0x98(%rsp)
cmpq $0x0, 0x98(%rsp)
je 0x529c
movq 0x98(%rsp), %rsi
leaq 0x4061(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x52b1
movl 0xa0(%rsp), %esi
leaq 0x3d4b(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
leaq 0x3d07(%rip), %rdi      # 0x8fbf
movb $0x0, %al
callq 0x1030
movl 0xac(%rsp), %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %edi
callq 0x3cf0
movq %rax, 0x88(%rsp)
cmpq $0x0, 0x88(%rsp)
je 0x5304
movq 0x88(%rsp), %rsi
leaq 0x3ff9(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x5319
movl 0x94(%rsp), %esi
leaq 0x3ce3(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
leaq 0x3cb2(%rip), %rdi      # 0x8fd2
movb $0x0, %al
callq 0x1030
movl 0xa8(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x84(%rsp), %edi
callq 0x3d80
movq %rax, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
je 0x5363
movq 0x78(%rsp), %rsi
leaq 0x3f9a(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x5378
movl 0x84(%rsp), %esi
leaq 0x3c84(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
movl 0xa4(%rsp), %esi
leaq 0x3c57(%rip), %rdi      # 0x8fdd
movb $0x0, %al
callq 0x1030
leaq 0x3d1d(%rip), %rdi      # 0x90b1
movb $0x0, %al
callq 0x1030
cmpl $0x0, 0xb0(%rsp)
jne 0x58ff
cmpl $0x0, 0xac(%rsp)
jne 0x58ff
cmpl $0x18, 0xc4(%rsp)
jae 0x53c6
jmp 0x59c8
movq 0xb8(%rsp), %rax
movl 0x8(%rax), %eax
shrl $0x0, %eax
andl $0xff, %eax
movl %eax, 0x74(%rsp)
movq 0xb8(%rsp), %rax
movl 0x8(%rax), %eax
shrl $0x18, %eax
andl $0xff, %eax
movl %eax, 0x70(%rsp)
movl 0x70(%rsp), %esi
leaq 0x3bf9(%rip), %rdi      # 0x8ff8
movb $0x0, %al
callq 0x1030
movl 0x70(%rsp), %edi
leaq -0x1621(%rip), %rsi     # 0x3df0
callq 0x59d0
leaq 0x3be9(%rip), %rdi      # 0x9006
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x8(%rax), %eax
shrl $0x10, %eax
andl $0xff, %eax
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %edi
callq 0x3e40
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
je 0x5466
movq 0x60(%rsp), %rsi
leaq 0x3e97(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x5478
movl 0x6c(%rsp), %esi
leaq 0x3b84(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
leaq 0x3b94(%rip), %rdi      # 0x9013
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x8(%rax), %eax
shrl $0x8, %eax
andl $0xff, %eax
movl %eax, 0x5c(%rsp)
movl 0x5c(%rsp), %edi
callq 0x40c0
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x54c8
movq 0x50(%rsp), %rsi
leaq 0x3e35(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x54da
movl 0x5c(%rsp), %esi
leaq 0x3b22(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
leaq 0x3b3f(%rip), %rdi      # 0x9020
movb $0x0, %al
callq 0x1030
movl 0x74(%rsp), %eax
movl %eax, 0x4c(%rsp)
movl 0x4c(%rsp), %edi
callq 0x4260
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x551b
movq 0x40(%rsp), %rsi
leaq 0x3de2(%rip), %rdi      # 0x92f4
movb $0x0, %al
callq 0x1030
jmp 0x552d
movl 0x4c(%rsp), %esi
leaq 0x3acf(%rip), %rdi      # 0x8ff5
movb $0x0, %al
callq 0x1030
leaq 0x3b7d(%rip), %rdi      # 0x90b1
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0xc(%rax), %esi
shrl $0x0, %esi
andl $0xff, %esi
addl $0x1, %esi
movq 0xb8(%rsp), %rax
movl 0xc(%rax), %edx
shrl $0x8, %edx
andl $0xff, %edx
addl $0x1, %edx
movq 0xb8(%rsp), %rax
movl 0xc(%rax), %ecx
shrl $0x10, %ecx
andl $0xff, %ecx
addl $0x1, %ecx
movq 0xb8(%rsp), %rax
movl 0xc(%rax), %r8d
shrl $0x18, %r8d
andl $0xff, %r8d
addl $0x1, %r8d
leaq 0x3a87(%rip), %rdi      # 0x9029
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x10(%rax), %esi
shrl $0x0, %esi
andl $0xff, %esi
movq 0xb8(%rsp), %rax
movl 0x10(%rax), %edx
shrl $0x8, %edx
andl $0xff, %edx
movq 0xb8(%rsp), %rax
movl 0x10(%rax), %ecx
shrl $0x10, %ecx
andl $0xff, %ecx
movq 0xb8(%rsp), %rax
movl 0x10(%rax), %r8d
shrl $0x18, %r8d
andl $0xff, %r8d
movq 0xb8(%rsp), %rax
movl 0x14(%rax), %r9d
shrl $0x0, %r9d
andl $0xff, %r9d
movq 0xb8(%rsp), %rax
movl 0x14(%rax), %r11d
shrl $0x8, %r11d
andl $0xff, %r11d
movq 0xb8(%rsp), %rax
movl 0x14(%rax), %r10d
shrl $0x10, %r10d
andl $0xff, %r10d
movq 0xb8(%rsp), %rax
movl 0x14(%rax), %eax
shrl $0x18, %eax
andl $0xff, %eax
leaq 0x39ea(%rip), %rdi      # 0x9045
movl %r11d, (%rsp)
movl %r10d, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x1030
movl 0xa4(%rsp), %eax
subl $0x18, %eax
shrl $0x4, %eax
movl %eax, 0x3c(%rsp)
cmpl $0x10, 0x3c(%rsp)
jle 0x568f
movl $0x10, 0x3c(%rsp)
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0x58fd
movl 0xc4(%rsp), %eax
movl 0x38(%rsp), %ecx
addl $0x1, %ecx
shll $0x4, %ecx
addl $0x18, %ecx
cmpl %ecx, %eax
jae 0x56c2
jmp 0x58fd
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
shrl $0x18, %eax
andl $0xf, %eax
movl %eax, 0x34(%rsp)
movl 0x38(%rsp), %esi
leaq 0x3980(%rip), %rdi      # 0x9072
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
shrl $0x18, %eax
andl $0xf0, %eax
movl %eax, 0x30(%rsp)
movl 0x30(%rsp), %esi
leaq 0x3953(%rip), %rdi      # 0x907e
movb $0x0, %al
callq 0x1030
movl 0x30(%rsp), %edi
leaq -0x12ad(%rip), %rsi     # 0x4490
callq 0x59d0
leaq 0x3967(%rip), %rdi      # 0x90b0
movb $0x0, %al
callq 0x1030
movl 0x34(%rsp), %esi
leaq 0x393a(%rip), %rdi      # 0x9095
movb $0x0, %al
callq 0x1030
movl 0x74(%rsp), %edi
movl 0x34(%rsp), %esi
callq 0x4530
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x5791
movq 0x28(%rsp), %rsi
leaq 0x3924(%rip), %rdi      # 0x90ac
movb $0x0, %al
callq 0x1030
jmp 0x57a3
movl 0x34(%rsp), %esi
leaq 0x3917(%rip), %rdi      # 0x90b3
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
shrl $0x10, %esi
andl $0xff, %esi
addl $0x1, %esi
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
shrl $0x0, %edx
andl $0xffff, %edx           # imm = 0xFFFF
leaq 0x38c5(%rip), %rdi      # 0x90ba
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
shrl $0x0, %esi
andl $0xff, %esi
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
shrl $0x8, %edx
andl $0xff, %edx
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %ecx
shrl $0x10, %ecx
andl $0xff, %ecx
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %edi
shll $0x2, %edi
addl $0x6, %edi
addl $0x1, %edi
movslq %edi, %rdi
movl (%rax,%rdi,4), %r8d
shrl $0x18, %r8d
andl $0xff, %r8d
leaq 0x3844(%rip), %rdi      # 0x90da
movb $0x0, %al
callq 0x1030
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
shrl $0x0, %esi
andl $-0x1, %esi
movq 0xb8(%rsp), %rax
movl 0x38(%rsp), %ecx
shll $0x2, %ecx
addl $0x6, %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
shrl $0x0, %edx
andl $-0x1, %edx
leaq 0x3812(%rip), %rdi      # 0x90f8
movb $0x0, %al
callq 0x1030
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x5697
jmp 0x5943
cmpl $0x0, 0xb0(%rsp)
jne 0x5918
cmpl $0x6002, 0xac(%rsp) # imm = 0x6002
jne 0x5918
jmp 0x5941
cmpl $0x0, 0xb0(%rsp)
jne 0x5931
cmpl $0x6001, 0xac(%rsp) # imm = 0x6001
jne 0x5931
jmp 0x593f
leaq 0x37e5(%rip), %rdi      # 0x911d
movb $0x0, %al
callq 0x1030
jmp 0x5941
jmp 0x5943
movl $0x8, %eax
cmpl 0xa4(%rsp), %eax
jbe 0x595c
movl $0x8, %eax
movl %eax, 0x18(%rsp)
jmp 0x5967
movl 0xa4(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0xc4(%rsp), %eax
jbe 0x597e
jmp 0x59c8
movl 0x24(%rsp), %ecx
movl 0xc4(%rsp), %eax
subl %ecx, %eax
movl %eax, 0xc4(%rsp)
movl 0x24(%rsp), %ecx
shrl $0x2, %ecx
movq 0xb8(%rsp), %rax
movl %ecx, %ecx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0xb8(%rsp)
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x51c6
addq $0xe8, %rsp
retq