Пример #1
0
        /// <summary>
        /// Decompresses the specified data.
        /// </summary>
        /// <param name="data">The compressed byte array.</param>
        /// <param name="pos">The starting position into the byte array.</param>
        /// <param name="Length">The number of compressed bytes to decompress.</param>
        /// <returns>An uncompressed byte array</returns>
        public static byte[] Decompress(byte[] data, int pos, int Length)
        {
            byte[] compressedData = new byte[Length];
            Array.Copy(data, pos + 50, compressedData, 0, Length);
            using (MemoryStream ms = new MemoryStream(compressedData))
            {
                Inflater inflater = new Inflater(false);

                using (InflaterInputStream zIn = new InflaterInputStream(ms, inflater))
                {
                    using (MemoryStream out1 = new MemoryStream())
                    {
                        int c;
                        try
                        {
                            while ((c = zIn.ReadByte()) != -1)
                            {
                                out1.WriteByte((byte)c);
                            }
                            return(out1.ToArray());
                        }
                        catch (IOException e)
                        {
                            throw new RecordFormatException(e.ToString());
                        }
                    }
                }
            }
        }
Пример #2
0
        public virtual void ZipDecompress(Stream compressed, Stream decompressed)
        {
            compressed.Seek(0, SeekOrigin.Begin);

            InflaterInputStream zipStream =
                new InflaterInputStream(compressed);

            zipStream.IsStreamOwner = false;
            int b = zipStream.ReadByte();

            while (b != -1)
            {
                decompressed.WriteByte((byte)b);
                b = zipStream.ReadByte();
            }

            decompressed.Flush();
            zipStream.Close();
        }
Пример #3
0
        public zTXtChunk(byte[] data, PNGImage image)
            : base(data, image)
        {
            int i = 0;

            while (data[i + 4] != 0)
            {
                i++;
            }

            this.Keyword           = ASCIIEncoding.ASCII.GetString(data, 4, i);
            this.CompressionMethod = (CompressionMethod)data[i + 5];

            ByteStreamReader bs = new ByteStreamReader(data);

            bs.Seek(i + 6, SeekOrigin.Begin);

            InflaterInputStream iis = new InflaterInputStream(bs, new Inflater(), data.Length - 4 - i - 2);
            StringBuilder       sb  = new StringBuilder();

            while (iis.Available == 1)
            {
                int b = iis.ReadByte();

                if (b == -1)
                {
                    break;
                }

                sb.Append(System.Text.ASCIIEncoding.ASCII.GetChars(new byte[] { (byte)b })[0]);
            }

            this.Text = sb.ToString();

            iis.Close();
            bs.Close();
        }
