Layer.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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-2016 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.Generic;
  18. using System.Collections.Specialized;
  19. using System.Diagnostics;
  20. using PDNWrapper;
  21. using System.Globalization;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Threading;
  25. using Unity.Collections;
  26. using Unity.Collections.LowLevel.Unsafe;
  27. namespace PhotoshopFile
  28. {
  29. [DebuggerDisplay("Name = {Name}")]
  30. internal class Layer
  31. {
  32. internal PsdFile PsdFile { get; private set; }
  33. /// <summary>
  34. /// The rectangle containing the contents of the layer.
  35. /// </summary>
  36. public Rectangle Rect { get; set; }
  37. public bool IsGroup { get; set; }
  38. public bool IsEndGroupMarker { get; set; }
  39. public Layer ParentLayer {get; set; }
  40. // ID from Key "lyid"
  41. public int LayerID { get; set; }
  42. /// <summary>
  43. /// Image channels.
  44. /// </summary>
  45. public ChannelList Channels { get; private set; }
  46. /// <summary>
  47. /// Returns alpha channel if it exists, otherwise null.
  48. /// </summary>
  49. public Channel AlphaChannel
  50. {
  51. get
  52. {
  53. if (Channels.ContainsId(-1))
  54. return Channels.GetId(-1);
  55. else
  56. return null;
  57. }
  58. }
  59. private string blendModeKey;
  60. /// <summary>
  61. /// Photoshop blend mode key for the layer
  62. /// </summary>
  63. public string BlendModeKey
  64. {
  65. get { return blendModeKey; }
  66. set
  67. {
  68. if (value.Length != 4)
  69. {
  70. throw new ArgumentException(
  71. "BlendModeKey must be 4 characters in length.");
  72. }
  73. blendModeKey = value;
  74. }
  75. }
  76. /// <summary>
  77. /// 0 = transparent ... 255 = opaque
  78. /// </summary>
  79. public byte Opacity { get; set; }
  80. /// <summary>
  81. /// false = base, true = non-base
  82. /// </summary>
  83. public bool Clipping { get; set; }
  84. private static int protectTransBit = BitVector32.CreateMask();
  85. private static int visibleBit = BitVector32.CreateMask(protectTransBit);
  86. BitVector32 flags = new BitVector32();
  87. /// <summary>
  88. /// If true, the layer is visible.
  89. /// </summary>
  90. public bool Visible
  91. {
  92. get { return !flags[visibleBit]; }
  93. set { flags[visibleBit] = !value; }
  94. }
  95. /// <summary>
  96. /// Protect the transparency
  97. /// </summary>
  98. public bool ProtectTrans
  99. {
  100. get { return flags[protectTransBit]; }
  101. set { flags[protectTransBit] = value; }
  102. }
  103. /// <summary>
  104. /// The descriptive layer name
  105. /// </summary>
  106. public string Name { get; set; }
  107. public BlendingRanges BlendingRangesData { get; set; }
  108. public MaskInfo Masks { get; set; }
  109. public List<LayerInfo> AdditionalInfo { get; set; }
  110. ///////////////////////////////////////////////////////////////////////////
  111. public Layer(PsdFile psdFile)
  112. {
  113. PsdFile = psdFile;
  114. Rect = Rectangle.Empty;
  115. Channels = new ChannelList();
  116. BlendModeKey = PsdBlendMode.Normal;
  117. AdditionalInfo = new List<LayerInfo>();
  118. IsGroup = false;
  119. ParentLayer = null;
  120. IsEndGroupMarker = false;
  121. }
  122. public Layer(PsdBinaryReader reader, PsdFile psdFile)
  123. : this(psdFile)
  124. {
  125. Util.DebugMessage(reader.BaseStream, "Load, Begin, Layer");
  126. Rect = reader.ReadRectangle();
  127. //-----------------------------------------------------------------------
  128. // Read channel headers. Image data comes later, after the layer header.
  129. int numberOfChannels = reader.ReadUInt16();
  130. for (int channel = 0; channel < numberOfChannels; channel++)
  131. {
  132. var ch = new Channel(reader, this);
  133. Channels.Add(ch);
  134. }
  135. //-----------------------------------------------------------------------
  136. //
  137. var signature = reader.ReadAsciiChars(4);
  138. if (signature != "8BIM")
  139. throw (new PsdInvalidException("Invalid signature in layer header."));
  140. BlendModeKey = reader.ReadAsciiChars(4);
  141. Opacity = reader.ReadByte();
  142. Clipping = reader.ReadBoolean();
  143. var flagsByte = reader.ReadByte();
  144. flags = new BitVector32(flagsByte);
  145. reader.ReadByte(); //padding
  146. //-----------------------------------------------------------------------
  147. // This is the total size of the MaskData, the BlendingRangesData, the
  148. // Name and the AdjustmentLayerInfo.
  149. var extraDataSize = reader.ReadUInt32();
  150. var extraDataStartPosition = reader.BaseStream.Position;
  151. Masks = new MaskInfo(reader, this);
  152. BlendingRangesData = new BlendingRanges(reader, this);
  153. Name = reader.ReadPascalString(4);
  154. //-----------------------------------------------------------------------
  155. // Process Additional Layer Information
  156. long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize;
  157. while (reader.BaseStream.Position < adjustmentLayerEndPos)
  158. {
  159. var layerInfo = LayerInfoFactory.Load(reader, this.PsdFile, false, adjustmentLayerEndPos);
  160. AdditionalInfo.Add(layerInfo);
  161. }
  162. foreach (var adjustmentInfo in AdditionalInfo)
  163. {
  164. switch (adjustmentInfo.Key)
  165. {
  166. case "luni":
  167. Name = ((LayerUnicodeName)adjustmentInfo).Name;
  168. break;
  169. case "lyid":
  170. LayerID = ((LayerId)adjustmentInfo).ID;
  171. break;
  172. }
  173. }
  174. Util.DebugMessage(reader.BaseStream, "Load, End, Layer, {0}", Name);
  175. PsdFile.LoadContext.OnLoadLayerHeader(this);
  176. }
  177. ///////////////////////////////////////////////////////////////////////////
  178. /// <summary>
  179. /// Create ImageData for any missing channels.
  180. /// </summary>
  181. public void CreateMissingChannels()
  182. {
  183. var channelCount = this.PsdFile.ColorMode.MinChannelCount();
  184. for (short id = 0; id < channelCount; id++)
  185. {
  186. if (!this.Channels.ContainsId(id))
  187. {
  188. var size = this.Rect.Height * this.Rect.Width;
  189. var ch = new Channel(id, this);
  190. ch.ImageData = new NativeArray<byte>(size, Allocator.TempJob);
  191. unsafe
  192. {
  193. UnsafeUtility.MemSet(ch.ImageData.GetUnsafePtr(), (byte)255, size);
  194. }
  195. this.Channels.Add(ch);
  196. }
  197. }
  198. }
  199. ///////////////////////////////////////////////////////////////////////////
  200. }
  201. }