public static KtxFile Load(Stream s, bool readKeyValuePairs) { using (BinaryReader br = new BinaryReader(s)) { KtxHeader header = ReadStruct <KtxHeader>(br); KtxKeyValuePair[] kvps = null; if (readKeyValuePairs) { int keyValuePairBytesRead = 0; List <KtxKeyValuePair> keyValuePairs = new List <KtxKeyValuePair>(); while (keyValuePairBytesRead < header.BytesOfKeyValueData) { int bytesRemaining = (int)(header.BytesOfKeyValueData - keyValuePairBytesRead); KtxKeyValuePair kvp = ReadNextKeyValuePair(br, out int read); keyValuePairBytesRead += read; keyValuePairs.Add(kvp); } kvps = keyValuePairs.ToArray(); } else { br.BaseStream.Seek(header.BytesOfKeyValueData, SeekOrigin.Current); // Skip over header data. } uint numberOfFaces = Math.Max(1, header.NumberOfFaces); List <KtxFace> faces = new List <KtxFace>((int)numberOfFaces); for (int i = 0; i < numberOfFaces; i++) { faces.Add(new KtxFace(header.NumberOfMipmapLevels)); } for (uint mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++) { uint imageSize = br.ReadUInt32(); // For cubemap textures, imageSize is actually the size of an individual face. bool isCubemap = header.NumberOfFaces == 6 && header.NumberOfArrayElements == 0; for (uint face = 0; face < numberOfFaces; face++) { byte[] faceData = br.ReadBytes((int)imageSize); faces[(int)face].Mipmaps[mipLevel] = new KtxMipmap(imageSize, faceData, header.PixelWidth / (uint)(Math.Pow(2, mipLevel)), header.PixelHeight / (uint)(Math.Pow(2, mipLevel))); uint cubePadding = 0u; if (isCubemap) { cubePadding = 3 - ((imageSize + 3) % 4); } br.BaseStream.Seek(cubePadding, SeekOrigin.Current); } uint mipPaddingBytes = 3 - ((imageSize + 3) % 4); br.BaseStream.Seek(mipPaddingBytes, SeekOrigin.Current); } return(new KtxFile(header, kvps, faces.ToArray())); } }
public KtxFile(KtxHeader header, KtxKeyValuePair[] keyValuePairs, KtxFace[] faces) { Header = header; KeyValuePairs = keyValuePairs; Faces = faces; }