Пример #4
0
        public Png(Stream s)
        {
            if (!Verify(s))
            {
                throw new InvalidDataException("PNG Signature is bogus");
            }

            s.Position += 8;
            var headerParsed = false;
            var isPaletted   = false;
            var is24Bit      = false;
            var data         = new List <byte>();

            for (;;)
            {
                var length  = IPAddress.NetworkToHostOrder(s.ReadInt32());
                var type    = Encoding.UTF8.GetString(s.ReadBytes(4));
                var content = s.ReadBytes(length);
                /*var crc = */ s.ReadInt32();

                if (!headerParsed && type != "IHDR")
                {
                    throw new InvalidDataException("Invalid PNG file - header does not appear first.");
                }

                using (var ms = new MemoryStream(content))
                {
                    switch (type)
                    {
                    case "IHDR":
                    {
                        if (headerParsed)
                        {
                            throw new InvalidDataException("Invalid PNG file - duplicate header.");
                        }
                        Width  = IPAddress.NetworkToHostOrder(ms.ReadInt32());
                        Height = IPAddress.NetworkToHostOrder(ms.ReadInt32());

                        var bitDepth  = ms.ReadUInt8();
                        var colorType = (PngColorType)ms.ReadByte();
                        isPaletted = IsPaletted(bitDepth, colorType);
                        is24Bit    = colorType == PngColorType.Color;

                        var dataLength = Width * Height;
                        if (!isPaletted)
                        {
                            dataLength *= 4;
                        }

                        Data = new byte[dataLength];

                        var compression = ms.ReadByte();
                        /*var filter = */ ms.ReadByte();
                        var interlace = ms.ReadByte();

                        if (compression != 0)
                        {
                            throw new InvalidDataException("Compression method not supported");
                        }

                        if (interlace != 0)
                        {
                            throw new InvalidDataException("Interlacing not supported");
                        }

                        headerParsed = true;

                        break;
                    }

                    case "PLTE":
                    {
                        Palette = new Color[256];
                        for (var i = 0; i < length / 3; i++)
                        {
                            var r = ms.ReadByte(); var g = ms.ReadByte(); var b = ms.ReadByte();
                            Palette[i] = Color.FromArgb(r, g, b);
                        }

                        break;
                    }

                    case "tRNS":
                    {
                        if (Palette == null)
                        {
                            throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
                        }

                        for (var i = 0; i < length; i++)
                        {
                            Palette[i] = Color.FromArgb(ms.ReadByte(), Palette[i]);
                        }

                        break;
                    }

                    case "IDAT":
                    {
                        data.AddRange(content);

                        break;
                    }

                    case "tEXt":
                    {
                        var key = ms.ReadASCIIZ();
                        EmbeddedData.Add(key, ms.ReadASCII(length - key.Length - 1));

                        break;
                    }

                    case "IEND":
                    {
                        using (var ns = new MemoryStream(data.ToArray()))
                        {
                            using (var ds = new InflaterInputStream(ns))
                            {
                                var pxStride   = isPaletted ? 1 : is24Bit ? 3 : 4;
                                var srcStride  = Width * pxStride;
                                var destStride = Width * (isPaletted ? 1 : 4);

                                var prevLine = new byte[srcStride];
                                for (var y = 0; y < Height; y++)
                                {
                                    var filter = (PngFilter)ds.ReadByte();
                                    var line   = ds.ReadBytes(srcStride);

                                    for (var i = 0; i < srcStride; i++)
                                    {
                                        line[i] = i < pxStride
                                                                                                ? UnapplyFilter(filter, line[i], 0, prevLine[i], 0)
                                                                                                : UnapplyFilter(filter, line[i], line[i - pxStride], prevLine[i], prevLine[i - pxStride]);
                                    }

                                    if (is24Bit)
                                    {
                                        // Fold alpha channel into RGB data
                                        for (var i = 0; i < line.Length / 3; i++)
                                        {
                                            Array.Copy(line, 3 * i, Data, y * destStride + 4 * i, 3);
                                            Data[y * destStride + 4 * i + 3] = 255;
                                        }
                                    }
                                    else
                                    {
                                        Array.Copy(line, 0, Data, y * destStride, line.Length);
                                    }

                                    prevLine = line;
                                }
                            }
                        }

                        if (isPaletted && Palette == null)
                        {
                            throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
                        }

                        return;
                    }
                    }
                }
            }
        }
Пример #5
0
 public override int ReadByte()
 {
     return(ist.ReadByte());
 }
