Example #1
0
        public void ColorRGB24_Accessor()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24 v = new ColorRGB24(r, g, b);
            float      c;

            Assert.DoesNotThrow(() => c = v[0]);
            Assert.DoesNotThrow(() => c = v[1]);
            Assert.DoesNotThrow(() => c = v[2]);
            Assert.Throws <IndexOutOfRangeException>(() => c = v[+3]);
            Assert.Throws <IndexOutOfRangeException>(() => c = v[-1]);

            Assert.DoesNotThrow(() => v[0] = 1.0f);
            Assert.DoesNotThrow(() => v[1] = 1.0f);
            Assert.DoesNotThrow(() => v[2] = 1.0f);
            Assert.Throws <IndexOutOfRangeException>(() => v[+3] = 0.0f);
            Assert.Throws <IndexOutOfRangeException>(() => v[-1] = 0.0f);

            Assert.DoesNotThrow(() => v[2] = 0.0f);
            Assert.DoesNotThrow(() => v[2] = 1.0f);
            Assert.Throws <InvalidOperationException>(() => v[2] = -1.0f);
            Assert.Throws <InvalidOperationException>(() => v[2] = +1.1f);
        }
Example #2
0
        public void ColorRGB24_CastFromColor()
        {
            const double Epsilon = 0.25;

            Random random = new Random();
            double r      = NextComponent(random, 1.0);
            double g      = NextComponent(random, 1.0);
            double b      = NextComponent(random, 1.0);

            Color c = Color.FromArgb(byte.MaxValue, (int)(r * byte.MaxValue), (int)(g * byte.MaxValue), (int)(b * byte.MaxValue));

            ColorRGB24 v = (ColorRGB24)c;

            Assert.AreEqual((float)r, v[0], Epsilon);
            Assert.AreEqual((float)g, v[1], Epsilon);
            Assert.AreEqual((float)b, v[2], Epsilon);

            // Not influenced by alpha
            c = Color.FromArgb(0, (int)(r * byte.MaxValue), (int)(g * byte.MaxValue), (int)(b * byte.MaxValue));
            v = (ColorRGB24)c;

            Assert.AreEqual((float)r, v[0], Epsilon);
            Assert.AreEqual((float)g, v[1], Epsilon);
            Assert.AreEqual((float)b, v[2], Epsilon);
        }
Example #3
0
        public void ColorRGB24_CastToRGBA()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24  v     = new ColorRGB24(r, g, b);
            ColorRGBA32 vRGBA = v;
        }
Example #4
0
        public void ColorRGB24_PixelType()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24 v = new ColorRGB24(r, g, b);

            Assert.AreNotEqual(PixelLayout.None, v.PixelType);
        }
Example #5
0
        public void ColorRGB24_TestConstructor1()
        {
            byte r = (byte)byte.MaxValue;
            byte g = (byte)byte.MaxValue;
            byte b = (byte)byte.MaxValue;

            ColorRGB24 v = new ColorRGB24(r, g, b);

            Assert.AreEqual(r, v.Red);
            Assert.AreEqual(g, v.Green);
            Assert.AreEqual(b, v.Blue);
        }
Example #6
0
        public void ColorRGB24_CastToVertex4()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24 v      = new ColorRGB24(r, g, b);
            Vertex3ub  vArray = v;

            Assert.AreEqual(r, vArray.x);
            Assert.AreEqual(g, vArray.y);
            Assert.AreEqual(b, vArray.z);
        }
Example #7
0
        public void ColorRGB24_CastToRGBA()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24  v     = new ColorRGB24(r, g, b);
            ColorRGBA32 vRGBA = v;

            Assert.AreEqual(v.Red, vRGBA.Red);
            Assert.AreEqual(v.Green, vRGBA.Green);
            Assert.AreEqual(v.Blue, vRGBA.Blue);
            Assert.AreEqual(byte.MaxValue, vRGBA.Alpha);
        }
Example #8
0
        public void ColorRGB24_CastToArray()
        {
            byte r = (byte)NextComponent(byte.MaxValue);
            byte g = (byte)NextComponent(byte.MaxValue);
            byte b = (byte)NextComponent(byte.MaxValue);

            ColorRGB24 v = new ColorRGB24(r, g, b);

            byte[] vArray = v;

            Assert.AreEqual(3, vArray.Length);
            Assert.AreEqual(r, vArray[0]);
            Assert.AreEqual(g, vArray[1]);
            Assert.AreEqual(b, vArray[2]);
        }
