Пример #1
0
        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));
        }