Example #1
0
            public ShpD2Frame(Stream s)
            {
                var flags = (FormatFlags)s.ReadUInt16();

                s.Position += 1;
                var width  = s.ReadUInt16();
                var height = s.ReadUInt8();

                Size = new Size(width, height);

                // Subtract header size
                var dataLeft = s.ReadUInt16() - 10;
                var dataSize = s.ReadUInt16();

                byte[] table;
                if ((flags & FormatFlags.PaletteTable) != 0)
                {
                    var n = (flags & FormatFlags.VariableLengthTable) != 0 ? s.ReadUInt8() : (byte)16;
                    table = new byte[n];
                    for (var i = 0; i < n; i++)
                    {
                        table[i] = s.ReadUInt8();
                    }

                    dataLeft -= n;
                }
                else
                {
                    table = new byte[256];
                    for (var i = 0; i < 256; i++)
                    {
                        table[i] = (byte)i;
                    }
                    table[1] = 0x7f;
                    table[2] = 0x7e;
                    table[3] = 0x7d;
                    table[4] = 0x7c;
                }

                Data = new byte[width * height];

                // Decode image data
                var compressed = s.ReadBytes(dataLeft);

                if ((flags & FormatFlags.NotLCWCompressed) == 0)
                {
                    var temp = new byte[dataSize];
                    LCWCompression.DecodeInto(compressed, temp);
                    compressed = temp;
                }

                RLEZerosCompression.DecodeInto(compressed, Data, 0);

                // Lookup values in lookup table
                for (var j = 0; j < Data.Length; j++)
                {
                    Data[j] = table[Data[j]];
                }
            }
Example #2
0
            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;
                        RLEZerosCompression.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;
            }