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); } } }
/////////////////////////////////////////////////////////////////////////// /// <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); }