Path: blob/master/thirdparty/libktx/external/dfdutils/queries.c
9903 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 querying info from a data format descriptor.11* @author Mark Callow12*/1314#include <stdint.h>15#include <stdio.h>16#include <stdlib.h>17#include <string.h>18#include <KHR/khr_df.h>19#include "dfd.h"2021/**22* @~English23* @brief Get the number and size of the image components from a DFD.24*25* This simplified function is for use only with the DFDs for unpacked26* formats which means all components have the same size.27*28* @param DFD Pointer to a Data Format Descriptor to interpret,29described as 32-bit words in native endianness.30Note that this is the whole descriptor, not just31the basic descriptor block.32* @param numComponents pointer to a 32-bit word in which the number of33components will be written.34* @param componentByteLength pointer to a 32-bit word in which the size of35a component in bytes will be written.36*/37void38getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,39uint32_t* componentByteLength)40{41const uint32_t *BDFDB = DFD+1;42uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);43uint32_t sampleNumber;44uint32_t currentChannel = ~0U; /* Don't start matched. */4546/* This is specifically for unpacked formats which means the size of */47/* each component is the same. */48*numComponents = 0;49for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {50uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleNumber, BITLENGTH) + 1) >> 3U;51uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);5253if (sampleChannel == currentChannel) {54/* Continuation of the same channel. */55/* Accumulate the byte length. */56*componentByteLength += sampleByteLength;57} else {58/* Everything is new. Hopefully. */59currentChannel = sampleChannel;60(*numComponents)++;61*componentByteLength = sampleByteLength;62}63}64}6566/**67* @~English68* @brief Return the number of "components" in the data.69*70* Calculates the number of uniques samples in the DFD by combining71* multiple samples for the same channel. For uncompressed colorModels72* this is the same as the number of components in the image data. For73* block-compressed color models this is the number of samples in74* the color model, typically 1 and in a few cases 2.75*76* @param DFD Pointer to a Data Format Descriptor for which,77* described as 32-bit words in native endianness.78* Note that this is the whole descriptor, not just79* the basic descriptor block.80*/81uint32_t getDFDNumComponents(const uint32_t* DFD)82{83const uint32_t *BDFDB = DFD+1;84uint32_t currentChannel = ~0U; /* Don't start matched. */85uint32_t numComponents = 0;86uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);87uint32_t sampleNumber;8889for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {90uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);91if (sampleChannel != currentChannel) {92numComponents++;93currentChannel = sampleChannel;94}95}96return numComponents;97}9899/**100* @~English101* @brief Reconstruct the value of bytesPlane0 from sample info.102*103* @deprecated Use reconstructDFDBytesPlanesFromSamples. This does not handle104* the possible second plane of the ETC1S model.105*106* Reconstruct the value for data that has been variable-rate compressed107* and and whose bytesPlane0 value has been set to 0. For DFDs that108* are valid for KTX files. Little-endian data only and no multi-plane models109* except ETC1S.110*111* @param DFD Pointer to the Data Format Descriptor for which to provide112* the value described as 32-bit words in native endianness.113* Note that this is the whole descriptor, not just114* the basic descriptor block.115* @return The number of bytes a pixel occupies in bytesPlane0.116*/117uint32_t118reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD)119{120const uint32_t *BDFDB = DFD+1;121uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);122uint32_t sampleNumber;123124uint32_t bitsPlane0 = 0;125int32_t largestOffset = 0;126uint32_t sampleNumberWithLargestOffset = 0;127128// Special case these depth{,-stencil} formats. The unused bits are129// in the MSBs so have no visibility in the DFD therefore the max offset130// algorithm below returns a value that is too small.131if (KHR_DFDSVAL(BDFDB, 0, CHANNELID) == KHR_DF_CHANNEL_COMMON_DEPTH) {132if (numSamples == 1) {133if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 24) {134// X8_D24_UNORM_PACK32,135return 4;136}137} else if (numSamples == 2) {138if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 16) {139// D16_UNORM_S8_UINT140return 4;141}142if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 32143&& KHR_DFDSVAL(BDFDB, 1, CHANNELID) == KHR_DF_CHANNEL_COMMON_STENCIL) {144// D32_SFLOAT_S8_UINT145return 8;146}147}148}149if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) {150// Size of the first plane.151return 8;152}153for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {154int32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleNumber, BITOFFSET);155if (sampleBitOffset > largestOffset) {156largestOffset = sampleBitOffset;157sampleNumberWithLargestOffset = sampleNumber;158}159}160161/* The sample bitLength field stores the bit length - 1. */162uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleNumberWithLargestOffset, BITLENGTH) + 1;163bitsPlane0 = largestOffset + sampleBitLength;164return bitsPlane0 >> 3U;165}166167/**168* @~English169* @brief Reconstruct the values of bytesPlane[01] from sample info.170*171* Reconstruct the values for data that has been variable-rate compressed172* and whose bytesPlane[01] values have been set to 0 and update the173* fields of the target DFD. For DFDs that are valid for KTX files.174* Little-endian data only and no multi-plane models except ETC1S hence175* only looking at bytesPlane0 abd bytesPlane1.176*177* @param DFD Pointer to a Data Format Descriptor for which,178* described as 32-bit words in native endianness.179* Note that this is the whole descriptor, not just180* the basic descriptor block.181*/182183void184reconstructDFDBytesPlanesFromSamples(uint32_t* DFD)185{186uint32_t *BDFDB = DFD+1;187188KHR_DFDSETVAL(BDFDB, BYTESPLANE0, reconstructDFDBytesPlane0FromSamples(DFD));189if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) {190if (KHR_DFDSAMPLECOUNT(BDFDB) == 2)191KHR_DFDSETVAL(BDFDB, BYTESPLANE1, 8);192}193}194195/**196* @~English197* @brief Reconstruct the value of bytesPlane0 from sample info.198*199* @see reconstructDFDBytesPlane0FromSamples for details.200* @deprecated For backward comparibility only. Use201* reconstructDFDBytesPlanesFromSamples.202*203* @param DFD Pointer to the Data Format Descriptor for which to provide204* the value described as 32-bit words in native endianness.205* Note that this is the whole descriptor, not just206* the basic descriptor block.207* @param bytesPlane0 pointer to a 32-bit word in which the recreated208* value of bytesPlane0 will be written.209*/210void211recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0)212{213*bytesPlane0 = reconstructDFDBytesPlane0FromSamples(DFD);214}215216217