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