private static bool ReadFileRecord(IFileRecord record, BinaryReader reader) { var chars = reader.ReadChars(record.Magic.Length); if (VisualC.CompareMemory(chars, record.Magic, record.Magic.Length) != 0) { reader.BaseStream.Position -= record.Magic.Length; return(false); } var compressedLength = reader.ReadInt32(); var decompressedLength = reader.ReadInt32(); reader.BaseStream.Position += 4; var inputBuffer = new byte[compressedLength]; reader.Read(inputBuffer, 0, compressedLength); var outputBuffer = new byte[decompressedLength]; LZ4Codec.Decode(inputBuffer, 0, inputBuffer.Length, outputBuffer, 0, decompressedLength); var stream = new MemoryStream(outputBuffer); var recordReader = new BinaryReader(stream); record.Read(recordReader); return(true); }
/// <summary/> protected virtual void OnLoad(BinaryReader reader) { var header = reader.ReadChars(_assetHeader.Length); if (VisualC.CompareMemory(_assetHeader, header, header.Length) != 0) { throw new InvalidDataException("Could not load asset with invalid header."); } }
/// <summary> /// Checks if the given stream is valid instance binary. /// </summary> /// <param name="stream">The stream to check.</param> /// <param name="seekAfterwards">Determines if the stream's position is set back to zero.</param> public static bool CheckHeader(Stream stream, bool seekAfterwards = false) { var magic = new byte[7]; stream.Read(magic, 0, magic.Length); var valid = VisualC.CompareMemory(magic, _file, magic.Length) == 0; if (seekAfterwards) { stream.Position = 0L; } return(valid); }
private IWaveSource GetSoundSource(Stream stream) { var magic = new byte[8]; stream.Read(magic, 0, 8); stream.Position = 0; if (VisualC.CompareMemory(magic, _mp3Magic, 3) == 0 || VisualC.CompareMemory(magic, _mp3Magic2, 2) == 0) { return(new DmoMp3Decoder(stream)); } if (VisualC.CompareMemory(magic, _oggMagic, 4) == 0) { stream.Position = 0x1C; stream.Read(magic, 0, 8); stream.Position = 0; if (VisualC.CompareMemory(magic, _opusMagic, 8) == 0) { throw new NotSupportedException("Ogg Opus is not currently supported."); } var decoder = new VorbisDecoder(stream); var converter = new SampleToPcm16(decoder); return(converter); } if (VisualC.CompareMemory(magic, _flacMagic, 4) == 0) { return(new FlacFile(stream, FlacPreScanMode.Sync)); } if (VisualC.CompareMemory(magic, _riffMagic, 4) == 0) { stream.Position = 8; stream.Read(magic, 0, 7); if (VisualC.CompareMemory(magic, _waveMagic, 7) == 0) { return(new MediaFoundationDecoder(stream)); } stream.Position = 0; } if (VisualC.CompareMemory(magic, _m4aMagic, 7) == 0) { return(new MediaFoundationDecoder(stream)); } throw new FormatException("The stream is an unsupported format."); }
/// <summary> /// Returns the content type of the given stream. /// </summary> public static ContentType?PeekContent(Stream stream) { ContentType?type; using (var reader = new BinaryReader(stream, Encoding.UTF8, true)) { var magic = reader.ReadBytes(4); if (VisualC.CompareMemory(magic, AssetBase.Magic, 4) != 0) { type = null; } else { type = (ContentType)reader.ReadByte(); } } stream.Position = 0; return(type); }
/// <summary /> protected override void OnLoad(BinaryReader reader) { var header = reader.ReadChars(_robloxMeshVersion1.Length); if (VisualC.CompareMemory(header, _robloxMeshVersion1, header.Length) == 0) // special case for roblox mesh { return; } reader.BaseStream.Position = 0; base.OnLoad(reader); var vertCount = reader.ReadInt32(); Vertices = new Vertex[vertCount]; for (var i = 0; i < vertCount; i++) { var vert = new Vertex(); vert.Load(reader); Vertices[i] = vert; } }
private static void LoadShaders() { using (var cache = File.OpenRead(RenderSettings.ShaderCache)) using (var reader = new BinaryReader(cache)) { var magic = reader.ReadChars(_cacheMagic.Length); if (VisualC.CompareMemory(magic, _cacheMagic, magic.Length) != 0) { throw new InvalidDataException("The shader cache did not match the magic bytes."); } do { var compressedLength = reader.ReadInt32(); var decompressedLength = reader.ReadInt32(); var inputBuffer = reader.ReadBytes(compressedLength); var outputBuffer = LZ4Codec.Decode(inputBuffer, 0, compressedLength, decompressedLength); using (var shaderStream = new MemoryStream(outputBuffer)) using (var shaderReader = new BinaryReader(shaderStream)) { var name = shaderReader.ReadString(); var passCount = shaderReader.ReadInt32(); var passes = new List <GfxShader.Pass>(passCount); for (int i = 0; i < passCount; i++) { var pass = new GfxShader.Pass(); pass.Load(shaderReader); passes[i] = pass; } var source = shaderReader.ReadString(); var shader = new GfxShader(name, passes, source); shader.Passes.ForEach(p => p.Load()); _shaders[name] = shader; } } while (cache.Position < cache.Length); } }
public HDRImage(Stream stream, bool staging = false) { int i; var str = new char[10]; using (var reader = new BinaryReader(stream)) { reader.Read(str, 0, 10); if (VisualC.CompareMemory(str, _magicBytes, 10) != 0) { throw new InvalidDataException("Magic bytes invalid."); } stream.Position++; var cmd = new char[200]; i = 0; char c = (char)0, oldc; while (true) { oldc = c; c = reader.ReadChar(); if (c == 0xa && oldc == 0xa) { break; } cmd[i++] = c; } var reso = new char[200]; i = 0; while (true) { c = reader.ReadChar(); reso[i++] = c; if (c == 0xa) { break; } } int w, h; if (VisualC.ScanString(new string(reso), "-Y %ld +X %ld", out h, out w) != 2) { throw new InvalidDataException(); } Width = w; Height = h; var colours = new Color3[w * h]; var scanline = new byte[w, 4]; // convert image i = 0; for (int y = h - 1; y >= 0; y--) { if (Decrunch(scanline, w, reader) == false) { break; } WorkOnRGBE(scanline, w, colours, i); } var stride = w * 4; var buffer = new DataStream(h * stride, true, true); for (var y = 0; y < h; ++y) { for (var x = 0; x < w; x++) { var colour = colours[y + x]; var rgba = (int)colour.Red | ((int)colour.Green << 8) | ((int)colour.Blue << 16) | (1 << 24); buffer.Write(rgba); } } Texture2D = new Texture2D(Renderer.Device, new Texture2DDescription { Width = w, Height = h, ArraySize = 1, BindFlags = staging ? BindFlags.None : BindFlags.ShaderResource, Usage = staging ? ResourceUsage.Staging : ResourceUsage.Default, Format = Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = 0, CpuAccessFlags = staging ? CpuAccessFlags.Read : CpuAccessFlags.None, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(buffer.DataPointer, stride)); } }
private static void LoadTexture(Stream input, out Texture output) { if (input == null) { output = null; return; } var magic = new byte[4]; input.Read(magic, 0, 4); input.Position = 0; var a = (char)magic[0]; var b = (char)magic[1]; var c = (char)magic[2]; var d = (char)magic[3]; if (VisualC.CompareMemory(magic, DDSImage.MagicBytes, 4) == 0) { var test = new DDSImage(input); output = new Texture(test.Texture2D) { Name = "Cubemap (DDS)" }; return; } var faces = new DataRectangle[6]; using (var decoder = new BitmapDecoder(Renderer.ImagingFactory, input, DecodeOptions.CacheOnDemand)) { var frame = decoder.GetFrame(0); var converter = new FormatConverter(Renderer.ImagingFactory); converter.Initialize( frame, PixelFormat.Format32bppPRGBA, BitmapDitherType.None, null, 0.0, BitmapPaletteType.Custom); var width = frame.Size.Width; var height = frame.Size.Height; var ratio = width / (float)height; if (Math.Abs(ratio - 2) < 0.001) // panorama { throw new NotImplementedException(); } if (Math.Abs(ratio - 1.333f) < 0.001) // cubic { var tileDim = (int)(width / 4f); var stride = tileDim * 4; Action <int, int, int> loadFace = delegate(int index, int coordX, int coordY) { var faceStream = new DataStream(tileDim * stride, false, true); using (var crop = new BitmapClipper(Renderer.ImagingFactory)) { crop.Initialize(converter, new RawBox(coordX, coordY, tileDim, tileDim)); crop.CopyPixels(stride, faceStream); } faces[index] = new DataRectangle(faceStream.DataPointer, stride); }; loadFace(0, tileDim * 2, tileDim); loadFace(1, 0, tileDim); loadFace(2, tileDim, 0); loadFace(3, tileDim, tileDim * 2); loadFace(4, tileDim, tileDim); loadFace(5, tileDim * 3, tileDim); var texture2D = new Texture2D(Renderer.Device, new Texture2DDescription { Width = tileDim, Height = tileDim, ArraySize = 6, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Immutable, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = ResourceOptionFlags.TextureCube, SampleDescription = new SampleDescription(1, 0) }, faces); converter.Dispose(); output = new Texture(texture2D); output.Name = output.NativeTexture.Tag.ToString(); } else { throw new NotImplementedException(); } } }
public void Read(BinaryReader propReader) { var encode = propReader.ReadInt32(); short declaringTypeId; short propertyTag; DecodePropertyTag(encode, out declaringTypeId, out propertyTag); EncodeTag = encode; DeclaringTypeId = declaringTypeId; PropertyTag = propertyTag; CachedProperty cached; if (TypeRecord.Type.TaggedProperties.TryGetValue(encode, out cached)) { Name = cached.Name; Property = cached; PropertyType = cached.PropertyType; } DataType = (DataType)propReader.ReadByte(); while (propReader.BaseStream.Position < propReader.BaseStream.Length) { switch (DataType) { case DataType.String: Data.Add(propReader.ReadString()); break; case DataType.Content: Data.Add(propReader.ReadString()); break; case DataType.Boolean: Data.Add(propReader.ReadBoolean()); break; case DataType.Int16: Data.Add(propReader.ReadInt16()); break; case DataType.Int32: Data.Add(propReader.ReadInt32()); break; case DataType.Int64: Data.Add(propReader.ReadInt64()); break; case DataType.Single: Data.Add(propReader.ReadSingle()); break; case DataType.Double: Data.Add(propReader.ReadDouble()); break; case DataType.Enum: Data.Add(propReader.ReadInt16()); break; case DataType.FontFamily: Data.Add(new FontFamily(propReader.ReadString())); break; case DataType.Referent: var referent = propReader.ReadInt32(); Data.Add(referent == -1 ? Referent.Null : Context.GlobalReferents[referent]); break; case DataType.UserData: if (VisualC.CompareMemory(propReader.ReadBytes(3), _nullChars, 3) == 0) { Data.Add(null); } else { propReader.BaseStream.Position -= 3; // go back to start var id = propReader.ReadByte(); IDataType userData; switch (id) { case 0: userData = new Vector3(); break; case 1: userData = new Vector2(); break; case 2: userData = new Vector4(); break; case 3: userData = new Colour(); break; case 4: userData = new Axes(); break; case 5: userData = new CFrame(); break; case 6: userData = new UDim2(); break; case 7: userData = new ColourSequence(); break; case 8: userData = new NumberSequence(); break; case 9: userData = new NumberRange(); break; case 10: userData = new Faces(); break; case 11: userData = new Matrix3(); break; case 12: userData = new PhysicalProperties(); break; case 13: userData = new Plane(); break; case 15: userData = new Ray(); break; case 16: userData = new Region3(); break; case 17: userData = new Vector3int16(); break; case 18: userData = new Region3int16(); break; case 19: userData = new DateTime(); break; case 20: userData = new TimeSpan(); break; case 21: userData = new BinaryData(); break; case 22: userData = new MaterialNodeCollection(); break; case 23: userData = new InstanceId(); break; case 24: userData = new FontFamily(); break; default: throw new IndexOutOfRangeException($"No DataType with data ID \"{id}\" found."); } userData.Load(propReader); Data.Add(userData); } break; default: throw new ArgumentOutOfRangeException(); } } }
/// <summary> /// </summary> /// <param name="input"></param> /// <param name="existing"></param> /// <param name="skipMagic"></param> /// <returns></returns> public static Instance Deserialize(Stream input, Instance existing = null, bool skipMagic = false) { using (var reader = new BinaryReader(input)) { #region Header if (!skipMagic) { var magic = reader.ReadChars(7); if (VisualC.CompareMemory(magic, _file, 4) != 0) { throw new InvalidDataException("The file does not have a valid header."); } } var version = reader.ReadString(); if (version != Version) { throw new InvalidDataException($"The serializer ({Version}) does not support version \"{version}\""); } var totalTypes = reader.ReadInt32(); var totalObjects = reader.ReadInt32(); reader.ReadBytes(8); // read reserved 8 bytes var context = new Context { TotalTypes = totalTypes, TotalObjects = totalObjects }; #endregion #region Types var typeHeaders = new TypeRecord[totalTypes]; for (int i = 0; i < totalTypes; i++) { var typeRecord = new TypeRecord(context); if (!ReadFileRecord(typeRecord, reader)) { throw new InvalidDataException("Type headers misaligned"); } typeHeaders[i] = typeRecord; } #endregion #region Referents & Object Creation var objects = new Instance[totalObjects]; int objIndex = 0; for (int i = 0; i < totalTypes; i++) { var typeRecord = typeHeaders[i]; foreach (var referent in typeRecord.Referents.Values) { var instance = (Instance)typeRecord.Type.GetInstance(); instance.BeforeDeserialization(); objects[objIndex++] = instance; referent.Instance = instance; if (objIndex == 0) { context.Root = instance; } } } #endregion #region Reading Properties for (int i = 0; i < totalTypes; i++) { var typeRecord = typeHeaders[i]; var propCount = reader.ReadInt32(); for (int j = 0; j < propCount; j++) { var propRecord = new PropertyRecord(context, typeRecord); if (!ReadFileRecord(propRecord, reader)) { break; } typeRecord.Properties.Add(propRecord.EncodeTag, propRecord); } } #endregion #region Setting Properties for (int pass = 0; pass < 2; pass++) { for (int i = 0; i < totalTypes; i++) { var typeRecord = typeHeaders[i]; int j = 0; foreach (var referent in typeRecord.Referents.Values) { var instance = referent.Instance; foreach (var prop in typeRecord.Properties.Values) { if (prop.Name == "Parent") { if (pass == 1) { continue; } } else if (pass == 0) { continue; } PropertyRecord record; if (typeRecord.Properties.TryGetValue(prop.EncodeTag, out record)) { var data = record.Data[j]; var refr = data as Referent; if (refr != null) { data = refr.Instance; } if (prop.DataType == DataType.Content || (record.Property.PropertyType == typeof(FontFamily) && data is string)) // coerce string into content { data = Dynamic.CoerceConvert(data, record.Property.PropertyType); } //prop.Property.Set(instance, data); prop.Property.Set.FastDynamicInvoke(instance, data); } } j++; } } } #endregion var end = reader.ReadChars(3); if (VisualC.CompareMemory(end, _end, 3) != 0) { throw new InvalidDataException("End bytes did not match."); } for (var i = 0; i < objects.Length; i++) { objects[i].AfterDeserialization(context); } return(objects[0]); } }