Пример #6
0
        public Png(Stream s)
        {
            if (!Verify(s))
            {
                throw new InvalidDataException("PNG Signature is bogus");
            }

            s.Position += 8;
            var headerParsed = false;
            var data         = new List <byte>();

            Type = SpriteFrameType.Rgba32;

            while (true)
            {
                var length  = IPAddress.NetworkToHostOrder(s.ReadInt32());
                var type    = Encoding.UTF8.GetString(s.ReadBytes(4));
                var content = s.ReadBytes(length);
                /*var crc = */
                s.ReadInt32();

                if (!headerParsed && type != "IHDR")
                {
                    throw new InvalidDataException("Invalid PNG file - header does not appear first.");
                }

                using (var ms = new MemoryStream(content))
                {
                    switch (type)
                    {
                    case "IHDR":
                    {
                        if (headerParsed)
                        {
                            throw new InvalidDataException("Invalid PNG file - duplicate header.");
                        }
                        Width  = IPAddress.NetworkToHostOrder(ms.ReadInt32());
                        Height = IPAddress.NetworkToHostOrder(ms.ReadInt32());

                        var bitDepth  = ms.ReadUInt8();
                        var colorType = (PngColorType)ms.ReadByte();
                        if (IsPaletted(bitDepth, colorType))
                        {
                            Type = SpriteFrameType.Indexed8;
                        }
                        else if (colorType == PngColorType.Color)
                        {
                            Type = SpriteFrameType.Rgb24;
                        }

                        Data = new byte[Width * Height * PixelStride];

                        var compression = ms.ReadByte();
                        /*var filter = */
                        ms.ReadByte();
                        var interlace = ms.ReadByte();

                        if (compression != 0)
                        {
                            throw new InvalidDataException("Compression method not supported");
                        }

                        if (interlace != 0)
                        {
                            throw new InvalidDataException("Interlacing not supported");
                        }

                        headerParsed = true;

                        break;
                    }

                    case "PLTE":
                    {
                        Palette = new Color[256];
                        for (var i = 0; i < length / 3; i++)
                        {
                            var r = ms.ReadByte(); var g = ms.ReadByte(); var b = ms.ReadByte();
                            Palette[i] = Color.FromArgb(r, g, b);
                        }

                        break;
                    }

                    case "tRNS":
                    {
                        if (Palette == null)
                        {
                            throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
                        }

                        for (var i = 0; i < length; i++)
                        {
                            Palette[i] = Color.FromArgb(ms.ReadByte(), Palette[i]);
                        }

                        break;
                    }

                    case "IDAT":
                    {
                        data.AddRange(content);

                        break;
                    }

                    case "tEXt":
                    {
                        var key = ms.ReadASCIIZ();
                        EmbeddedData.Add(key, ms.ReadASCII(length - key.Length - 1));

                        break;
                    }

                    case "IEND":
                    {
                        using (var ns = new MemoryStream(data.ToArray()))
                        {
                            using (var ds = new InflaterInputStream(ns))
                            {
                                var pxStride  = PixelStride;
                                var rowStride = Width * pxStride;

                                var prevLine = new byte[rowStride];
                                for (var y = 0; y < Height; y++)
                                {
                                    var filter = (PngFilter)ds.ReadByte();
                                    var line   = ds.ReadBytes(rowStride);

                                    for (var i = 0; i < rowStride; i++)
                                    {
                                        line[i] = i < pxStride
                                                                                                        ? UnapplyFilter(filter, line[i], 0, prevLine[i], 0)
                                                                                                        : UnapplyFilter(filter, line[i], line[i - pxStride], prevLine[i], prevLine[i - pxStride]);
                                    }

                                    Array.Copy(line, 0, Data, y * rowStride, rowStride);

                                    prevLine = line;
                                }
                            }
                        }

                        if (Type == SpriteFrameType.Indexed8 && Palette == null)
                        {
                            throw new InvalidDataException("Non-Palette indexed PNG are not supported.");
                        }

                        return;
                    }
                    }
                }
            }
        }
Пример #7
0
        private void ReadScanlines(MemoryStream dataStream, byte[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation)
        {
            dataStream.Position = 0;

            int scanlineLength = CalculateScanlineLength(colorTypeInformation);

            int scanlineStep = CalculateScanlineStep(colorTypeInformation);

            byte[] lastScanline = new byte[scanlineLength];
            byte[] currScanline = new byte[scanlineLength];

            byte a = 0;
            byte b = 0;
            byte c = 0;

            int row = 0, filter = 0, column = -1;

            using (InflaterInputStream compressedStream = new InflaterInputStream(dataStream))
            {
                int readByte = 0;
                while ((readByte = compressedStream.ReadByte()) >= 0)
                {
                    if (column == -1)
                    {
                        filter = readByte;

                        column++;
                    }
                    else
                    {
                        currScanline[column] = (byte)readByte;

                        if (column >= scanlineStep)
                        {
                            a = currScanline[column - scanlineStep];
                            c = lastScanline[column - scanlineStep];
                        }
                        else
                        {
                            a = 0;
                            c = 0;
                        }

                        b = lastScanline[column];

                        if (filter == 1)
                        {
                            currScanline[column] = (byte)(currScanline[column] + a);
                        }
                        else if (filter == 2)
                        {
                            currScanline[column] = (byte)(currScanline[column] + b);
                        }
                        else if (filter == 3)
                        {
                            currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((a + b) / 2d));
                        }
                        else if (filter == 4)
                        {
                            currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c));
                        }

                        column++;

                        if (column == scanlineLength)
                        {
                            colorReader.ReadScanline(currScanline, pixels, _header);

                            column = -1;
                            row++;

                            Extensions.Swap(ref currScanline, ref lastScanline);
                        }
                    }
                }
            }
        }
