| 543 | } |
| 544 | |
| 545 | void ValidationContext::validateIndices() { |
| 546 | const auto supercompressionScheme = ktxSupercmpScheme(header.supercompressionScheme); |
| 547 | |
| 548 | // Validate dataFormatDescriptor index |
| 549 | if (header.dataFormatDescriptor.byteOffset == 0 || header.dataFormatDescriptor.byteLength == 0) |
| 550 | error(HeaderData::IndexDFDMissing, header.dataFormatDescriptor.byteOffset, header.dataFormatDescriptor.byteLength); |
| 551 | |
| 552 | const auto levelIndexSize = sizeof(ktxLevelIndexEntry) * numLevels; |
| 553 | std::size_t expectedOffset = KTX2_HEADER_SIZE + levelIndexSize; |
| 554 | expectedOffset = align(expectedOffset, std::size_t{4}); |
| 555 | if (expectedOffset != header.dataFormatDescriptor.byteOffset) |
| 556 | error(HeaderData::IndexDFDInvalidOffset, header.dataFormatDescriptor.byteOffset, expectedOffset); |
| 557 | expectedOffset += header.dataFormatDescriptor.byteLength; |
| 558 | |
| 559 | if (header.dataFormatDescriptor.byteOffset != 0 && header.dataFormatDescriptor.byteLength != 0) |
| 560 | if (header.keyValueData.byteOffset != 0) |
| 561 | if (header.dataFormatDescriptor.byteLength != header.keyValueData.byteOffset - header.dataFormatDescriptor.byteOffset) |
| 562 | error(HeaderData::IndexDFDInvalidLength, header.dataFormatDescriptor.byteLength, header.keyValueData.byteOffset - header.dataFormatDescriptor.byteOffset); |
| 563 | |
| 564 | // Validate keyValueData index |
| 565 | if (header.keyValueData.byteLength != 0) { |
| 566 | expectedOffset = align(expectedOffset, std::size_t{4}); |
| 567 | if (expectedOffset != header.keyValueData.byteOffset) |
| 568 | error(HeaderData::IndexKVDInvalidOffset, header.keyValueData.byteOffset, expectedOffset); |
| 569 | expectedOffset += header.keyValueData.byteLength; |
| 570 | } else { |
| 571 | if (header.keyValueData.byteOffset != 0) |
| 572 | error(HeaderData::IndexKVDOffsetWithoutLength, header.keyValueData.byteOffset); |
| 573 | } |
| 574 | |
| 575 | // Validate supercompressionGlobalData index |
| 576 | if (header.supercompressionGlobalData.byteLength != 0) { |
| 577 | expectedOffset = align(expectedOffset, std::size_t{8}); |
| 578 | if (expectedOffset != header.supercompressionGlobalData.byteOffset) |
| 579 | error(HeaderData::IndexSGDInvalidOffset, header.supercompressionGlobalData.byteOffset, expectedOffset); |
| 580 | expectedOffset += header.supercompressionGlobalData.byteLength; |
| 581 | } else { |
| 582 | if (header.supercompressionGlobalData.byteOffset != 0) |
| 583 | error(HeaderData::IndexSGDOffsetWithoutLength, header.supercompressionGlobalData.byteOffset); |
| 584 | } |
| 585 | |
| 586 | if (isSupercompressionWithGlobalData(supercompressionScheme)) { |
| 587 | if (header.supercompressionGlobalData.byteLength == 0) |
| 588 | error(HeaderData::IndexSGDMissing, toString(supercompressionScheme)); |
| 589 | } else if (isSupercompressionWithNoGlobalData(supercompressionScheme)) { |
| 590 | if (header.supercompressionGlobalData.byteLength != 0) |
| 591 | error(HeaderData::IndexSGDNotApplicable, header.supercompressionGlobalData.byteLength, toString(supercompressionScheme)); |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | inline uint32_t calcLevelAlignment(ktxSupercmpScheme scheme, uint8_t blockByteLength) { |
| 596 | if (scheme != KTX_SS_NONE) |
nothing calls this directly
no test coverage detected