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;
 }
示例#3
0
        /// <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();
 }
示例#5
0
        /// <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));
 }
示例#7
0
        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];
                            }
                        }
                    }
                }
            }
        }