public static byte[] GetTextureData(Texture2DMipInfo mipToLoad, bool decompress = true) { var imagebytes = new byte[decompress ? mipToLoad.uncompressedSize : mipToLoad.compressedSize]; //Debug.WriteLine("getting texture data for " + mipToLoad.Export.FullPath); if (mipToLoad.storageType == StorageTypes.pccUnc) { Buffer.BlockCopy(mipToLoad.Export.Data, mipToLoad.localExportOffset, imagebytes, 0, mipToLoad.uncompressedSize); } else if (mipToLoad.storageType == StorageTypes.pccLZO || mipToLoad.storageType == StorageTypes.pccZlib) { if (decompress) { try { TextureCompression.DecompressTexture(imagebytes, new MemoryStream(mipToLoad.Export.Data, mipToLoad.localExportOffset, mipToLoad.compressedSize), mipToLoad.storageType, mipToLoad.uncompressedSize, mipToLoad.compressedSize); } catch (Exception e) { throw new Exception($"{e.Message}\nStorageType: {mipToLoad.storageType}\n"); } } else { Buffer.BlockCopy(mipToLoad.Export.Data, mipToLoad.localExportOffset, imagebytes, 0, mipToLoad.compressedSize); } } else if (mipToLoad.storageType == StorageTypes.extUnc || mipToLoad.storageType == StorageTypes.extLZO || mipToLoad.storageType == StorageTypes.extZlib) { string filename = null; List <string> loadedFiles = MEDirectories.EnumerateGameFiles(mipToLoad.Export.Game, MEDirectories.GamePath(mipToLoad.Export.Game)); if (mipToLoad.Export.Game == MEGame.ME1) { var fullPath = loadedFiles.FirstOrDefault(x => Path.GetFileName(x).Equals(mipToLoad.TextureCacheName, StringComparison.InvariantCultureIgnoreCase)); if (fullPath != null) { filename = fullPath; } else { throw new FileNotFoundException($"Externally referenced texture file not found in game: {mipToLoad.TextureCacheName}."); } } else { string archive = mipToLoad.TextureCacheName + ".tfc"; var localDirectoryTFCPath = Path.Combine(Path.GetDirectoryName(mipToLoad.Export.FileRef.FilePath), archive); if (File.Exists(localDirectoryTFCPath)) { filename = localDirectoryTFCPath; } else { var tfcs = loadedFiles.Where(x => x.EndsWith(".tfc")).ToList(); var fullPath = loadedFiles.FirstOrDefault(x => Path.GetFileName(x).Equals(archive, StringComparison.InvariantCultureIgnoreCase)); if (fullPath != null) { filename = fullPath; } else { throw new FileNotFoundException($"Externally referenced texture cache not found: {archive}."); } } } //exceptions above will prevent filename from being null here try { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { try { fs.Seek(mipToLoad.externalOffset, SeekOrigin.Begin); if (mipToLoad.storageType == StorageTypes.extLZO || mipToLoad.storageType == StorageTypes.extZlib) { if (decompress) { using (MemoryStream tmpStream = new MemoryStream(fs.ReadBytes(mipToLoad.compressedSize))) { try { TextureCompression.DecompressTexture(imagebytes, tmpStream, mipToLoad.storageType, mipToLoad.uncompressedSize, mipToLoad.compressedSize); } catch (Exception e) { throw new Exception(e.Message + "\n" + "File: " + filename + "\n" + "StorageType: " + mipToLoad.storageType + "\n" + "External file offset: " + mipToLoad.externalOffset); } } } else { fs.Read(imagebytes, 0, mipToLoad.compressedSize); } } else { fs.Read(imagebytes, 0, mipToLoad.uncompressedSize); } } catch (Exception e) { throw new Exception(e.Message + "\n" + "File: " + filename + "\n" + "StorageType: " + mipToLoad.storageType + "\n" + "External file offset: " + mipToLoad.externalOffset); } } } catch (Exception e) { throw new Exception(e.Message + "\n" + "File: " + filename + "\n" + "StorageType: " + mipToLoad.storageType + "\n" + "External file offset: " + mipToLoad.externalOffset); } } return(imagebytes); }