/// <summary> /// Writes this ktx file into a stream. /// </summary> public void Write(Stream s) { if (MipMaps.Count < 1 || MipMaps[0].NumberOfFaces < 1) { throw new InvalidOperationException("The KTX structure should have at least 1 mipmap level and 1 Face before writing to file."); } using (BinaryWriter bw = new BinaryWriter(s, UTF8, true)) { uint bytesOfKeyValueData = (uint)KeyValuePairs.Sum(x => x.GetSizeWithPadding()); Header.BytesOfKeyValueData = bytesOfKeyValueData; Header.NumberOfFaces = MipMaps[0].NumberOfFaces; Header.NumberOfMipmapLevels = (uint)MipMaps.Count; Header.NumberOfArrayElements = 0; if (!Header.VerifyHeader()) { throw new InvalidOperationException("Please verify the header validity before writing to file."); } bw.WriteStruct(Header); foreach (KtxKeyValuePair keyValuePair in KeyValuePairs) { KtxKeyValuePair.WriteKeyValuePair(bw, keyValuePair); } for (int mip = 0; mip < Header.NumberOfMipmapLevels; mip++) { uint imageSize = MipMaps[mip].SizeInBytes; bw.Write(imageSize); bool isCubemap = Header.NumberOfFaces == 6 && Header.NumberOfArrayElements == 0; for (int f = 0; f < Header.NumberOfFaces; f++) { bw.Write(MipMaps[mip].Faces[f].Data); uint cubePadding = 0u; if (isCubemap) { cubePadding = 3 - ((imageSize + 3) % 4); } bw.AddPadding(cubePadding); } uint mipPaddingBytes = 3 - ((imageSize + 3) % 4); bw.AddPadding(mipPaddingBytes); } } }