private static byte[] EncodeIndexedBitmap(ParseContext context, BitmapEncoding encoding, Dialect dialect, IcoFrame source) { var numBits = BmpUtil.GetBitDepthForPixelFormat(encoding); var colorTable = BuildColorTable(1u << numBits, context, source); if (colorTable == null) { context.LastEncodeError = IcoErrorCode.TooManyColorsForBitDepth; return(null); } var writer = new ByteWriter(ByteOrder.LittleEndian); EncodeBitmapHeader(source, dialect, encoding, colorTable, writer, out var offsetToImageSize); var reverseTable = new Dictionary <Rgba32, int>(); for (var i = 0; i < colorTable.Length; i++) { if (!reverseTable.ContainsKey(colorTable[i])) { reverseTable.Add(colorTable[i], i); } } var offsetToData = (uint)writer.Data.Count; var padding = writer.Data.Count % 4; for (var y = source.CookedData.Height - 1; y >= 0; y--) { var bits = new BitWriter(writer); for (var x = 0; x < source.CookedData.Width; x++) { var color = source.CookedData[x, y]; if (source.Mask[x, y]) { switch (context.MaskedImagePixelEmitOptions) { case StrictnessPolicy.Compliant: color = new Rgba32(0, 0, 0, 255); break; case StrictnessPolicy.PreserveSource: // Pass through whatever the original pixel was. break; case StrictnessPolicy.Loose: color = colorTable.First(); break; } } color.A = 255; var index = reverseTable[color]; bits.AddBits((uint)numBits, (byte)index); } while ((writer.Data.Count % 4) != padding) { writer.AddUint8(0); } } return(FinalizeBitmap(source, encoding, dialect, writer, offsetToData, offsetToImageSize)); }