MCPcopy Create free account
hub / github.com/KhronosGroup/KTX-Software / unpackAndSave422

Method unpackAndSave422

tools/ktx/command_extract.cpp:546–707  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

544using namespace imageio;
545
546void CommandExtract::unpackAndSave422(std::string filepath, bool appendExtension,
547 VkFormat vkFormat, const FormatDescriptor& format, uint32_t width, uint32_t height,
548 const char* data, std::size_t size) {
549 (void) vkFormat;
550
551 assert(format.model() == KHR_DF_MODEL_YUVSDA);
552 assert(format.find(KHR_DF_CHANNEL_YUVSDA_Y));
553 // Create a custom format with the same precision but with only 3 channels
554 // Reuse similar 4 channel VkFormats and drop the last channel (There is no RGB variant of 10X6 and 12X4)
555 const auto precision = format.find(KHR_DF_CHANNEL_YUVSDA_Y)->bitLength + 1u;
556 auto unpackedFormat = createFormatDescriptor(
557 precision == 8 ? VK_FORMAT_R8G8B8A8_UNORM :
558 precision == 10 ? VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 :
559 precision == 12 ? VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 :
560 precision == 16 ? VK_FORMAT_R16G16B16A16_UNORM :
561 VK_FORMAT_UNDEFINED, *this);
562 unpackedFormat.removeLastChannel();
563
564 // 1 pixel (block) with 4 channel is unpacked to 2 pixel with 3 channels: Y0,Y1,U,V -> R0,G0,B0,R1,G1,B1
565 const auto blockYUVBytes = format.pixelByteCount();
566 const auto blockDimensionX = format.basic.texelBlockDimension0 + 1;
567 const auto blockDimensionY = format.basic.texelBlockDimension1 + 1;
568 const auto pixelBytes = unpackedFormat.pixelByteCount();
569 const auto channelBytes = pixelBytes / 3;
570 assert(format.sampleCount() == 4);
571 assert(format.basic.texelBlockDimension0 + 1 == 2);
572 assert(format.basic.texelBlockDimension1 + 1 == 1);
573 assert(format.basic.texelBlockDimension2 + 1 == 1);
574 assert(format.basic.texelBlockDimension3 + 1 == 1);
575 assert(size == width * height * blockYUVBytes / blockDimensionX / blockDimensionY);
576 (void) size;
577 (void) blockDimensionY;
578
579 uint32_t y0Offset = 0;
580 uint32_t y0Bits = 0;
581 uint32_t y0PositionX = 0;
582 uint32_t y1Offset = 0;
583 uint32_t y1Bits = 0;
584 uint32_t y1PositionX = 0;
585 uint32_t uOffset = 0;
586 uint32_t uBits = 0;
587 uint32_t uPositionX = 0;
588 uint32_t vOffset = 0;
589 uint32_t vBits = 0;
590 uint32_t vPositionX = 0;
591
592 for (const auto& sample : format.samples) {
593 switch (sample.channelType) {
594 case KHR_DF_CHANNEL_YUVSDA_Y:
595 if (y0Bits != 0) {
596 y1Offset = sample.bitOffset;
597 y1Bits = sample.bitLength + 1;
598 y1PositionX = sample.samplePosition0;
599 } else {
600 y0Offset = sample.bitOffset;
601 y0Bits = sample.bitLength + 1;
602 y0PositionX = sample.samplePosition0;
603 }

Callers

nothing calls this directly

Calls 13

assertFunction · 0.85
createFormatDescriptorFunction · 0.85
swapFunction · 0.85
convertUNORMToFloatFunction · 0.85
remapFunction · 0.85
convertFloatToUNORMFunction · 0.85
removeLastChannelMethod · 0.80
pixelByteCountMethod · 0.80
sampleCountMethod · 0.80
modelMethod · 0.45
findMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected