/// <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="buf">Preallocated array, optional</param> /// <returns>R G B (one byte per sample)</returns> public static int[] Palette2rgb(ImageLine line, PngChunkPLTE pal, PngChunkTRNS trns, int[] buf) { if (line is null) { throw new ArgumentNullException(nameof(line)); } if (pal is null) { throw new ArgumentNullException(nameof(pal)); } var isalpha = trns is object; var channels = isalpha ? 4 : 3; var nsamples = line.ImgInfo.Cols * channels; if (buf is null || buf.Length < nsamples) { buf = new int[nsamples]; } if (!line.SamplesUnpacked) { line = line.UnpackToNewImageLine(); } var isbyte = line.SampleType == Hjg.Pngcs.ImageLine.ESampleType.BYTE; var nindexesWithAlpha = trns?.GetPalletteAlpha().Length ?? 0; for (var c = 0; c < line.ImgInfo.Cols; c++) { var index = isbyte ? (line.ScanlineB[c] & 0xFF) : line.Scanline[c]; pal.GetEntryRgb(index, buf, c * channels); if (isalpha) { buf[(c * channels) + 3] = index < nindexesWithAlpha?trns.GetPalletteAlpha()[index] : 255; } } return(buf); }