| 2085 | } |
| 2086 | |
| 2087 | void |
| 2088 | ktxValidator::validateSgd(validationContext& ctx) |
| 2089 | { |
| 2090 | uint64_t sgdByteLength = ctx.header.supercompressionGlobalData.byteLength; |
| 2091 | if (ctx.header.supercompressionScheme == KTX_SS_BASIS_LZ) { |
| 2092 | if (sgdByteLength == 0) { |
| 2093 | addIssue(logger::eError, SGD.MissingSupercompressionGlobalData); |
| 2094 | return; |
| 2095 | } |
| 2096 | } else { |
| 2097 | if (sgdByteLength > 0) |
| 2098 | addIssue(logger::eError, SGD.UnexpectedSupercompressionGlobalData); |
| 2099 | return; |
| 2100 | } |
| 2101 | |
| 2102 | uint8_t* sgd = new uint8_t[sgdByteLength]; |
| 2103 | ctx.inp->read((char *)sgd, sgdByteLength); |
| 2104 | if (ctx.inp->fail()) |
| 2105 | addIssue(logger::eFatal, IOError.FileRead, strerror(errno)); |
| 2106 | else if (ctx.inp->eof()) |
| 2107 | addIssue(logger::eFatal, IOError.UnexpectedEOF); |
| 2108 | |
| 2109 | // firstImages contains the indices of the first images for each level. |
| 2110 | // The last array entry contains the total number of images which is what |
| 2111 | // we need here. |
| 2112 | uint32_t* firstImages = new uint32_t[ctx.levelCount+1]; |
| 2113 | // Temporary invariant value |
| 2114 | uint32_t layersFaces = ctx.layerCount * ctx.header.faceCount; |
| 2115 | firstImages[0] = 0; |
| 2116 | for (uint32_t level = 1; level <= ctx.levelCount; level++) { |
| 2117 | // NOTA BENE: numFaces * depth is only reasonable because they can't |
| 2118 | // both be > 1. I.e there are no 3d cubemaps. |
| 2119 | firstImages[level] = firstImages[level - 1] |
| 2120 | + layersFaces * MAX(ctx.header.pixelDepth >> (level - 1), 1); |
| 2121 | } |
| 2122 | uint32_t& imageCount = firstImages[ctx.levelCount]; |
| 2123 | |
| 2124 | ktxBasisLzGlobalHeader& bgdh = *reinterpret_cast<ktxBasisLzGlobalHeader*>(sgd); |
| 2125 | uint32_t numSamples = KHR_DFDSAMPLECOUNT(ctx.pActualDfd + 1); |
| 2126 | |
| 2127 | uint64_t expectedBgdByteLength = sizeof(ktxBasisLzGlobalHeader) |
| 2128 | + sizeof(ktxBasisLzEtc1sImageDesc) * imageCount |
| 2129 | + bgdh.endpointsByteLength |
| 2130 | + bgdh.selectorsByteLength |
| 2131 | + bgdh.tablesByteLength; |
| 2132 | |
| 2133 | ktxBasisLzEtc1sImageDesc* imageDescs = BGD_ETC1S_IMAGE_DESCS(sgd); |
| 2134 | ktxBasisLzEtc1sImageDesc* image = imageDescs; |
| 2135 | for (; image < imageDescs + imageCount; image++) { |
| 2136 | if (image->imageFlags & ~ETC1S_P_FRAME) |
| 2137 | addIssue(logger::eError, SGD.InvalidImageFlagBit); |
| 2138 | // Crosscheck the DFD. |
| 2139 | if (image->alphaSliceByteOffset == 0 && numSamples == 2) |
| 2140 | addIssue(logger::eError, SGD.DfdMismatchAlpha); |
| 2141 | if (image->alphaSliceByteOffset > 0 && numSamples == 1) |
| 2142 | addIssue(logger::eError, SGD.DfdMismatchNoAlpha); |
| 2143 | } |
| 2144 | |