Example #9
0
        private BitmapRGB24 ApplyEffectRGB24(BitmapRGB24 input)
        {
            ColorRGB24[] pix = new ColorRGB24[input.Size.Elements];

            var c = this.Contrast;

            for (int i = 0; i < pix.Length; i++)
            {
                pix[i].Red   = (byte)((pix[i].Red - 127) * c);
                pix[i].Green = (byte)((pix[i].Green - 127) * c);
                pix[i].Blue  = (byte)((pix[i].Blue - 127) * c);
            }

            return(new BitmapRGB24(input.Size, pix));
        }
Example #10
0
        private void BoxBlurRGB24(BitmapRGB24 input, BitmapRGB24 output, BitmapRGB32 mask = null)
        {
            Contract.Requires(input != null);
            Contract.Requires(output != null);
            Contract.Requires(input.Width == output.Width);
            Contract.Requires(input.Height == output.Height);

            int radius = this.Radius;
            int w      = input.Width;
            int h      = input.Height;
            var bmp    = output;

            var   pix = bmp.Pixels;
            float div = (float)Math.Pow((radius * 2 + 1), 2);

            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    var tr = 0.0;
                    var tg = 0.0;
                    var tb = 0.0;

                    for (int ky = -radius; ky <= radius; ky++)
                    {
                        for (int kx = -radius; kx <= radius; kx++)
                        {
                            var px = Math.Max(Math.Min(x + kx, w - 1), 0);
                            var py = Math.Max(Math.Min(y + ky, h - 1), 0);
                            var p  = input[px, py];
                            tr += p.Red;
                            tg += p.Green;
                            tb += p.Blue;
                            //div += 1;
                        }
                    }
                    //total.Alpha = 1.0f;
                    bmp[x, y] = new ColorRGB24((byte)(tr / 255.0 * (255.0 / div)),
                                               (byte)(tg / 255.0 * (255.0 / div)), (byte)(tb / 255.0 * (255.0 / div)));
                }
            }
        }
