queries.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* -*- tab-width: 4; -*- */
  2. /* vi: set sw=2 ts=4 expandtab: */
  3. /* Copyright 2019-2020 The Khronos Group Inc.
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @~English
  9. * @brief Utilities for querying info from a data format descriptor.
  10. * @author Mark Callow
  11. */
  12. #include <stdint.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <KHR/khr_df.h>
  17. #include "dfd.h"
  18. /**
  19. * @~English
  20. * @brief Get the number and size of the image components from a DFD.
  21. *
  22. * This simplified function is for use only with the DFDs for unpacked
  23. * formats which means all components have the same size.
  24. *
  25. * @param DFD Pointer to a Data Format Descriptor to interpret,
  26. described as 32-bit words in native endianness.
  27. Note that this is the whole descriptor, not just
  28. the basic descriptor block.
  29. * @param numComponents pointer to a 32-bit word in which the number of
  30. components will be written.
  31. * @param componentByteLength pointer to a 32-bit word in which the size of
  32. a component in bytes will be written.
  33. */
  34. void
  35. getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,
  36. uint32_t* componentByteLength)
  37. {
  38. const uint32_t *BDFDB = DFD+1;
  39. uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
  40. uint32_t sampleCounter;
  41. uint32_t currentChannel = ~0U; /* Don't start matched. */
  42. /* This is specifically for unpacked formats which means the size of */
  43. /* each component is the same. */
  44. *numComponents = 0;
  45. for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
  46. uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1) >> 3U;
  47. uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
  48. if (sampleChannel == currentChannel) {
  49. /* Continuation of the same channel. */
  50. /* Accumulate the byte length. */
  51. *componentByteLength += sampleByteLength;
  52. } else {
  53. /* Everything is new. Hopefully. */
  54. currentChannel = sampleChannel;
  55. (*numComponents)++;
  56. *componentByteLength = sampleByteLength;
  57. }
  58. }
  59. }
  60. /**
  61. * @~English
  62. * @brief Return the number of "components" in the data.
  63. *
  64. * Calculates the number of uniques samples in the DFD by combining
  65. * multiple samples for the same channel. For uncompressed colorModels
  66. * this is the same as the number of components in the image data. For
  67. * block-compressed color models this is the number of samples in
  68. * the color model, typically 1 and in a few cases 2.
  69. *
  70. * @param DFD Pointer to a Data Format Descriptor for which,
  71. * described as 32-bit words in native endianness.
  72. * Note that this is the whole descriptor, not just
  73. * the basic descriptor block.
  74. */
  75. uint32_t getDFDNumComponents(const uint32_t* DFD)
  76. {
  77. const uint32_t *BDFDB = DFD+1;
  78. uint32_t currentChannel = ~0U; /* Don't start matched. */
  79. uint32_t numComponents = 0;
  80. uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
  81. uint32_t sampleCounter;
  82. for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
  83. uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
  84. if (sampleChannel != currentChannel) {
  85. numComponents++;
  86. currentChannel = sampleChannel;
  87. }
  88. }
  89. return numComponents;
  90. }
  91. /**
  92. * @~English
  93. * @brief Recreate the value of bytesPlane0 from sample info.
  94. *
  95. * This can be use to recreate the value of bytesPlane0 for data that
  96. * has been variable-rate compressed so has bytesPlane0 = 0. For DFDs
  97. * that are valid for KTX files. Little-endian data only and no multi-plane
  98. * formats.
  99. *
  100. * @param DFD Pointer to a Data Format Descriptor for which,
  101. * described as 32-bit words in native endianness.
  102. * Note that this is the whole descriptor, not just
  103. * the basic descriptor block.
  104. * @param bytesPlane0 pointer to a 32-bit word in which the recreated
  105. * value of bytesPlane0 will be written.
  106. */
  107. void
  108. recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0)
  109. {
  110. const uint32_t *BDFDB = DFD+1;
  111. uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
  112. uint32_t sampleCounter;
  113. uint32_t bitsPlane0 = 0;
  114. uint32_t* bitOffsets = malloc(sizeof(uint32_t) * numSamples);
  115. memset(bitOffsets, -1, sizeof(uint32_t) * numSamples);
  116. for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
  117. uint32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
  118. /* The sample bitLength field stores the bit length - 1. */
  119. uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
  120. uint32_t i;
  121. for (i = 0; i < numSamples; i++) {
  122. if (sampleBitOffset == bitOffsets[i]) {
  123. // This sample is being repeated as in e.g. RGB9E5.
  124. break;
  125. }
  126. }
  127. if (i == numSamples) {
  128. // Previously unseen bitOffset. Bump size.
  129. bitsPlane0 += sampleBitLength;
  130. bitOffsets[sampleCounter] = sampleBitOffset;
  131. }
  132. }
  133. free(bitOffsets);
  134. *bytesPlane0 = bitsPlane0 >> 3U;
  135. }