public TmpTDReader(Stream s) { var width = s.ReadUInt16(); var height = s.ReadUInt16(); var size = new Size(width, height); s.Position += 8; var imgStart = s.ReadUInt32(); s.Position += 8; var indexEnd = s.ReadInt32(); var indexStart = s.ReadInt32(); s.Position = indexStart; var count = indexEnd - indexStart; var tiles = new TmpTile[count]; Frames = tiles.AsReadOnly(); var tilesIndex = 0; foreach (var b in s.ReadBytes(count)) { if (b != 255) { s.Position = imgStart + b * width * height; tiles[tilesIndex++] = new TmpTile(s.ReadBytes(width * height), size); } else tiles[tilesIndex++] = new TmpTile(null, size); } }
/// <summary> /// Read the bytes from the stream. /// </summary> /// <param name="stream">The current stream.</param> /// <param name="length">The number of bytes to read.</param> /// <param name="bufferLength">The buffer length.</param> /// <returns>The bytes read.</returns> public static byte[] ReadBytes(this System.IO.Stream stream, int length, int bufferLength) { using (MemoryStream res = new MemoryStream()) { var cnt = length / bufferLength; var rem = (int)(length % bufferLength); var buff = new byte[bufferLength]; var end = false; for (long i = 0; i < cnt; i++) { if (!stream.ReadBytes(buff, 0, bufferLength, res)) { end = true; break; } } if (!end && rem > 0) { stream.ReadBytes(new byte[rem], 0, rem, res); } res.Close(); return(res.ToArray()); } }
public TmpRAReader(Stream s) { var width = s.ReadUInt16(); var height = s.ReadUInt16(); var size = new Size(width, height); s.Position += 12; var imgStart = s.ReadUInt32(); s.Position += 8; var indexEnd = s.ReadInt32(); s.Position += 4; var indexStart = s.ReadInt32(); s.Position = indexStart; foreach (byte b in s.ReadBytes(indexEnd - indexStart)) { if (b != 255) { s.Position = imgStart + b * width * height; tiles.Add(new TmpTile(s.ReadBytes(width * height), size)); } else tiles.Add(new TmpTile(null, size)); } }
TmpRAFrame[] ParseFrames(Stream s) { var start = s.Position; var width = s.ReadUInt16(); var height = s.ReadUInt16(); var size = new Size(width, height); s.Position += 12; var imgStart = s.ReadUInt32(); s.Position += 8; var indexEnd = s.ReadInt32(); s.Position += 4; var indexStart = s.ReadInt32(); s.Position = indexStart; var count = indexEnd - indexStart; var tiles = new TmpRAFrame[count]; var tilesIndex = 0; foreach (var b in s.ReadBytes(count)) { if (b != 255) { s.Position = imgStart + b * width * height; tiles[tilesIndex++] = new TmpRAFrame(s.ReadBytes(width * height), size); } else tiles[tilesIndex++] = new TmpRAFrame(null, size); } s.Position = start; return tiles; }
/// <summary> /// ID3v2タグを読む /// </summary> /// <param name="strm"></param> /// <param name="createImageObject"></param> /// <returns></returns> public static ID3tag readID3tag(System.IO.Stream strm, bool createImageObject) { // ヘッダ読み込み byte[] id3_header = strm.ReadBytes(HEADER_LEN); Header header = readHeader(id3_header); if (header == null) { return(null); } if (header.Size >= strm.Length) { return(null); } ID3tag tag = new ID3tag(); tag.head = header; // 拡張ヘッダがあるときサイズだけ読んでスキップ if (tag.head.Flag.HasFlag(HEADER_FLAG.EXTENSION)) { byte[] ext_header = strm.ReadBytes(EXT_HEADER_LEN); var size = tag.head.Version == ID3V2_VER.ID3V23 ? ReadUInt32(ext_header, 0) : ReadUInt28(ext_header, 0) - EXT_HEADER_LEN; // v3とv4でEXT_HEADER_LENの扱いが違う strm.Seek(size, System.IO.SeekOrigin.Current); } // 全Frameのデータ領域を読み出す byte[] frame_buf = strm.ReadBytes(header.Size); // .2, .3の場合は非同期化の解除 if (header.Version != ID3V2_VER.ID3V24 && header.Flag.HasFlag(HEADER_FLAG.UNSYNC)) { decodeUnsync(ref frame_buf); } // 各Frameのデータ読み出し var tagBodyStream = new MemoryStream(frame_buf, 0, frame_buf.Length); while (true) { try { Frame fr = readFrame(tagBodyStream, tag, createImageObject); if (fr != null) { tag.frame.Add(fr); } } catch (EndOfTagException) { break; } } return(tag); }
public Terrain(Stream s) { // Try loading as a cnc .tem Width = s.ReadUInt16(); Height = s.ReadUInt16(); /*NumTiles = */s.ReadUInt16(); /*Zero1 = */s.ReadUInt16(); /*uint Size = */s.ReadUInt32(); var imgStart = s.ReadUInt32(); /*Zero2 = */s.ReadUInt32(); int indexEnd, indexStart; // ID1 = FFFFh for cnc if (s.ReadUInt16() == 65535) { /*ID2 = */s.ReadUInt16(); indexEnd = s.ReadInt32(); indexStart = s.ReadInt32(); } else { // Load as a ra .tem s.Position = 0; Width = s.ReadUInt16(); Height = s.ReadUInt16(); /*NumTiles = */s.ReadUInt16(); s.ReadUInt16(); /*XDim = */s.ReadUInt16(); /*YDim = */s.ReadUInt16(); /*uint FileSize = */s.ReadUInt32(); imgStart = s.ReadUInt32(); s.ReadUInt32(); s.ReadUInt32(); indexEnd = s.ReadInt32(); s.ReadUInt32(); indexStart = s.ReadInt32(); } s.Position = indexStart; foreach (byte b in s.ReadBytes(indexEnd - indexStart)) { if (b != 255) { s.Position = imgStart + b * Width * Height; TileBitmapBytes.Add(s.ReadBytes(Width * Height)); } else TileBitmapBytes.Add(null); } }
public ShpTSFrame(Stream s, Size frameSize) { var x = s.ReadUInt16(); var y = s.ReadUInt16(); var width = s.ReadUInt16(); var height = s.ReadUInt16(); // Pad the dimensions to an even number to avoid issues with half-integer offsets var dataWidth = width; var dataHeight = height; if (dataWidth % 2 == 1) dataWidth += 1; if (dataHeight % 2 == 1) dataHeight += 1; Offset = new int2(x + (dataWidth - frameSize.Width) / 2, y + (dataHeight - frameSize.Height) / 2); Size = new Size(dataWidth, dataHeight); FrameSize = frameSize; Format = s.ReadUInt8(); s.Position += 11; FileOffset = s.ReadUInt32(); if (FileOffset == 0) return; // Parse the frame data as we go (but remember to jump back to the header before returning!) var start = s.Position; s.Position = FileOffset; Data = new byte[dataWidth * dataHeight]; if (Format == 3) { // Format 3 provides RLE-zero compressed scanlines for (var j = 0; j < height; j++) { var length = s.ReadUInt16() - 2; Format2.DecodeInto(s.ReadBytes(length), Data, dataWidth * j); } } else { // Format 2 provides uncompressed length-prefixed scanlines // Formats 1 and 0 provide an uncompressed full-width row var length = Format == 2 ? s.ReadUInt16() - 2 : width; for (var j = 0; j < height; j++) s.ReadBytes(Data, dataWidth * j, length); } s.Position = start; }
public ShpTSReader(Stream stream) { stream.ReadUInt16(); var width = stream.ReadUInt16(); var height = stream.ReadUInt16(); var size = new Size(width, height); var frameCount = stream.ReadUInt16(); var frames = new FrameHeader[frameCount]; Frames = frames.AsReadOnly(); for (var i = 0; i < frames.Length; i++) frames[i] = new FrameHeader(stream, size); for (var i = 0; i < frameCount; i++) { var f = frames[i]; if (f.FileOffset == 0) continue; stream.Position = f.FileOffset; var frameSize = f.Size.Width * f.Size.Height; // Uncompressed if (f.Format == 1 || f.Format == 0) f.Data = stream.ReadBytes(frameSize); // Uncompressed scanlines else if (f.Format == 2) { f.Data = new byte[frameSize]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; var offset = f.Size.Width * j; stream.ReadBytes(f.Data, offset, length); } } // RLE-zero compressed scanlines else if (f.Format == 3) { f.Data = new byte[frameSize]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; var offset = f.Size.Width * j; Format2.DecodeInto(stream.ReadBytes(length), f.Data, offset); } } } }
public static PfsHeader ReadFromStream(System.IO.Stream s) { var start = s.Position; var hdr = new PfsHeader { Version = s.ReadInt64LE(), Magic = s.ReadInt64LE(), Id = s.ReadInt64LE(), Fmode = s.ReadUInt8(), Clean = s.ReadUInt8(), ReadOnly = s.ReadUInt8(), Rsv = s.ReadUInt8(), Mode = (PfsMode)s.ReadUInt16LE(), Unk1 = s.ReadUInt16LE(), BlockSize = s.ReadUInt32LE(), NBackup = s.ReadUInt32LE(), NBlock = s.ReadInt64LE(), DinodeCount = s.ReadInt64LE(), Ndblock = s.ReadInt64LE(), DinodeBlockCount = s.ReadInt64LE(), InodeBlockSig = DinodeS64.ReadFromStream(s) }; s.Position = start + 0x370; hdr.Seed = s.ReadBytes(16); return(hdr); }
public static PfsHeader ReadFromStream(System.IO.Stream s) { var start = s.Position; var hdr = new PfsHeader { Version = s.ReadInt64LE(), Magic = s.ReadInt64LE(), Id = s.ReadInt64LE(), Fmode = s.ReadUInt8(), Clean = s.ReadUInt8(), ReadOnly = s.ReadUInt8(), Rsv = s.ReadUInt8(), Mode = (PfsMode)s.ReadUInt16LE(), Unk1 = s.ReadUInt16LE(), BlockSize = s.ReadUInt32LE(), NBackup = s.ReadUInt32LE(), NBlock = s.ReadInt64LE(), DinodeCount = s.ReadInt64LE(), Ndblock = s.ReadInt64LE(), DinodeBlockCount = s.ReadInt64LE(), }; s.Position += 8; // skip a 64-bit zero hdr.InodeBlockSig = DinodeS64.ReadFromStream(s); if (hdr.Version != 1 || hdr.Magic != 20130315) { throw new InvalidDataException($"Invalid PFS superblock version ({hdr.Version}) or magic ({hdr.Magic})"); } s.Position = start + 0x370; hdr.Seed = s.ReadBytes(16); return(hdr); }
public R8Image(Stream s) { // Scan forward until we find some data var type = s.ReadUInt8(); while (type == 0) type = s.ReadUInt8(); var width = s.ReadInt32(); var height = s.ReadInt32(); var x = s.ReadInt32(); var y = s.ReadInt32(); Size = new Size(width, height); Offset = new int2(width / 2 - x, height / 2 - y); /*var imageOffset = */ s.ReadInt32(); var paletteOffset = s.ReadInt32(); var bpp = s.ReadUInt8(); if (bpp != 8) throw new InvalidDataException("Error: {0} bits per pixel are not supported.".F(bpp)); var frameHeight = s.ReadUInt8(); var frameWidth = s.ReadUInt8(); FrameSize = new Size(frameWidth, frameHeight); // Skip alignment byte s.ReadUInt8(); Data = s.ReadBytes(width * height); // Ignore palette if (type == 1 && paletteOffset != 0) s.Seek(520, SeekOrigin.Current); }
/// <summary> /// Read the bytes from the stream. /// </summary> /// <param name="stream">The current stream.</param> /// <param name="buffer">The buffer of bytes.</param> /// <param name="offset">The offset.</param> /// <param name="length">The number of bytes to read.</param> /// <param name="destination">The destination stream.</param> /// <returns>The bytes read.</returns> public static bool ReadBytes(this System.IO.Stream stream, byte[] buffer, int offset, int length, System.IO.Stream destination) { var bytes = stream.ReadBytes(buffer, offset, length); var len = bytes.Length; destination.Write(bytes, 0, len); return(len == offset + length); }
/// <summary> /// 値をバイト配列として読み取ります。 /// </summary> /// <param name="src">値を読み取るストリーム。</param> /// <returns>値となるバイト配列。</returns> public byte[] Read( Stream src ) { var position = src.Position; src.Seek( this.Position, SeekOrigin.Begin ); var value = src.ReadBytes( this.Length ); src.Seek( position, SeekOrigin.Begin ); return value; }
public object Deserialize(System.IO.Stream stream) { long count = ZigZag.DeserializeInt64(stream); if (count == 1) { return(null); } int c = (int)(count >> 1); return(stream.ReadBytes(c)); }
public object Deserialize(System.IO.Stream stream) { long count = ZigZag.DeserializeInt64(stream); if (count == 1) { return(null); } var c = (int)(count >> 1); var bytes = stream.ReadBytes(c); return(Encoding.UTF8.GetString(bytes)); }
/// <summary> /// Requests that the provided stream be authenticated /// </summary> /// <param name="stream"></param> /// <param name="additionalChallenge">Additional data to include in the challenge. If using SSL certificates, /// adding the thumbprint to the challenge will allow detecting man in the middle attacks.</param> /// <returns></returns> public ScramServerSession AuthenticateAsServer(Stream stream, byte[] additionalChallenge = null) { if (additionalChallenge == null) additionalChallenge = new byte[] { }; byte[] usernameBytes = stream.ReadBytes(); byte[] clientNonce = stream.ReadBytes(); ScramUserCredential user; if (!Users.TryLookup(usernameBytes, out user)) return null; byte[] serverNonce = m_nonce.Next(); stream.WriteByte((byte)user.HashMethod); stream.WriteWithLength(serverNonce); stream.WriteWithLength(user.Salt); stream.Write(user.Iterations); stream.Flush(); byte[] authMessage = Scram.ComputeAuthMessage(serverNonce, clientNonce, user.Salt, usernameBytes, user.Iterations, additionalChallenge); byte[] clientSignature = user.ComputeClientSignature(authMessage); byte[] serverSignature = user.ComputeServerSignature(authMessage); byte[] clientProof = stream.ReadBytes(); byte[] clientKeyVerify = Scram.XOR(clientProof, clientSignature); byte[] storedKeyVerify = user.ComputeStoredKey(clientKeyVerify); if (storedKeyVerify.SecureEquals(user.StoredKey)) { //Client holds the password //Send ServerSignature stream.WriteWithLength(serverSignature); stream.Flush(); return new ScramServerSession(user.UserName); } return null; }
public static Blck Read(Stream stream) { var result = new Blck(); var b = (byte)stream.ReadByte(); result.unknown = (b & 0x80) == 0x80; if (!result.unknown) throw new UnknownNodeFlagException(); result.nameLength = (short)(b & 0x7f); result.name = stream.ReadUtf8String(result.nameLength); result.length = stream.ReadInt32(); using (var memStream = new MemoryStream(stream.ReadBytes(result.length))) result.children = Aval.Read(memStream).ToList(); return result; }
/// <summary> /// Read from a stream asynchronously. /// </summary> /// <param name="stream">The stream.</param> /// <param name="length">The number of bytes to read.</param> /// <param name="completed">The completed action.</param> /// <param name="error">The error action.</param> public static void ReadAsync(this System.IO.Stream stream, int length, Action <byte[]> completed, Action <Exception> error) { var buff = new byte[length]; stream.BeginRead( buff, 0, length, ar => { try { byte[] bytes = null; try { var len = stream.EndRead(ar); bytes = len < 1 ? new byte[0] : len < length ? stream.ReadBytes(buff, len, length - len) : buff; } catch { bytes = new byte[0]; } if (completed != null) { completed(bytes); } } catch (Exception ex) { if (error != null) { error(ex); } } }, null); }
/// <summary> /// Requests that the provided stream be authenticated /// </summary> /// <param name="stream"></param> /// <param name="additionalChallenge">Additional data to include in the challenge. If using SSL certificates, /// adding the thumbprint to the challenge will allow detecting man in the middle attacks.</param> /// <returns></returns> public SrpServerSession AuthenticateAsServer(Stream stream, byte[] additionalChallenge = null) { if (additionalChallenge == null) additionalChallenge = new byte[] { }; // Header // C => S // int16 usernameLength (max 1024 characters) // byte[] usernameBytes int len = stream.ReadInt16(); if (len < 0 || len > 1024) return null; var usernameBytes = stream.ReadBytes(len); var username = UTF8.GetString(usernameBytes); var user = Users.Lookup(username); var session = new SrpServerSession(user); if (session.TryAuthenticate(stream, additionalChallenge)) { return session; } return null; }
/// <summary> /// Read from a stream. /// </summary> /// <param name="stream">The stream.</param> /// <param name="length">The number of bytes to read.</param> /// <param name="completed">The completed action.</param> /// <param name="error">The error action.</param> public static void Read(this System.IO.Stream stream, int length, Action <byte[]> completed, Action <Exception> error) { var buff = new byte[length]; try { byte[] bytes = null; try { // Read the data from the stream. int len = stream.Read(buff, 0, length); bytes = len < 1 ? new byte[0] : len < length ? stream.ReadBytes(buff, len, length - len) : buff; } catch { bytes = new byte[0]; } if (completed != null) { completed(bytes); } } catch (Exception ex) { if (error != null) { error(ex); } } }
internal void Load(Stream s) { Name = Encoding.ASCII.GetString(s.ReadBytes(8)).TrimEnd('\0'); VirtualSize = s.ReadUIntLE(); SectionRVA = s.ReadUIntLE(); SizeOfRawData = s.ReadUIntLE(); PointerToRawData = s.ReadUIntLE(); PointerToRelocations = s.ReadUIntLE(); PointerToLineNumbers = s.ReadUIntLE(); NumberOfRelocations = s.ReadUShortLE(); NumberOfLineNumbers = s.ReadUShortLE(); SectionFlags = (SectionFlags)s.ReadUIntLE(); }
private static ImageFrame ReadImageFrame(Stream stream, byte[] globalColorTable, GraphicControlExtension graphicControlExtension) { var imageDescriptor = ImageDescriptor.Read(stream); var imageFrame = new ImageFrame { ImageDescriptor = imageDescriptor, LocalColorTable = globalColorTable, GraphicControlExtension = graphicControlExtension }; if (imageDescriptor.LocalColorTableFlag) { imageFrame.LocalColorTable = stream.ReadBytes(imageDescriptor.LocalColorTableSize * 3); } imageFrame.ColorDepth = stream.ReadByte(); var lzwDecoder = new LzwDecoder(stream); var imageData = lzwDecoder.DecodeImageData(imageDescriptor.ImageWidth, imageDescriptor.ImageHeight, imageFrame.ColorDepth); ApplicationData.Read(stream); imageFrame.Bitmap = CreateBitmap( imageData, imageFrame.GetPalette(), imageDescriptor.InterlaceFlag, imageDescriptor.ImageWidth, imageDescriptor.ImageHeight); return imageFrame; }
public static Image Decode(Stream stream) { var result = new Image { Header = stream.ReadString(6), LogicalScreenDescriptor = LogicalScreenDescriptor.Read(stream) }; if (result.LogicalScreenDescriptor.GlobalColorTableFlag) { result.GlobalColorTable = stream.ReadBytes(result.LogicalScreenDescriptor.GlobalColorTableSize * 3); } GraphicControlExtension graphicControlExtension = null; var componentType = stream.ReadByte(); while (componentType != 0) { if (componentType == ImageDescriptor.ImageSeparator) { var imageFrame = ReadImageFrame(stream, result.GlobalColorTable, graphicControlExtension); result.Frames.Add(imageFrame); } else if (componentType == Const.ExtensionIntroducer) { var extensionType = stream.ReadByte(); switch (extensionType) { case GraphicControlExtension.GraphicControlLabel: { graphicControlExtension = GraphicControlExtension.Read(stream); break; } case CommentExtension.CommentLabel: { var commentExtension = CommentExtension.Read(stream); result.CommentExtensions.Add(commentExtension); break; } case ApplicationExtension.ExtensionLabel: { var applicationExtension = ApplicationExtension.Read(stream); result.ApplictionExtensions.Add(applicationExtension); break; } case PlainTextExtension.PlainTextLabel: { var plainTextExtension = PlainTextExtension.Read(stream); result.PlainTextEntensions.Add(plainTextExtension); break; } } } else if (componentType == Const.EndIntroducer) { break; } componentType = stream.ReadByte(); } return result; }
/// <summary> /// Reads all the remaining bytes after the current position of this stream. /// </summary> /// <param name="stream">The stream to read.</param> /// <returns>A byte array storing the read bytes.</returns> public static byte[] ReadAllBytes(this Stream stream) { return(stream.ReadBytes((Int32)(stream.Length - stream.Position))); }
public VxlReader(Stream s) { if (!s.ReadASCII(16).StartsWith("Voxel Animation")) throw new InvalidDataException("Invalid vxl header"); s.ReadUInt32(); LimbCount = s.ReadUInt32(); s.ReadUInt32(); BodySize = s.ReadUInt32(); s.Seek(770, SeekOrigin.Current); // Read Limb headers Limbs = new VxlLimb[LimbCount]; for (var i = 0; i < LimbCount; i++) { Limbs[i] = new VxlLimb(); Limbs[i].Name = s.ReadASCII(16); s.Seek(12, SeekOrigin.Current); } // Skip to the Limb footers s.Seek(802 + 28*LimbCount + BodySize, SeekOrigin.Begin); var LimbDataOffset = new uint[LimbCount]; for (var i = 0; i < LimbCount; i++) { LimbDataOffset[i] = s.ReadUInt32(); s.Seek(8, SeekOrigin.Current); Limbs[i].Scale = s.ReadFloat(); s.Seek(48, SeekOrigin.Current); Limbs[i].Bounds = new float[6]; for (var j = 0; j < 6; j++) Limbs[i].Bounds[j] = s.ReadFloat(); Limbs[i].Size = s.ReadBytes(3); Limbs[i].Type = (NormalType)s.ReadByte(); } for (var i = 0; i < LimbCount; i++) { s.Seek(802 + 28*LimbCount + LimbDataOffset[i], SeekOrigin.Begin); ReadVoxelData(s, Limbs[i]); } }
public static Single ReadSingle(this Stream stream) { return(BitConverter.ToSingle(stream.ReadBytes(sizeof(Single)), 0)); }
public bool AuthenticateAsClient(Stream stream, byte[] additionalChallenge = null) { if (additionalChallenge == null) additionalChallenge = new byte[] { }; byte[] clientNonce = m_nonce.Next(); stream.WriteWithLength(m_usernameBytes); stream.WriteWithLength(clientNonce); stream.Flush(); HashMethod hashMethod = (HashMethod)stream.ReadByte(); byte[] serverNonce = stream.ReadBytes(); byte[] salt = stream.ReadBytes(); int iterations = stream.ReadInt32(); SetServerValues(hashMethod, salt, iterations); byte[] authMessage = Scram.ComputeAuthMessage(serverNonce, clientNonce, salt, m_usernameBytes, iterations, additionalChallenge); byte[] clientSignature = ComputeClientSignature(authMessage); byte[] clientProof = Scram.XOR(m_clientKey, clientSignature); stream.WriteWithLength(clientProof); stream.Flush(); byte[] serverSignature = ComputeServerSignature(authMessage); byte[] serverSignatureVerify = stream.ReadBytes(); return (serverSignature.SecureEquals(serverSignatureVerify)); }
/// <summary> /// Read the bytes from the stream. /// </summary> /// <param name="stream">The current stream.</param> /// <param name="length">The number of bytes to read.</param> /// <returns>The bytes read.</returns> public static byte[] ReadBytes(this System.IO.Stream stream, int length) { return(stream.ReadBytes(new byte[length], 0, length)); }
public String(SectionHeader header, Stream stream) : base(header, stream) { Value = Encoding.UTF8.GetString(stream.ReadBytes((int) header.Size)).TrimNullChars(); }
public static UInt64 ReadUInt64(this Stream stream) { return(BitConverter.ToUInt64(stream.ReadBytes(sizeof(UInt64)), 0)); }
public static Double ReadDouble(this Stream stream) { return(BitConverter.ToDouble(stream.ReadBytes(sizeof(Double)), 0)); }
public void Read(System.IO.Stream r) { //Read the "Magic" (this is a series of bytes that is always the same on every RW4File) var b = r.ReadBytes(RW4_Magic.Length); for (int i = 0; i < b.Length; i++) { if (b[i] != RW4_Magic[i]) { throw new ModelFormatException(r, "Not a RW4 file", b); } } _fileTypeCode = r.ReadU32(); if (_fileTypeCode == 1) { file_type = RW4Model.FileTypes.Model; } else if (_fileTypeCode == 0x04000000) { file_type = RW4Model.FileTypes.Texture; } else { throw new ModelFormatException(r, "Unknown2 file type", _fileTypeCode); } uint _fileTypeConstant = (file_type == RW4Model.FileTypes.Model ? 16U : 4U); uint _sectionCount = r.ReadU32(); r.expect(_sectionCount, "H001 Section count not repeated"); r.expect(_fileTypeConstant, "H002"); r.expect(0, "H003"); SectionIndexBegin = r.ReadU32(); uint _firstHeaderSectionBegin = r.ReadU32(); // Always 0x98? r.expect(new UInt32[] { 0, 0, 0 }, "H010"); uint _sectionIndexEnd = r.ReadU32(); r.expect(_fileTypeConstant, "H011"); //this.unknown_size_or_offset_013 = r.ReadU32(); uint _fileSize = r.ReadU32() + _sectionIndexEnd; // if (r.Length != _fileSize) throw new ModelFormatException(r, "H012", _fileSize); //< TODO r.expect(new UInt32[] { 4, 0, 1, 0, 1 }, "H020"); this.Unknown = r.ReadU32(); r.expect(new UInt32[] { 4, 0, 1, 0, 1 }, "H040"); r.expect(new UInt32[] { 0, 1, 0, 0, 0, 0, 0 }, "H041"); if (r.Position != _firstHeaderSectionBegin) { throw new ModelFormatException(r, "H099", r.Position); } r.Seek(_firstHeaderSectionBegin, SeekOrigin.Begin); r.expect(0x10004, "H140"); // Offsets of header sections relative to the 0x10004. 4, 12, 28, 28 + (12+4*section_type_count), ... + 36, ... + 28 uint[] _offsets = new uint[6]; for (int i = 0; i < _offsets.Length; i++) { _offsets[i] = r.ReadU32() + _firstHeaderSectionBegin; } // A list of section types in the file? If so, redundant with section index if (_offsets[2] != r.Position) { throw new ModelFormatException(r, "H145", r.Position); } r.expect(0x10005, "H150"); uint _sectionTypeCount = r.ReadU32(); r.expect(12, "H151"); //read the list if section types, contains the 'indirect' section codes uint[] _sectionTypes = new uint[_sectionTypeCount]; for (int i = 0; i < _sectionTypeCount; i++) { _sectionTypes[i] = r.ReadU32(); } if (_offsets[3] != r.Position) { throw new ModelFormatException(r, "H146", r.Position); } r.expect(0x10006, "H160"); // TODO: I think this is actually a variable length structure, with 12 byte header and 3 being the length in qwords r.expect(new UInt32[] { 3, 0x18, _fileTypeCode, 0xffb00000, _fileTypeCode, 0, 0, 0 }, "H161"); if (_offsets[4] != r.Position) { throw new ModelFormatException(r, "H147", r.Position); } r.expect(0x10007, "H170"); uint _fixupCount = r.ReadU32(); r.expect(0, "H171"); r.expect(0, "H172"); // Fixup index always immediately follows section index r.expect(SectionIndexBegin + _sectionCount * 24 + _fixupCount * 8, "H173"); r.expect(SectionIndexBegin + _sectionCount * 24, "H174"); r.expect(_fixupCount, "H176"); if (_offsets[5] != r.Position) { throw new ModelFormatException(r, "H148", r.Position); } r.expect(0x10008, "H180"); r.expect(new UInt32[] { 0, 0 }, "H181"); HeaderEnd = (uint)r.Position; r.Seek(SectionIndexBegin, SeekOrigin.Begin); this.Sections = new List <RW4Section>(); for (int i = 0; i < _sectionCount; i++) { RW4Section _newSection = new RW4Section(); _newSection.LoadHeader(r, (uint)i, _sectionIndexEnd); this.Sections.Add(_newSection); } for (int i = 0; i < _fixupCount; i++) { uint sind = r.ReadU32(); var offset = r.ReadU32(); this.Sections[(int)sind].fixup_offsets.Add(offset); } SectionIndexPadding = _sectionIndexEnd - (uint)r.Position; r.ReadPadding(SectionIndexPadding); //process the indirect section codes bool[] used = new bool[_sectionTypes.Length]; foreach (var s in Sections) { used[s.type_code_indirect] = true; if (_sectionTypes[s.type_code_indirect] != s.type_code) { throw new ModelFormatException(r, "H300", s.type_code_indirect); } } for (int i = 0; i < fixed_section_types.Length; i++) { if (_sectionTypes[i] != fixed_section_types[i]) { throw new ModelFormatException(r, "H301", i); } } for (int i = fixed_section_types.Length; i < _sectionTypes.Length; i++) { if (!used[i]) { throw new ModelFormatException(r, "H302", _sectionTypes[i]); } } }
public static Int16 ReadInt16(this Stream stream) { return(BitConverter.ToInt16(stream.ReadBytes(sizeof(Int16)), 0)); }