static void Process8BitIndexedRow(ImageLine line, Chunks.PngChunkPLTE plte, Color[] pixels) { int row = line.ImageRow; ImageInfo imgInfo = line.ImgInfo; int numRows = imgInfo.Rows; int numCols = imgInfo.Cols; int bitDepth = imgInfo.BitDepth; int channels = imgInfo.Channels; // int channels = 3; float max = GetBitDepthMaxValue(bitDepth); if (line.SampleType == ImageLine.ESampleType.BYTE) { byte[] scanline = line.ScanlineB; for (int col = 0; col < numCols; col++) { int index = scanline[col] & 0xFF; RGB <int> rgb = plte.GetEntryRgb(index, col * channels); pixels[IndexPngToTexture(row, col, numRows, numCols)] = RGB.ToColor(rgb, max); } } else { int[] scanline = line.Scanline; for (int col = 0; col < numCols; col++) { int index = scanline[col]; RGB <int> rgb = plte.GetEntryRgb(index, col * channels); pixels[IndexPngToTexture(row, col, numRows, numCols)] = RGB.ToColor(rgb, max); } } }
static void Process4BitIndexedRow(ImageLine line, Chunks.PngChunkPLTE plte, Color[] pixels) { if (!line.SamplesUnpacked) { line = line.UnpackToNewImageLine(); } int row = line.ImageRow; ImageInfo info = line.ImgInfo; int numRows = info.Rows; int numCols = info.Cols; int channels = info.Channels; // int channels = 3; int numSamples = numCols * channels; int bitDepth = info.BitDepth; float max = GetBitDepthMaxValue(bitDepth); if (line.SampleType == ImageLine.ESampleType.BYTE) { byte[] scanline = line.ScanlineB; for (int col = 0; col < numCols / 2; col++) { // int index = scanline[col] & 0xFF; // RGB<int> rgb = plte.GetEntryRgb( index , col*channels ); // pixels[ IndexPngToTexture( row , col , numRows , numCols ) ] = RGB.ToColor( rgb , max ); byte B = scanline[col]; int lhsIndex = (B & 0xF0) >> 4; //Left hand nybble int rhsIndex = (B & 0x0F); //Right hand nybble RGB <int> lhsRgb = plte.GetEntryRgb(lhsIndex, col * channels); RGB <int> rhsRgb = plte.GetEntryRgb(rhsIndex, col * channels); pixels[IndexPngToTexture(row, col * 2 + 0, numRows, numCols)] = RGB.ToColor(lhsRgb, max); pixels[IndexPngToTexture(row, col * 2 + 1, numRows, numCols)] = RGB.ToColor(rhsRgb, max); } } else { throw new System.Exception($"Unpacking int not implemented for bit depth {bitDepth} & {channels} channels\n"); //TODO: 1 int will contain 16 indices I believe } }
static void Process8BitIndexedRow(ImageLine imageLine, Chunks.PngChunkPLTE plte, Chunks.PngChunkTRNS trns, Color[] pixels) { #if DEBUG UnityEngine.Assertions.Assert.IsNotNull(trns, "make sure this image contains no transparency data"); #endif int row = imageLine.ImageRow; ImageInfo imgInfo = imageLine.ImgInfo; int numRows = imgInfo.Rows; int numCols = imgInfo.Cols; int bitDepth = imgInfo.BitDepth; int channels = imgInfo.Channels;// int channels = 4; float max = GetBitDepthMaxValue(bitDepth); int[] paletteAlpha = trns.PaletteAlpha; int numIndicesWithAlpha = paletteAlpha.Length; if (imageLine.SampleType == ImageLine.ESampleType.BYTE) { byte[] scanline = imageLine.ScanlineB; for (int col = 0; col < numCols; col++) { int index = scanline[col] & 0xFF; RGB <int> rgb = plte.GetEntryRgb(index, col * channels); RGBA <int> rgba = rgb.RGBA(index < numIndicesWithAlpha ? paletteAlpha[index] : 255); pixels[IndexPngToTexture(row, col, numRows, numCols)] = RGBA.ToColor(rgba, max); } } else { int[] scanline = imageLine.Scanline; for (int col = 0; col < numCols; col++) { int index = scanline[col]; RGB <int> rgb = plte.GetEntryRgb(index, col * channels); RGBA <int> rgba = rgb.RGBA(index < numIndicesWithAlpha ? paletteAlpha[index] : 255); pixels[IndexPngToTexture(row, col, numRows, numCols)] = RGBA.ToColor(rgba, max); } } }
public static int[] Palette2rgb(ImageLine line, Chunks.PngChunkPLTE pal, int[] buf) => Palette2rgb(line, pal, null, buf);
/// <summary> Given an indexed line with a palette, unpacks as a RGB array </summary> /// <param name="line"> ImageLine as returned from PngReader </param> /// <param name="pal"> Palette chunk </param> /// <param name="trns"> TRNS chunk (optional) </param> /// <param name="buffer"> Preallocated array, optional </param> /// <returns> R G B (one byte per sample) </returns> public static int[] Palette2rgb(ImageLine line, Chunks.PngChunkPLTE pal, Chunks.PngChunkTRNS trns, int[] buffer) { int numCols = line.ImgInfo.Cols; bool isalpha = trns != null; int channels = isalpha ? 4 : 3; int nsamples = numCols * channels; if (buffer == null || buffer.Length < nsamples) { buffer = new int[nsamples]; } if (line.SamplesUnpacked == false) { line = line.UnpackToNewImageLine(); } int nindexesWithAlpha = trns != null ? trns.PaletteAlpha.Length : 0; if (line.SampleType == Pngcs.ImageLine.ESampleType.BYTE) { var scanline = line.ScanlineB; if (isalpha) { var paletteAlpha = trns.PaletteAlpha; for (int col = 0; col < numCols; col++) { int index = scanline[col] & 0xFF; pal.GetEntryRgb(index, buffer, col * channels); int alpha = index < nindexesWithAlpha ? paletteAlpha[index] : 255; buffer[col * channels + 3] = alpha; } } else { for (int col = 0; col < numCols; col++) { int index = scanline[col] & 0xFF; pal.GetEntryRgb(index, buffer, col * channels); } } } else { var scanline = line.Scanline; if (isalpha) { var paletteAlpha = trns.PaletteAlpha; for (int col = 0; col < numCols; col++) { int index = scanline[col]; pal.GetEntryRgb(index, buffer, col * channels); int alpha = index < nindexesWithAlpha ? paletteAlpha[index] : 255; buffer[col * channels + 3] = alpha; } } else { for (int col = 0; col < numCols; col++) { int index = scanline[col]; pal.GetEntryRgb(index, buffer, col * channels); } } } return(buffer); }