This project is read-only.

problem with PngDecoder

May 5, 2010 at 7:22 PM

Some pictures get error, some are wrong. Here is the result and test project. Thanks for any response.

Coordinator
May 8, 2010 at 8:57 PM
Thx a lot for this notification and the test project, I will care about
as far as possible.
Coordinator
May 8, 2010 at 9:48 PM

Bugs solved. Download the latest source code or replace the PaletteIndexReader.cs with the following code:

// ===============================================================================
// PaletteIndexReader.cs
// .NET Image Tools
// ===============================================================================
// Copyright (c) .NET Image Tools Development Group. 
// All rights reserved.
// ===============================================================================

namespace ImageTools.IO.Png
{
    /// 
    /// A color reader for reading palette indices from the PNG file.
    /// 
    sealed class PaletteIndexReader : IColorReader
    {
        /// 
        /// The index of the current row.
        /// 
        private int _row;
        /// 
        /// Stores the palette. Each entry is a color in RGB format.
        /// 
        private byte[] _palette;
        /// 
        /// Stores the alpha values of the palette entries. This member can be null,
        /// if the colors does not have alpha values and the array can have less
        /// values than the number of colors.
        /// 
        private byte[] _paletteAlpha;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// <param name="palette" />The palette as simple byte array. It will contains 3 values for each
        /// color, which represents the red-, the green- and the blue channel.
        /// <param name="paletteAlpha" />The alpha palette. Can be null, if the image does not have an
        /// alpha channel and can contain less entries than the number of colors in the palette.
        public PaletteIndexReader(byte[] palette, byte[] paletteAlpha)
        {
            _palette = palette;

            // Set the palette alpha array. This 
            // array is optional. If it is null, no alpha
            // values will be set.
            _paletteAlpha = paletteAlpha;
        }

        #region IColorReader Members

        /// 
        /// Reads the specified scanline.
        /// 
        /// <param name="scanline" />The scanline.
        /// <param name="pixels" />The pixels, where the colors should be stored in RGBA format.
        /// <param name="header" />The header, which contains information about the png file, like
        /// the width of the image and the height.
        public void ReadScanline(byte[] scanline, byte[] pixels, PngHeader header)
        {
            // Go through all items in the scanline array. The length of the scanline
            // is equals to the width of the image and each byte is a index to a color
            // in the palette and a index to the alpha value in the alpha palette array.

            int offset = 0, index = 0;

            if (_paletteAlpha != null && _paletteAlpha.Length > 0)
            {
                // If the alpha palette is not null and does one or
                // more entries, this means, that the image contains and alpha
                // channel and we should try to read it.
                for (int i = 0; i < scanline.Length; i++)
                {
                    index = scanline[i];

                    offset = (_row * header.Width + i) * 4;

                    pixels[offset + 0] = _palette[index * 3];
                    pixels[offset + 1] = _palette[index * 3 + 1];
                    pixels[offset + 2] = _palette[index * 3 + 2];

                    if (_paletteAlpha.Length > index)
                    {
                        // If the pixel array contains an entry for 
                        // the current color use it...
                        pixels[offset + 3] = _paletteAlpha[index];
                    }
                    else
                    {
                        // Otherwise take the last entry in the array.
                        pixels[offset + 3] = 255;
                    }
                }
            }
            else
            {
                for (int i = 0; i < scanline.Length; i++)
                {
                    index = scanline[i];

                    offset = (_row * header.Width + i) * 4;

                    pixels[offset + 0] = _palette[index * 3];
                    pixels[offset + 1] = _palette[index * 3 + 1];
                    pixels[offset + 2] = _palette[index * 3 + 2];
                    pixels[offset + 3] = (byte)255;
                }
            }

            _row++;
        }

        #endregion
    }
}

May 9, 2010 at 3:16 AM

Amazing, it works, this really help me a lot, but i still get error with some other pictures:

, ,

Coordinator
May 9, 2010 at 8:20 AM
I will have a look. Your Images are very special, this is the first time I see an PNG that uses a palette, so I am very happy to have them for testing.

Am 09.05.2010 04:16, schrieb WhoAreYou:

From: WhoAreYou

Amazing, it works, this really help me a lot, but i still get error with some other pictures:

, ,


May 9, 2010 at 8:43 AM

Thanks a lot.

 

Coordinator
May 9, 2010 at 4:23 PM
Had a look at the images. As you can see in the comments of the
PNGDecoder only images with 8 bits per channel are supported at the moment.

I will definitly add this feature but I cant promise to implement it the
next time. I suggest to convert your image to a palette format with 8
bits per channel, I think it doesnt costs too much.

Thx a lot for the image, this is the first time, that I see such a PNG
file, where are they from or how did you generate them?
May 9, 2010 at 4:51 PM

It's from another png decoder library pr2. But seem like it's for winform not silverlight. And there are also many pictures from a java png decoder library javapng which ImageTools can not open too.

Thanks again