//public void AddChannel(Channel ch) //{ // this._channels.Add(ch.Usage, ch); //} public Layer(BinaryPSDReader reader, Document document) { this._document = document; this._rect = reader.ReadPSDRectangle(); ushort numChannels = reader.ReadUInt16(); this._channels = new Dictionary <int, Channel>(); for (int channelNum = 0; channelNum < numChannels; channelNum++) { Channel ch = new Channel(reader, this); if (this._channels.ContainsKey(ch.Usage)) { continue; //TODO: !! } this._channels.Add(ch.Usage, ch); } string sHeader = new string(reader.ReadPSDChars(4)); if (sHeader != "8BIM") { throw(new Exception("Layer Channelheader error!")); } //'levl'=Levels 'curv'=Curves 'brit'=Brightness/contrast 'blnc'=Color balance 'hue '=Old Hue/saturation, Photoshop 4.0 'hue2'=New Hue/saturation, Photoshop 5.0 'selc'=Selective color 'thrs'=Threshold 'nvrt'=Invert 'post'=Posterize this.BlendKey = new string(reader.ReadPSDChars(4)); int nBlend = -1; try { nBlend = (int)Enum.Parse(typeof(_blendKeysPsd), this.BlendKey); } catch { throw new Exception("Unknown blend key: " + this.BlendKey); } if (nBlend >= 0) { BlendKeys key = (BlendKeys)nBlend; this.BlendKey = Enum.GetName(typeof(BlendKeys), key); } this.Opacity = reader.ReadByte(); this.Clipping = reader.ReadByte(); this.Flags = reader.ReadByte(); reader.ReadByte(); //padding uint extraDataSize = reader.ReadUInt32(); long nChannelEndPos = reader.BaseStream.Position + (long)extraDataSize; if (extraDataSize > 0) { uint nLength; this._mask = new Mask(reader, this); if (this._mask.Rectangle == null) { this._mask = null; } //blending ranges this._blendRanges = new List <System.Drawing.Color>(); nLength = reader.ReadUInt32(); //First come Composite gray blend source / destination; Contains 2 black values followed by 2 white values. Present but irrelevant for Lab & Grayscale. //Then 4+4 for each channel (source + destination colors) for (uint i = 0; i < nLength / 8; i++) { this._blendRanges.Add(System.Drawing.Color.FromArgb((int)reader.ReadUInt32())); this._blendRanges.Add(System.Drawing.Color.FromArgb((int)reader.ReadUInt32())); } //Name //nLength = (uint)reader.ReadByte(); //reader.BaseStream.Position -= 1; //TODO: wtf did I do here? this.Name = reader.ReadPascalString(); //TODO: sometimes there's a 2-byte padding here, but it's not 4-aligned... What is it? long posBefore = reader.BaseStream.Position; sHeader = new string(reader.ReadPSDChars(4)); if (sHeader != "8BIM") { reader.BaseStream.Position -= 2; sHeader = new string(reader.ReadPSDChars(4)); } if (sHeader != "8BIM") { reader.BaseStream.Position = posBefore; } else { reader.BaseStream.Position -= 4; this._resources = LayerResource.ReadLayerResources(reader, null); } if (reader.BaseStream.Position != nChannelEndPos) { reader.BaseStream.Position = nChannelEndPos; } } }
public void Write(BinaryPSDWriter writer) { writer.WritePSDRectangle(this._rect); // new Rectangle(this._rect).Write(writer); writer.Write((ushort)this._channels.Count); foreach (Channel channel in this._channels.Values) { channel.Write(writer); } writer.Write("8BIM"); BlendKeys bk = (BlendKeys)Enum.Parse(typeof(BlendKeys), this.BlendKey); _blendKeysPsd bkPsd = (_blendKeysPsd)(int)bk; writer.Write(bkPsd.ToString()); writer.Write(this.Opacity); writer.Write(this.Clipping); writer.Write(this.Flags); writer.Write((byte)0); //padding writer.StartLengthBlock(typeof(uint)); if (this._mask != null || (this._blendRanges != null && this._blendRanges.Count > 0) || !string.IsNullOrEmpty(this.Name)) { if (this._mask != null) { this._mask.Write(writer); } else { writer.Write((uint)0); //TODO: should be a static of Mask..? } //blending ranges writer.Write((uint)this._blendRanges.Count * 4); foreach (System.Drawing.Color clr in this._blendRanges) { writer.Write((uint)clr.ToArgb()); } //why is there padding here? Seems unnecessary. long namePosition = writer.BaseStream.Position; writer.WritePascalString(this.Name); int paddingBytes = (int)((writer.BaseStream.Position - namePosition) % 4); for (int i = 0; i < paddingBytes; i++) { writer.Write((byte)0); } foreach (LayerResource res in this._resources.Values) { res.Write(writer); } } writer.EndLengthBlock(); }
public Layer(BinaryReverseReader reader, Document document) { this._document = document; this._rect = new ERectangle(); this._rect.Y = reader.ReadInt32(); this._rect.X = reader.ReadInt32(); this._rect.Height = reader.ReadInt32() - this._rect.Y; this._rect.Width = reader.ReadInt32() - this._rect.X; this.NumChannels = reader.ReadUInt16(); this._channels = new Dictionary <int, Channel>(); for (int channelNum = 0; channelNum < this.NumChannels; channelNum++) { Channel ch = new Channel(reader, this); this._channels.Add(ch.Usage, ch); } string sHeader = new string(reader.ReadChars(4)); if (sHeader != "8BIM") { throw(new Exception("Layer Channelheader error!")); } this.BlendKey = new string(reader.ReadChars(4)); int nBlend = -1; try { nBlend = (int)Enum.Parse(typeof(_blendKeysPsd), this.BlendKey); } catch { } if (nBlend >= 0) { BlendKeys key = (BlendKeys)nBlend; this.BlendKey = Enum.GetName(typeof(BlendKeys), key); } this.Opacity = reader.ReadByte(); //(byte)(255 - (int)reader.ReadByte()); //paLayerInfo[#Opacity] = 256 - m_oReader.readUC() --256-ScaleCharToQuantum(ReadBlobByte(image)) this.Clipping = reader.ReadByte(); this.Flags = reader.ReadByte(); reader.ReadByte(); //padding uint nSize = reader.ReadUInt32(); long nChannelEndPos = reader.BaseStream.Position + (long)nSize; if (nSize > 0) { uint nLength; //uint nCombinedlength = 0; this._mask = new Mask(reader, this); if (this._mask.Rectangle == null) { this._mask = null; } //reader.BaseStream.Position+=nLength-16; //nCombinedlength+= nLength + 4; //blending ranges nLength = reader.ReadUInt32(); for (uint i = 0; i < nLength / 8; i++) { uint color1 = reader.ReadUInt32(); uint color2 = reader.ReadUInt32(); } //nCombinedlength+= nLength + 4; //Name nLength = (uint)reader.ReadByte(); reader.BaseStream.Position -= 1; this.Name = reader.ReadPascalString(); //nCombinedlength+= nLength + 4; #region Adjustment etc layers //TODO: there's probably a 2-byte padding here sHeader = new string(reader.ReadChars(4)); if (sHeader != "8BIM") { reader.BaseStream.Position -= 2; sHeader = new string(reader.ReadChars(4)); } reader.BaseStream.Position -= 4; do { try { this.ReadPSDChannelTag(reader); } catch { //dunno what the last bytes are for, just skip them: reader.BaseStream.Position = nChannelEndPos; } }while(reader.BaseStream.Position < nChannelEndPos); #endregion } }