Path: blob/master/thirdparty/libktx/external/dfdutils/printdfd.c
9906 views
/* -*- tab-width: 4; -*- */1/* vi: set sw=2 ts=4 expandtab: */23/* Copyright 2019-2020 The Khronos Group Inc.4* SPDX-License-Identifier: Apache-2.05*/67/**8* @file9* @~English10* @brief Utilities for printing data format descriptors.11*/1213/*14* Author: Andrew Garrard15*/1617#include <assert.h>18#include <stdbool.h>19#include <stdio.h>20#include <string.h>21#include <KHR/khr_df.h>22#include "dfd.h"2324enum {25// These constraints are not mandated by the spec and only used as a26// reasonable upper limit to stop parsing garbage data during print27MAX_NUM_BDFD_SAMPLES = 16,28MAX_NUM_DFD_BLOCKS = 10,29};3031const char* dfdToStringVendorID(khr_df_vendorid_e value) {32switch (value) {33case KHR_DF_VENDORID_KHRONOS:34return "KHR_DF_VENDORID_KHRONOS";3536case KHR_DF_VENDORID_MAX:37// These enum values are not meant for string representation. Ignore38break;39}40return NULL;41}4243const char* dfdToStringDescriptorType(khr_df_khr_descriptortype_e value) {44switch (value) {45case KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT:46return "KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT";47case KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES:48return "KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES";49case KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS:50return "KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS";5152case KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_WRITE_BIT:53case KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_DECODE_BIT:54case KHR_DF_KHR_DESCRIPTORTYPE_MAX:55// These enum values are not meant for string representation. Ignore56break;57}58return NULL;59}6061const char* dfdToStringVersionNumber(khr_df_versionnumber_e value) {62switch (value) {63case KHR_DF_VERSIONNUMBER_1_1:64// case KHR_DF_VERSIONNUMBER_1_0: // Fallthrough, Matching values65return "KHR_DF_VERSIONNUMBER_1_1";66case KHR_DF_VERSIONNUMBER_1_2:67return "KHR_DF_VERSIONNUMBER_1_2";68case KHR_DF_VERSIONNUMBER_1_3:69return "KHR_DF_VERSIONNUMBER_1_3";7071// case KHR_DF_VERSIONNUMBER_LATEST: // Fallthrough, Matching values72case KHR_DF_VERSIONNUMBER_MAX:73// These enum values are not meant for string representation. Ignore74break;75}76return NULL;77}7879const char* dfdToStringFlagsBit(uint32_t bit_index, bool bit_value) {80switch (bit_index) {81case 0:82return bit_value ? "KHR_DF_FLAG_ALPHA_PREMULTIPLIED" : "KHR_DF_FLAG_ALPHA_STRAIGHT";83default:84return NULL;85}86}8788const char* dfdToStringTransferFunction(khr_df_transfer_e value) {89switch (value) {90case KHR_DF_TRANSFER_UNSPECIFIED:91return "KHR_DF_TRANSFER_UNSPECIFIED";92case KHR_DF_TRANSFER_LINEAR:93return "KHR_DF_TRANSFER_LINEAR";94case KHR_DF_TRANSFER_SRGB:95// case KHR_DF_TRANSFER_SRGB_EOTF:96// case KHR_DF_TRANSFER_SCRGB:97// case KHR_DF_TRANSFER_SCRGB_EOTF: // Fallthrough, matching values98return "KHR_DF_TRANSFER_SRGB";99case KHR_DF_TRANSFER_ITU:100// case KHR_DF_ITU_OETF:101// case KHR_DF_TRANSFER_BT601:102// case KHR_DF_TRANSFER_BT601_OETF:103// case KHR_DF_TRANSFER_BT709:104// case KHR_DF_TRANSFER_BT709_OETF:105// case KHR_DF_TRANSFER_BT2020:106// case KHR_DF_TRANSFER_BT2020_OETF:107// case KHR_DF_TRANSFER_SMTPE170M:108// case KHR_DF_TRANSFER_SMTPE170M_OETF:109// case KHR_DF_TRANSFER_SMTPE170M_EOTF:110// case KHR_DF_TRANSFER_SMTPE170M: // Fallthrough, matching values111return "KHR_DF_TRANSFER_ITU";112case KHR_DF_TRANSFER_NTSC:113// case KHR_DF_TRANSFER_NTSC_EOTF: // Fallthrough, matching values114return "KHR_DF_TRANSFER_NTSC";115case KHR_DF_TRANSFER_SLOG:116//case KHR_DF_TRANSFER_SLOG_OETF: // Fallthrough, matching values117return "KHR_DF_TRANSFER_SLOG";118case KHR_DF_TRANSFER_SLOG2:119// case KHR_DF_TRANSFER_SLOG2_OETF:120return "KHR_DF_TRANSFER_SLOG2";121case KHR_DF_TRANSFER_BT1886:122// case KHR_DF_TRANSFER_BT1886_EOTF: // Fallthrough, matching values123return "KHR_DF_TRANSFER_BT1886";124case KHR_DF_TRANSFER_HLG_OETF:125return "KHR_DF_TRANSFER_HLG_OETF";126case KHR_DF_TRANSFER_HLG_EOTF:127return "KHR_DF_TRANSFER_HLG_EOTF";128case KHR_DF_TRANSFER_PQ_EOTF:129return "KHR_DF_TRANSFER_PQ_EOTF";130case KHR_DF_TRANSFER_PQ_OETF:131return "KHR_DF_TRANSFER_PQ_OETF";132case KHR_DF_TRANSFER_DCIP3:133// case KHR_DF_TRANSFER_DCIP3_EOTF: // Fallthrough, matching values134return "KHR_DF_TRANSFER_DCIP3";135case KHR_DF_TRANSFER_PAL_OETF:136return "KHR_DF_TRANSFER_PAL_OETF";137case KHR_DF_TRANSFER_PAL625_EOTF:138return "KHR_DF_TRANSFER_PAL625_EOTF";139case KHR_DF_TRANSFER_ST240:140// case KHR_DF_TRANSFER_ST240_EOTF:141// case KHR_DF_TRANSFER_ST240_OETF: // Fallthrough, matching values142return "KHR_DF_TRANSFER_ST240";143case KHR_DF_TRANSFER_ACESCC:144// case KHR_DF_TRANSFER_ACESCC_OETF: // Fallthrough, matching values145return "KHR_DF_TRANSFER_ACESCC";146case KHR_DF_TRANSFER_ACESCCT:147// case KHR_DF_TRANSFER_ACESCCT_OETF: // Fallthrough, matching values148return "KHR_DF_TRANSFER_ACESCCT";149case KHR_DF_TRANSFER_ADOBERGB:150// case KHR_DF_TRANSFER_ADOBERGB_EOTF: // Fallthrough, matching values151return "KHR_DF_TRANSFER_ADOBERGB";152case KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF:153return "KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF";154155case KHR_DF_TRANSFER_MAX:156// These enum values are not meant for string representation. Ignore157break;158}159return NULL;160}161162const char* dfdToStringColorPrimaries(khr_df_primaries_e value) {163switch (value) {164case KHR_DF_PRIMARIES_UNSPECIFIED:165return "KHR_DF_PRIMARIES_UNSPECIFIED";166case KHR_DF_PRIMARIES_BT709:167// case KHR_DF_PRIMARIES_SRGB: // Fallthrough, Matching values168return "KHR_DF_PRIMARIES_BT709";169case KHR_DF_PRIMARIES_BT601_EBU:170return "KHR_DF_PRIMARIES_BT601_EBU";171case KHR_DF_PRIMARIES_BT601_SMPTE:172return "KHR_DF_PRIMARIES_BT601_SMPTE";173case KHR_DF_PRIMARIES_BT2020:174return "KHR_DF_PRIMARIES_BT2020";175case KHR_DF_PRIMARIES_CIEXYZ:176return "KHR_DF_PRIMARIES_CIEXYZ";177case KHR_DF_PRIMARIES_ACES:178return "KHR_DF_PRIMARIES_ACES";179case KHR_DF_PRIMARIES_ACESCC:180return "KHR_DF_PRIMARIES_ACESCC";181case KHR_DF_PRIMARIES_NTSC1953:182return "KHR_DF_PRIMARIES_NTSC1953";183case KHR_DF_PRIMARIES_PAL525:184return "KHR_DF_PRIMARIES_PAL525";185case KHR_DF_PRIMARIES_DISPLAYP3:186return "KHR_DF_PRIMARIES_DISPLAYP3";187case KHR_DF_PRIMARIES_ADOBERGB:188return "KHR_DF_PRIMARIES_ADOBERGB";189190case KHR_DF_PRIMARIES_MAX:191// These enum values are not meant for string representation. Ignore192break;193}194return NULL;195}196197const char* dfdToStringColorModel(khr_df_model_e value) {198switch (value) {199case KHR_DF_MODEL_UNSPECIFIED:200return "KHR_DF_MODEL_UNSPECIFIED";201case KHR_DF_MODEL_RGBSDA:202return "KHR_DF_MODEL_RGBSDA";203case KHR_DF_MODEL_YUVSDA:204return "KHR_DF_MODEL_YUVSDA";205case KHR_DF_MODEL_YIQSDA:206return "KHR_DF_MODEL_YIQSDA";207case KHR_DF_MODEL_LABSDA:208return "KHR_DF_MODEL_LABSDA";209case KHR_DF_MODEL_CMYKA:210return "KHR_DF_MODEL_CMYKA";211case KHR_DF_MODEL_XYZW:212return "KHR_DF_MODEL_XYZW";213case KHR_DF_MODEL_HSVA_ANG:214return "KHR_DF_MODEL_HSVA_ANG";215case KHR_DF_MODEL_HSLA_ANG:216return "KHR_DF_MODEL_HSLA_ANG";217case KHR_DF_MODEL_HSVA_HEX:218return "KHR_DF_MODEL_HSVA_HEX";219case KHR_DF_MODEL_HSLA_HEX:220return "KHR_DF_MODEL_HSLA_HEX";221case KHR_DF_MODEL_YCGCOA:222return "KHR_DF_MODEL_YCGCOA";223case KHR_DF_MODEL_YCCBCCRC:224return "KHR_DF_MODEL_YCCBCCRC";225case KHR_DF_MODEL_ICTCP:226return "KHR_DF_MODEL_ICTCP";227case KHR_DF_MODEL_CIEXYZ:228return "KHR_DF_MODEL_CIEXYZ";229case KHR_DF_MODEL_CIEXYY:230return "KHR_DF_MODEL_CIEXYY";231case KHR_DF_MODEL_BC1A:232// case KHR_DF_MODEL_DXT1A: // Fallthrough, Matching values233return "KHR_DF_MODEL_BC1A";234case KHR_DF_MODEL_BC2:235// case KHR_DF_MODEL_DXT2: // Fallthrough, Matching values236// case KHR_DF_MODEL_DXT3: // Fallthrough, Matching values237return "KHR_DF_MODEL_BC2";238case KHR_DF_MODEL_BC3:239// case KHR_DF_MODEL_DXT4: // Fallthrough, Matching values240// case KHR_DF_MODEL_DXT5: // Fallthrough, Matching values241return "KHR_DF_MODEL_BC3";242case KHR_DF_MODEL_BC4:243return "KHR_DF_MODEL_BC4";244case KHR_DF_MODEL_BC5:245return "KHR_DF_MODEL_BC5";246case KHR_DF_MODEL_BC6H:247return "KHR_DF_MODEL_BC6H";248case KHR_DF_MODEL_BC7:249return "KHR_DF_MODEL_BC7";250case KHR_DF_MODEL_ETC1:251return "KHR_DF_MODEL_ETC1";252case KHR_DF_MODEL_ETC2:253return "KHR_DF_MODEL_ETC2";254case KHR_DF_MODEL_ASTC:255return "KHR_DF_MODEL_ASTC";256case KHR_DF_MODEL_ETC1S:257return "KHR_DF_MODEL_ETC1S";258case KHR_DF_MODEL_PVRTC:259return "KHR_DF_MODEL_PVRTC";260case KHR_DF_MODEL_PVRTC2:261return "KHR_DF_MODEL_PVRTC2";262case KHR_DF_MODEL_UASTC:263return "KHR_DF_MODEL_UASTC";264265case KHR_DF_MODEL_MAX:266// These enum values are not meant for string representation. Ignore267break;268}269return NULL;270}271272const char* dfdToStringSampleDatatypeQualifiersBit(uint32_t bit_index, bool bit_value) {273if (!bit_value)274return NULL;275276switch (1u << bit_index) {277case KHR_DF_SAMPLE_DATATYPE_LINEAR:278return "KHR_DF_SAMPLE_DATATYPE_LINEAR";279case KHR_DF_SAMPLE_DATATYPE_EXPONENT:280return "KHR_DF_SAMPLE_DATATYPE_EXPONENT";281case KHR_DF_SAMPLE_DATATYPE_SIGNED:282return "KHR_DF_SAMPLE_DATATYPE_SIGNED";283case KHR_DF_SAMPLE_DATATYPE_FLOAT:284return "KHR_DF_SAMPLE_DATATYPE_FLOAT";285}286return NULL;287}288289const char* dfdToStringChannelId(khr_df_model_e model, khr_df_model_channels_e value) {290switch (model) {291case KHR_DF_MODEL_RGBSDA:292switch (value) {293case KHR_DF_CHANNEL_RGBSDA_RED:294return "KHR_DF_CHANNEL_RGBSDA_RED";295case KHR_DF_CHANNEL_RGBSDA_GREEN:296return "KHR_DF_CHANNEL_RGBSDA_GREEN";297case KHR_DF_CHANNEL_RGBSDA_BLUE:298return "KHR_DF_CHANNEL_RGBSDA_BLUE";299case KHR_DF_CHANNEL_RGBSDA_STENCIL:300return "KHR_DF_CHANNEL_RGBSDA_STENCIL";301case KHR_DF_CHANNEL_RGBSDA_DEPTH:302return "KHR_DF_CHANNEL_RGBSDA_DEPTH";303case KHR_DF_CHANNEL_RGBSDA_ALPHA:304return "KHR_DF_CHANNEL_RGBSDA_ALPHA";305default:306return NULL;307}308309case KHR_DF_MODEL_YUVSDA:310switch (value) {311case KHR_DF_CHANNEL_YUVSDA_Y:312return "KHR_DF_CHANNEL_YUVSDA_Y";313case KHR_DF_CHANNEL_YUVSDA_U:314return "KHR_DF_CHANNEL_YUVSDA_U";315case KHR_DF_CHANNEL_YUVSDA_V:316return "KHR_DF_CHANNEL_YUVSDA_V";317case KHR_DF_CHANNEL_YUVSDA_STENCIL:318return "KHR_DF_CHANNEL_YUVSDA_STENCIL";319case KHR_DF_CHANNEL_YUVSDA_DEPTH:320return "KHR_DF_CHANNEL_YUVSDA_DEPTH";321case KHR_DF_CHANNEL_YUVSDA_ALPHA:322return "KHR_DF_CHANNEL_YUVSDA_ALPHA";323default:324return NULL;325}326327case KHR_DF_MODEL_YIQSDA:328switch (value) {329case KHR_DF_CHANNEL_YIQSDA_Y:330return "KHR_DF_CHANNEL_YIQSDA_Y";331case KHR_DF_CHANNEL_YIQSDA_I:332return "KHR_DF_CHANNEL_YIQSDA_I";333case KHR_DF_CHANNEL_YIQSDA_Q:334return "KHR_DF_CHANNEL_YIQSDA_Q";335case KHR_DF_CHANNEL_YIQSDA_STENCIL:336return "KHR_DF_CHANNEL_YIQSDA_STENCIL";337case KHR_DF_CHANNEL_YIQSDA_DEPTH:338return "KHR_DF_CHANNEL_YIQSDA_DEPTH";339case KHR_DF_CHANNEL_YIQSDA_ALPHA:340return "KHR_DF_CHANNEL_YIQSDA_ALPHA";341default:342return NULL;343}344345case KHR_DF_MODEL_LABSDA:346switch (value) {347case KHR_DF_CHANNEL_LABSDA_L:348return "KHR_DF_CHANNEL_LABSDA_L";349case KHR_DF_CHANNEL_LABSDA_A:350return "KHR_DF_CHANNEL_LABSDA_A";351case KHR_DF_CHANNEL_LABSDA_B:352return "KHR_DF_CHANNEL_LABSDA_B";353case KHR_DF_CHANNEL_LABSDA_STENCIL:354return "KHR_DF_CHANNEL_LABSDA_STENCIL";355case KHR_DF_CHANNEL_LABSDA_DEPTH:356return "KHR_DF_CHANNEL_LABSDA_DEPTH";357case KHR_DF_CHANNEL_LABSDA_ALPHA:358return "KHR_DF_CHANNEL_LABSDA_ALPHA";359default:360return NULL;361}362363case KHR_DF_MODEL_CMYKA:364switch (value) {365case KHR_DF_CHANNEL_CMYKSDA_CYAN:366return "KHR_DF_CHANNEL_CMYKSDA_CYAN";367case KHR_DF_CHANNEL_CMYKSDA_MAGENTA:368return "KHR_DF_CHANNEL_CMYKSDA_MAGENTA";369case KHR_DF_CHANNEL_CMYKSDA_YELLOW:370return "KHR_DF_CHANNEL_CMYKSDA_YELLOW";371case KHR_DF_CHANNEL_CMYKSDA_BLACK:372return "KHR_DF_CHANNEL_CMYKSDA_BLACK";373case KHR_DF_CHANNEL_CMYKSDA_ALPHA:374return "KHR_DF_CHANNEL_CMYKSDA_ALPHA";375default:376return NULL;377}378379case KHR_DF_MODEL_XYZW:380switch (value) {381case KHR_DF_CHANNEL_XYZW_X:382return "KHR_DF_CHANNEL_XYZW_X";383case KHR_DF_CHANNEL_XYZW_Y:384return "KHR_DF_CHANNEL_XYZW_Y";385case KHR_DF_CHANNEL_XYZW_Z:386return "KHR_DF_CHANNEL_XYZW_Z";387case KHR_DF_CHANNEL_XYZW_W:388return "KHR_DF_CHANNEL_XYZW_W";389default:390return NULL;391}392393case KHR_DF_MODEL_HSVA_ANG:394switch (value) {395case KHR_DF_CHANNEL_HSVA_ANG_VALUE:396return "KHR_DF_CHANNEL_HSVA_ANG_VALUE";397case KHR_DF_CHANNEL_HSVA_ANG_SATURATION:398return "KHR_DF_CHANNEL_HSVA_ANG_SATURATION";399case KHR_DF_CHANNEL_HSVA_ANG_HUE:400return "KHR_DF_CHANNEL_HSVA_ANG_HUE";401case KHR_DF_CHANNEL_HSVA_ANG_ALPHA:402return "KHR_DF_CHANNEL_HSVA_ANG_ALPHA";403default:404return NULL;405}406407case KHR_DF_MODEL_HSLA_ANG:408switch (value) {409case KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS:410return "KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS";411case KHR_DF_CHANNEL_HSLA_ANG_SATURATION:412return "KHR_DF_CHANNEL_HSLA_ANG_SATURATION";413case KHR_DF_CHANNEL_HSLA_ANG_HUE:414return "KHR_DF_CHANNEL_HSLA_ANG_HUE";415case KHR_DF_CHANNEL_HSLA_ANG_ALPHA:416return "KHR_DF_CHANNEL_HSLA_ANG_ALPHA";417default:418return NULL;419}420421case KHR_DF_MODEL_HSVA_HEX:422switch (value) {423case KHR_DF_CHANNEL_HSVA_HEX_VALUE:424return "KHR_DF_CHANNEL_HSVA_HEX_VALUE";425case KHR_DF_CHANNEL_HSVA_HEX_SATURATION:426return "KHR_DF_CHANNEL_HSVA_HEX_SATURATION";427case KHR_DF_CHANNEL_HSVA_HEX_HUE:428return "KHR_DF_CHANNEL_HSVA_HEX_HUE";429case KHR_DF_CHANNEL_HSVA_HEX_ALPHA:430return "KHR_DF_CHANNEL_HSVA_HEX_ALPHA";431default:432return NULL;433}434435case KHR_DF_MODEL_HSLA_HEX:436switch (value) {437case KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS:438return "KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS";439case KHR_DF_CHANNEL_HSLA_HEX_SATURATION:440return "KHR_DF_CHANNEL_HSLA_HEX_SATURATION";441case KHR_DF_CHANNEL_HSLA_HEX_HUE:442return "KHR_DF_CHANNEL_HSLA_HEX_HUE";443case KHR_DF_CHANNEL_HSLA_HEX_ALPHA:444return "KHR_DF_CHANNEL_HSLA_HEX_ALPHA";445default:446return NULL;447}448449case KHR_DF_MODEL_YCGCOA:450switch (value) {451case KHR_DF_CHANNEL_YCGCOA_Y:452return "KHR_DF_CHANNEL_YCGCOA_Y";453case KHR_DF_CHANNEL_YCGCOA_CG:454return "KHR_DF_CHANNEL_YCGCOA_CG";455case KHR_DF_CHANNEL_YCGCOA_CO:456return "KHR_DF_CHANNEL_YCGCOA_CO";457case KHR_DF_CHANNEL_YCGCOA_ALPHA:458return "KHR_DF_CHANNEL_YCGCOA_ALPHA";459default:460return NULL;461}462463case KHR_DF_MODEL_CIEXYZ:464switch (value) {465case KHR_DF_CHANNEL_CIEXYZ_X:466return "KHR_DF_CHANNEL_CIEXYZ_X";467case KHR_DF_CHANNEL_CIEXYZ_Y:468return "KHR_DF_CHANNEL_CIEXYZ_Y";469case KHR_DF_CHANNEL_CIEXYZ_Z:470return "KHR_DF_CHANNEL_CIEXYZ_Z";471default:472return NULL;473}474475case KHR_DF_MODEL_CIEXYY:476switch (value) {477case KHR_DF_CHANNEL_CIEXYY_X:478return "KHR_DF_CHANNEL_CIEXYY_X";479case KHR_DF_CHANNEL_CIEXYY_YCHROMA:480return "KHR_DF_CHANNEL_CIEXYY_YCHROMA";481case KHR_DF_CHANNEL_CIEXYY_YLUMA:482return "KHR_DF_CHANNEL_CIEXYY_YLUMA";483default:484return NULL;485}486487case KHR_DF_MODEL_BC1A:488switch (value) {489case KHR_DF_CHANNEL_BC1A_COLOR:490return "KHR_DF_CHANNEL_BC1A_COLOR";491case KHR_DF_CHANNEL_BC1A_ALPHA:492return "KHR_DF_CHANNEL_BC1A_ALPHA";493default:494return NULL;495}496497case KHR_DF_MODEL_BC2:498switch (value) {499case KHR_DF_CHANNEL_BC2_COLOR:500return "KHR_DF_CHANNEL_BC2_COLOR";501case KHR_DF_CHANNEL_BC2_ALPHA:502return "KHR_DF_CHANNEL_BC2_ALPHA";503default:504return NULL;505}506507case KHR_DF_MODEL_BC3:508switch (value) {509case KHR_DF_CHANNEL_BC3_COLOR:510return "KHR_DF_CHANNEL_BC3_COLOR";511case KHR_DF_CHANNEL_BC3_ALPHA:512return "KHR_DF_CHANNEL_BC3_ALPHA";513default:514return NULL;515}516517case KHR_DF_MODEL_BC4:518switch (value) {519case KHR_DF_CHANNEL_BC4_DATA:520return "KHR_DF_CHANNEL_BC4_DATA";521default:522return NULL;523}524525case KHR_DF_MODEL_BC5:526switch (value) {527case KHR_DF_CHANNEL_BC5_RED:528return "KHR_DF_CHANNEL_BC5_RED";529case KHR_DF_CHANNEL_BC5_GREEN:530return "KHR_DF_CHANNEL_BC5_GREEN";531default:532return NULL;533}534535case KHR_DF_MODEL_BC6H:536switch (value) {537case KHR_DF_CHANNEL_BC6H_COLOR:538return "KHR_DF_CHANNEL_BC6H_COLOR";539default:540return NULL;541}542543case KHR_DF_MODEL_BC7:544switch (value) {545case KHR_DF_CHANNEL_BC7_COLOR:546return "KHR_DF_CHANNEL_BC7_COLOR";547default:548return NULL;549}550551case KHR_DF_MODEL_ETC1:552switch (value) {553case KHR_DF_CHANNEL_ETC1_COLOR:554return "KHR_DF_CHANNEL_ETC1_COLOR";555default:556return NULL;557}558559case KHR_DF_MODEL_ETC2:560switch (value) {561case KHR_DF_CHANNEL_ETC2_RED:562return "KHR_DF_CHANNEL_ETC2_RED";563case KHR_DF_CHANNEL_ETC2_GREEN:564return "KHR_DF_CHANNEL_ETC2_GREEN";565case KHR_DF_CHANNEL_ETC2_COLOR:566return "KHR_DF_CHANNEL_ETC2_COLOR";567case KHR_DF_CHANNEL_ETC2_ALPHA:568return "KHR_DF_CHANNEL_ETC2_ALPHA";569default:570return NULL;571}572573case KHR_DF_MODEL_ASTC:574switch (value) {575case KHR_DF_CHANNEL_ASTC_DATA:576return "KHR_DF_CHANNEL_ASTC_DATA";577default:578return NULL;579}580581case KHR_DF_MODEL_ETC1S:582switch (value) {583case KHR_DF_CHANNEL_ETC1S_RGB:584return "KHR_DF_CHANNEL_ETC1S_RGB";585case KHR_DF_CHANNEL_ETC1S_RRR:586return "KHR_DF_CHANNEL_ETC1S_RRR";587case KHR_DF_CHANNEL_ETC1S_GGG:588return "KHR_DF_CHANNEL_ETC1S_GGG";589case KHR_DF_CHANNEL_ETC1S_AAA:590return "KHR_DF_CHANNEL_ETC1S_AAA";591default:592return NULL;593}594595case KHR_DF_MODEL_PVRTC:596switch (value) {597case KHR_DF_CHANNEL_PVRTC_COLOR:598return "KHR_DF_CHANNEL_PVRTC_COLOR";599default:600return NULL;601}602603case KHR_DF_MODEL_PVRTC2:604switch (value) {605case KHR_DF_CHANNEL_PVRTC2_COLOR:606return "KHR_DF_CHANNEL_PVRTC2_COLOR";607default:608return NULL;609}610611case KHR_DF_MODEL_UASTC:612switch (value) {613case KHR_DF_CHANNEL_UASTC_RGB:614return "KHR_DF_CHANNEL_UASTC_RGB";615case KHR_DF_CHANNEL_UASTC_RGBA:616return "KHR_DF_CHANNEL_UASTC_RGBA";617case KHR_DF_CHANNEL_UASTC_RRR:618return "KHR_DF_CHANNEL_UASTC_RRR";619case KHR_DF_CHANNEL_UASTC_RRRG:620return "KHR_DF_CHANNEL_UASTC_RRRG";621case KHR_DF_CHANNEL_UASTC_RG:622return "KHR_DF_CHANNEL_UASTC_RG";623default:624return NULL;625}626627default:628break;629}630631switch (value) {632case KHR_DF_CHANNEL_UNSPECIFIED_0:633return "KHR_DF_CHANNEL_UNSPECIFIED_0";634case KHR_DF_CHANNEL_UNSPECIFIED_1:635return "KHR_DF_CHANNEL_UNSPECIFIED_1";636case KHR_DF_CHANNEL_UNSPECIFIED_2:637return "KHR_DF_CHANNEL_UNSPECIFIED_2";638case KHR_DF_CHANNEL_UNSPECIFIED_3:639return "KHR_DF_CHANNEL_UNSPECIFIED_3";640case KHR_DF_CHANNEL_UNSPECIFIED_4:641return "KHR_DF_CHANNEL_UNSPECIFIED_4";642case KHR_DF_CHANNEL_UNSPECIFIED_5:643return "KHR_DF_CHANNEL_UNSPECIFIED_5";644case KHR_DF_CHANNEL_UNSPECIFIED_6:645return "KHR_DF_CHANNEL_UNSPECIFIED_6";646case KHR_DF_CHANNEL_UNSPECIFIED_7:647return "KHR_DF_CHANNEL_UNSPECIFIED_7";648case KHR_DF_CHANNEL_UNSPECIFIED_8:649return "KHR_DF_CHANNEL_UNSPECIFIED_8";650case KHR_DF_CHANNEL_UNSPECIFIED_9:651return "KHR_DF_CHANNEL_UNSPECIFIED_9";652case KHR_DF_CHANNEL_UNSPECIFIED_10:653return "KHR_DF_CHANNEL_UNSPECIFIED_10";654case KHR_DF_CHANNEL_UNSPECIFIED_11:655return "KHR_DF_CHANNEL_UNSPECIFIED_11";656case KHR_DF_CHANNEL_UNSPECIFIED_12:657return "KHR_DF_CHANNEL_UNSPECIFIED_12";658case KHR_DF_CHANNEL_UNSPECIFIED_13:659return "KHR_DF_CHANNEL_UNSPECIFIED_13";660case KHR_DF_CHANNEL_UNSPECIFIED_14:661return "KHR_DF_CHANNEL_UNSPECIFIED_14";662case KHR_DF_CHANNEL_UNSPECIFIED_15:663return "KHR_DF_CHANNEL_UNSPECIFIED_15";664default:665break;666}667668return NULL;669}670671/**672* @internal673*/674static void printFlagBits(uint32_t flags, const char*(*toStringFn)(uint32_t, bool)) {675bool first = true;676for (uint32_t bit_index = 0; bit_index < 32; ++bit_index) {677uint32_t bit_mask = 1u << bit_index;678bool bit_value = (bit_mask & (uint32_t) flags) != 0;679680const char* comma = first ? "" : ", ";681const char* str = toStringFn(bit_index, bit_value);682if (str) {683printf("%s%s", comma, str);684first = false;685} else if (bit_value) {686printf("%s%u", comma, bit_mask);687first = false;688}689}690}691692/**693* @internal694*/695static void printFlagBitsJSON(uint32_t indent, const char* nl, uint32_t flags, const char*(*toStringFn)(uint32_t, bool)) {696bool first = true;697for (uint32_t bit_index = 0; bit_index < 32; ++bit_index) {698uint32_t bit_mask = 1u << bit_index;699bool bit_value = (bit_mask & (uint32_t) flags) != 0;700701const char* str = toStringFn(bit_index, bit_value);702if (str) {703printf("%s%s%*s\"%s\"", first ? "" : ",", first ? "" : nl, indent, "", str);704first = false;705} else if (bit_value) {706printf("%s%s%*s%u", first ? "" : ",", first ? "" : nl, indent, "", bit_mask);707first = false;708}709}710if (!first)711printf("%s", nl);712}713714/**715* @~English716* @brief Print a human-readable interpretation of a data format descriptor.717*718* @param DFD Pointer to a data format descriptor.719* @param dataSize The maximum size that can be considered as part of the DFD.720**/721void printDFD(uint32_t *DFD, uint32_t dataSize)722{723#define PRINT_ENUM(VALUE, TO_STRING_FN) { \724int value = VALUE; \725const char* str = TO_STRING_FN(value); \726if (str) \727printf("%s", str); \728else \729printf("%u", value); \730}731732const uint32_t sizeof_dfdTotalSize = sizeof(uint32_t);733const uint32_t sizeof_DFDBHeader = sizeof(uint32_t) * 2;734const uint32_t sizeof_BDFD = sizeof(uint32_t) * KHR_DF_WORD_SAMPLESTART;735const uint32_t sizeof_BDFDSample = sizeof(uint32_t) * KHR_DF_WORD_SAMPLEWORDS;736737uint32_t dfdTotalSize = dataSize >= sizeof_dfdTotalSize ? DFD[0] : 0;738uint32_t remainingSize = dfdTotalSize < dataSize ? dfdTotalSize : dataSize;739if (remainingSize < sizeof_dfdTotalSize)740return; // Invalid DFD: dfdTotalSize must be present741742uint32_t* block = DFD + 1;743remainingSize -= sizeof_dfdTotalSize;744745printf("DFD total bytes: %u\n", dfdTotalSize);746747for (int i = 0; i < MAX_NUM_DFD_BLOCKS; ++i) { // At most only iterate MAX_NUM_DFD_BLOCKS block748if (remainingSize < sizeof_DFDBHeader)749break; // Invalid DFD: Missing or partial block header750751const khr_df_vendorid_e vendorID = KHR_DFDVAL(block, VENDORID);752const khr_df_khr_descriptortype_e descriptorType = KHR_DFDVAL(block, DESCRIPTORTYPE);753const khr_df_versionnumber_e versionNumber = KHR_DFDVAL(block, VERSIONNUMBER);754const uint32_t blockSize = KHR_DFDVAL(block, DESCRIPTORBLOCKSIZE);755756printf("Vendor ID: ");757PRINT_ENUM(vendorID, dfdToStringVendorID);758printf("\nDescriptor type: ");759PRINT_ENUM(descriptorType, dfdToStringDescriptorType);760printf("\nVersion: ");761PRINT_ENUM(versionNumber, dfdToStringVersionNumber);762printf("\nDescriptor block size: %u", blockSize);763printf("\n");764765if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT) {766if (remainingSize < sizeof_BDFD)767break; // Invalid DFD: Missing or partial basic DFD block768769const int model = KHR_DFDVAL(block, MODEL);770771khr_df_flags_e flags = KHR_DFDVAL(block, FLAGS);772printf("Flags: 0x%X (", flags);773printFlagBits(flags, dfdToStringFlagsBit);774printf(")\nTransfer: ");775PRINT_ENUM(KHR_DFDVAL(block, TRANSFER), dfdToStringTransferFunction);776printf("\nPrimaries: ");777PRINT_ENUM(KHR_DFDVAL(block, PRIMARIES), dfdToStringColorPrimaries);778printf("\nModel: ");779PRINT_ENUM(model, dfdToStringColorModel);780printf("\n");781782printf("Dimensions: %u, %u, %u, %u\n",783KHR_DFDVAL(block, TEXELBLOCKDIMENSION0) + 1,784KHR_DFDVAL(block, TEXELBLOCKDIMENSION1) + 1,785KHR_DFDVAL(block, TEXELBLOCKDIMENSION2) + 1,786KHR_DFDVAL(block, TEXELBLOCKDIMENSION3) + 1);787printf("Plane bytes: %u, %u, %u, %u, %u, %u, %u, %u\n",788KHR_DFDVAL(block, BYTESPLANE0),789KHR_DFDVAL(block, BYTESPLANE1),790KHR_DFDVAL(block, BYTESPLANE2),791KHR_DFDVAL(block, BYTESPLANE3),792KHR_DFDVAL(block, BYTESPLANE4),793KHR_DFDVAL(block, BYTESPLANE5),794KHR_DFDVAL(block, BYTESPLANE6),795KHR_DFDVAL(block, BYTESPLANE7));796797int samples = (blockSize - sizeof_BDFD) / sizeof_BDFDSample;798if (samples > MAX_NUM_BDFD_SAMPLES)799samples = MAX_NUM_BDFD_SAMPLES; // Too many BDFD samples800for (int sample = 0; sample < samples; ++sample) {801if (remainingSize < sizeof_BDFD + (sample + 1) * sizeof_BDFDSample)802break; // Invalid DFD: Missing or partial basic DFD sample803804khr_df_model_channels_e channelType = KHR_DFDSVAL(block, sample, CHANNELID);805printf("Sample %u:\n", sample);806807khr_df_sample_datatype_qualifiers_e qualifiers = KHR_DFDSVAL(block, sample, QUALIFIERS);808printf(" Qualifiers: 0x%X (", qualifiers);809printFlagBits(qualifiers, dfdToStringSampleDatatypeQualifiersBit);810printf(")\n");811printf(" Channel Type: 0x%X", channelType);812{813const char* str = dfdToStringChannelId(model, channelType);814if (str)815printf(" (%s)\n", str);816else817printf(" (%u)\n", channelType);818}819printf(" Length: %u bits Offset: %u\n",820KHR_DFDSVAL(block, sample, BITLENGTH) + 1,821KHR_DFDSVAL(block, sample, BITOFFSET));822printf(" Position: %u, %u, %u, %u\n",823KHR_DFDSVAL(block, sample, SAMPLEPOSITION0),824KHR_DFDSVAL(block, sample, SAMPLEPOSITION1),825KHR_DFDSVAL(block, sample, SAMPLEPOSITION2),826KHR_DFDSVAL(block, sample, SAMPLEPOSITION3));827printf(" Lower: 0x%08x\n Upper: 0x%08x\n",828KHR_DFDSVAL(block, sample, SAMPLELOWER),829KHR_DFDSVAL(block, sample, SAMPLEUPPER));830}831} else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS) {832// TODO: Implement DFD print for ADDITIONAL_DIMENSIONS833} else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES) {834// TODO: Implement DFD print for ADDITIONAL_PLANES835} else {836printf("Unknown block\n");837}838839const uint32_t advance = sizeof_DFDBHeader > blockSize ? sizeof_DFDBHeader : blockSize;840if (advance > remainingSize)841break;842remainingSize -= advance;843block += advance / 4;844}845#undef PRINT_ENUM846}847848/**849* @~English850* @brief Print a JSON interpretation of a data format descriptor.851*852* @param DFD Pointer to a data format descriptor.853* @param dataSize The maximum size that can be considered as part of the DFD.854* @param base_indent The number of indentations to include at the front of every line855* @param indent_width The number of spaces to add with each nested scope856* @param minified Specifies whether the JSON output should be minified857**/858void printDFDJSON(uint32_t* DFD, uint32_t dataSize, uint32_t base_indent, uint32_t indent_width, bool minified)859{860if (minified) {861base_indent = 0;862indent_width = 0;863}864const char* space = minified ? "" : " ";865const char* nl = minified ? "" : "\n";866867#define LENGTH_OF_INDENT(INDENT) ((base_indent + INDENT) * indent_width)868869/** Prints an enum as string or number */870#define PRINT_ENUM(INDENT, NAME, VALUE, TO_STRING_FN, COMMA) { \871int value = VALUE; \872printf("%*s\"" NAME "\":%s", LENGTH_OF_INDENT(INDENT), "", space); \873const char* str = TO_STRING_FN(value); \874if (str) \875printf("\"%s\"", str); \876else \877printf("%u", value); \878printf(COMMA "%s", nl); \879}880881/** Prints an enum as string or number if the to string function fails with a trailing comma*/882#define PRINT_ENUM_C(INDENT, NAME, VALUE, TO_STRING_FN) \883PRINT_ENUM(INDENT, NAME, VALUE, TO_STRING_FN, ",")884885/** Prints an enum as string or number if the to string function fails without a trailing comma*/886#define PRINT_ENUM_E(INDENT, NAME, VALUE, TO_STRING_FN) \887PRINT_ENUM(INDENT, NAME, VALUE, TO_STRING_FN, "")888889#define PRINT_INDENT(INDENT, FMT, ...) { \890printf("%*s" FMT, LENGTH_OF_INDENT(INDENT), "", __VA_ARGS__); \891}892893#define PRINT_INDENT_NOARG(INDENT, FMT) { \894printf("%*s" FMT, LENGTH_OF_INDENT(INDENT), ""); \895}896897const uint32_t sizeof_dfdTotalSize = sizeof(uint32_t);898const uint32_t sizeof_DFDBHeader = sizeof(uint32_t) * 2;899const uint32_t sizeof_BDFD = sizeof(uint32_t) * KHR_DF_WORD_SAMPLESTART;900const uint32_t sizeof_BDFDSample = sizeof(uint32_t) * KHR_DF_WORD_SAMPLEWORDS;901902uint32_t dfdTotalSize = dataSize >= sizeof_dfdTotalSize ? DFD[0] : 0;903PRINT_INDENT(0, "\"totalSize\":%s%u,%s", space, dfdTotalSize, nl)904905uint32_t remainingSize = dfdTotalSize < dataSize ? dfdTotalSize : dataSize;906if (remainingSize < sizeof_dfdTotalSize) {907PRINT_INDENT(0, "\"blocks\":%s[]%s", space, nl) // Print empty blocks to confirm to the json scheme908return; // Invalid DFD: dfdTotalSize must be present909}910911uint32_t* block = DFD + 1;912remainingSize -= sizeof_dfdTotalSize;913PRINT_INDENT(0, "\"blocks\":%s[", space)914915for (int i = 0; i < MAX_NUM_DFD_BLOCKS; ++i) { // At most only iterate MAX_NUM_DFD_BLOCKS block916if (remainingSize < sizeof_DFDBHeader)917break; // Invalid DFD: Missing or partial block header918919const khr_df_vendorid_e vendorID = KHR_DFDVAL(block, VENDORID);920const khr_df_khr_descriptortype_e descriptorType = KHR_DFDVAL(block, DESCRIPTORTYPE);921const khr_df_versionnumber_e versionNumber = KHR_DFDVAL(block, VERSIONNUMBER);922const uint32_t blockSize = KHR_DFDVAL(block, DESCRIPTORBLOCKSIZE);923924const int model = KHR_DFDVAL(block, MODEL);925926if (i == 0) {927printf("%s", nl);928} else {929printf(",%s", nl);930}931PRINT_INDENT(1, "{%s", nl)932PRINT_ENUM_C(2, "vendorId", vendorID, dfdToStringVendorID);933PRINT_ENUM_C(2, "descriptorType", descriptorType, dfdToStringDescriptorType);934PRINT_ENUM_C(2, "versionNumber", versionNumber, dfdToStringVersionNumber);935PRINT_INDENT(2, "\"descriptorBlockSize\":%s%u", space, blockSize)936937if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT) {938if (remainingSize < sizeof_BDFD) {939// Invalid DFD: Missing or partial basic DFD block940printf("%s", nl);941PRINT_INDENT(1, "}%s", nl) // End of block942break;943}944945printf(",%s", nl);946PRINT_INDENT(2, "\"flags\":%s[%s", space, nl)947khr_df_flags_e flags = KHR_DFDVAL(block, FLAGS);948printFlagBitsJSON(LENGTH_OF_INDENT(3), nl, flags, dfdToStringFlagsBit);949PRINT_INDENT(2, "],%s", nl)950951PRINT_ENUM_C(2, "transferFunction", KHR_DFDVAL(block, TRANSFER), dfdToStringTransferFunction);952PRINT_ENUM_C(2, "colorPrimaries", KHR_DFDVAL(block, PRIMARIES), dfdToStringColorPrimaries);953PRINT_ENUM_C(2, "colorModel", model, dfdToStringColorModel);954PRINT_INDENT(2, "\"texelBlockDimension\":%s[%u,%s%u,%s%u,%s%u],%s", space,955KHR_DFDVAL(block, TEXELBLOCKDIMENSION0) + 1, space,956KHR_DFDVAL(block, TEXELBLOCKDIMENSION1) + 1, space,957KHR_DFDVAL(block, TEXELBLOCKDIMENSION2) + 1, space,958KHR_DFDVAL(block, TEXELBLOCKDIMENSION3) + 1, nl)959PRINT_INDENT(2, "\"bytesPlane\":%s[%u,%s%u,%s%u,%s%u,%s%u,%s%u,%s%u,%s%u],%s", space,960KHR_DFDVAL(block, BYTESPLANE0), space,961KHR_DFDVAL(block, BYTESPLANE1), space,962KHR_DFDVAL(block, BYTESPLANE2), space,963KHR_DFDVAL(block, BYTESPLANE3), space,964KHR_DFDVAL(block, BYTESPLANE4), space,965KHR_DFDVAL(block, BYTESPLANE5), space,966KHR_DFDVAL(block, BYTESPLANE6), space,967KHR_DFDVAL(block, BYTESPLANE7), nl)968969PRINT_INDENT(2, "\"samples\":%s[%s", space, nl)970int samples = (blockSize - sizeof_BDFD) / sizeof_BDFDSample;971if (samples > MAX_NUM_BDFD_SAMPLES)972samples = MAX_NUM_BDFD_SAMPLES;973for (int sample = 0; sample < samples; ++sample) {974if (remainingSize < sizeof_BDFD + (sample + 1) * sizeof_BDFDSample)975break; // Invalid DFD: Missing or partial basic DFD sample976977if (sample != 0)978printf(",%s", nl);979PRINT_INDENT(3, "{%s", nl)980981khr_df_sample_datatype_qualifiers_e qualifiers = KHR_DFDSVAL(block, sample, QUALIFIERS);982if (qualifiers == 0) {983PRINT_INDENT(4, "\"qualifiers\":%s[],%s", space, nl)984985} else {986PRINT_INDENT(4, "\"qualifiers\":%s[%s", space, nl)987printFlagBitsJSON(LENGTH_OF_INDENT(5), nl, qualifiers, dfdToStringSampleDatatypeQualifiersBit);988PRINT_INDENT(4, "],%s", nl)989}990991khr_df_model_channels_e channelType = KHR_DFDSVAL(block, sample, CHANNELID);992const char* channelStr = dfdToStringChannelId(model, channelType);993if (channelStr)994PRINT_INDENT(4, "\"channelType\":%s\"%s\",%s", space, channelStr, nl)995else996PRINT_INDENT(4, "\"channelType\":%s%u,%s", space, channelType, nl)997998PRINT_INDENT(4, "\"bitLength\":%s%u,%s", space, KHR_DFDSVAL(block, sample, BITLENGTH), nl)999PRINT_INDENT(4, "\"bitOffset\":%s%u,%s", space, KHR_DFDSVAL(block, sample, BITOFFSET), nl)1000PRINT_INDENT(4, "\"samplePosition\":%s[%u,%s%u,%s%u,%s%u],%s", space,1001KHR_DFDSVAL(block, sample, SAMPLEPOSITION0), space,1002KHR_DFDSVAL(block, sample, SAMPLEPOSITION1), space,1003KHR_DFDSVAL(block, sample, SAMPLEPOSITION2), space,1004KHR_DFDSVAL(block, sample, SAMPLEPOSITION3), nl)10051006if (qualifiers & KHR_DF_SAMPLE_DATATYPE_SIGNED) {1007PRINT_INDENT(4, "\"sampleLower\":%s%d,%s", space, KHR_DFDSVAL(block, sample, SAMPLELOWER), nl)1008PRINT_INDENT(4, "\"sampleUpper\":%s%d%s", space, KHR_DFDSVAL(block, sample, SAMPLEUPPER), nl)1009} else {1010PRINT_INDENT(4, "\"sampleLower\":%s%u,%s", space, (unsigned int) KHR_DFDSVAL(block, sample, SAMPLELOWER), nl)1011PRINT_INDENT(4, "\"sampleUpper\":%s%u%s", space, (unsigned int) KHR_DFDSVAL(block, sample, SAMPLEUPPER), nl)1012}10131014PRINT_INDENT_NOARG(3, "}")1015}1016printf("%s", nl);1017PRINT_INDENT(2, "]%s", nl) // End of samples1018} else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS) {1019printf("%s", nl);1020// printf(",%s", nl); // If there is extra member printed1021// TODO: Implement DFD print for ADDITIONAL_DIMENSIONS1022} else if (vendorID == KHR_DF_VENDORID_KHRONOS && descriptorType == KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES) {1023printf("%s", nl);1024// printf(",%s", nl); // If there is extra member printed1025// TODO: Implement DFD print for ADDITIONAL_PLANES1026} else {1027printf("%s", nl);1028// printf(",%s", nl); // If there is extra member printed1029// TODO: What to do with unknown blocks for json?1030// Unknown block data in binary?1031}10321033PRINT_INDENT_NOARG(1, "}") // End of block10341035const uint32_t advance = sizeof_DFDBHeader > blockSize ? sizeof_DFDBHeader : blockSize;1036if (advance > remainingSize)1037break;1038remainingSize -= advance;1039block += advance / 4;1040}1041printf("%s", nl);1042PRINT_INDENT(0, "]%s", nl) // End of blocks10431044#undef PRINT_ENUM1045#undef PRINT_ENUM_C1046#undef PRINT_ENUM_E1047#undef PRINT_INDENT1048#undef PRINT_INDENT_NOARG1049}105010511052