public MaskInfo(PsdBinaryReader reader, Layer layer) { Debug.WriteLine("MaskInfo started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); var maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; var startPosition = reader.BaseStream.Position; var endPosition = startPosition + maskLength; // Read layer mask var rectangle = reader.ReadRectangle(); var backgroundColor = reader.ReadByte(); var flagsByte = reader.ReadByte(); LayerMask = new Mask(layer, rectangle, backgroundColor, new BitVector32(flagsByte)); // User mask is supplied separately when there is also a vector mask. if (maskLength == 36) { var userFlagsByte = reader.ReadByte(); var userBackgroundColor = reader.ReadByte(); var userRectangle = reader.ReadRectangle(); UserMask = new Mask(layer, userRectangle, userBackgroundColor, new BitVector32(userFlagsByte)); } // 20-byte mask data will end with padding. reader.BaseStream.Position = endPosition; }
//public BitVector32 Flags //{ // get { return flags; } //} /// <summary> /// Initializes a new instance of the <see cref="Layer"/> class using the provided reader containing the PSD file data. /// </summary> /// <param name="reader">The reader containing the PSD file data.</param> /// <param name="psdFile">The PSD file to set as the parent.</param> public Layer(BinaryReverseReader reader, PsdFile psdFile) { Children = new List<Layer>(); PsdFile = psdFile; // read the rect Rect rect = new Rect(); rect.y = reader.ReadInt32(); rect.x = reader.ReadInt32(); rect.height = reader.ReadInt32() - rect.y; rect.width = reader.ReadInt32() - rect.x; Rect = rect; // read the channels int channelCount = reader.ReadUInt16(); Channels = new List<Channel>(); SortedChannels = new SortedList<short, Channel>(); for (int index = 0; index < channelCount; ++index) { Channel channel = new Channel(reader, this); Channels.Add(channel); SortedChannels.Add(channel.ID, channel); } // read the header and verify it if (new string(reader.ReadChars(4)) != "8BIM") { throw new IOException("Layer Channelheader error!"); } // read the blend mode key (unused) (defaults to "norm") reader.ReadChars(4); // read the opacity Opacity = reader.ReadByte(); // read the clipping (unused) (< 0 = base, > 0 = non base) reader.ReadByte(); // read all of the flags (protectTrans, visible, obsolete, ver5orLater, pixelDataIrrelevant) flags = new BitVector32(reader.ReadByte()); // skip a padding byte reader.ReadByte(); uint num3 = reader.ReadUInt32(); long position1 = reader.BaseStream.Position; MaskData = new Mask(reader, this); BlendingRangesData = new BlendingRanges(reader); long position2 = reader.BaseStream.Position; // read the name Name = reader.ReadPascalString(); // read the adjustment info int count = (int)((reader.BaseStream.Position - position2) % 4L); reader.ReadBytes(count); AdjustmentInfo = new List<AdjustmentLayerInfo>(); long num4 = position1 + num3; while (reader.BaseStream.Position < num4) { try { AdjustmentInfo.Add(new AdjustmentLayerInfo(reader, this)); } catch { reader.BaseStream.Position = num4; } } foreach (AdjustmentLayerInfo adjustmentLayerInfo in AdjustmentInfo) { if (adjustmentLayerInfo.Key == "TySh") { ReadTextLayer(adjustmentLayerInfo.DataReader); } else if (adjustmentLayerInfo.Key == "luni") { // read the unicode name BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader; dataReader.ReadBytes(3); dataReader.ReadByte(); Name = dataReader.ReadString().TrimEnd(new char[1]); } } reader.BaseStream.Position = num4; }
/// <summary> /// Gets the color at the given pixel position in the given mask. /// </summary> /// <param name="mask">The mask to sample.</param> /// <param name="x">The x position.</param> /// <param name="y">The y position.</param> /// <returns>The mask color.</returns> private static byte GetColor(Mask mask, int x, int y) { byte num = byte.MaxValue; if (mask.PositionIsRelative) { x -= (int)mask.Rect.x; y -= (int)mask.Rect.y; } else { x = x + (int)mask.Layer.Rect.x - (int)mask.Rect.x; y = y + (int)mask.Layer.Rect.y - (int)mask.Rect.y; } if (y >= 0 && (y < mask.Rect.height && x >= 0) && x < mask.Rect.width) { int index = (y * (int)mask.Rect.width) + x; num = index >= mask.ImageData.Length ? byte.MaxValue : mask.ImageData[index]; } return num; }
public Layer(BinaryReverseReader reader, PsdFile psdFile) { Debug.WriteLine("Layer started at " + reader.BaseStream.Position); m_psdFile = psdFile; m_rect = new Rectangle { Y = reader.ReadInt32(), X = reader.ReadInt32() }; m_rect.Height = reader.ReadInt32() - m_rect.Y; m_rect.Width = reader.ReadInt32() - m_rect.X; //----------------------------------------------------------------------- int numberOfChannels = reader.ReadUInt16(); m_channels.Clear(); for (int channel = 0; channel < numberOfChannels; channel++) { var ch = new Channel(reader, this); m_channels.Add(ch); m_sortedChannels.Add(ch.ID, ch); } //----------------------------------------------------------------------- var signature = new string(reader.ReadChars(4)); if (signature != LayerConstants.EightBimSignature) throw (new IOException("Layer Channelheader error!")); m_blendModeKey = new string(reader.ReadChars(4)); m_opacity = reader.ReadByte(); m_clipping = reader.ReadByte() > 0; //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- reader.ReadByte(); //padding //----------------------------------------------------------------------- Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position); // this is the total size of the MaskData, the BlendingRangesData, the // Name and the AdjustmenLayerInfo uint extraDataSize = reader.ReadUInt32(); // remember the start position for calculation of the // AdjustmenLayerInfo size long extraDataStartPosition = reader.BaseStream.Position; m_maskData = new Mask(reader, this); m_blendingRangesData = new BlendingRanges(reader, this); //----------------------------------------------------------------------- var namePosition = reader.BaseStream.Position; m_name = reader.ReadPascalString(); var paddingBytes = (int)((reader.BaseStream.Position - namePosition) % 4); Debug.Print("Layer {0} padding bytes after name", paddingBytes); reader.ReadBytes(paddingBytes); //----------------------------------------------------------------------- m_adjustmentInfo.Clear(); long adjustmenLayerEndPos = extraDataStartPosition + extraDataSize; while (reader.BaseStream.Position < adjustmenLayerEndPos) { try { m_adjustmentInfo.Add(new AdjusmentLayerInfo(reader, this)); } catch { reader.BaseStream.Position = adjustmenLayerEndPos; } } //----------------------------------------------------------------------- // make shure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = adjustmenLayerEndPos; }
/// <summary> /// Initializes a new instance of the <see cref="Layer"/> class using the provided reader containing the PSD file data. /// </summary> /// <param name="reader">The reader containing the PSD file data.</param> /// <param name="psdFile">The PSD file to set as the parent.</param> public Layer(BinaryReverseReader reader, PsdFile psdFile) { Children = new List <Layer>(); PsdFile = psdFile; // read the rect Rect rect = new Rect(); rect.y = reader.ReadInt32(); rect.x = reader.ReadInt32(); rect.height = reader.ReadInt32() - rect.y; rect.width = reader.ReadInt32() - rect.x; Rect = rect; // read the channels int channelCount = reader.ReadUInt16(); Channels = new List <Channel>(); SortedChannels = new SortedList <short, Channel>(); for (int index = 0; index < channelCount; ++index) { Channel channel = new Channel(reader, this); Channels.Add(channel); //Debug.Log(Time.time + "channel.ID=" + channel.ID + ",layer=" + this.Name); SortedChannels.Add(channel.ID, channel); } string head = reader.readStringNew(4); //Debug.Log(Time.time + ",head=" + head); // read the header and verify it if (head != "8BIM") { throw new IOException("Layer Channelheader error!"); } // read the blend mode key (unused) (defaults to "norm") //reader.ReadChars(4); string layerRecordsBlendModeKey = reader.readStringNew(4); // read the opacity Opacity = reader.ReadByte(); // read the clipping (unused) (< 0 = base, > 0 = non base) int Clipping = reader.ReadByte(); // read all of the flags (protectTrans, visible, obsolete, ver5orLater, pixelDataIrrelevant) flags = new BitVector32(reader.ReadByte()); // skip a padding byte int Filler = reader.ReadByte(); imageTransparent = Convert.ToSingle(Opacity) / byte.MaxValue; Debug.Log("layerRecordsBlendModeKey=" + layerRecordsBlendModeKey + ",Opacity=" + Opacity + ",Clipping=" + Clipping + ",flags=" + flags + ", Filler=" + Filler + ",LayerTransparent=" + imageTransparent); uint num3 = reader.ReadUInt32(); long position1 = reader.BaseStream.Position; MaskData = new Mask(reader, this); BlendingRangesData = new BlendingRanges(reader); long position2 = reader.BaseStream.Position; // read the name Name = reader.ReadPascalString(); //Debug.Log(Time.time + ",read layer Name=" + Name + ".end"); // read the adjustment info int count = (int)((reader.BaseStream.Position - position2) % 4L); reader.ReadBytes(count); //Debug.Log(Time.time + ",read count=" + count + ".end"); AdjustmentInfo = new List <AdjustmentLayerInfo>(); long num4 = position1 + num3; while (reader.BaseStream.Position < num4) { try { AdjustmentInfo.Add(new AdjustmentLayerInfo(reader, this)); } catch { reader.BaseStream.Position = num4; } } string keyInfo = ""; foreach (AdjustmentLayerInfo adjustmentLayerInfo in AdjustmentInfo) { keyInfo += ",key=" + adjustmentLayerInfo.Key + "\n"; if (adjustmentLayerInfo.Key == "TySh") { ReadTextLayer(adjustmentLayerInfo.DataReader); } else if (adjustmentLayerInfo.Key == "luni") { // read the unicode name BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader; byte[] temp1 = dataReader.ReadBytes(3); byte charCount = dataReader.ReadByte(); //本来 charCount 是文本串的长度,可以传入ReadString()限定读取长度,但Text除串头无文本长度信息,因此改为读一段Unicode字符串 Name = dataReader.ReadString(); if (Name == "") { Name = defaultLayerName; } } //此处针对字体 图层样式 else if (adjustmentLayerInfo.Key == "lrFX") //样式 相关,对于字体来说,就是描边之类的 { parseLrfxKeyword(adjustmentLayerInfo); //yanruTODO测试屏蔽 } //仅对于图片的 else if (adjustmentLayerInfo.Key == "lspf") { BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader; byte[] data = dataReader.ReadBytes(4); printbytes(data, "lspf data", true); } else if (adjustmentLayerInfo.Key == "lclr") { BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader; byte[] data = dataReader.ReadBytes(10); printbytes(data, "lclr data", true); } } Debug.Log("layer=" + Name + ",Totalkey=\n" + keyInfo); reader.BaseStream.Position = num4; }
public Layer(BinaryReverseReader reader, PsdFile psdFile) { Debug.WriteLine("Layer started at " + reader.BaseStream.Position.ToString()); m_psdFile = psdFile; m_rect = new Rectangle(); m_rect.Y = reader.ReadInt32(); m_rect.X = reader.ReadInt32(); m_rect.Height = reader.ReadInt32() - m_rect.Y; m_rect.Width = reader.ReadInt32() - m_rect.X; //----------------------------------------------------------------------- int numberOfChannels = reader.ReadUInt16(); this.m_channels.Clear(); for (int channel = 0; channel < numberOfChannels; channel++) { Channel ch = new Channel(reader, this); m_channels.Add(ch); m_sortedChannels.Add(ch.ID, ch); } //----------------------------------------------------------------------- string signature = new string(reader.ReadChars(4)); if (signature != "8BIM") throw (new IOException("Layer Channelheader error!")); m_blendModeKey = new string(reader.ReadChars(4)); m_opacity = reader.ReadByte(); m_clipping = reader.ReadByte() > 0; //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- reader.ReadByte(); //padding //----------------------------------------------------------------------- Debug.WriteLine("Layer extraDataSize started at " + reader.BaseStream.Position.ToString()); // this is the total size of the MaskData, the BlendingRangesData, the // Name and the AdjustmentLayerInfo uint extraDataSize = reader.ReadUInt32(); // remember the start position for calculation of the // AdjustmentLayerInfo size long extraDataStartPosition = reader.BaseStream.Position; m_maskData = new Mask(reader, this); m_blendingRangesData = new BlendingRanges(reader, this); //----------------------------------------------------------------------- long namePosition = reader.BaseStream.Position; m_name = reader.ReadPascalString(); int paddingBytes =(int)((reader.BaseStream.Position - namePosition) % 4); Debug.Print("Layer {0} padding bytes after name", paddingBytes); reader.ReadBytes(paddingBytes); //----------------------------------------------------------------------- m_adjustmentInfo.Clear(); long adjustmentLayerEndPos = extraDataStartPosition + extraDataSize; while (reader.BaseStream.Position < adjustmentLayerEndPos) { try { AdjustmentLayerInfo ali = new AdjustmentLayerInfo(reader, this); if (ali.Key.Equals("lrFX")) { //A sub-key - we want to merge its sub-layer info items with this dict. m_adjustmentInfo.AddRange(new Effects(ali)._resources.Values); } else m_adjustmentInfo.Add(ali); // Just add the items } catch { reader.BaseStream.Position = adjustmentLayerEndPos; } } //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = adjustmentLayerEndPos; }