/// <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); }
/// <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"); } } }