Mask.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Photoshop PSD FileType Plugin for Paint.NET
  4. // http://psdplugin.codeplex.com/
  5. //
  6. // This software is provided under the MIT License:
  7. // Copyright (c) 2006-2007 Frank Blumenberg
  8. // Copyright (c) 2010-2014 Tao Yue
  9. //
  10. // Portions of this file are provided under the BSD 3-clause License:
  11. // Copyright (c) 2006, Jonas Beckeman
  12. //
  13. // See LICENSE.txt for complete licensing and attribution information.
  14. //
  15. /////////////////////////////////////////////////////////////////////////////////
  16. using System;
  17. using System.Collections.Specialized;
  18. using System.Diagnostics;
  19. using PDNWrapper;
  20. using System.Globalization;
  21. using Unity.Collections;
  22. namespace PhotoshopFile
  23. {
  24. internal class Mask
  25. {
  26. /// <summary>
  27. /// The layer to which this mask belongs
  28. /// </summary>
  29. public Layer Layer { get; private set; }
  30. /// <summary>
  31. /// The rectangle enclosing the mask.
  32. /// </summary>
  33. public Rectangle Rect { get; set; }
  34. private byte backgroundColor;
  35. public byte BackgroundColor
  36. {
  37. get { return backgroundColor; }
  38. set
  39. {
  40. if ((value != 0) && (value != 255))
  41. throw new PsdInvalidException("Mask background must be fully-opaque or fully-transparent.");
  42. backgroundColor = value;
  43. }
  44. }
  45. private static int positionVsLayerBit = BitVector32.CreateMask();
  46. private static int disabledBit = BitVector32.CreateMask(positionVsLayerBit);
  47. private static int invertOnBlendBit = BitVector32.CreateMask(disabledBit);
  48. private BitVector32 flags;
  49. public BitVector32 Flags { get { return flags; } }
  50. /// <summary>
  51. /// If true, the position of the mask is relative to the layer.
  52. /// </summary>
  53. public bool PositionVsLayer
  54. {
  55. get { return flags[positionVsLayerBit]; }
  56. set { flags[positionVsLayerBit] = value; }
  57. }
  58. public bool Disabled
  59. {
  60. get { return flags[disabledBit]; }
  61. set { flags[disabledBit] = value; }
  62. }
  63. /// <summary>
  64. /// if true, invert the mask when blending.
  65. /// </summary>
  66. public bool InvertOnBlend
  67. {
  68. get { return flags[invertOnBlendBit]; }
  69. set { flags[invertOnBlendBit] = value; }
  70. }
  71. /// <summary>
  72. /// Mask image data.
  73. /// </summary>
  74. public NativeArray<byte> ImageData { get; set; }
  75. public Mask(Layer layer)
  76. {
  77. Layer = layer;
  78. this.flags = new BitVector32();
  79. }
  80. public Mask(Layer layer, Rectangle rect, byte color, BitVector32 flags)
  81. {
  82. Layer = layer;
  83. Rect = rect;
  84. BackgroundColor = color;
  85. this.flags = flags;
  86. }
  87. }
  88. /// <summary>
  89. /// Mask info for a layer. Contains both the layer and user masks.
  90. /// </summary>
  91. internal class MaskInfo
  92. {
  93. public Mask LayerMask { get; set; }
  94. public Mask UserMask { get; set; }
  95. /// <summary>
  96. /// Construct MaskInfo with null masks.
  97. /// </summary>
  98. public MaskInfo()
  99. {
  100. }
  101. public MaskInfo(PsdBinaryReader reader, Layer layer)
  102. {
  103. Util.DebugMessage(reader.BaseStream, "Load, Begin, MaskInfo");
  104. var maskLength = reader.ReadUInt32();
  105. if (maskLength <= 0)
  106. return;
  107. var startPosition = reader.BaseStream.Position;
  108. var endPosition = startPosition + maskLength;
  109. // Read layer mask
  110. var rectangle = reader.ReadRectangle();
  111. var backgroundColor = reader.ReadByte();
  112. var flagsByte = reader.ReadByte();
  113. LayerMask = new Mask(layer, rectangle, backgroundColor, new BitVector32(flagsByte));
  114. // User mask is supplied separately when there is also a vector mask.
  115. if (maskLength == 36)
  116. {
  117. var userFlagsByte = reader.ReadByte();
  118. var userBackgroundColor = reader.ReadByte();
  119. var userRectangle = reader.ReadRectangle();
  120. UserMask = new Mask(layer, userRectangle, userBackgroundColor, new BitVector32(userFlagsByte));
  121. }
  122. // 20-byte mask data will end with padding.
  123. reader.BaseStream.Position = endPosition;
  124. Util.DebugMessage(reader.BaseStream, "Load, End, MaskInfo");
  125. }
  126. }
  127. }