private static unsafe void GetMaskAlphaRow(int y, DecodeContext layerContext, MaskDecodeContext maskContext, ref NativeArray <byte> alphaBuffer)
        {
            if (maskContext == null)
            {
                return;
            }
            var mask = maskContext.Mask;

            // Background color for areas not covered by the mask
            byte backgroundColor = mask.InvertOnBlend
                ? (byte)(255 - mask.BackgroundColor)
                : mask.BackgroundColor;

            {
                var alphaBufferPtr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(alphaBuffer);
                UnsafeUtility.MemSet(alphaBufferPtr, backgroundColor, alphaBuffer.Length);
            }
            if (maskContext.IsRowEmpty(y))
            {
                return;
            }

            //////////////////////////////////////
            // Transfer mask into the alpha array
            var pMaskData = mask.ImageData;
            {
                // Get pointers to starting positions
                int alphaColumn = maskContext.Rectangle.X - layerContext.Rectangle.X;
                var pAlpha      = alphaColumn;
                var pAlphaEnd   = pAlpha + maskContext.Rectangle.Width;

                int maskRow      = y - mask.Rect.Y;
                int maskColumn   = maskContext.Rectangle.X - mask.Rect.X;
                int idxMaskPixel = (maskRow * mask.Rect.Width) + maskColumn;
                var pMask        = idxMaskPixel * layerContext.ByteDepth;

                // Take the high-order byte if values are 16-bit (little-endian)
                if (layerContext.ByteDepth == 2)
                {
                    pMask++;
                }

                // Decode mask into the alpha array.
                if (layerContext.ByteDepth == 4)
                {
                    DecodeMaskAlphaRow32(alphaBuffer, pAlpha, pAlphaEnd, pMaskData, pMask);
                }
                else
                {
                    DecodeMaskAlphaRow(alphaBuffer, pAlpha, pAlphaEnd, pMaskData, pMask, layerContext.ByteDepth);
                }

                // Obsolete since Photoshop CS6, but retained for compatibility with
                // older versions.  Note that the background has already been inverted.
                if (mask.InvertOnBlend)
                {
                    Util.Invert(alphaBuffer, pAlpha, pAlphaEnd);
                }
            }
        }
예제 #2
0
        ///////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Gets one row of alpha values from the mask.
        /// </summary>
        /// <param name="y">The y-coordinate of the row.</param>
        /// <param name="layerContext">The decode context for the layer containing
        ///   the mask.</param>
        /// <param name="maskContext">The decode context for the mask.</param>
        /// <returns>An array of alpha values for the row, corresponding to the
        ///   width of the layer decode context.</returns>
        unsafe private static byte[] GetMaskAlphaRow(
            int y, DecodeContext layerContext, MaskDecodeContext maskContext)
        {
            if (maskContext == null)
            {
                return(null);
            }
            var mask = maskContext.Mask;

            // Background color for areas not covered by the mask
            byte backgroundColor = mask.InvertOnBlend
        ? (byte)(255 - mask.BackgroundColor)
        : mask.BackgroundColor;

            fixed(byte *pAlpha = &maskContext.AlphaBuffer[0])
            {
                Util.Fill(pAlpha, pAlpha + maskContext.AlphaBuffer.Length,
                          backgroundColor);
            }

            if (maskContext.IsRowEmpty(y))
            {
                return(maskContext.AlphaBuffer);
            }

            //////////////////////////////////////
            // Transfer mask into the alpha array
            fixed(byte *pAlphaRow = &maskContext.AlphaBuffer[0],
                  pMaskData       = &mask.ImageData[0])
            {
                // Get pointers to starting positions
                int   alphaColumn = maskContext.Rectangle.X - layerContext.Rectangle.X;
                byte *pAlpha      = pAlphaRow + alphaColumn;
                byte *pAlphaEnd   = pAlpha + maskContext.Rectangle.Width;

                int   maskRow      = y - maskContext.Mask.Rect.Y;
                int   maskColumn   = maskContext.Rectangle.X - maskContext.Mask.Rect.X;
                int   idxMaskPixel = (maskRow * mask.Rect.Width) + maskColumn;
                byte *pMask        = pMaskData + idxMaskPixel * layerContext.ByteDepth;

                // Take the high-order byte if values are 16-bit (little-endian)
                if (layerContext.ByteDepth == 2)
                {
                    pMask++;
                }

                // Decode mask into the alpha array.
                if (layerContext.ByteDepth == 4)
                {
                    DecodeMaskAlphaRow32(pAlpha, pAlphaEnd, pMask);
                }
                else
                {
                    DecodeMaskAlphaRow(pAlpha, pAlphaEnd, pMask, layerContext.ByteDepth);
                }

                // Obsolete since Photoshop CS6, but retained for compatibility with
                // older versions.  Note that the background has already been inverted.
                if (mask.InvertOnBlend)
                {
                    Util.Invert(pAlpha, pAlphaEnd);
                }
            }

            return(maskContext.AlphaBuffer);
        }