Ejemplo n.º 1
0
        public void ExtractPalettedAlphaRows(int lastRow)
        {
            // For vertical and gradient filtering, we need to decode the part above the
            // cropTop row, in order to have the correct spatial predictors.
            int topRow   = this.AlphaFilterType is WebpAlphaFilterType.None or WebpAlphaFilterType.Horizontal ? 0 : this.LastRow;
            int firstRow = this.LastRow < topRow ? topRow : this.LastRow;

            if (lastRow > firstRow)
            {
                // Special method for paletted alpha data.
                Span <byte> output           = this.Alpha.Memory.Span;
                Span <uint> pixelData        = this.Vp8LDec.Pixels.Memory.Span;
                Span <byte> pixelDataAsBytes = MemoryMarshal.Cast <uint, byte>(pixelData);
                Span <byte> dst   = output.Slice(this.Width * firstRow);
                Span <byte> input = pixelDataAsBytes.Slice(this.Vp8LDec.Width * firstRow);

                if (this.Vp8LDec.Transforms.Count == 0 || this.Vp8LDec.Transforms[0].TransformType != Vp8LTransformType.ColorIndexingTransform)
                {
                    WebpThrowHelper.ThrowImageFormatException("error while decoding alpha channel, expected color index transform data is missing");
                }

                Vp8LTransform transform = this.Vp8LDec.Transforms[0];
                ColorIndexInverseTransformAlpha(transform, firstRow, lastRow, input, dst);
                this.AlphaApplyFilter(firstRow, lastRow, dst, this.Width);
            }

            this.LastRow = lastRow;
        }
Ejemplo n.º 2
0
        private static void ColorIndexInverseTransformAlpha(
            Vp8LTransform transform,
            int yStart,
            int yEnd,
            Span <byte> src,
            Span <byte> dst)
        {
            int         bitsPerPixel = 8 >> transform.Bits;
            int         width        = transform.XSize;
            Span <uint> colorMap     = transform.Data.Memory.Span;

            if (bitsPerPixel < 8)
            {
                int srcOffset     = 0;
                int dstOffset     = 0;
                int pixelsPerByte = 1 << transform.Bits;
                int countMask     = pixelsPerByte - 1;
                int bitMask       = (1 << bitsPerPixel) - 1;
                for (int y = yStart; y < yEnd; y++)
                {
                    int packedPixels = 0;
                    for (int x = 0; x < width; x++)
                    {
                        if ((x & countMask) == 0)
                        {
                            packedPixels = src[srcOffset];
                            srcOffset++;
                        }

                        dst[dstOffset] = GetAlphaValue((int)colorMap[packedPixels & bitMask]);
                        dstOffset++;
                        packedPixels >>= bitsPerPixel;
                    }
                }
            }
            else
            {
                MapAlpha(src, colorMap, dst, yStart, yEnd, width);
            }
        }