Beispiel #1
0
        /// <summary>
        /// Calculates the length of the scanline.
        /// </summary>
        /// <param name="colorTypeInformation">The color type information.</param>
        /// <param name="header">The header.</param>
        /// <returns>The scanline length</returns>
        private static int CalculateScanlineLength(ColorTypeInformation colorTypeInformation, Header header)
        {
            int ScanlineLength = header.Width * header.BitDepth * colorTypeInformation.ScanlineFactor;

            int Amount = ScanlineLength % 8;

            if (Amount != 0)
            {
                ScanlineLength += 8 - Amount;
            }

            return(ScanlineLength / 8);
        }
Beispiel #2
0
        /// <summary>
        /// Reads the scanlines.
        /// </summary>
        /// <param name="dataStream">The data stream.</param>
        /// <param name="pixels">The pixels.</param>
        /// <param name="colorReader">The color reader.</param>
        /// <param name="colorTypeInformation">The color type information.</param>
        /// <param name="header">The header.</param>
        private void ReadScanlines(MemoryStream dataStream, Color[] pixels, IColorReader colorReader, ColorTypeInformation colorTypeInformation, Header header)
        {
            dataStream.Seek(0, SeekOrigin.Begin);

            var ScanlineLength = CalculateScanlineLength(colorTypeInformation, header);
            var ScanlineStep   = CalculateScanlineStep(colorTypeInformation, header);

            byte[] LastScanline = new byte[ScanlineLength];
            byte[] CurrentScanline = new byte[ScanlineLength];
            int    Filter = 0, Column = -1, Row = 0;

            using (InflateStream CompressedStream = new InflateStream(dataStream))
            {
                int ReadByte;
                while ((ReadByte = CompressedStream.ReadByte()) >= 0)
                {
                    if (Column == -1)
                    {
                        Filter = ReadByte;
                        ++Column;
                    }
                    else
                    {
                        CurrentScanline[Column] = (byte)ReadByte;
                        byte a;
                        byte b;
                        byte c;
                        if (Column >= ScanlineStep)
                        {
                            a = CurrentScanline[Column - ScanlineStep];
                            c = LastScanline[Column - ScanlineStep];
                        }
                        else
                        {
                            a = 0;
                            c = 0;
                        }

                        b = LastScanline[Column];
                        switch (Filter)
                        {
                        case 1:
                            CurrentScanline[Column] = (byte)(CurrentScanline[Column] + a);
                            break;

                        case 2:
                            CurrentScanline[Column] = (byte)(CurrentScanline[Column] + b);
                            break;

                        case 3:
                            CurrentScanline[Column] = (byte)(CurrentScanline[Column] + (byte)((a + b) / 2));
                            break;

                        case 4:
                            CurrentScanline[Column] = (byte)(CurrentScanline[Column] + PaethPredicator(a, b, c));
                            break;
                        }

                        ++Column;

                        if (Column == ScanlineLength)
                        {
                            colorReader.ReadScanline(CurrentScanline, pixels, header, Row);
                            ++Row;
                            Column = -1;
                            var Holder = CurrentScanline;
                            CurrentScanline = LastScanline;
                            LastScanline    = Holder;
                        }
                    }
                }
            }
            //dataStream.Seek(0, SeekOrigin.Begin);

            //var ScanlineLength = CalculateScanlineLength(colorTypeInformation, header);
            //var ScanlineStep = CalculateScanlineStep(colorTypeInformation, header);

            //byte[] LastScanline = new byte[ScanlineLength];
            //byte[] CurrentScanline = new byte[ScanlineLength];

            //using (InflateStream CompressedStream = new InflateStream(dataStream))
            //{
            //    using (MemoryStream DecompressedStream = new MemoryStream())
            //    {
            //        CompressedStream.CopyTo(DecompressedStream);
            //        DecompressedStream.Flush();
            //        byte[] DecompressedArray = DecompressedStream.ToArray();
            //        for (int y = 0, Column = 0; y < header.Height; ++y, Column += (ScanlineLength + 1))
            //        {
            //            Array.Copy(DecompressedArray, Column + 1, CurrentScanline, 0, ScanlineLength);
            //            if (DecompressedArray[Column] < 0)
            //                break;
            //            byte[] Result = Filters[(FilterType)DecompressedArray[Column]].Decode(CurrentScanline, LastScanline, ScanlineStep);
            //            colorReader.ReadScanline(Result, pixels, header, y);
            //            Array.Copy(CurrentScanline, LastScanline, ScanlineLength);
            //        }
            //    }
            //}
        }
Beispiel #3
0
 /// <summary>
 /// Calculates the scanline step.
 /// </summary>
 /// <param name="colorTypeInformation">The color type information.</param>
 /// <param name="header">The header.</param>
 /// <returns>The scanline step</returns>
 private static int CalculateScanlineStep(ColorTypeInformation colorTypeInformation, Header header)
 {
     return(header.BitDepth >= 8 ? (colorTypeInformation.ScanlineFactor * header.BitDepth) / 8 : 1);
 }