// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- /// <summary> /// Gets an array of <see cref="Vector2F"/> values representing the attributes data in each element. /// </summary> /// <param name="attribute">The <see cref="FvtxVertexAttribute"/>, which data is referenced.</param> /// <returns>An array containing the attributes data in each element.</returns> public Vector2F[] GetAttributeDataAsVector2F(FvtxVertexAttribute attribute) { List<Vector2F> typedData = new List<Vector2F>(); using (BinaryDataReader reader = new BinaryDataReader(new MemoryStream(Data))) { reader.ByteOrder = ByteOrder.BigEndian; // Go through the array elements. for (int i = 0; i < Data.Length; i += (int)Stride) { reader.Position = i + attribute.Offset; switch (attribute.Format) { case FvtxVertexAttributeFormat.Two_32Bit_Float: typedData.Add(reader.ReadVector2F()); break; case FvtxVertexAttributeFormat.Two_16Bit_Normalized: ushort x = reader.ReadUInt16(); ushort y = reader.ReadUInt16(); typedData.Add(new Vector2F(x / 65535f, y / 65535f)); break; default: throw new BfresException("Cannot retrieve attribute data as Vector2F: Mismatching format."); } } } return typedData.ToArray(); }
public override void Convert(ResourceLocation source, ResourceLocation dest) { ContentBinaryReader br = new ContentBinaryReader(source); BinaryDataReader data = br.ReadBinaryData(); float xllcorner = data.GetDataSingle("xllcorner"); float yllcorner = data.GetDataSingle("yllcorner"); int width = data.GetDataInt32("width"); int height = data.GetDataInt32("height"); float[] demData = new float[height * width]; int bits = data.GetDataInt32("bits", 32); ContentBinaryReader br2 = data.GetData("data"); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { demData[i * width + j] = br2.ReadSingle(); } } br2.Close(); data.Close(); // ========================================================= BinaryDataWriter result = new BinaryDataWriter(); result.AddEntry("xllcorner", xllcorner); result.AddEntry("yllcorner", yllcorner); result.AddEntry("width", width); result.AddEntry("height", height); result.AddEntry("bits", 8); Stream dataStream = result.AddEntryStream("data"); ContentBinaryWriter bw = new ContentBinaryWriter(dataStream); for (int i = 0; i < demData.Length; i++) { bw.Write((byte)(demData[i] * 255)); } bw.Close(); bw = new ContentBinaryWriter(dest); bw.Write(result); bw.Close(); }
/// <summary> /// Reads data from DataReader, and updates the world of entities. /// </summary> /// <param name="data">data</param> public void Update(byte[] data) { using (BinaryDataReader reader = new BinaryDataReader(data)) { while (reader.Position < reader.Length) { uint key = reader.ReadUInt(); if (key == uint.MaxValue) { break; } if (!_entities.TryGetValue(key, out EcsEntityExtended entity)) { entity = CreateEntity(key); } using (BinaryDataReader entityReader = reader.ReadNode()) { while (entityReader.Position < entityReader.Length) { byte index = entityReader.ReadByte(); if (index == byte.MaxValue) { break; } using (BinaryDataReader componentReader = entityReader.ReadNode()) { IEcsComponent component; if (entity.HasComponent(index)) { component = entity.GetComponent(index); } else { component = EcsTypeManager.CreateComponent(index); entity.AddComponent(index, component); } Serializer.GetSerializer(EcsTypeManager.Types[index]) .Update(component, componentReader); } } while (entityReader.Position < entityReader.Length) { entity.RemoveComponent(entityReader.ReadByte()); } } } while (reader.Position < reader.Length) { _entities[reader.ReadUInt()].Destroy(); } } }
void LoadProperties() { Properties = new List <EditableProperty>(); BinaryDataReader dataReader = new BinaryDataReader(new MemoryStream(data)); dataReader.ByteOrder = order; dataReader.Position = 0; ushort Count = dataReader.ReadUInt16(); ushort Unk1 = dataReader.ReadUInt16(); for (int i = 0; i < Count; i++) { var EntryOffset = dataReader.Position; uint NameOffset = dataReader.ReadUInt32(); uint DataOffset = dataReader.ReadUInt32(); ushort ValueLen = dataReader.ReadUInt16(); byte dataType = dataReader.ReadByte(); dataReader.ReadByte(); //padding ? if (!(dataType == 1 || dataType == 2)) { UnknownPropertiesCount++; continue; } var pos = dataReader.Position; dataReader.Position = EntryOffset + NameOffset; string propName = dataReader.ReadString(BinaryStringFormat.ZeroTerminated); var type = (EditableProperty.ValueType)dataType; dataReader.Position = EntryOffset + DataOffset; string[] values = new string[ValueLen]; for (int j = 0; j < ValueLen; j++) { if (type == EditableProperty.ValueType.int32) { values[j] = dataReader.ReadInt32().ToString(); } else { values[j] = dataReader.ReadSingle().ToString(); } } Properties.Add(new EditableProperty() { Name = propName, type = type, ValueOffset = EntryOffset + DataOffset, ValueCount = ValueLen, value = values }); OriginalProperties.Add(propName); dataReader.Position = pos; } }
public void Load(BinaryDataReader reader) { reader.Seek(0); string Magic = reader.ReadString(4); Console.WriteLine(Magic); if (Magic != "DDS ") { MessageBox.Show("The file does not appear to be a valid DDS file."); } header = new Header(); header.size = reader.ReadUInt32(); header.flags = reader.ReadUInt32(); header.height = reader.ReadUInt32(); header.width = reader.ReadUInt32(); header.pitchOrLinearSize = reader.ReadUInt32(); header.depth = reader.ReadUInt32(); header.mipmapCount = reader.ReadUInt32(); header.reserved1 = new uint[11]; for (int i = 0; i < 11; ++i) { header.reserved1[i] = reader.ReadUInt32(); } header.ddspf.size = reader.ReadUInt32(); header.ddspf.flags = reader.ReadUInt32(); header.ddspf.fourCC = reader.ReadString(4); header.ddspf.RGBBitCount = reader.ReadUInt32(); header.ddspf.RBitMask = reader.ReadUInt32(); header.ddspf.GBitMask = reader.ReadUInt32(); header.ddspf.BBitMask = reader.ReadUInt32(); header.ddspf.ABitMask = reader.ReadUInt32(); header.caps = reader.ReadUInt32(); header.caps2 = reader.ReadUInt32(); header.caps3 = reader.ReadUInt32(); header.caps4 = reader.ReadUInt32(); header.reserved2 = reader.ReadUInt32(); int DX10HeaderSize = 0; if (header.ddspf.fourCC == "DX10") { IsDX10 = true; DX10HeaderSize = 20; ReadDX10Header(reader); } reader.TemporarySeek((int)(4 + header.size + DX10HeaderSize), SeekOrigin.Begin); bdata = reader.ReadBytes((int)(reader.BaseStream.Length - reader.Position)); reader.Dispose(); reader.Close(); }
private static SpriteLink.Resource ReadResourceLink(BinaryDataReader reader) { var name = reader.ReadCString(); var version = reader.ReadUInt16(); return(new SpriteLink.Resource { Name = name, Version = version }); }
/// <summary> /// Reads <see cref="Matrix3x4"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Matrix3x4"/> instances.</returns> public static IList <Matrix3x4> ReadMatrix3x4s(this BinaryDataReader self, int count) { Matrix3x4[] values = new Matrix3x4[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadMatrix3x4(); } return(values); }
private static void ReadArrayRaw(JsonArray jsonArray, ref BinaryDataReader reader) { int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { jsonArray.Add(ReadValue(ref reader)); } }
/// <summary> /// /// </summary> /// <param name="reader"></param> private static void ReadSRT2D(BinaryDataReader reader) { ValueSrt2D = new Srt2D(); Syroot.Maths.Vector2F scaleVector2F = new Syroot.Maths.Vector2F(reader.ReadSingle(), reader.ReadSingle()); ValueSrt2D.Scaling = scaleVector2F; ValueSrt2D.Rotation = reader.ReadSingle(); Syroot.Maths.Vector2F transVector2F = new Syroot.Maths.Vector2F(reader.ReadSingle(), reader.ReadSingle()); ValueSrt2D.Translation = transVector2F; }
private ByamlPathPoint ReadPathPoint(BinaryDataReader reader) { ByamlPathPoint point = new ByamlPathPoint(); point.Position = reader.ReadVector3F(); point.Normal = reader.ReadVector3F(); point.Unknown = reader.ReadUInt32(); return(point); }
internal Field(BinaryDataReader reader) { Hash = reader.ReadUInt32(); Bitmask = reader.ReadUInt32(); Offset = reader.ReadUInt16(); Shift = reader.ReadSByte(); Type = (FieldType)reader.ReadByte(); Name = BCSVHashHelper.GetHashName(Hash); }
/// <summary> /// Reads <see cref="Vector3D"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Vector3D"/> instances.</returns> internal static Vector3D[] ReadVector3Ds(this BinaryDataReader self, int count) { Vector3D[] values = new Vector3D[count]; for (int i = 0; i < count; i++) { values[i] = ReadVector3D(self); } return(values); }
protected override NinepatchLayer Deserialize(BinaryDataReader reader) { return(new NinepatchLayer { Top = reader.ReadByte(), Bottom = reader.ReadByte(), Left = reader.ReadByte(), Right = reader.ReadByte() }); }
/// <summary> /// Read a sized reference table. /// </summary> /// <param name="br"></param> public SizedReferenceTable(ref BinaryDataReader br) { count = br.ReadUInt32(); sizedReferences = new List <SizedReference>(); for (int i = 0; i < count; i++) { sizedReferences.Add(new SizedReference(ref br)); } }
public static SubItem ReadFrom(BinaryDataReader dataReader) { var dataUnitType = (DataUnitType)dataReader.ReadByte(); var subItem = SubItemFactory.Instance.Create(dataUnitType); dataReader.Input.SkipBytes(1); Read16BitLengthPrefixedData(dataReader, () => subItem.ReadContentFrom(dataReader)); return(subItem); }
private List<ByamlPathPoint> ReadPath(BinaryDataReader reader, int length) { List<ByamlPathPoint> byamlPath = new List<ByamlPathPoint>(); for (int j = 0; j < length; j++) { byamlPath.Add(ReadPathPoint(reader)); } return byamlPath; }
/// <summary> /// Reads <see cref="Half"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Half"/> instances.</returns> public static IList <Half> ReadHalfs(this BinaryDataReader self, int count) { Half[] values = new Half[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadHalf(); } return(values); }
public static GobDelta.StartMovement ReadGobStartMovement(this BinaryDataReader reader) { return new GobDelta.StartMovement { Origin = reader.ReadInt32Coord(), Destination = reader.ReadInt32Coord(), TotalSteps = reader.ReadInt32() }; }
private void ReadDX10Header(BinaryDataReader reader) { DX10header = new DX10Header(); DX10header.DXGI_Format = reader.ReadEnum <DXGI_FORMAT>(true); DX10header.ResourceDim = reader.ReadUInt32(); DX10header.miscFlag = reader.ReadUInt32(); DX10header.arrayFlag = reader.ReadUInt32(); DX10header.miscFlags2 = reader.ReadUInt32(); }
/// <summary> /// Reads <see cref="Bounding"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Bounding"/> instances.</returns> public static IList <Bounding> ReadBoundings(this BinaryDataReader self, int count) { Bounding[] values = new Bounding[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadBounding(); } return(values); }
/// <summary> /// Deserializes the BYAML data from the given <paramref name="stream"/> and returns thew new deserialized /// instance of type <typeparamref name="T"/>. /// </summary> /// <typeparam name="T">The type of the data to deserialize.</typeparam> /// <param name="stream">The <see cref="Stream"/> providing the data to deserialize.</param> /// <returns>The deserialized instance of type <typeparamref name="T"/>.</returns> public T Deserialize <T>(Stream stream) { // Open a reader on the given stream. using (BinaryDataReader reader = new BinaryDataReader(stream, true)) { reader.ByteOrder = Settings.ByteOrder; return((T)Read(reader, typeof(T))); } }
public static ComponentSpecification ReadFrom(BinaryDataReader dataReader) { return(new ComponentSpecification { S_PrecisionAndSignOfComponentSamples = dataReader.ReadByte(), XR_HorizontalSubSamplingFactor = dataReader.ReadByte(), YR_VerticalSubSamplingFactor = dataReader.ReadByte() }); }
/// <summary> /// Reads <see cref="Vector4U"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Vector4U"/> instances.</returns> public static IList <Vector4U> ReadVector4Us(this BinaryDataReader self, int count) { Vector4U[] values = new Vector4U[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadVector4U(); } return(values); }
/// <summary> /// Reads <see cref="Decimal10x5"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="Decimal10x5"/> instances.</returns> public static IList <Decimal10x5> ReadDecimal10x5s(this BinaryDataReader self, int count) { Decimal10x5[] values = new Decimal10x5[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadDecimal10x5(); } return(values); }
public static GobDelta.Light ReadGobLight(this BinaryDataReader reader) { return new GobDelta.Light { Offset = reader.ReadInt32Coord(), Size = reader.ReadUInt16(), Intensity = reader.ReadByte() }; }
/// <summary> /// Reads a <see cref="AnimConstant"/> instance from the current stream and returns it. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <returns>The <see cref="AnimConstant"/> instance.</returns> public static AnimConstant[] ReadAnimConstants(this BinaryDataReader self, int count) { AnimConstant[] values = new AnimConstant[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadAnimConstant(); } return(values); }
public static MapInvalidateRegion ReadMapInvalidateRegionEvent(this BinaryDataReader reader) { var ul = reader.ReadInt32Coord(); var br = reader.ReadInt32Coord(); return(new MapInvalidateRegion { Region = Rect.FromLTRB(ul, br) }); }
// ---- 8-bit (4 x 2) ---- private static Vector4F Read_4_4_UNorm(this BinaryDataReader self) { byte value = self.ReadByte(); return(new Vector4F( (value & 0b00001111) / 127f, (value >> 4) / 127f, 0, 0)); }
/// <summary> /// Reads <see cref="Vector4Bool"/> instances from the current stream and returns them. /// </summary> /// <param name="self">The extended <see cref="BinaryDataReader"/>.</param> /// <param name="count">The number of instances to read.</param> /// <param name="format">The <see cref="BinaryBooleanFormat"/> in which values are stored.</param> /// <returns>The <see cref="Vector4Bool"/> instances.</returns> public static IList <Vector4Bool> ReadVector4Bools(this BinaryDataReader self, int count, BinaryBooleanFormat format = BinaryBooleanFormat.NonZeroByte) { Vector4Bool[] values = new Vector4Bool[count]; for (int i = 0; i < count; i++) { values[i] = self.ReadVector4Bool(format); } return(values); }
public static GobDelta.Position ReadGobPosition(this BinaryDataReader reader) { var c = reader.ReadInt32Coord(); var a = reader.ReadUInt16(); return new GobDelta.Position { Coord = c, Angle = (a / 65536.0) * Math.PI * 2 }; }
public FixedTimeSpirit(BinaryDataReader reader) { // Read the fields SpiritId = reader.ReadUInt32(); UnknownOne = reader.ReadUInt16(); UnknownTwo = reader.ReadUInt16(); AppearanceDuration = reader.ReadUInt32(); AppearanceInterval = reader.ReadUInt32(); StartDateTime = Container.ReadDateTime(reader); }
// ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="BfresNameOffset"/> struct from the given /// <see cref="BinaryDataReader"/>, which base streams position is advanced by 4 bytes. A temporary seek is /// performed to read in the referenced name. /// </summary> /// <param name="reader">The <see cref="BinaryDataReader"/> to read the data from.</param> internal BfresNameOffset(BinaryDataReader reader) { Address = (uint)reader.Position; ToSelf = reader.ReadInt32(); ToFile = (uint)(Address + ToSelf); // Strings are DWORD length-prefixed zero-postfixed, we decide to read a zero-terminated string here. // To read the length-prefix, you would have to seek 4 bytes back, as the offsets point to the first char. using (reader.TemporarySeek(ToFile, SeekOrigin.Begin)) { Name = reader.ReadString(BinaryStringFormat.ZeroTerminated); } }
// ---- METHODS (PRIVATE) -------------------------------------------------------------------------------------- private void Load(BfresLoaderContext context, BinaryDataReader dataReader) { Internal = new Internals(); Type = (FmatMaterialParameterType)context.Reader.ReadByte(); if (!Enum.IsDefined(typeof(FmatMaterialParameterType), Type)) { throw new BfresException("FmatMaterialParameter.Type invalid"); } Internal.Size = context.Reader.ReadByte(); Internal.Offset = context.Reader.ReadUInt16(); Internal.Unknown0x04 = context.Reader.ReadUInt32(); Internal.Unknown0x08 = context.Reader.ReadUInt32(); Internal.Index = context.Reader.ReadUInt16(); Internal.IndexRepeated = context.Reader.ReadUInt16(); if (Internal.Index != Internal.IndexRepeated) { context.Warnings.Add("FmatMaterial.Index has not the same value as FmatMaterial.IndexRepeated"); } Internal.NameOffset = context.Reader.ReadBfresNameOffset(); Name = Internal.NameOffset.Name; // Load the value from the given BinaryDataReader. dataReader.Position = Internal.Offset; switch (Type) { case FmatMaterialParameterType.Int32: Value = dataReader.ReadInt32(); break; case FmatMaterialParameterType.Single: Value = dataReader.ReadSingle(); break; case FmatMaterialParameterType.Vector2F: Value = dataReader.ReadVector2F(); break; case FmatMaterialParameterType.Vector3F: Value = dataReader.ReadVector3F(); break; case FmatMaterialParameterType.Vector4F: Value = dataReader.ReadVector4F(); break; case FmatMaterialParameterType.Matrix2x3: // Stored in column-major order, our structure however is row-major. float m11 = dataReader.ReadSingle(); float m21 = dataReader.ReadSingle(); float m12 = dataReader.ReadSingle(); float m22 = dataReader.ReadSingle(); float m13 = dataReader.ReadSingle(); float m23 = dataReader.ReadSingle(); Value = new Matrix2x3(m11, m12, m13, m21, m22, m23); break; } }
// ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="BfresOffset"/> struct from the given /// <see cref="BinaryDataReader"/>, which base streams position is advanced by 4 bytes. /// </summary> internal BfresOffset(BinaryDataReader reader) { Address = (uint)reader.Position; ToSelf = reader.ReadInt32(); ToFile = (uint)(Address + ToSelf); }
/// <summary> /// Gets an array of <see cref="Vector3F"/> values representing the attributes data in each element. /// </summary> /// <param name="attribute">The <see cref="FvtxVertexAttribute"/>, which data is referenced.</param> /// <returns>An array containing the attributes data in each element.</returns> public Vector3F[] GetAttributeDataAsVector3F(FvtxVertexAttribute attribute) { List<Vector3F> typedData = new List<Vector3F>(); using (BinaryDataReader reader = new BinaryDataReader(new MemoryStream(Data))) { reader.ByteOrder = ByteOrder.BigEndian; // Go through the array elements. for (int i = 0; i < Data.Length; i += (int)Stride) { reader.Position = i + attribute.Offset; switch (attribute.Format) { case FvtxVertexAttributeFormat.Three_32Bit_Float: typedData.Add(reader.ReadVector3F()); break; case FvtxVertexAttributeFormat.Three_10Bit_Signed: // Actually 32 bits, first 2 bits always 0b01. Packed like 01XXXXXXXXXXYYYYYYYYYYZZZZZZZZZZ. uint packedBytes = reader.ReadUInt32(); short x = (short)((packedBytes >> 20) & 0x3FF); short y = (short)((packedBytes >> 10) & 0x3FF); short z = (short)(packedBytes & 0x3FF); // Divide by 511 to get the float value. typedData.Add(new Vector3F(x / 511f, y / 511f, z / 511f)); break; default: throw new BfresException("Cannot retrieve attribute data as Vector3F: Mismatching format."); } } } return typedData.ToArray(); }
// ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="FmatMaterialParameter"/> class from the given /// <see cref="BfresLoaderContext"/>. The reader of the context has to be positioned at the start of the data. /// The provided <see cref="BinaryDataReader"/> reads over the material parameter data section in the correct /// endianness. /// </summary> /// <param name="context">The loader context providing information about how to load the data.</param> /// <param name="dataReader">The <see cref="BinaryDataReader"/> to read material parameter data with.</param> internal FmatMaterialParameter(BfresLoaderContext context, BinaryDataReader dataReader) { Load(context, dataReader); }
// ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="FshuSection"/> for the given <see cref="BfresFile"/>. /// The stream of the file has to be positioned at the beginning of the data. Since FSHU sections can /// originate from different index group in a BFRES files, the additional parameter specifies this group. /// </summary> /// <param name="reader">The <see cref="BinaryDataReader"/> providing the data.</param> /// <param name="group">The group from which the section originates from.</param> internal FshuSection(BinaryDataReader reader, int group) { }
private void LoadMaterialParameters(BfresLoaderContext context) { // Load the data before the parameters to extract their values. context.Reader.Position = Internal.MaterialParameterDataOffset.ToFile; Internal.MaterialParameterData = context.Reader.ReadBytes((int)Internal.MaterialParameterDataSize); // Load the array, and pass a reader on the parameter data array. context.Reader.Position = Internal.MaterialParameterOffset.ToFile; MaterialParameters = new List<FmatMaterialParameter>(Internal.MaterialParameterCount); using (BinaryDataReader parameterDataReader = new BinaryDataReader( new MemoryStream(Internal.MaterialParameterData))) { parameterDataReader.ByteOrder = ByteOrder.BigEndian; for (int i = 0; i < Internal.MaterialParameterCount; i++) { MaterialParameters.Add(new FmatMaterialParameter(context, parameterDataReader)); } } // Load the index group, just for internal use and because I feel nasty today. context.Reader.Position = Internal.MaterialParameterIndexGroupOffset.ToFile; Internal.MaterialParameterIndexGroup = new BfresIndexGroup(context); if (Internal.MaterialParameterIndexGroup.NodeCount != Internal.MaterialParameterCount) { context.Warnings.Add("FmatMaterial.MaterialParameterIndexGroup has node count unequal to header"); } }
/// <summary> /// Decompresses the Yaz0-compressed contents of the input <see cref="Stream"/> and writes them directly into /// the given output <see cref="MemoryStream"/>. Both streams stay open after this method returned the number of /// decompressed bytes written. /// </summary> /// <param name="input">The input <see cref="Stream"/> from which the Yaz0-compressed data will be read.</param> /// <param name="output">The output <see cref="MemoryStream"/> to which the decompressed data will be written /// directly.</param> /// <returns>The number of decompressed bytes written to the output stream.</returns> public static int Decompress(Stream input, MemoryStream output) { using (BinaryDataReader reader = new BinaryDataReader(input, true)) using (BinaryDataWriter writer = new BinaryDataWriter(output, true)) { reader.ByteOrder = ByteOrder.BigEndian; // Read and check the header. if (reader.ReadString(4) != "Yaz0") { throw new Yaz0Exception("Invalid Yaz0 header."); } uint decompressedSize = reader.ReadUInt32(); reader.Position += 8; // Padding // Decompress the data. int decompressedBytes = 0; while (decompressedBytes < decompressedSize) { // Read the configuration byte of a decompression setting group, and go through each bit of it. byte groupConfig = reader.ReadByte(); for (int i = 7; i >= 0; i--) { // Check if bit of the current chunk is set. if ((groupConfig & (1 << i)) == (1 << i)) { // Bit is set, copy 1 raw byte to the output. writer.Write(reader.ReadByte()); decompressedBytes++; } else if (decompressedBytes < decompressedSize) // This does not make sense for last byte. { // Bit is not set and data copying configuration follows, either 2 or 3 bytes long. ushort dataBackSeekOffset = reader.ReadUInt16(); int dataSize; // If the nibble of the first back seek offset byte is 0, the config is 3 bytes long. byte nibble = (byte)(dataBackSeekOffset >> 12/*1 byte (8 bits) + 1 nibble (4 bits)*/); if (nibble == 0) { // Nibble is 0, the number of bytes to read is in third byte, which is (size + 0x12). dataSize = reader.ReadByte() + 0x12; } else { // Nibble is not 0, and determines (size + 0x02) of bytes to read. dataSize = nibble + 0x02; // Remaining bits are the real back seek offset. dataBackSeekOffset &= 0x0FFF; } // Since bytes can be reread right after they were written, write and read bytes one by one. for (int j = 0; j < dataSize; j++) { // Read one byte from the current back seek position. writer.Position -= dataBackSeekOffset + 1; byte readByte = (byte)writer.BaseStream.ReadByte(); // Write the byte to the end of the memory stream. writer.Seek(0, SeekOrigin.End); writer.Write(readByte); decompressedBytes++; } } } } return decompressedBytes; } }
public PackedDataReadVisitor(Stream stream) { _stream = stream; _reader = new BinaryDataReader(stream); }
// ---- CONSTRUCTORS ------------------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="BfresLoaderContext"/> class for the given <see cref="BfresFile"/> /// instance using the given <see cref="BinaryDataReader"/>. /// </summary> /// <param name="bfresFile">The <see cref="BfresFile"/> instance to load the data in.</param> /// <param name="reader">The <see cref="BinaryDataReader"/> to use for reading the data.</param> internal BfresLoaderContext(BfresFile bfresFile, BinaryDataReader reader) { BfresFile = bfresFile; Reader = reader; Warnings = new List<string>(); }