/Platters/classes/photoshop/Layer.cs

http://skimpt.googlecode.com/ · C# · 968 lines · 592 code · 212 blank · 164 comment · 36 complexity · 0f1c85b34ef98cbbeeab9424e61d17d7 MD5 · raw file

  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 2006, Frank Blumenberg
  3. //
  4. // See License.txt for complete licensing and attribution information.
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. /////////////////////////////////////////////////////////////////////////////////
  24. /////////////////////////////////////////////////////////////////////////////////
  25. //
  26. // This code contains code from the Endogine sprite engine by Jonas Beckeman.
  27. // http://www.endogine.com/CS/
  28. //
  29. /////////////////////////////////////////////////////////////////////////////////
  30. using System;
  31. using System.Collections.Generic;
  32. using System.Collections.Specialized;
  33. using System.Text;
  34. using System.Drawing;
  35. using System.IO;
  36. using System.Diagnostics;
  37. namespace Photoshop
  38. {
  39. public class Layer
  40. {
  41. ///////////////////////////////////////////////////////////////////////////
  42. public class Channel
  43. {
  44. private Layer m_layer;
  45. /// <summary>
  46. /// The layer to which this channel belongs
  47. /// </summary>
  48. public Layer Layer
  49. {
  50. get { return m_layer; }
  51. }
  52. private short m_id;
  53. /// <summary>
  54. /// 0 = red, 1 = green, etc.
  55. /// &#x2013;1 = transparency mask
  56. /// &#x2013;2 = user supplied layer mask
  57. /// </summary>
  58. public short ID
  59. {
  60. get { return m_id; }
  61. set { m_id = value; }
  62. }
  63. /// <summary>
  64. /// The length of the compressed channel data.
  65. /// </summary>
  66. public int Length;
  67. private byte[] m_data;
  68. /// <summary>
  69. /// The compressed raw channel data
  70. /// </summary>
  71. public byte[] Data
  72. {
  73. get { return m_data; }
  74. set { m_data = value; }
  75. }
  76. /// <summary>
  77. /// The raw image data from the channel.
  78. /// </summary>
  79. public byte[] m_imageData;
  80. public byte[] ImageData
  81. {
  82. get { return m_imageData; }
  83. set { m_imageData = value; }
  84. }
  85. private ImageCompression m_imageCompression;
  86. public ImageCompression ImageCompression
  87. {
  88. get { return m_imageCompression; }
  89. set { m_imageCompression = value; }
  90. }
  91. //////////////////////////////////////////////////////////////////
  92. internal Channel(short id, Layer layer)
  93. {
  94. m_id = id;
  95. m_layer = layer;
  96. m_layer.Channels.Add(this);
  97. m_layer.SortedChannels.Add(this.ID, this);
  98. }
  99. internal Channel(BinaryReverseReader reader, Layer layer)
  100. {
  101. Debug.WriteLine("Channel started at " + reader.BaseStream.Position.ToString());
  102. m_id = reader.ReadInt16();
  103. Length = reader.ReadInt32();
  104. m_layer = layer;
  105. }
  106. internal void Save(BinaryReverseWriter writer)
  107. {
  108. Debug.WriteLine("Channel Save started at " + writer.BaseStream.Position.ToString());
  109. writer.Write(m_id);
  110. CompressImageData();
  111. writer.Write(Data.Length+2); // 2 bytes for the image compression
  112. }
  113. //////////////////////////////////////////////////////////////////
  114. internal void LoadPixelData(BinaryReverseReader reader)
  115. {
  116. Debug.WriteLine("Channel.LoadPixelData started at " + reader.BaseStream.Position.ToString());
  117. m_data = reader.ReadBytes((int)Length);
  118. using (BinaryReverseReader readerImg = DataReader)
  119. {
  120. m_imageCompression = (ImageCompression)readerImg.ReadInt16();
  121. int bytesPerRow = 0;
  122. switch (m_layer.PsdFile.Depth)
  123. {
  124. case 1:
  125. bytesPerRow = m_layer.m_rect.Width;//NOT Shure
  126. break;
  127. case 8:
  128. bytesPerRow = m_layer.m_rect.Width;
  129. break;
  130. case 16:
  131. bytesPerRow = m_layer.m_rect.Width * 2;
  132. break;
  133. }
  134. m_imageData = new byte[m_layer.m_rect.Height * bytesPerRow];
  135. switch (m_imageCompression)
  136. {
  137. case ImageCompression.Raw:
  138. readerImg.Read(m_imageData, 0, m_imageData.Length);
  139. break;
  140. case ImageCompression.Rle:
  141. {
  142. int[] rowLenghtList = new int[m_layer.m_rect.Height];
  143. for (int i = 0; i < rowLenghtList.Length; i++)
  144. rowLenghtList[i] = readerImg.ReadInt16();
  145. for (int i = 0; i < m_layer.m_rect.Height; i++)
  146. {
  147. int rowIndex = i * m_layer.m_rect.Width;
  148. RleHelper.DecodedRow(readerImg.BaseStream, m_imageData, rowIndex, bytesPerRow);
  149. //if (rowLenghtList[i] % 2 == 1)
  150. // readerImg.ReadByte();
  151. }
  152. }
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. }
  159. private void CompressImageData()
  160. {
  161. if (m_imageCompression == ImageCompression.Rle)
  162. {
  163. MemoryStream dataStream = new MemoryStream();
  164. BinaryReverseWriter writer = new BinaryReverseWriter(dataStream);
  165. // we will write the correct lengths later, so remember
  166. // the position
  167. long lengthPosition = writer.BaseStream.Position;
  168. int[] rleRowLenghs = new int[m_layer.m_rect.Height];
  169. if (m_imageCompression == ImageCompression.Rle)
  170. {
  171. for (int i = 0; i < rleRowLenghs.Length; i++)
  172. {
  173. writer.Write((short)0x1234);
  174. }
  175. }
  176. //---------------------------------------------------------------
  177. int bytesPerRow = 0;
  178. switch (m_layer.PsdFile.Depth)
  179. {
  180. case 1:
  181. bytesPerRow = m_layer.m_rect.Width;//NOT Shure
  182. break;
  183. case 8:
  184. bytesPerRow = m_layer.m_rect.Width;
  185. break;
  186. case 16:
  187. bytesPerRow = m_layer.m_rect.Width * 2;
  188. break;
  189. }
  190. //---------------------------------------------------------------
  191. for (int row = 0; row < m_layer.m_rect.Height; row++)
  192. {
  193. int rowIndex = row * m_layer.m_rect.Width;
  194. rleRowLenghs[row] = RleHelper.EncodedRow(writer.BaseStream, m_imageData, rowIndex, bytesPerRow);
  195. }
  196. //---------------------------------------------------------------
  197. long endPosition = writer.BaseStream.Position;
  198. writer.BaseStream.Position = lengthPosition;
  199. for (int i = 0; i < rleRowLenghs.Length; i++)
  200. {
  201. writer.Write((short)rleRowLenghs[i]);
  202. }
  203. writer.BaseStream.Position = endPosition;
  204. dataStream.Close();
  205. m_data = dataStream.ToArray();
  206. dataStream.Dispose();
  207. }
  208. else
  209. {
  210. m_data = (byte[])m_imageData.Clone();
  211. }
  212. }
  213. internal void SavePixelData(BinaryReverseWriter writer)
  214. {
  215. Debug.WriteLine("Channel SavePixelData started at " + writer.BaseStream.Position.ToString());
  216. writer.Write((short)m_imageCompression);
  217. writer.Write(m_imageData);
  218. }
  219. //////////////////////////////////////////////////////////////////
  220. public BinaryReverseReader DataReader
  221. {
  222. get
  223. {
  224. if (m_data == null)
  225. return null;
  226. return new BinaryReverseReader(new System.IO.MemoryStream(this.m_data));
  227. }
  228. }
  229. }
  230. ///////////////////////////////////////////////////////////////////////////
  231. public class Mask
  232. {
  233. private Layer m_layer;
  234. /// <summary>
  235. /// The layer to which this mask belongs
  236. /// </summary>
  237. public Layer Layer
  238. {
  239. get { return m_layer; }
  240. }
  241. private Rectangle m_rect = Rectangle.Empty;
  242. /// <summary>
  243. /// The rectangle enclosing the mask.
  244. /// </summary>
  245. public Rectangle Rect
  246. {
  247. get { return m_rect; }
  248. set { m_rect = value; }
  249. }
  250. private byte m_defaultColor;
  251. public byte DefaultColor
  252. {
  253. get { return m_defaultColor; }
  254. set { m_defaultColor = value; }
  255. }
  256. private static int m_positionIsRelativeBit = BitVector32.CreateMask();
  257. private static int m_disabledBit = BitVector32.CreateMask(m_positionIsRelativeBit);
  258. private static int m_invertOnBlendBit = BitVector32.CreateMask(m_disabledBit);
  259. private BitVector32 m_flags = new BitVector32();
  260. /// <summary>
  261. /// If true, the position of the mask is relative to the layer.
  262. /// </summary>
  263. public bool PositionIsRelative
  264. {
  265. get
  266. {
  267. return m_flags[m_positionIsRelativeBit];
  268. }
  269. set
  270. {
  271. m_flags[m_positionIsRelativeBit] = value;
  272. }
  273. }
  274. public bool Disabled
  275. {
  276. get { return m_flags[m_disabledBit]; }
  277. set { m_flags[m_disabledBit] = value; }
  278. }
  279. /// <summary>
  280. /// if true, invert the mask when blending.
  281. /// </summary>
  282. public bool InvertOnBlendBit
  283. {
  284. get { return m_flags[m_invertOnBlendBit]; }
  285. set { m_flags[m_invertOnBlendBit] = value; }
  286. }
  287. ///////////////////////////////////////////////////////////////////////////
  288. internal Mask(Layer layer)
  289. {
  290. m_layer = layer;
  291. m_layer.MaskData = this;
  292. }
  293. ///////////////////////////////////////////////////////////////////////////
  294. internal Mask(BinaryReverseReader reader, Layer layer)
  295. {
  296. Debug.WriteLine("Mask started at " + reader.BaseStream.Position.ToString());
  297. m_layer = layer;
  298. uint maskLength = reader.ReadUInt32();
  299. if (maskLength <= 0)
  300. return;
  301. long startPosition = reader.BaseStream.Position;
  302. //-----------------------------------------------------------------------
  303. m_rect = new Rectangle();
  304. m_rect.Y = reader.ReadInt32();
  305. m_rect.X = reader.ReadInt32();
  306. m_rect.Height = reader.ReadInt32() - m_rect.Y;
  307. m_rect.Width = reader.ReadInt32() - m_rect.X;
  308. m_defaultColor = reader.ReadByte();
  309. //-----------------------------------------------------------------------
  310. byte flags = reader.ReadByte();
  311. m_flags = new BitVector32(flags);
  312. //-----------------------------------------------------------------------
  313. if (maskLength == 36)
  314. {
  315. BitVector32 realFlags = new BitVector32(reader.ReadByte());
  316. byte realUserMaskBackground = reader.ReadByte();
  317. Rectangle rect = new Rectangle();
  318. rect.Y = reader.ReadInt32();
  319. rect.X = reader.ReadInt32();
  320. rect.Height = reader.ReadInt32() - m_rect.Y;
  321. rect.Width = reader.ReadInt32() - m_rect.X;
  322. }
  323. // there is other stuff following, but we will ignore this.
  324. reader.BaseStream.Position = startPosition + maskLength;
  325. }
  326. ///////////////////////////////////////////////////////////////////////////
  327. public void Save(BinaryReverseWriter writer)
  328. {
  329. Debug.WriteLine("Mask Save started at " + writer.BaseStream.Position.ToString());
  330. if (m_rect.IsEmpty)
  331. {
  332. writer.Write((uint)0);
  333. return;
  334. }
  335. using (new LengthWriter(writer))
  336. {
  337. writer.Write(m_rect.Top);
  338. writer.Write(m_rect.Left);
  339. writer.Write(m_rect.Bottom);
  340. writer.Write(m_rect.Right);
  341. writer.Write(m_defaultColor);
  342. writer.Write((byte)m_flags.Data);
  343. // padding 2 bytes so that size is 20
  344. writer.Write((int)0);
  345. }
  346. }
  347. //////////////////////////////////////////////////////////////////
  348. /// <summary>
  349. /// The raw image data from the channel.
  350. /// </summary>
  351. public byte[] m_imageData;
  352. public byte[] ImageData
  353. {
  354. get { return m_imageData; }
  355. set { m_imageData = value; }
  356. }
  357. internal void LoadPixelData(BinaryReverseReader reader)
  358. {
  359. Debug.WriteLine("Mask.LoadPixelData started at " + reader.BaseStream.Position.ToString());
  360. if (m_rect.IsEmpty || m_layer.SortedChannels.ContainsKey(-2) == false)
  361. return;
  362. Channel maskChannel = m_layer.SortedChannels[-2];
  363. maskChannel.Data = reader.ReadBytes((int)maskChannel.Length);
  364. using (BinaryReverseReader readerImg = maskChannel.DataReader)
  365. {
  366. maskChannel.ImageCompression = (ImageCompression)readerImg.ReadInt16();
  367. int bytesPerRow = 0;
  368. switch (m_layer.PsdFile.Depth)
  369. {
  370. case 1:
  371. bytesPerRow = m_rect.Width;//NOT Shure
  372. break;
  373. case 8:
  374. bytesPerRow = m_rect.Width;
  375. break;
  376. case 16:
  377. bytesPerRow = m_rect.Width * 2;
  378. break;
  379. }
  380. maskChannel.ImageData = new byte[m_rect.Height * bytesPerRow];
  381. // Fill Array
  382. for (int i = 0; i < maskChannel.ImageData.Length; i++)
  383. {
  384. maskChannel.ImageData[i] = 0xAB;
  385. }
  386. m_imageData = (byte[])maskChannel.ImageData.Clone();
  387. switch (maskChannel.ImageCompression)
  388. {
  389. case ImageCompression.Raw:
  390. readerImg.Read(maskChannel.ImageData, 0, maskChannel.ImageData.Length);
  391. break;
  392. case ImageCompression.Rle:
  393. {
  394. int[] rowLenghtList = new int[m_rect.Height];
  395. for (int i = 0; i < rowLenghtList.Length; i++)
  396. rowLenghtList[i] = readerImg.ReadInt16();
  397. for (int i = 0; i < m_rect.Height; i++)
  398. {
  399. int rowIndex = i * m_rect.Width;
  400. RleHelper.DecodedRow(readerImg.BaseStream, maskChannel.ImageData, rowIndex, bytesPerRow);
  401. }
  402. }
  403. break;
  404. default:
  405. break;
  406. }
  407. m_imageData = (byte[])maskChannel.ImageData.Clone();
  408. }
  409. }
  410. internal void SavePixelData(BinaryReverseWriter writer)
  411. {
  412. //writer.Write(m_data);
  413. }
  414. ///////////////////////////////////////////////////////////////////////////
  415. }
  416. ///////////////////////////////////////////////////////////////////////////
  417. public class BlendingRanges
  418. {
  419. private Layer m_layer;
  420. /// <summary>
  421. /// The layer to which this channel belongs
  422. /// </summary>
  423. public Layer Layer
  424. {
  425. get { return m_layer; }
  426. }
  427. private byte[] m_data = new byte[0];
  428. public byte[] Data
  429. {
  430. get { return m_data; }
  431. set { m_data = value; }
  432. }
  433. ///////////////////////////////////////////////////////////////////////////
  434. public BlendingRanges(Layer layer)
  435. {
  436. m_layer = layer;
  437. m_layer.BlendingRangesData = this;
  438. }
  439. ///////////////////////////////////////////////////////////////////////////
  440. public BlendingRanges(BinaryReverseReader reader, Layer layer)
  441. {
  442. Debug.WriteLine("BlendingRanges started at " + reader.BaseStream.Position.ToString());
  443. m_layer = layer;
  444. int dataLength = reader.ReadInt32();
  445. if (dataLength <= 0)
  446. return;
  447. m_data = reader.ReadBytes(dataLength);
  448. }
  449. ///////////////////////////////////////////////////////////////////////////
  450. public void Save(BinaryReverseWriter writer)
  451. {
  452. Debug.WriteLine("BlendingRanges Save started at " + writer.BaseStream.Position.ToString());
  453. writer.Write((uint)m_data.Length);
  454. writer.Write(m_data);
  455. }
  456. }
  457. ///////////////////////////////////////////////////////////////////////////
  458. public class AdjusmentLayerInfo
  459. {
  460. private Layer m_layer;
  461. /// <summary>
  462. /// The layer to which this info belongs
  463. /// </summary>
  464. internal Layer Layer
  465. {
  466. get { return m_layer; }
  467. }
  468. private string m_key;
  469. public string Key
  470. {
  471. get { return m_key; }
  472. set { m_key = value; }
  473. }
  474. private byte[] m_data;
  475. public byte[] Data
  476. {
  477. get { return m_data; }
  478. set { m_data = value; }
  479. }
  480. public AdjusmentLayerInfo(string key, Layer layer)
  481. {
  482. m_key = key;
  483. m_layer = layer;
  484. m_layer.AdjustmentInfo.Add(this);
  485. }
  486. public AdjusmentLayerInfo(BinaryReverseReader reader, Layer layer)
  487. {
  488. Debug.WriteLine("AdjusmentLayerInfo started at " + reader.BaseStream.Position.ToString());
  489. m_layer = layer;
  490. string signature = new string(reader.ReadChars(4));
  491. if (signature != "8BIM")
  492. {
  493. throw new IOException("Could not read an image resource");
  494. }
  495. m_key = new string(reader.ReadChars(4));
  496. uint dataLength = reader.ReadUInt32();
  497. m_data = reader.ReadBytes((int)dataLength);
  498. }
  499. public void Save(BinaryReverseWriter writer)
  500. {
  501. Debug.WriteLine("AdjusmentLayerInfo Save started at " + writer.BaseStream.Position.ToString());
  502. string signature = "8BIM";
  503. writer.Write(signature.ToCharArray());
  504. writer.Write(m_key.ToCharArray());
  505. writer.Write((uint)m_data.Length);
  506. writer.Write(m_data);
  507. }
  508. //////////////////////////////////////////////////////////////////
  509. public BinaryReverseReader DataReader
  510. {
  511. get
  512. {
  513. return new BinaryReverseReader(new System.IO.MemoryStream(this.m_data));
  514. }
  515. }
  516. }
  517. ///////////////////////////////////////////////////////////////////////////
  518. private PsdFile m_psdFile;
  519. internal PsdFile PsdFile
  520. {
  521. get { return m_psdFile; }
  522. }
  523. private Rectangle m_rect = Rectangle.Empty;
  524. /// <summary>
  525. /// The rectangle containing the contents of the layer.
  526. /// </summary>
  527. public Rectangle Rect
  528. {
  529. get { return m_rect; }
  530. set { m_rect = value; }
  531. }
  532. /// <summary>
  533. /// Channel information.
  534. /// </summary>
  535. private List<Channel> m_channels = new List<Channel>();
  536. public List<Channel> Channels
  537. {
  538. get { return m_channels; }
  539. }
  540. private SortedList<short, Channel> m_sortedChannels = new SortedList<short, Channel>();
  541. public SortedList<short, Channel> SortedChannels
  542. {
  543. get
  544. {
  545. return m_sortedChannels;
  546. }
  547. }
  548. private string m_blendModeKey="norm";
  549. /// <summary>
  550. /// The blend mode key for the layer
  551. /// </summary>
  552. /// <remarks>
  553. /// <list type="table">
  554. /// </item>
  555. /// <term>norm</term><description>normal</description>
  556. /// <term>dark</term><description>darken</description>
  557. /// <term>lite</term><description>lighten</description>
  558. /// <term>hue </term><description>hue</description>
  559. /// <term>sat </term><description>saturation</description>
  560. /// <term>colr</term><description>color</description>
  561. /// <term>lum </term><description>luminosity</description>
  562. /// <term>mul </term><description>multiply</description>
  563. /// <term>scrn</term><description>screen</description>
  564. /// <term>diss</term><description>dissolve</description>
  565. /// <term>over</term><description>overlay</description>
  566. /// <term>hLit</term><description>hard light</description>
  567. /// <term>sLit</term><description>soft light</description>
  568. /// <term>diff</term><description>difference</description>
  569. /// <term>smud</term><description>exlusion</description>
  570. /// <term>div </term><description>color dodge</description>
  571. /// <term>idiv</term><description>color burn</description>
  572. /// </list>
  573. /// </remarks>
  574. public string BlendModeKey
  575. {
  576. get { return m_blendModeKey; }
  577. set
  578. {
  579. if (value.Length != 4) throw new ArgumentException("Key length must be 4");
  580. }
  581. }
  582. private byte m_opacity;
  583. /// <summary>
  584. /// 0 = transparent ... 255 = opaque
  585. /// </summary>
  586. public byte Opacity
  587. {
  588. get { return m_opacity; }
  589. set { m_opacity = value; }
  590. }
  591. private bool m_clipping;
  592. /// <summary>
  593. /// false = base, true = non&#x2013;base
  594. /// </summary>
  595. public bool Clipping
  596. {
  597. get { return m_clipping; }
  598. set { m_clipping = value; }
  599. }
  600. private static int m_protectTransBit = BitVector32.CreateMask();
  601. private static int m_visibleBit = BitVector32.CreateMask(m_protectTransBit);
  602. BitVector32 m_flags = new BitVector32();
  603. /// <summary>
  604. /// If true, the layer is visible.
  605. /// </summary>
  606. public bool Visible
  607. {
  608. get { return !m_flags[m_visibleBit]; }
  609. set { m_flags[m_visibleBit] = !value; }
  610. }
  611. /// <summary>
  612. /// Protect the transparency
  613. /// </summary>
  614. public bool ProtectTrans
  615. {
  616. get { return m_flags[m_protectTransBit]; }
  617. set { m_flags[m_protectTransBit] = value; }
  618. }
  619. private string m_name;
  620. /// <summary>
  621. /// The descriptive layer name
  622. /// </summary>
  623. public string Name
  624. {
  625. get { return m_name; }
  626. set { m_name = value; }
  627. }
  628. private BlendingRanges m_blendingRangesData;
  629. public Layer.BlendingRanges BlendingRangesData
  630. {
  631. get { return m_blendingRangesData; }
  632. set { m_blendingRangesData = value; }
  633. }
  634. private Mask m_maskData;
  635. public Layer.Mask MaskData
  636. {
  637. get { return m_maskData; }
  638. set { m_maskData = value; }
  639. }
  640. private List<AdjusmentLayerInfo> m_adjustmentInfo = new List<AdjusmentLayerInfo>();
  641. public List<Layer.AdjusmentLayerInfo> AdjustmentInfo
  642. {
  643. get { return m_adjustmentInfo; }
  644. set { m_adjustmentInfo = value; }
  645. }
  646. ///////////////////////////////////////////////////////////////////////////
  647. public Layer(PsdFile psdFile)
  648. {
  649. m_psdFile = psdFile;
  650. m_psdFile.Layers.Add(this);
  651. }
  652. public Layer(BinaryReverseReader reader, PsdFile psdFile)
  653. {
  654. Debug.WriteLine("Layer started at " + reader.BaseStream.Position.ToString());
  655. m_psdFile = psdFile;
  656. m_rect = new Rectangle();
  657. m_rect.Y = reader.ReadInt32();
  658. m_rect.X = reader.ReadInt32();
  659. m_rect.Height = reader.ReadInt32() - m_rect.Y;
  660. m_rect.Width = reader.ReadInt32() - m_rect.X;
  661. //-----------------------------------------------------------------------
  662. int numberOfChannels = reader.ReadUInt16();
  663. this.m_channels.Clear();
  664. for (int channel = 0; channel < numberOfChannels; channel++)
  665. {
  666. Channel ch = new Channel(reader, this);
  667. m_channels.Add(ch);
  668. m_sortedChannels.Add(ch.ID, ch);
  669. }
  670. //-----------------------------------------------------------------------
  671. string signature = new string(reader.ReadChars(4));
  672. if (signature != "8BIM")
  673. throw (new IOException("Layer Channelheader error!"));
  674. m_blendModeKey = new string(reader.ReadChars(4));
  675. m_opacity = reader.ReadByte();
  676. m_clipping = reader.ReadByte() > 0;
  677. //-----------------------------------------------------------------------
  678. byte flags = reader.ReadByte();
  679. m_flags = new BitVector32(flags);
  680. //-----------------------------------------------------------------------
  681. reader.ReadByte(); //padding
  682. //-----------------------------------------------------------------------
  683. Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position.ToString());
  684. // this is the total size of the MaskData, the BlendingRangesData, the
  685. // Name and the AdjustmenLayerInfo
  686. uint extraDataSize = reader.ReadUInt32();
  687. // remember the start position for calculation of the
  688. // AdjustmenLayerInfo size
  689. long extraDataStartPosition = reader.BaseStream.Position;
  690. m_maskData = new Mask(reader, this);
  691. m_blendingRangesData = new BlendingRanges(reader, this);
  692. //-----------------------------------------------------------------------
  693. long namePosition = reader.BaseStream.Position;
  694. m_name = reader.ReadPascalString();
  695. int paddingBytes =(int)((reader.BaseStream.Position - namePosition) % 4);
  696. Debug.Print("Layer {0} padding bytes after name", paddingBytes);
  697. reader.ReadBytes(paddingBytes);
  698. //-----------------------------------------------------------------------
  699. m_adjustmentInfo.Clear();
  700. long adjustmenLayerEndPos = extraDataStartPosition + extraDataSize;
  701. while (reader.BaseStream.Position < adjustmenLayerEndPos)
  702. {
  703. try
  704. {
  705. m_adjustmentInfo.Add(new AdjusmentLayerInfo(reader, this));
  706. }
  707. catch
  708. {
  709. reader.BaseStream.Position = adjustmenLayerEndPos;
  710. }
  711. }
  712. //-----------------------------------------------------------------------
  713. // make shure we are not on a wrong offset, so set the stream position
  714. // manually
  715. reader.BaseStream.Position = adjustmenLayerEndPos;
  716. }
  717. ///////////////////////////////////////////////////////////////////////////
  718. public void Save(BinaryReverseWriter writer)
  719. {
  720. Debug.WriteLine("Layer Save started at " + writer.BaseStream.Position.ToString());
  721. writer.Write(m_rect.Top);
  722. writer.Write(m_rect.Left);
  723. writer.Write(m_rect.Bottom);
  724. writer.Write(m_rect.Right);
  725. //-----------------------------------------------------------------------
  726. writer.Write((short)m_channels.Count);
  727. foreach (Channel ch in m_channels)
  728. ch.Save(writer);
  729. //-----------------------------------------------------------------------
  730. string signature = "8BIM";
  731. writer.Write(signature.ToCharArray());
  732. writer.Write(m_blendModeKey.ToCharArray());
  733. writer.Write(m_opacity);
  734. writer.Write((byte)(m_clipping ? 1 : 0));
  735. writer.Write((byte)m_flags.Data);
  736. //-----------------------------------------------------------------------
  737. writer.Write((byte)0);
  738. //-----------------------------------------------------------------------
  739. using (new LengthWriter(writer))
  740. {
  741. m_maskData.Save(writer);
  742. m_blendingRangesData.Save(writer);
  743. long namePosition = writer.BaseStream.Position;
  744. writer.WritePascalString(m_name);
  745. int paddingBytes = (int)((writer.BaseStream.Position - namePosition) % 4);
  746. Debug.Print("Layer {0} write padding bytes after name", paddingBytes);
  747. for (int i = 0; i < paddingBytes;i++ )
  748. writer.Write((byte)0);
  749. foreach (AdjusmentLayerInfo info in m_adjustmentInfo)
  750. {
  751. info.Save(writer);
  752. }
  753. }
  754. }
  755. }
  756. }