Пример #8
0
        public static void ExtractTmod(string file, string folder, bool createOverrideFolders, bool createYaml, Action <double> updateProgress)
        {
            var   buffer         = new byte[1048576];
            var   properties     = new Dictionary <string, string>();
            var   archiveEntries = new List <ArchiveIndexEntry>();
            ulong headerSize     = 0;

            using (var stream = File.OpenRead(file))
            {
                using (var reader = new MyBinaryReader(stream))
                {
                    headerSize = ReadProperties(properties, stream, reader);

                    // Read archive index entries (remainder of header)
                    while ((ulong)stream.Position < headerSize)
                    {
                        var entry = new ArchiveIndexEntry();
                        entry.file         = reader.ReadString();
                        entry.archiveIndex = reader.Read7BitEncodedInt();
                        entry.byteOffset   = reader.Read7BitEncodedInt();
                        entry.size         = reader.Read7BitEncodedInt();
                        entry.hash         = reader.Read7BitEncodedInt();

                        archiveEntries.Add(entry);
                    }

                    int    offset = 0, byteRead = 0;
                    double count = 0;
                    if (stream.Position != (long)headerSize)
                    {
                        stream.Position = (long)headerSize;
                    }

                    using (InflaterInputStream decompressionStream = new InflaterInputStream(stream))
                    {
                        foreach (var entry in archiveEntries.OrderBy(e => e.byteOffset))
                        {
                            updateProgress(count / archiveEntries.Count * 100d);
                            log.InfoFormat("Extracting {0}", entry.file);
                            string extractPath = Path.Combine(folder, entry.file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
                            if (createOverrideFolders)
                            {
                                extractPath = Path.Combine(Path.GetDirectoryName(extractPath), TroveMod.OverrideFolder, Path.GetFileName(extractPath));
                            }
                            SettingsDataProvider.ResolveFolder(Path.GetDirectoryName(extractPath));

                            // Advance data position to the next entry offset if needed
                            while (offset < entry.byteOffset && byteRead != -1)
                            {
                                byteRead = decompressionStream.ReadByte();
                                offset++;
                            }
                            offset += SaveBytes(extractPath, stream, decompressionStream, Convert.ToInt64(headerSize) + Convert.ToInt64(entry.byteOffset), entry.size, buffer);
                        }
                    }
                }
            }

            try
            {
                if (createYaml)
                {
                    string title    = properties.ContainsKey(TitleValue) ? properties[TitleValue] : Path.GetFileNameWithoutExtension(file);
                    string yamlPath = Path.Combine(folder, SettingsDataProvider.GetSafeFilename(title) + ".yaml");
                    log.InfoFormat("Generating YAML file: {0}", yamlPath);

                    ModDetails details = new ModDetails()
                    {
                        Author      = properties[AuthorValue],
                        Title       = properties[TitleValue],
                        Notes       = properties[NotesValue],
                        PreviewPath = properties[PreviewPathValue],
                        Files       = archiveEntries.Select(e => e.file).ToList()
                    };
                    if (properties.ContainsKey(TagsValue))
                    {
                        string tags = properties[TagsValue];
                        if (!string.IsNullOrWhiteSpace(tags))
                        {
                            details.Tags = tags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                        }
                    }
                    details.SaveYamlFile(yamlPath);
                }
            }
            catch (Exception ex) { log.Error("Error generating YAML file", ex); }

            log.InfoFormat("Completed extracting files from {0}", file);
        }
 public override int ReadByte() => ist.ReadByte();