private static string ParseClassId(BinaryReverseReader reader)
        {
            int length = reader.ReadInt32();

            if (length == 0)
            {
                length = 4;
            }

            return(Encoding.ASCII.GetString(reader.ReadBytes(length)).TrimEnd('\0'));
        }
        private static string ParseKey(BinaryReverseReader reader)
        {
            int length = reader.ReadInt32();

            if (length == 0)
            {
                length = 4;
            }

            byte[] bytes = reader.ReadBytes(length);

            return(Encoding.ASCII.GetString(bytes));
        }
Esempio n. 3
0
        private static ReadOnlyCollection <Brush> DecodeVersion6(BinaryReverseReader reader, short majorVersion)
        {
            short minorVersion = reader.ReadInt16();
            long  unusedDataLength;

            switch (minorVersion)
            {
            case 1:
                // Skip the Int16 bounds rectangle and the unknown Int16.
                unusedDataLength = 10L;
                break;

            case 2:
                // Skip the unknown bytes.
                unusedDataLength = 264L;
                break;

            default:
                throw new FormatException(string.Format(CultureInfo.CurrentCulture, Resources.UnsupportedABRSubVersion, majorVersion, minorVersion));
            }

            BrushSectionParser parser = new BrushSectionParser(reader);

            List <Brush> brushes = new List <Brush>(parser.SampledBrushes.Count);

            long sampleSectionOffset = parser.SampleSectionOffset;

            if (parser.SampledBrushes.Count > 0 && sampleSectionOffset >= 0)
            {
                reader.BaseStream.Position = sampleSectionOffset;

                uint sectionLength = reader.ReadUInt32();

                long sectionEnd = reader.BaseStream.Position + sectionLength;

                while (reader.BaseStream.Position < sectionEnd)
                {
                    uint brushLength = reader.ReadUInt32();

                    // The brush data is padded to 4 byte alignment.
                    long paddedBrushLength = ((long)brushLength + 3) & ~3;

                    long endOffset = reader.BaseStream.Position + paddedBrushLength;

                    string tag = reader.ReadPascalString();

                    // Skip the unneeded data that comes before the Int32 bounds rectangle.
                    reader.BaseStream.Position += unusedDataLength;

                    Rectangle bounds = reader.ReadInt32Rectangle();
                    if (bounds.Width <= 0 || bounds.Height <= 0)
                    {
                        // Skip any brushes that have invalid dimensions.
                        reader.BaseStream.Position += (endOffset - reader.BaseStream.Position);
                        continue;
                    }

                    short depth = reader.ReadInt16();
                    if (depth != 8 && depth != 16)
                    {
                        // Skip any brushes with an unknown bit depth.
                        reader.BaseStream.Position += (endOffset - reader.BaseStream.Position);
                        continue;
                    }

                    SampledBrush sampledBrush = parser.SampledBrushes.FindBrush(tag);
                    if (sampledBrush != null)
                    {
                        AbrImageCompression compression = (AbrImageCompression)reader.ReadByte();

                        int height = bounds.Height;
                        int width  = bounds.Width;

                        byte[] alphaData = null;

                        if (compression == AbrImageCompression.RLE)
                        {
                            short[] compressedRowLengths = new short[height];

                            for (int y = 0; y < height; y++)
                            {
                                compressedRowLengths[y] = reader.ReadInt16();
                            }

                            int alphaDataSize = width * height;
                            int bytesPerRow   = width;

                            if (depth == 16)
                            {
                                alphaDataSize *= 2;
                                bytesPerRow   *= 2;
                            }

                            alphaData = new byte[alphaDataSize];

                            for (int y = 0; y < height; y++)
                            {
                                RLEHelper.DecodedRow(reader, alphaData, y * width, bytesPerRow);
                            }
                        }
                        else
                        {
                            int alphaDataSize = width * height;

                            if (depth == 16)
                            {
                                alphaDataSize *= 2;
                            }

                            alphaData = reader.ReadBytes(alphaDataSize);
                        }

                        var brush = CreateSampledBrush(width, height, depth, alphaData, sampledBrush.Name, sampledBrush.Spacing);

                        brushes.Add(brush);

                        // Some brushes only store the largest item and scale it down.
                        var scaledBrushes = parser.SampledBrushes.Where(i => i.Tag.Equals(tag, StringComparison.Ordinal) && i.Diameter < sampledBrush.Diameter);
                        if (scaledBrushes.Any())
                        {
                            int originalWidth  = brush.Surface.Width;
                            int originalHeight = brush.Surface.Height;

                            foreach (var item in scaledBrushes.OrderByDescending(p => p.Diameter))
                            {
                                Size size = ComputeBrushSize(originalWidth, originalHeight, item.Diameter);

                                Brush scaledBrush = new Brush(size.Width, size.Height, item.Name, item.Spacing);
                                scaledBrush.Surface.FitSurface(ResamplingAlgorithm.SuperSampling, brush.Surface);

                                brushes.Add(scaledBrush);
                            }
                        }
                    }

                    long remaining = endOffset - reader.BaseStream.Position;
                    // Skip any remaining bytes until the next sampled brush.
                    if (remaining > 0)
                    {
                        reader.BaseStream.Position += remaining;
                    }
                }
            }

            return(brushes.AsReadOnly());
        }