internal EntryInfo(RawEntryInfo raw) { this.NameHash = raw.NameHash; this.Offset = raw.Offset; this.CompressedSize = raw.CompressedSize; this.UncompressedSize = raw.UncompressedSize; this.CompressedBlockIndex = raw.CompressedBlockIndex; this.CompressionType = raw.CompressionType; this.CompressionFlags = raw.CompressionFlags; }
public EntryInfo( uint nameHash, uint offset, uint compressedSize, uint uncompressedSize, ushort compressedBlockIndex, CompressionType compressionType, CompressionFlags compressionFlags) { this.NameHash = nameHash; this.Offset = offset; this.CompressedSize = compressedSize; this.UncompressedSize = uncompressedSize; this.CompressedBlockIndex = compressedBlockIndex; this.CompressionType = compressionType; this.CompressionFlags = compressionFlags; }
/// <summary> /// Reads the bitmap data for the frame from a buffer and decompresses it. /// </summary> /// <param name="frame">The frame to read.</param> /// <param name="buffer">The buffer to read the frame from.</param> /// <param name="dataOffset">The index where the frame data for the file begins.</param> /// <param name="flags">The details of the compression.</param> /// <returns>The decompressed pixel data.</returns> private byte[] ReadFrameData(Frame frame, byte[] buffer, int dataOffset, CompressionFlags flags) { byte[] croppedData, data; int croppedSize; int height, width; int lineLength; bool compressed; byte[] decodedLine; int stride = CalculateStride(_width); height = Math.Abs(frame.Height); width = Math.Abs(frame.Width); croppedSize = frame.Width * frame.Height; croppedData = new byte[croppedSize]; compressed = (CompressionFlags.None & flags) != CompressionFlags.None; if (compressed) { // Decode the data for (int line = 0; line < frame.Height; line++) { lineLength = buffer[dataOffset + line]; decodedLine = DecodeLine(buffer, dataOffset + height, lineLength, width); Array.Copy(decodedLine, 0, croppedData, line * width, width); } data = UnCrop(frame, croppedData); } else { data = new byte[(_width * stride) * _height]; Array.Copy(buffer, dataOffset, data, 0, data.Length); } return(data); }
void IDefinition.FromArray(byte[] buffer) { BinaryReader bin = new BinaryReader(new MemoryStream(buffer)); VertexType = (VertexDefinition)bin.ReadInt32(); VertexCount = bin.ReadUInt16(); TriangleCount = bin.ReadUInt16(); bin.BaseStream.Seek(16, SeekOrigin.Current); Compression = (CompressionFlags)bin.ReadUInt16(); bin.BaseStream.Seek(28, SeekOrigin.Current); RawOffset = bin.ReadUInt32(); RawSize = bin.ReadUInt32(); HeaderSize = bin.ReadUInt32(); RawDataSize = bin.ReadUInt32(); }
/// <summary> /// Parses a CFS file. /// </summary> private void Parse(byte[] buffer) { int offset = 0; _totalSize = buffer.Length; _version = (int)BitConverter.ToInt16(buffer, offset); offset += 2; if (_version == 4) { _frameCount = (int)BitConverter.ToInt16(buffer, offset); offset += 2; if (_frameCount <= 0) { throw new Exception("There is an invalid number of frames: " + _frameCount); } _animationTime = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _width = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _height = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _rows = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _columns = (int)BitConverter.ToInt16(buffer, offset); offset += 2; // TODO: docs say shadows then lights; verify _lightLength = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _shadowLength = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _userDataLength = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _compression = (CompressionFlags)buffer[offset]; offset++; _maxSolidIndex = (int)buffer[offset]; offset++; _dataSize = (int)BitConverter.ToInt32(buffer, offset); offset += 4; _category = ASCIIEncoding.ASCII.GetString(buffer, offset, 16); offset += 16; _blitMode = (BlitMode)buffer[offset]; offset++; _rowMode = (RowMode)buffer[offset]; offset++; _sortAdjust = (int)BitConverter.ToInt16(buffer, offset); offset += 2; _sortTransform = (SortTransform)buffer[offset]; offset++; _userPaletteStart = (int)buffer[offset]; offset++; _userPaletteLength = (int)buffer[offset]; offset++; _description = ASCIIEncoding.ASCII.GetString(buffer, offset, 48); offset += 48; _unknownData = new byte[32]; Buffer.BlockCopy(buffer, offset, _unknownData, 0, _unknownData.Length); offset += _unknownData.Length; _palette = new int[256]; for (int i = 0; i < _palette.Length; i++) { int argb; argb = BitConverter.ToInt32(buffer, offset); offset += 4; argb |= unchecked ((int)0xFF000000); _palette[i] = argb; } _frames = new Frame[_frameCount]; // Read all the frame meta info for (int i = 0; i < _frameCount; i++) { _frames[i] = ReadFrameInfo(buffer, offset); offset += 12; } // Read the user data if (_userDataLength > 0) { _userData = new byte[_userDataLength]; Array.Copy(buffer, offset, _userData, 0, _userDataLength); offset += _userDataLength; } else { _userData = new byte[] { }; } // Read the frames for (int i = 0; i < _frameCount; i++) { //_frames[i].Data = ReadFrameData(_frames[i], buffer, offset, _compression); } } else { throw new Exception("Unknown file version: " + _version); } }
public bool IsCompressed() { return(CompressionFlags.HasFlag(FileFlags.IsCompressed)); }
public void Deserialize(Stream input, string fileName) { var version = input.ReadValueU16(); if (version < 2 || version > 5) { throw new FormatException(String.Format("unsupported cfs version in {0}", fileName)); } var header = new Header(); if (version >= 5) { header = input.ReadStructure <Header>(); } else if (version >= 4) { var oldHeader = input.ReadStructure <OldHeader4>(); header.FrameCount = oldHeader.FrameCount; header.AnimationTime = oldHeader.AnimationTime; header.Width = oldHeader.Width; header.Height = oldHeader.Height; header.RowCount = oldHeader.RowCount; header.ColumnCount = oldHeader.ColumnCount; header.ShadowCount = oldHeader.ShadowCount; header.LightCount = oldHeader.LightCount; header.UserDataSize = oldHeader.UserDataSize; header.CompressionFlags = (CompressionFlags)oldHeader.CompressionFlags; header.MaxSolidIndex = oldHeader.MaxSolidIndex; header.DataSize = oldHeader.DataSize; header.Category = oldHeader.Category; header.BlitMode = oldHeader.BlitMode; header.RowMeaning = oldHeader.RowMeaning; header.YSortAdjust = oldHeader.YSortAdjust; header.SortTransform = oldHeader.SortTransform; header.UserPaletteStart = oldHeader.UserPaletteStart; header.UserPalette = oldHeader.UserPalette; header.Description = oldHeader.Description; } else if (version >= 3) { var oldHeader = input.ReadStructure <OldHeader3>(); header.FrameCount = oldHeader.FrameCount; header.AnimationTime = oldHeader.AnimationTime; header.Width = oldHeader.Width; header.Height = oldHeader.Height; header.RowCount = oldHeader.RowCount; header.ColumnCount = oldHeader.ColumnCount; header.ShadowCount = oldHeader.ShadowCount; header.LightCount = oldHeader.LightCount; header.UserDataSize = oldHeader.UserDataSize; header.CompressionFlags = (CompressionFlags)oldHeader.CompressionFlags; header.MaxSolidIndex = oldHeader.MaxSolidIndex; header.DataSize = oldHeader.DataSize; header.Category = oldHeader.Category; header.BlitMode = oldHeader.BlitMode; header.RowMeaning = oldHeader.RowMeaning; header.YSortAdjust = oldHeader.YSortAdjust; header.SortTransform = oldHeader.SortTransform; header.UserPaletteStart = oldHeader.UserPaletteStart; header.UserPalette = oldHeader.UserPalette; } else if (version >= 1) { var oldHeader = input.ReadStructure <OldHeader2>(); header.FrameCount = oldHeader.FrameCount; header.AnimationTime = oldHeader.AnimationTime; header.Width = oldHeader.Width; header.Height = oldHeader.Height; header.RowCount = oldHeader.RowCount; header.ColumnCount = oldHeader.ColumnCount; header.ShadowCount = oldHeader.ShadowCount; header.LightCount = oldHeader.LightCount; header.UserDataSize = oldHeader.UserDataSize; header.CompressionFlags = (CompressionFlags)oldHeader.CompressionFlags; header.MaxSolidIndex = oldHeader.MaxSolidIndex; header.DataSize = oldHeader.DataSize; } if (header.LightCount != 0 && header.LightCount != 32) { throw new FormatException(); } else if (header.ShadowCount != 0 && header.ShadowCount != 8) { throw new FormatException(); } this.AnimationTime = header.AnimationTime; this.Width = header.Width; this.Height = header.Height; this.RowCount = header.RowCount; this.ColumnCount = header.ColumnCount; this.ShadowCount = header.ShadowCount; this.LightCount = header.LightCount; this.MaxSolidIndex = header.MaxSolidIndex; this.CompressionFlags = header.CompressionFlags; for (int i = 0; i < this.Palette.Length; i++) { this.Palette[i] = input.ReadValueU32(); } this.UserData = new byte[header.UserDataSize]; if (input.Read(this.UserData, 0, this.UserData.Length) != this.UserData.Length) { throw new FormatException(); } var infos = new FrameInfo[header.FrameCount]; for (int i = 0; i < infos.Length; i++) { infos[i] = input.ReadStructure <FrameInfo>(); } uint compressionFlags = (uint)header.CompressionFlags; if ((compressionFlags & ~0x1FFu) != 0) { throw new FormatException(String.Format("unknown compression flags in {0}", fileName)); } else if (header.Unknown20 != 0 && header.Unknown20 != 3) { // WHAT DOES THIS VALUE MEAN AUGH throw new NotSupportedException(); } if ((header.CompressionFlags & CompressionFlags.NoCompression) != 0) { if ((header.CompressionFlags & ~(CompressionFlags.NoPixels | CompressionFlags.NoCompression)) != 0) { throw new FormatException(String.Format("other compression flags set with NoCompression flag in {0}", fileName)); } } using (var data = input.ReadToMemoryStream(header.DataSize)) { this.Frames = new Frame[header.FrameCount]; for (int i = 0; i < header.FrameCount; i++) { var info = infos[i]; data.Seek(info.Offset, SeekOrigin.Begin); var frame = this.Frames[i] = new Frame(); frame.X = info.X; frame.Y = info.Y; frame.Width = Math.Abs(info.Width); frame.Height = Math.Abs(info.Height); frame.Pixels = new byte[frame.Width * frame.Height]; if ((header.CompressionFlags & CompressionFlags.NoCompression) != 0) { // uncompressed data data.Read(frame.Pixels, 0, frame.Pixels.Length); } else { // compressed data var lengths = new int[frame.Height]; var max = 0; for (int y = 0; y < frame.Height; y++) { int length = data.ReadValueU8(); if (length == 0xFF) { length = data.ReadValueU16(); } lengths[y] = length; max = Math.Max(max, length); } var scanline = new byte[max]; for (int y = 0, offset = 0; y < frame.Height; y++, offset = y * frame.Width) { var length = lengths[y]; if (data.Read(scanline, 0, length) != length) { throw new FormatException(); } for (int x = 0; x < length;) { offset += (scanline[x] >> 4) & 0xF; // transparent var literalCount = scanline[x] & 0xF; if (literalCount > 0) { Array.Copy(scanline, x + 1, frame.Pixels, offset, literalCount); } offset += literalCount; x += 1 + literalCount; } } } // flip horizontal if (info.Width < 0) { for (int y = 0, offset = 0; y < frame.Height; y++, offset += frame.Width) { Array.Reverse(frame.Pixels, offset, frame.Width); } } // flip vertical if (info.Height < 0) { var scanline = new byte[frame.Height]; for (int x = 0; x < frame.Width; x++) { for (int y = 0, offset = x; y < frame.Height; y++, offset += frame.Width) { scanline[y] = frame.Pixels[offset]; } for (int y = 0, offset = x; y < frame.Height; y++, offset += frame.Width) { frame.Pixels[offset] = scanline[frame.Height - 1 - y]; } } } } } }