Example #11
0
        public override void Decode(Frame output)
        {
            int width = 0, height = 0;
            byte depth = 0;
            PNGColorType colorType = PNGColorType.TruecolorWithAlpha;
            Frame result = output;

            // TODO: Verify signature

            // Pull the PNG into a data buffer.
            if (this.Bitstream == null || this.Bitstream.Length < 1)
                return;

            var bytes = new byte[this.Bitstream.Length];
            this.Bitstream.Read(bytes, 0, bytes.Length);
            var buf = new DataBuffer(bytes, ByteOrder.BigEndian);

            var signature = buf.ReadInt64();
            if (signature != PNGCodec.BitstreamSignature)
            {
            }

            bool ihdrDone = false;
            //bool iendDone = false;
            using (var pixelStream = new MemoryStream())
            {
                var zout = new ZOutputStream(pixelStream);

                // Start reading chunks.
                while (buf.Available > 0)
                {
                    int length = buf.ReadInt32();
                    string chunk = string.Concat((char)buf.ReadByte(), (char)buf.ReadByte(), (char)buf.ReadByte(), (char)buf.ReadByte());

                    switch (chunk)
                    {
                        case "IHDR":
                            if (ihdrDone)
                                throw new NotImplementedException();
                            else
                                ihdrDone = true;

                            if (length != 13)
                                throw new NotImplementedException();

                            width = buf.ReadInt32();
                            height = buf.ReadInt32();
                            depth = buf.ReadByte();
                            colorType = (PNGColorType)buf.ReadByte();
                            byte xmethod = buf.ReadByte();
                            PNGFilterMethod filterMethod = (PNGFilterMethod)buf.ReadByte();
                            byte interlaceMethod = buf.ReadByte();

                            break;

                        case "IDAT":
                            var data = buf.ReadBytes(length);
                            zout.Write(data, 0, data.Length);
                            break;

                        default:
                            Console.WriteLine("Skipping unknown chunk \"{0}\" in PNG bitstream at offset {1}", chunk, (buf.Position - 8).ToString("X"));
                            buf.Position += (length > buf.Available) ? buf.Available : length;
                            break;
                    }
                    int crc32 = buf.ReadInt32();
                }

                if (depth == 8)
                {
                    if (colorType == PNGColorType.TruecolorWithAlpha)
                    {
                        //var pd = new byte[width * height * 4];
                        var pd = new byte[pixelStream.Length];
                        pixelStream.Position = 0;
                        pixelStream.Read(pd, 0, pd.Length);

                        ColorRGB32[] pix = new ColorRGB32[width * height];
                        ColorRGB32 p = new ColorRGB32();

                        //File.WriteAllBytes("dump.bin", pd);

                        for (int i = 0, n = 0; i < pix.Length; i++)
                        {
                            if (i % width == 0)
                                n++;

                            p.Red = pd[n++];
                            p.Green = pd[n++];
                            p.Blue = pd[n++];
                            p.Alpha = pd[n++];
                            pix[i] = p;
                        }

                        result.Video[0] = new BitmapRGB32(width, height, pix);
                    }
                    else if (colorType == PNGColorType.Truecolor)
                    {
                        //var pd = new byte[width * height * 3];
                        var pd = new byte[pixelStream.Length];
                        pixelStream.Position = 0;
                        pixelStream.Read(pd, 0, pd.Length);
                        ColorRGB24[] pix = new ColorRGB24[width * height];
                        ColorRGB24 p = new ColorRGB24();

                        //File.WriteAllBytes("dump.bin", pd);

                        for (int i = 0, n = 0; i < pix.Length; i++)
                        {
                            if (i % width == 0)
                                n++;

                            p.Red = pd[n++];
                            p.Green = pd[n++];
                            p.Blue = pd[n++];
                            pix[i] = p;
                        }

                        result.Video[0] = new BitmapRGB24(width, height, pix);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Example #12
0
        private void DecodeBitmap()
        {
            var dc = this.context;

            if (dc.Stage < TGADecodeStage.FooterDecoded)
            {
                this.DecodeFooter(dc);
            }

            var header = dc.Header;

            // Syntax sugar
            int w = dc.Header.Width;
            int h = dc.Header.Height;

            if (w < 1 || h < 1)
            {
                throw new NotImplementedException();
            }

            if (header.BitsPerPixel % 8 != 0)
            {
                throw new NotImplementedException("BitsPerPixel not multiple of 8");
            }
            // Number of bytes per scanline
            int stride = header.Width * (header.BitsPerPixel / 8);

            // Read all the bytes that contain pixel data
            var data = new byte[dc.PixelDataLength];

            this.Bitstream.Seek(dc.PixelDataOffset, SeekOrigin.Begin);
            this.Bitstream.Read(data, 0, data.Length);

            if (header.ColorMapType == TGAColorMapType.ColorMapped) // Read color map data
            {
                throw new NotImplementedException();
            }
            else if (header.ImageType == TGAImageType.UncompressedTrueColor)
            {
                if (header.BitsPerPixel == 16)
                {
                    throw new NotImplementedException(); // TODO: Implement support for 16-bit TGA decoding.
                }
                else if (header.BitsPerPixel == 24)
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB24[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB24(w, h, pixels);

                    var n = -1;

                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        var line = new ColorRGB24[w];
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0; x < line.Length; ++x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        var line = new ColorRGB24[w];

                        // BTT + Right-to-Left (RTL) pixel order.
                        for (int y = h; y > 0; --y)
                        {
                            // Iterate over the pixels in the scanline from right-to-left.
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }

                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        // Top-to-bottom (TTB) + LTR pixel order.
                        for (int i = 0; i < pixels.Length; i++)
                        {
                            // All pixels can be decoded in one pass; TTB + LTR is the way bitmaps are laid out in memory.
                            pixels[i].Blue  = data[++n];
                            pixels[i].Green = data[++n];
                            pixels[i].Red   = data[++n];
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        var line = new ColorRGB24[w];

                        for (int y = 0; y < h; ++y)
                        {
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                            }
                            line.CopyTo(pixels, y * line.Length);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else if (header.BitsPerPixel == 32) // Same as above, plus alpha channel.
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB32[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB32(w, h, pixels);

                    int n    = -1;
                    var line = new ColorRGB32[w];
                    // Most common scanline direction first; TGA stores scanlines bottom-to-top by default.
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        // Bottom-to-top (BTT) + Left-to-right (LTR) pixel order.
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0; x < line.Length; ++x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            // Iterate over the pixels in the scanline from right-to-left.
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        for (int i = 0; i < pixels.Length; ++i)
                        {
                            // All pixels can be decoded in one pass; TTB + LTR is the way bitmaps are laid out in memory.
                            pixels[i].Blue  = data[++n];
                            pixels[i].Green = data[++n];
                            pixels[i].Red   = data[++n];
                            pixels[i].Alpha = data[++n];
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        for (int y = 0; y < h; ++y)
                        {
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue  = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red   = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, y * line.Length);
                        }
                    }
                }
            }
            else if (header.ImageType == TGAImageType.RunLengthEncodedTrueColor)
            {
                int  n   = -1;
                bool raw = false;
                byte p;

                if (header.BitsPerPixel == 16)
                {
                    throw new NotImplementedException();
                }
                if (header.BitsPerPixel == 24)
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB24[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB24(w, h, pixels);
                    ColorRGB24 px = new ColorRGB24();

                    // Operate on a line-by-line basis; RLE packets will never wrap from one scanline to another.
                    var line = new ColorRGB24[w];

                    // Most common scanline direction first; TGA stores scanlines bottom-to-top by default.
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0, e = 0; x < line.Length; ++x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = w, e = 0; x >= 0; --x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        for (int i = 0, e = 0; i < pixels.Length; ++i)
                        {
                            if (e == 0)
                            {
                                // Read the "packet header"
                                p = data[++n];
                                // Highest bit of packet header indicates RLE (1) or RAW (0).
                                raw = (p & 0x80) != 0x80;
                                // Remaining 7 bits indicate RLE packet length.
                                e = 1 + (p & 0x7F);

                                // Read color
                                px.Blue  = data[++n];
                                px.Green = data[++n];
                                px.Red   = data[++n];
                            }
                            else if (raw)
                            {
                                px.Blue  = data[++n];
                                px.Green = data[++n];
                                px.Red   = data[++n];
                            }

                            pixels[i] = px;
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        throw new NotImplementedException();

                        /*
                         * for (int y = 0; y < h; y++)
                         * {
                         *  for (int x = w - 1; x >= 0; x--)
                         *  {
                         *      if (e == 0)
                         *      {
                         *          // Read the "packet header"
                         *          p = data[++n];
                         *          // Highest bit of packet header indicates RLE (1) or RAW (0).
                         *          raw = (p & 0x80) != 0x80;
                         *          // Remaining 7 bits indicate RLE packet length.
                         *          e = 1 + (p & 0x7F);
                         *
                         *          // Read color
                         *          px.Blue = data[++n];
                         *          px.Green = data[++n];
                         *          px.Red = data[++n];
                         *      }
                         *      else if (raw)
                         *      {
                         *          px.Blue = data[++n];
                         *          px.Green = data[++n];
                         *          px.Red = data[++n];
                         *      }
                         *
                         *      line[x] = px;
                         *  }
                         * }*/
                    }
                }
                else if (header.BitsPerPixel == 32) // Just like above, but with an alpha channel.
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB32[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB32(w, h, pixels);
                    ColorRGB32 px = new ColorRGB32();
                    // Operate on a line-by-line basis; RLE packets will never wrap from one scanline to another.
                    var line = new ColorRGB32[w];
                    var len  = line.Length;
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0, e = 0; x < len; ++x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                    px.Alpha = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue  = data[++n];
                                    px.Green = data[++n];
                                    px.Red   = data[++n];
                                    px.Alpha = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        throw new NotImplementedException();
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        throw new NotImplementedException();
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            dc.Stage = TGADecodeStage.BitmapDecoded;
        }
Example #13
0
        public override void Decode(Frame output)
        {
            int          width = 0, height = 0;
            byte         depth     = 0;
            PNGColorType colorType = PNGColorType.TruecolorWithAlpha;
            Frame        result    = output;

            // TODO: Verify signature

            // Pull the PNG into a data buffer.
            if (this.Bitstream == null || this.Bitstream.Length < 1)
            {
                return;
            }

            var bytes = new byte[this.Bitstream.Length];

            this.Bitstream.Read(bytes, 0, bytes.Length);
            var buf = new DataBuffer(bytes, ByteOrder.BigEndian);

            var signature = buf.ReadInt64();

            if (signature != PNGCodec.BitstreamSignature)
            {
            }

            bool ihdrDone = false;

            //bool iendDone = false;
            using (var pixelStream = new MemoryStream())
            {
                var zout = new ZOutputStream(pixelStream);

                // Start reading chunks.
                while (buf.Available > 0)
                {
                    int    length = buf.ReadInt32();
                    string chunk  = string.Concat((char)buf.ReadByte(), (char)buf.ReadByte(), (char)buf.ReadByte(), (char)buf.ReadByte());

                    switch (chunk)
                    {
                    case "IHDR":
                        if (ihdrDone)
                        {
                            throw new NotImplementedException();
                        }
                        else
                        {
                            ihdrDone = true;
                        }

                        if (length != 13)
                        {
                            throw new NotImplementedException();
                        }

                        width     = buf.ReadInt32();
                        height    = buf.ReadInt32();
                        depth     = buf.ReadByte();
                        colorType = (PNGColorType)buf.ReadByte();
                        byte            xmethod         = buf.ReadByte();
                        PNGFilterMethod filterMethod    = (PNGFilterMethod)buf.ReadByte();
                        byte            interlaceMethod = buf.ReadByte();

                        break;

                    case "IDAT":
                        var data = buf.ReadBytes(length);
                        zout.Write(data, 0, data.Length);
                        break;

                    default:
                        Console.WriteLine("Skipping unknown chunk \"{0}\" in PNG bitstream at offset {1}", chunk, (buf.Position - 8).ToString("X"));
                        buf.Position += (length > buf.Available) ? buf.Available : length;
                        break;
                    }
                    int crc32 = buf.ReadInt32();
                }

                if (depth == 8)
                {
                    if (colorType == PNGColorType.TruecolorWithAlpha)
                    {
                        //var pd = new byte[width * height * 4];
                        var pd = new byte[pixelStream.Length];
                        pixelStream.Position = 0;
                        pixelStream.Read(pd, 0, pd.Length);

                        ColorRGB32[] pix = new ColorRGB32[width * height];
                        ColorRGB32   p   = new ColorRGB32();

                        //File.WriteAllBytes("dump.bin", pd);

                        for (int i = 0, n = 0; i < pix.Length; i++)
                        {
                            if (i % width == 0)
                            {
                                n++;
                            }

                            p.Red   = pd[n++];
                            p.Green = pd[n++];
                            p.Blue  = pd[n++];
                            p.Alpha = pd[n++];
                            pix[i]  = p;
                        }

                        result.Video[0] = new BitmapRGB32(width, height, pix);
                    }
                    else if (colorType == PNGColorType.Truecolor)
                    {
                        //var pd = new byte[width * height * 3];
                        var pd = new byte[pixelStream.Length];
                        pixelStream.Position = 0;
                        pixelStream.Read(pd, 0, pd.Length);
                        ColorRGB24[] pix = new ColorRGB24[width * height];
                        ColorRGB24   p   = new ColorRGB24();

                        //File.WriteAllBytes("dump.bin", pd);

                        for (int i = 0, n = 0; i < pix.Length; i++)
                        {
                            if (i % width == 0)
                            {
                                n++;
                            }

                            p.Red   = pd[n++];
                            p.Green = pd[n++];
                            p.Blue  = pd[n++];
                            pix[i]  = p;
                        }

                        result.Video[0] = new BitmapRGB24(width, height, pix);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Example #14
0
        public unsafe override void EncodeImage(Image image)
        {
            this.Open();
            this.Bitstream.Seek(TGABitstreamHeader.Length, System.IO.SeekOrigin.Begin);

            var tga = image as TGAImage;

            if (tga == null)
                throw new NotImplementedException();

            var header = this.context.Header;
            header.Width = (ushort)tga.Width;
            header.Height = (ushort)tga.Height;

            // Temporarily force RLE off until RLE is implemented properly.
            tga.UseRunLengthEncoding = false;

            var bitmap = tga.Flatten();

            if (bitmap is BitmapRGB24)
            {
                header.BitsPerPixel = 24;
                header.AttributeBits = 0;
                header.ImageDescriptor = TGAImageDescriptor.BottomLeft;
                var bmp = bitmap as BitmapRGB24;

                if (tga.UseRunLengthEncoding)
                {
                    throw new NotImplementedException();
                    header.ImageType = TGAImageType.RunLengthEncodedTrueColor;
                    var buffer = new byte[(bmp.Size.Elements * 4)];
                    var pix = bmp.Pixels;
                    int n = 0;
                    var line = new ColorRGB24[tga.Width];

                    // Operate on each scanline.
                    for (int s = tga.Height - 1; s >= 0; --s)
                    {
                        // Copy pixels from source image into scanline buffer.
                        Array.Copy(pix, s * tga.Width, line, 0, line.Length);

                        int idx = 0;
                        int start = 0;

                    BeginPacket:
                        if (idx >= line.Length)
                            goto EndLine;
                        else
                        {
                            start = idx;

                            if (line[idx] == line[idx + 1])
                                goto NextPixelRLE;
                        }

                    NextPixelRLE:
                        if (line[idx] == line[++idx])
                            idx = 0;

                    EndLine:
                        continue;
                    }
                    this.Bitstream.Write(buffer, 0, ++n);
                }
                else
                {
                    header.ImageType = TGAImageType.UncompressedTrueColor;

                    var buffer = new byte[bmp.Size.Elements * 3];
                    var pix = bmp.Pixels;
                    for (int i = 0, n = -1; i < pix.Length; ++i)
                    {
                        buffer[++n] = pix[i].Blue;
                        buffer[++n] = pix[i].Green;
                        buffer[++n] = pix[i].Red;
                    }
                    this.Bitstream.Write(buffer, 0, buffer.Length);
                }
            }
            else if (bitmap is BitmapRGB32)
            {
                var bmp = bitmap as BitmapRGB32;

                if (tga.UseRunLengthEncoding)
                    throw new NotImplementedException();
                else
                {
                    header.ImageType = TGAImageType.UncompressedTrueColor;

                    var buffer = new byte[bmp.Size.Elements * 4];
                    var pix = bmp.Pixels;

                    ColorRGB32 p;
                    for (int i = 0, n = -1; i < pix.Length; ++i)
                    {
                        p = pix[i];
                        buffer[++n] = p.Blue;
                        buffer[++n] = p.Green;
                        buffer[++n] = p.Red;
                        buffer[++n] = p.Alpha;
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            this.context.Header = header;
            this.Close();
        }
Example #15
0
        public unsafe override void EncodeImage(Image image)
        {
            this.Open();
            this.Bitstream.Seek(TGABitstreamHeader.Length, System.IO.SeekOrigin.Begin);

            var tga = image as TGAImage;

            if (tga == null)
            {
                throw new NotImplementedException();
            }

            var header = this.context.Header;

            header.Width  = (ushort)tga.Width;
            header.Height = (ushort)tga.Height;

            // Temporarily force RLE off until RLE is implemented properly.
            tga.UseRunLengthEncoding = false;

            var bitmap = tga.Flatten();

            if (bitmap is BitmapRGB24)
            {
                header.BitsPerPixel    = 24;
                header.AttributeBits   = 0;
                header.ImageDescriptor = TGAImageDescriptor.BottomLeft;
                var bmp = bitmap as BitmapRGB24;

                if (tga.UseRunLengthEncoding)
                {
                    throw new NotImplementedException();
                    header.ImageType = TGAImageType.RunLengthEncodedTrueColor;
                    var buffer = new byte[(bmp.Size.Elements * 4)];
                    var pix    = bmp.Pixels;
                    int n      = 0;
                    var line   = new ColorRGB24[tga.Width];

                    // Operate on each scanline.
                    for (int s = tga.Height - 1; s >= 0; --s)
                    {
                        // Copy pixels from source image into scanline buffer.
                        Array.Copy(pix, s * tga.Width, line, 0, line.Length);

                        int idx   = 0;
                        int start = 0;

BeginPacket:
                        if (idx >= line.Length)
                        {
                            goto EndLine;
                        }
                        else
                        {
                            start = idx;

                            if (line[idx] == line[idx + 1])
                            {
                                goto NextPixelRLE;
                            }
                        }

NextPixelRLE:
                        if (line[idx] == line[++idx])
                        {
                            idx = 0;
                        }

EndLine:
                        continue;
                    }
                    this.Bitstream.Write(buffer, 0, ++n);
                }
                else
                {
                    header.ImageType = TGAImageType.UncompressedTrueColor;

                    var buffer = new byte[bmp.Size.Elements * 3];
                    var pix    = bmp.Pixels;
                    for (int i = 0, n = -1; i < pix.Length; ++i)
                    {
                        buffer[++n] = pix[i].Blue;
                        buffer[++n] = pix[i].Green;
                        buffer[++n] = pix[i].Red;
                    }
                    this.Bitstream.Write(buffer, 0, buffer.Length);
                }
            }
            else if (bitmap is BitmapRGB32)
            {
                var bmp = bitmap as BitmapRGB32;


                if (tga.UseRunLengthEncoding)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    header.ImageType = TGAImageType.UncompressedTrueColor;

                    var buffer = new byte[bmp.Size.Elements * 4];
                    var pix    = bmp.Pixels;

                    ColorRGB32 p;
                    for (int i = 0, n = -1; i < pix.Length; ++i)
                    {
                        p           = pix[i];
                        buffer[++n] = p.Blue;
                        buffer[++n] = p.Green;
                        buffer[++n] = p.Red;
                        buffer[++n] = p.Alpha;
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            this.context.Header = header;
            this.Close();
        }
Example #16
0
        private void DecodeBitmap()
        {
            var dc = this.context;
            if (dc.Stage < TGADecodeStage.FooterDecoded)
                this.DecodeFooter(dc);

            var header = dc.Header;

            // Syntax sugar
            int w = dc.Header.Width;
            int h = dc.Header.Height;

            if (w < 1 || h < 1)
                throw new NotImplementedException();

            if (header.BitsPerPixel % 8 != 0)
                throw new NotImplementedException("BitsPerPixel not multiple of 8");
            // Number of bytes per scanline
            int stride = header.Width * (header.BitsPerPixel / 8);

            // Read all the bytes that contain pixel data
            var data = new byte[dc.PixelDataLength];
            this.Bitstream.Seek(dc.PixelDataOffset, SeekOrigin.Begin);
            this.Bitstream.Read(data, 0, data.Length);

            if (header.ColorMapType == TGAColorMapType.ColorMapped) // Read color map data
                throw new NotImplementedException();
            else if (header.ImageType == TGAImageType.UncompressedTrueColor)
            {
                if (header.BitsPerPixel == 16)
                    throw new NotImplementedException(); // TODO: Implement support for 16-bit TGA decoding.
                else if (header.BitsPerPixel == 24)
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB24[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB24(w, h, pixels);

                    var n = -1;

                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        var line = new ColorRGB24[w];
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0; x < line.Length; ++x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }

                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        var line = new ColorRGB24[w];

                        // BTT + Right-to-Left (RTL) pixel order.
                        for (int y = h; y > 0; --y)
                        {
                            // Iterate over the pixels in the scanline from right-to-left.
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }

                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        // Top-to-bottom (TTB) + LTR pixel order.
                        for (int i = 0; i < pixels.Length; i++)
                        {
                            // All pixels can be decoded in one pass; TTB + LTR is the way bitmaps are laid out in memory.
                            pixels[i].Blue = data[++n];
                            pixels[i].Green = data[++n];
                            pixels[i].Red = data[++n];
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        var line = new ColorRGB24[w];

                        for (int y = 0; y < h; ++y)
                        {
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                            }
                            line.CopyTo(pixels, y * line.Length);
                        }
                    }
                    else
                        throw new NotImplementedException();
                }
                else if (header.BitsPerPixel == 32) // Same as above, plus alpha channel.
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB32[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB32(w, h, pixels);

                    int n = -1;
                    var line = new ColorRGB32[w];
                    // Most common scanline direction first; TGA stores scanlines bottom-to-top by default.
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        // Bottom-to-top (BTT) + Left-to-right (LTR) pixel order.
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0; x < line.Length; ++x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            // Iterate over the pixels in the scanline from right-to-left.
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, (y - 1) * line.Length);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        for (int i = 0; i < pixels.Length; ++i)
                        {
                            // All pixels can be decoded in one pass; TTB + LTR is the way bitmaps are laid out in memory.
                            pixels[i].Blue = data[++n];
                            pixels[i].Green = data[++n];
                            pixels[i].Red = data[++n];
                            pixels[i].Alpha = data[++n];
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        for (int y = 0; y < h; ++y)
                        {
                            for (int x = line.Length - 1; x >= 0; --x)
                            {
                                line[x].Blue = data[++n];
                                line[x].Green = data[++n];
                                line[x].Red = data[++n];
                                line[x].Alpha = data[++n];
                            }
                            line.CopyTo(pixels, y * line.Length);
                        }
                    }
                }
            }
            else if (header.ImageType == TGAImageType.RunLengthEncodedTrueColor)
            {
                int n = -1;
                bool raw = false;
                byte p;

                if (header.BitsPerPixel == 16)
                {
                    throw new NotImplementedException();
                }
                if (header.BitsPerPixel == 24)
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB24[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB24(w, h, pixels);
                    ColorRGB24 px = new ColorRGB24();

                    // Operate on a line-by-line basis; RLE packets will never wrap from one scanline to another.
                    var line = new ColorRGB24[w];

                    // Most common scanline direction first; TGA stores scanlines bottom-to-top by default.
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0, e = 0; x < line.Length; ++x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = w, e = 0; x >= 0; --x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        for (int i = 0, e = 0; i < pixels.Length; ++i)
                        {
                            if (e == 0)
                            {
                                // Read the "packet header"
                                p = data[++n];
                                // Highest bit of packet header indicates RLE (1) or RAW (0).
                                raw = (p & 0x80) != 0x80;
                                // Remaining 7 bits indicate RLE packet length.
                                e = 1 + (p & 0x7F);

                                // Read color
                                px.Blue = data[++n];
                                px.Green = data[++n];
                                px.Red = data[++n];
                            }
                            else if (raw)
                            {
                                px.Blue = data[++n];
                                px.Green = data[++n];
                                px.Red = data[++n];
                            }

                            pixels[i] = px;
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        throw new NotImplementedException();
                        /*
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = w - 1; x >= 0; x--)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                }

                                line[x] = px;
                            }
                        }*/
                    }
                }
                else if (header.BitsPerPixel == 32) // Just like above, but with an alpha channel.
                {
                    // Create an array of all the pixels in the bitmap (width x height).
                    var pixels = new ColorRGB32[w * h];
                    // ...and assign it to the Bitmap that will eventually be returned.
                    dc.DecodedBitmap = new BitmapRGB32(w, h, pixels);
                    ColorRGB32 px = new ColorRGB32();
                    // Operate on a line-by-line basis; RLE packets will never wrap from one scanline to another.
                    var line = new ColorRGB32[w];
                    var len = line.Length;
                    if (dc.PixelOrder == TGAPixelOrder.BottomLeft)
                    {
                        for (int y = h; y > 0; --y)
                        {
                            for (int x = 0, e = 0; x < len; ++x, --e)
                            {
                                if (e == 0)
                                {
                                    // Read the "packet header"
                                    p = data[++n];
                                    // Highest bit of packet header indicates RLE (1) or RAW (0).
                                    raw = (p & 0x80) != 0x80;
                                    // Remaining 7 bits indicate RLE packet length.
                                    e = 1 + (p & 0x7F);

                                    // Read color
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                    px.Alpha = data[++n];
                                }
                                else if (raw)
                                {
                                    px.Blue = data[++n];
                                    px.Green = data[++n];
                                    px.Red = data[++n];
                                    px.Alpha = data[++n];
                                }

                                line[x] = px;
                            }
                            line.CopyTo(pixels, (y - 1) * w);
                        }
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.BottomRight)
                    {
                        throw new NotImplementedException();
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopLeft)
                    {
                        throw new NotImplementedException();
                    }
                    else if (dc.PixelOrder == TGAPixelOrder.TopRight)
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                    throw new NotImplementedException();
            }

            dc.Stage = TGADecodeStage.BitmapDecoded;
        }