public Header(BinaryPSDReader reader) { this.Version = reader.ReadUInt16(); if (Version != 1) throw new Exception("Can not read .psd version " + Version); byte[] buf = new byte[256]; reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved this.Channels = reader.ReadInt16(); this.Rows = reader.ReadUInt32(); this.Columns = reader.ReadUInt32(); this.BitsPerPixel = reader.ReadUInt16(); this.ColorMode = (ColorModes)reader.ReadInt16(); }
public Header(BinaryPSDReader reader) { this.Version = reader.ReadUInt16(); if (Version != 1) { throw new Exception("Can not read .psd version " + Version); } byte[] buf = new byte[256]; reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved this.Channels = reader.ReadInt16(); this.Rows = reader.ReadUInt32(); this.Columns = reader.ReadUInt32(); this.BitsPerPixel = reader.ReadUInt16(); this.ColorMode = (ColorModes)reader.ReadInt16(); }
public Mask(BinaryPSDReader reader, Layer layer) : base(layer) { this._layer = layer; int nLength = (int)reader.ReadUInt32(); if (nLength == 0) { return; } long nStart = reader.BaseStream.Position; this.Rectangle = reader.ReadPSDRectangle(); //new Rectangle(reader).ToERectangle(); this._color = reader.ReadByte(); this._flags = reader.ReadByte(); if (nLength == 20) { reader.ReadUInt16(); //padding } else if (nLength == 36) { this._flags2 = reader.ReadByte(); //same flags as above according to docs!?!? this._maskBg = reader.ReadByte(); //Real user mask background. Only 0 or 255 - ie bool?!? this._otherRectangle = reader.ReadPSDRectangle(); //new Rectangle(reader).ToERectangle(); //same as above rectangle according to docs?!?! } reader.BaseStream.Position = nStart + nLength; }
public Mask(BinaryPSDReader reader, Layer layer) : base(layer) { this._layer = layer; int nLength = (int)reader.ReadUInt32(); if (nLength == 0) return; long nStart = reader.BaseStream.Position; this.Rectangle = reader.ReadPSDRectangle(); //new Rectangle(reader).ToERectangle(); this._color = reader.ReadByte(); this._flags = reader.ReadByte(); if (nLength == 20) reader.ReadUInt16(); //padding else if (nLength == 36) { this._flags2 = reader.ReadByte();//same flags as above according to docs!?!? this._maskBg = reader.ReadByte(); //Real user mask background. Only 0 or 255 - ie bool?!? this._otherRectangle = reader.ReadPSDRectangle(); //new Rectangle(reader).ToERectangle(); //same as above rectangle according to docs?!?! } reader.BaseStream.Position = nStart + nLength; }
public Channel(BinaryPSDReader reader, Layer layer) { this._usage = reader.ReadInt16(); long length = (long)reader.ReadUInt32(); this._layer = layer; }
public ImageResource(BinaryPSDReader reader) { this.ID = reader.ReadUInt16(); this.Name = reader.ReadPascalString(); uint settingLength = reader.ReadUInt32(); this.Data = reader.ReadBytes((int)settingLength); if (reader.BaseStream.Position % 2 == 1) reader.ReadByte(); }
public static string ReadSpecialString(BinaryPSDReader r) { uint length = r.ReadUInt32(); if (length == 0) { length = 4; } return(new string(r.ReadPSDChars((int)length))); }
public DynVal(BinaryPSDReader r, bool asDescriptor) { if (asDescriptor) { uint version = r.ReadUInt32(); string unknown = Endogine.Serialization.ReadableBinary.CreateHexEditorString(r.ReadBytes(6)); } this.ObjectType = GetMeaningOfFourCC(ReadSpecialString(r)); this.Children = DynVal.ReadValues(r); }
//public LayerResource(LayerResource res) //{ // Prepare(); // this.Tag = res.Tag; //} public LayerResource(BinaryPSDReader reader) { //this.Tag = new string(reader.ReadPSDChars(4)); uint settingLength = reader.ReadUInt32(); this.Data = reader.ReadBytes((int)settingLength); if (!(this is EffectBase)) { reader.JumpToEvenNthByte(2); } }
public static List <DynVal> ReadValues(BinaryPSDReader r) { int numValues = (int)r.ReadUInt32(); List <DynVal> values = new List <DynVal>(); for (int i = 0; i < numValues; i++) { DynVal vt = ReadValue(r, false); if (vt != null) { values.Add(vt); } } return(values); }
public Document(string a_sFilename) { this.Init(); FileStream stream = new FileStream(a_sFilename, FileMode.Open, FileAccess.Read); //stream. BinaryPSDReader reader = new BinaryPSDReader(stream); string signature = new string(reader.ReadPSDChars(4)); if (signature != "8BPS") { return; } this._header = new Header(reader); //this.Version = reader.ReadUInt16(); //if (Version != 1) // throw new Exception("Can not read .psd version " + Version); //byte[] buf = new byte[256]; //reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved //this.Channels = reader.ReadInt16(); //this.Rows = reader.ReadUInt32(); //this.Columns = reader.ReadUInt32(); //this.BitsPerPixel = (int)reader.ReadUInt16(); //this.ColorMode = (ColorModes)reader.ReadInt16(); #region Palette uint nPaletteLength = reader.ReadUInt32(); if (nPaletteLength > 0) { this.ColorTable = new List <Color>(); for (int i = 0; i < nPaletteLength; i += 3) { this.ColorTable.Add(Color.FromArgb((int)reader.ReadByte(), (int)reader.ReadByte(), (int)reader.ReadByte())); } //this.ColorTable.Add(Color.FromArgb(255, 10, 20)); if (this.ColorMode == ColorModes.Duotone) { } else { } } #endregion uint nResLength = reader.ReadUInt32(); //? Number of bytes, or number of entries?? if (nResLength > 0) { //read settings this._imageResources = ImageResource.ReadImageResources(reader); } //reader.JumpToEvenNthByte(4); uint nTotalLayersBytes = reader.ReadUInt32(); long nAfterLayersDefinitions = reader.BaseStream.Position + nTotalLayersBytes; if (nTotalLayersBytes == 8) { stream.Position += nTotalLayersBytes; //this.Unknown = Endogine.Serialization.ReadableBinary.CreateHexEditorString(reader.ReadBytes((int)reader.BytesToEnd)); } else { uint nSize = reader.ReadUInt32(); //What's the difference between nTotalLayersBytes and nSize really? long nLayersEndPos = reader.BaseStream.Position + nSize; short nNumLayers = reader.ReadInt16(); bool bSkipFirstAlpha = false; if (nNumLayers < 0) { bSkipFirstAlpha = true; nNumLayers = (short)-nNumLayers; } List <Layer> loadOrderLayers = new List <Layer>(); this._layers = new List <Layer>(); // new Dictionary<int, Layer>(); for (int nLayerNum = 0; nLayerNum < nNumLayers; nLayerNum++) { Layer layerInfo = new Layer(reader, this); layerInfo.DebugLayerLoadOrdinal = nLayerNum; //if (layerInfo.LayerID < 0) // layerInfo.LayerID = nLayerNum; //if (this._layers.ContainsKey(layerInfo.LayerID)) // throw(new Exception("Duplicate layer IDs! " + layerInfo.LayerID.ToString())); //else // this._layers.Add(layerInfo.LayerID, layerInfo); this._layers.Add(layerInfo); loadOrderLayers.Add(layerInfo); } for (int layerNum = 0; layerNum < nNumLayers; layerNum++) { Layer layer = (Layer)loadOrderLayers[layerNum]; layer.ReadPixels(reader); } reader.JumpToEvenNthByte(4); if (reader.BaseStream.Position != nLayersEndPos) { reader.BaseStream.Position = nLayersEndPos; // nAfterLayersDefinitions; } //Global layer mask uint maskLength = reader.ReadUInt32(); this._tempGlobalLayerMask = null; if (maskLength > 0) { this._tempGlobalLayerMask = reader.ReadBytes((int)maskLength); //TODO: the docs are obviously wrong here... //ushort overlayColorSpace = reader.ReadUInt16(); //undefined in docs //for (int i = 0; i < 4; i++) // reader.ReadUInt16(); //TODO: UInt16 if 16-bit color? Color components - says *both* 4*2 bytes, and 8 bytes in the docs? //reader.ReadUInt16(); //opacity (0-100) //reader.ReadByte(); //Kind: 0=Color selectedi.e. inverted; 1=Color protected;128=use value stored per layer. //reader.ReadByte(); //padding } //hmm... another section of "global" layer resources..? while (true) { long cpPos = reader.BaseStream.Position; string sHeader = new string(reader.ReadPSDChars(4)); reader.BaseStream.Position = cpPos; //TODO: -= 4 should work, but sometimes ReadPSDChars advances 5?!?! if (sHeader != "8BIM") { break; } LayerResource res = LayerResource.ReadLayerResource(reader, null); this._globalLayerResources.Add(res); } } bool readGlobalImage = true; if (readGlobalImage) { this._globalImage = new GlobalImage(this); this._globalImage.Load(reader); //the big merged bitmap (which is how the photoshop document looked when it was saved) //Bitmap bmp = this._globalImage.Bitmap; } reader.Close(); stream.Close(); }
public static List<DynVal> ReadValues(BinaryPSDReader r) { int numValues = (int)r.ReadUInt32(); List<DynVal> values = new List<DynVal>(); for (int i = 0; i < numValues; i++) { DynVal vt = ReadValue(r, false); if (vt != null) values.Add(vt); } return values; }
public static DynVal ReadValue(BinaryPSDReader r, bool ignoreName) { DynVal vt = new DynVal(); if (!ignoreName) vt.Name = GetMeaningOfFourCC(ReadSpecialString(r)); // r.ReadPascalString(); //else //TODO: should be assigned a sequential number? string type = new string(r.ReadPSDChars(4)); switch (type) { case "tdta": vt.Value = Endogine.Serialization.ReadableBinary.CreateHexEditorString(r.ReadBytes(9)); vt.Children = new List<DynVal>(); while (true) { DynVal child = new DynVal(); vt.Children.Add(child); if (child.ReadTdtaItem(r) == false) break; } //r.BaseStream.Position += 9; break; case "Objc": //Decriptor case "GlbO": //GlobalObject (same) string uniName = r.ReadPSDUnicodeString(); //uint numSub = r.ReadUInt32(); //if (numSub > 1) //{ // //A unicode text here!? What does this have to do with numSub?? // r.BaseStream.Position -= 4; // r.ReadPSDUnicodeString(); // r.BaseStream.Position -= 2; //Ehh... What?! //} ////TODO: ah: 1 = 1 short = unknown... //ushort unknown = r.ReadUInt16(); //vt.Children = ReadValues(r); vt = new DynVal(r, false); if (uniName.Length > 0) vt.UnicodeName = uniName; break; case "VlLs": //List vt.Children = new List<DynVal>(); int numValues = (int)r.ReadUInt32(); for (int i = 0; i < numValues; i++) { DynVal ob = ReadValue(r, true); if (ob != null) vt.Children.Add(ob); } break; case "doub": vt.Value = r.ReadPSDDouble(); break; case "UntF": //Unif float //TODO: need a specific type for this, with a double and a type (percent/pixel)? string tst = GetMeaningOfFourCC(new string(r.ReadPSDChars(4))); //#Prc #Pxl #Ang = percent / pixels / angle? double d = r.ReadPSDDouble(); tst += ": " + d; vt.Value = tst; break; case "enum": string namesp = ReadSpecialString(r); string item = ReadSpecialString(r); //vt.Value = namesp + "." + item; //TODO: cast to real enum vt.Value = GetMeaningOfFourCC(namesp) + "." + GetMeaningOfFourCC(item); break; case "long": vt.Value = r.ReadInt32(); //64? break; case "bool": vt.Value = r.ReadBoolean(); break; //case "obj ": //reference // break; case "TEXT": vt.Value = r.ReadPSDUnicodeString(); break; //case "Enmr": //Enumerated // break; //case "Clss": //Class // break; //case "GlbC": //GlobalClass // break; //case "alis": //Alias // break; default: throw new Exception("Unknown type: " + type); } if (vt.Value == null && vt.Children == null) return null; return vt; }
public static string ReadSpecialString(BinaryPSDReader r) { uint length = r.ReadUInt32(); if (length == 0) length = 4; return new string(r.ReadPSDChars((int)length)); }
public static DynVal ReadValue(BinaryPSDReader r, bool ignoreName) { DynVal vt = new DynVal(); if (!ignoreName) { vt.Name = GetMeaningOfFourCC(ReadSpecialString(r)); // r.ReadPascalString(); } //else //TODO: should be assigned a sequential number? string type = new string(r.ReadPSDChars(4)); switch (type) { case "tdta": vt.Value = Endogine.Serialization.ReadableBinary.CreateHexEditorString(r.ReadBytes(9)); vt.Children = new List <DynVal>(); while (true) { DynVal child = new DynVal(); vt.Children.Add(child); if (child.ReadTdtaItem(r) == false) { break; } } //r.BaseStream.Position += 9; break; case "Objc": //Decriptor case "GlbO": //GlobalObject (same) string uniName = r.ReadPSDUnicodeString(); //uint numSub = r.ReadUInt32(); //if (numSub > 1) //{ // //A unicode text here!? What does this have to do with numSub?? // r.BaseStream.Position -= 4; // r.ReadPSDUnicodeString(); // r.BaseStream.Position -= 2; //Ehh... What?! //} ////TODO: ah: 1 = 1 short = unknown... //ushort unknown = r.ReadUInt16(); //vt.Children = ReadValues(r); vt = new DynVal(r, false); if (uniName.Length > 0) { vt.UnicodeName = uniName; } break; case "VlLs": //List vt.Children = new List <DynVal>(); int numValues = (int)r.ReadUInt32(); for (int i = 0; i < numValues; i++) { DynVal ob = ReadValue(r, true); if (ob != null) { vt.Children.Add(ob); } } break; case "doub": vt.Value = r.ReadPSDDouble(); break; case "UntF": //Unif float //TODO: need a specific type for this, with a double and a type (percent/pixel)? string tst = GetMeaningOfFourCC(new string(r.ReadPSDChars(4))); //#Prc #Pxl #Ang = percent / pixels / angle? double d = r.ReadPSDDouble(); tst += ": " + d; vt.Value = tst; break; case "enum": string namesp = ReadSpecialString(r); string item = ReadSpecialString(r); //vt.Value = namesp + "." + item; //TODO: cast to real enum vt.Value = GetMeaningOfFourCC(namesp) + "." + GetMeaningOfFourCC(item); break; case "long": vt.Value = r.ReadInt32(); //64? break; case "bool": vt.Value = r.ReadBoolean(); break; //case "obj ": //reference // break; case "TEXT": vt.Value = r.ReadPSDUnicodeString(); break; //case "Enmr": //Enumerated // break; //case "Clss": //Class // break; //case "GlbC": //GlobalClass // break; //case "alis": //Alias // break; default: throw new Exception("Unknown type: " + type); } if (vt.Value == null && vt.Children == null) { return(null); } return(vt); }
//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 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 Document(string a_sFilename) { this.Init(); FileStream stream = new FileStream(a_sFilename, FileMode.Open, FileAccess.Read); //stream. BinaryPSDReader reader = new BinaryPSDReader(stream); string signature = new string(reader.ReadPSDChars(4)); if (signature != "8BPS") return; this._header = new Header(reader); //this.Version = reader.ReadUInt16(); //if (Version != 1) // throw new Exception("Can not read .psd version " + Version); //byte[] buf = new byte[256]; //reader.Read(buf, (int)reader.BaseStream.Position, 6); //6 bytes reserved //this.Channels = reader.ReadInt16(); //this.Rows = reader.ReadUInt32(); //this.Columns = reader.ReadUInt32(); //this.BitsPerPixel = (int)reader.ReadUInt16(); //this.ColorMode = (ColorModes)reader.ReadInt16(); #region Palette uint nPaletteLength = reader.ReadUInt32(); if (nPaletteLength > 0) { this.ColorTable = new List<Color>(); for (int i = 0; i < nPaletteLength; i+=3) { this.ColorTable.Add(Color.FromArgb((int)reader.ReadByte(), (int)reader.ReadByte(), (int)reader.ReadByte())); } //this.ColorTable.Add(Color.FromArgb(255, 10, 20)); if (this.ColorMode == ColorModes.Duotone) { } else { } } #endregion uint nResLength = reader.ReadUInt32(); //? Number of bytes, or number of entries?? if (nResLength > 0) { //read settings this._imageResources = ImageResource.ReadImageResources(reader); } //reader.JumpToEvenNthByte(4); uint nTotalLayersBytes = reader.ReadUInt32(); long nAfterLayersDefinitions = reader.BaseStream.Position + nTotalLayersBytes; if (nTotalLayersBytes == 8) { stream.Position += nTotalLayersBytes; //this.Unknown = Endogine.Serialization.ReadableBinary.CreateHexEditorString(reader.ReadBytes((int)reader.BytesToEnd)); } else { uint nSize = reader.ReadUInt32(); //What's the difference between nTotalLayersBytes and nSize really? long nLayersEndPos = reader.BaseStream.Position + nSize; short nNumLayers = reader.ReadInt16(); bool bSkipFirstAlpha = false; if (nNumLayers < 0) { bSkipFirstAlpha = true; nNumLayers = (short)-nNumLayers; } List<Layer> loadOrderLayers = new List<Layer>(); this._layers = new List<Layer>(); // new Dictionary<int, Layer>(); for (int nLayerNum = 0; nLayerNum < nNumLayers; nLayerNum++) { Layer layerInfo = new Layer(reader, this); layerInfo.DebugLayerLoadOrdinal = nLayerNum; //if (layerInfo.LayerID < 0) // layerInfo.LayerID = nLayerNum; //if (this._layers.ContainsKey(layerInfo.LayerID)) // throw(new Exception("Duplicate layer IDs! " + layerInfo.LayerID.ToString())); //else // this._layers.Add(layerInfo.LayerID, layerInfo); this._layers.Add(layerInfo); loadOrderLayers.Add(layerInfo); } for (int layerNum = 0; layerNum < nNumLayers; layerNum++) { Layer layer = (Layer)loadOrderLayers[layerNum]; layer.ReadPixels(reader); } reader.JumpToEvenNthByte(4); if (reader.BaseStream.Position != nLayersEndPos) reader.BaseStream.Position = nLayersEndPos; // nAfterLayersDefinitions; //Global layer mask uint maskLength = reader.ReadUInt32(); this._tempGlobalLayerMask = null; if (maskLength > 0) { this._tempGlobalLayerMask = reader.ReadBytes((int)maskLength); //TODO: the docs are obviously wrong here... //ushort overlayColorSpace = reader.ReadUInt16(); //undefined in docs //for (int i = 0; i < 4; i++) // reader.ReadUInt16(); //TODO: UInt16 if 16-bit color? Color components - says *both* 4*2 bytes, and 8 bytes in the docs? //reader.ReadUInt16(); //opacity (0-100) //reader.ReadByte(); //Kind: 0=Color selectedi.e. inverted; 1=Color protected;128=use value stored per layer. //reader.ReadByte(); //padding } //hmm... another section of "global" layer resources..? while (true) { long cpPos = reader.BaseStream.Position; string sHeader = new string(reader.ReadPSDChars(4)); reader.BaseStream.Position = cpPos; //TODO: -= 4 should work, but sometimes ReadPSDChars advances 5?!?! if (sHeader != "8BIM") { break; } LayerResource res = LayerResource.ReadLayerResource(reader, null); this._globalLayerResources.Add(res); } } bool readGlobalImage = true; if (readGlobalImage) { this._globalImage = new GlobalImage(this); this._globalImage.Load(reader); //the big merged bitmap (which is how the photoshop document looked when it was saved) //Bitmap bmp = this._globalImage.Bitmap; } reader.Close(); stream.Close(); }
//public LayerResource(LayerResource res) //{ // Prepare(); // this.Tag = res.Tag; //} public LayerResource(BinaryPSDReader reader) { //this.Tag = new string(reader.ReadPSDChars(4)); uint settingLength = reader.ReadUInt32(); this.Data = reader.ReadBytes((int)settingLength); if (!(this is EffectBase)) reader.JumpToEvenNthByte(2); }