| 145 | } |
| 146 | |
| 147 | void CommandDeflate::executeDeflate() { |
| 148 | InputStream inputStream(options.inputFilepath, *this); |
| 149 | validateToolInput(inputStream, fmtInFile(options.inputFilepath), *this); |
| 150 | |
| 151 | KTXTexture2 texture{nullptr}; |
| 152 | StreambufStream<std::streambuf*> ktx2Stream{inputStream->rdbuf(), std::ios::in | std::ios::binary}; |
| 153 | auto ret = ktxTexture2_CreateFromStream(ktx2Stream.stream(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, texture.pHandle()); |
| 154 | if (ret != KTX_SUCCESS) |
| 155 | fatal(rc::INVALID_FILE, "Failed to create KTX2 texture: {}", ktxErrorString(ret)); |
| 156 | |
| 157 | if (texture->supercompressionScheme != KTX_SS_NONE) { |
| 158 | switch (texture->supercompressionScheme) { |
| 159 | case KTX_SS_ZLIB: |
| 160 | case KTX_SS_ZSTD: |
| 161 | if (!options.quiet) { |
| 162 | warning("Modifying existing {} supercompression of {}.", |
| 163 | toString(texture->supercompressionScheme), |
| 164 | options.inputFilepath); |
| 165 | } |
| 166 | break; |
| 167 | default: |
| 168 | fatal(rc::INVALID_FILE, |
| 169 | "Cannot further deflate a KTX2 file supercompressed with {}.", |
| 170 | toString(texture->supercompressionScheme)); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | if (options.zstd) { |
| 175 | ret = ktxTexture2_DeflateZstd(texture, *options.zstd); |
| 176 | if (ret != KTX_SUCCESS) |
| 177 | fatal(rc::IO_FAILURE, "Zstd deflation failed. KTX Error: {}", ktxErrorString(ret)); |
| 178 | } |
| 179 | |
| 180 | if (options.zlib) { |
| 181 | ret = ktxTexture2_DeflateZLIB(texture, *options.zlib); |
| 182 | if (ret != KTX_SUCCESS) |
| 183 | fatal(rc::IO_FAILURE, "ZLIB deflation failed. KTX Error: {}", ktxErrorString(ret)); |
| 184 | } |
| 185 | |
| 186 | const auto& findMetadataValue = [&](const char* const key) { |
| 187 | const char* value; |
| 188 | uint32_t valueLen; |
| 189 | std::string result; |
| 190 | auto ret = ktxHashList_FindValue(&texture->kvDataHead, key, |
| 191 | &valueLen, (void**)&value); |
| 192 | if (ret == KTX_SUCCESS) { |
| 193 | // The values we are looking for are required to be NUL terminated. |
| 194 | result.assign(value, valueLen - 1); |
| 195 | } |
| 196 | return result; |
| 197 | }; |
| 198 | |
| 199 | const auto updateMetadataValue = [&](const char* const key, |
| 200 | const std::string& value) { |
| 201 | ktxHashList_DeleteKVPair(&texture->kvDataHead, key); |
| 202 | ktxHashList_AddKVPair(&texture->kvDataHead, key, |
| 203 | static_cast<uint32_t>(value.size() + 1), // +1 to include \0 |
| 204 | value.c_str()); |
nothing calls this directly
no test coverage detected