/// <summary> Create Color[] from PNG file, async </summary>
        public static async Task <ReadColorsResult> ReadColorsAsync
        (
            string filePath
        )
        {
            ReadColorsResult results = new ReadColorsResult {
                pixels = null,
                width  = -1,
                height = -1,
                textureFormatInfered = 0
            };
            PngReader reader = null;

            try
            {
                reader = FileHelper.CreatePngReader(filePath);
                var info = reader.ImgInfo;
                results.height = info.Rows;
                results.width  = info.Cols;
                results.pixels = new Color[results.width * results.height];

                int channels = info.Channels;
                int bitDepth = info.BitDepth;

                //select appropriate texture format:
                results.textureFormatInfered = GetTextureFormat(bitDepth, channels, info.Indexed);

                //create pixel array:
                await Task.Run(() => {
                    ReadSamples(reader, results);
                });
            }
            catch (System.Exception ex)
            {
                Debug.LogException(ex);
                if (results.pixels == null)
                {
                    results.width  = 2;
                    results.height = 2;
                    results.pixels = new Color[results.width * results.height];
                }
                if (results.textureFormatInfered == 0)
                {
                    results.textureFormatInfered = TextureFormat.RGBA32;
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
            }
            return(results);
        }
Exemplo n.º 2
0
        /// <summary> Create Color[] from PNG file </summary>
        public static ReadColorsResult ReadColors
        (
            string filePath
        )
        {
            ReadColorsResult results = new ReadColorsResult {
                pixels = null,
                width  = -1,
                height = -1,
                textureFormatInfered = 0
            };
            PngReader reader = null;

            try
            {
                reader = FileHelper.CreatePngReader(filePath);
                var info = reader.ImgInfo;
                results.height = info.Rows;
                results.width  = info.Cols;
                results.pixels = new Color[results.width * results.height];

                int channels = info.Channels;
                int bitDepth = info.BitDepth;
                if (info.Indexed)
                {
                    throw new System.NotImplementedException("indexed png not implemented");
                }

                //select appropriate texture format:
                results.textureFormatInfered = GetTextureFormat(bitDepth, channels);

                //create pixel array:
                for (int row = 0; row < results.height; row++)
                {
                    ImageLine imageLine = reader.ReadRowInt(row);
                    var       scanline  = imageLine.Scanline;
                    if (imageLine.SampleType == ImageLine.ESampleType.INT)
                    {
                        for (int col = 0; col < results.width; col++)
                        {
                            var color = new Color();
                            for (int ch = 0; ch < channels; ch++)
                            {
                                int   raw    = scanline[col * channels + ch];
                                float rawMax = GetBitDepthMaxValue(bitDepth);
                                float value  = (float)raw / rawMax;

                                //
                                if (ch == 0)
                                {
                                    color.r = value;
                                }
                                else if (ch == 1)
                                {
                                    color.g = value;
                                }
                                else if (ch == 2)
                                {
                                    color.b = value;
                                }
                                else if (ch == 3)
                                {
                                    color.a = value;
                                }
                                else
                                {
                                    throw new System.Exception($"channel { ch } not implemented");
                                }
                            }
                            results.pixels[IndexPngToTexture(row, col, results.height, results.width)] = color;
                        }
                    }
                    else
                    {
                        throw new System.Exception($"imageLine.SampleType { imageLine.SampleType } not implemented");
                    }
                }
            }
            catch (System.Exception ex)
            {
                Debug.LogException(ex);
                if (results.pixels == null)
                {
                    results.width  = 2;
                    results.height = 2;
                    results.pixels = new Color[results.width * results.height];
                }
                if (results.textureFormatInfered == 0)
                {
                    results.textureFormatInfered = TextureFormat.RGBA32;
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.End();
                }
            }
            return(results);
        }
        /// <summary> Reads samples using given reader </summary>
        static void ReadSamples(PngReader reader, ReadColorsResult results)
        {
            var info     = reader.ImgInfo;
            int channels = info.Channels;
            int bitDepth = info.BitDepth;
            int numCols  = results.width;
            int numRows  = results.height;

            Color[] pixels = results.pixels;
            float   max    = GetBitDepthMaxValue(bitDepth);

            if (!info.Indexed)
            {
                if (!info.Packed)
                {
                    for (int row = 0; row < numRows; row++)
                    {
                        ImageLine imageLine = reader.ReadRow(row);
                        ProcessNByteRow(imageLine, pixels);
                    }
                }
                else
                {
                    if (bitDepth == 4)
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRowByte(row);
                            Process4BitRow(imageLine, pixels);
                        }
                    }
                    else if (bitDepth == 2)
                    {
                        throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                    }
                    else if (bitDepth == 1)
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRowByte(row);
                            Process1BitRow(imageLine, pixels);
                        }
                    }
                    else
                    {
                        throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                    }
                }
            }
            else
            {
                var plte = reader.GetMetadata().GetPLTE();
                if (bitDepth == 8)
                {
                    if (info.Alpha)
                    {
                        var trns = reader.GetMetadata().GetTRNS();                        // transparency metadata, can be null
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRow(row);
                            Process8BitIndexedRow(imageLine, plte, trns, pixels);
                        }
                    }
                    else
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRow(row);
                            Process8BitIndexedRow(imageLine, plte, pixels);
                        }
                    }
                }
                else if (bitDepth == 4)
                {
                    for (int row = 0; row < numRows; row++)
                    {
                        ImageLine imageLine = reader.ReadRow(row);
                        Process4BitIndexedRow(imageLine, plte, pixels);
                    }
                }
                else
                {
                    throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                }
            }
        }