Example #1
0
        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);
        }
Example #2
0
        /// <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.");
            }
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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.");
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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;
            }
        }
Example #7
0
        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);
                }
        }
Example #8
0
        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));
            }
        }
Example #9
0
        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();
                }
            }
        }
Example #10
0
            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();
                    }
                }
            }
Example #11
0
        /// <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]);
            }
        }