/// <summary> /// Initializes a new instance of the <see cref="ImageResource"/> class using a reader. /// </summary> /// <param name="reader">The reader to use to create the instance.</param> public ImageResource(BinaryReverseReader reader) { // read the OS type string osType = new string(reader.ReadChars(4)); if (osType != "8BIM" && osType != "MeSa") { throw new InvalidOperationException("Could not read an image resource"); } // read the ID ID = reader.ReadInt16(); // read the name Name = string.Empty; Name = reader.ReadPascalString(); // read the length of the data in bytes uint length = reader.ReadUInt32(); // read the actual data Data = reader.ReadBytes((int)length); if (reader.BaseStream.Position % 2L != 1L) { return; } reader.ReadByte(); }
/// <summary> /// Initializes a new instance of the <see cref="ImageResource"/> class using a reader. /// </summary> /// <param name="reader">The reader to use to create the instance.</param> public ImageResource(BinaryReverseReader reader) { // read the OS type string osType = new string(reader.ReadChars(4)); if (osType != "8BIM" && osType != "MeSa") { throw new InvalidOperationException("Could not read an image resource"); } // read the ID ID = reader.ReadInt16(); // read the name Name = string.Empty; Name = reader.ReadPascalString(); // read the length of the data in bytes uint length = reader.ReadUInt32(); // read the actual data Data = reader.ReadBytes((int)length); if (reader.BaseStream.Position % 2L != 1L) { return; } reader.ReadByte(); }
/// <summary> /// Initializes a new instance of the <see cref="Mask"/> class. /// </summary> /// <param name="reader">The reader to use to initialize the instance.</param> /// <param name="layer">The layer this mask belongs to.</param> internal Mask(BinaryReverseReader reader, Layer layer) { Layer = layer; uint num1 = reader.ReadUInt32(); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; rect = new Rect(); rect.y = reader.ReadInt32(); rect.x = reader.ReadInt32(); rect.height = reader.ReadInt32() - rect.y; rect.width = reader.ReadInt32() - rect.x; DefaultColor = reader.ReadByte(); flags = new BitVector32(reader.ReadByte()); if ((int)num1 == 36) { reader.ReadByte(); // bit vector reader.ReadByte(); // ??? reader.ReadInt32(); // rect Y reader.ReadInt32(); // rect X reader.ReadInt32(); // rect total height (actual height = this - Y) reader.ReadInt32(); // rect total width (actual width = this - Y) } reader.BaseStream.Position = position + num1; }
/// <summary> /// Initializes a new instance of the <see cref="Mask"/> class. /// </summary> /// <param name="reader">The reader to use to initialize the instance.</param> /// <param name="layer">The layer this mask belongs to.</param> internal Mask(BinaryReverseReader reader, Layer layer) { Layer = layer; uint num1 = reader.ReadUInt32(); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; rect = new Rect(); rect.y = reader.ReadInt32(); rect.x = reader.ReadInt32(); rect.height = reader.ReadInt32() - rect.y; rect.width = reader.ReadInt32() - rect.x; DefaultColor = reader.ReadByte(); flags = new BitVector32(reader.ReadByte()); if ((int)num1 == 36) { reader.ReadByte(); // bit vector reader.ReadByte(); // ??? reader.ReadInt32(); // rect Y reader.ReadInt32(); // rect X reader.ReadInt32(); // rect total height (actual height = this - Y) reader.ReadInt32(); // rect total width (actual width = this - Y) } reader.BaseStream.Position = position + num1; }
/////////////////////////////////////////////////////////////////////////// private void LoadLayerAndMaskInfo(BinaryReverseReader reader) { Debug.WriteLine("LoadLayerAndMaskInfo started at " + reader.BaseStream.Position.ToString()); uint layersAndMaskLength = reader.ReadUInt32(); if (layersAndMaskLength <= 0) { return; } long startPosition = reader.BaseStream.Position; LoadLayers(reader); LoadGlobalLayerMask(reader); //----------------------------------------------------------------------- //Debug.Assert(reader.BaseStream.Position == startPosition + layersAndMaskLength, "LoadLayerAndMaskInfo"); //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersAndMaskLength; }
private void LoadColorModeData(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); if (num <= 0U) { return; } ColorModeData = reader.ReadBytes((int)num); }
private void LoadGlobalLayerMask(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); if (num <= 0U) { return; } reader.ReadBytes((int)num); }
/// <summary> /// A peculiar type of ascii string frequently used throughout the Descriptor data structure. /// First 4 bytes are length (in bytes), followed by string. If length is 0, length is assumed to be 4. No idea why they did this... RLE compression? /// </summary> /// <param name="r"></param> /// <returns></returns> public static string ReadSpecialString(BinaryReverseReader r) { uint length = r.ReadUInt32(); if (length == 0) { length = 4; } return(new string(r.ReadPSDChars((int)length))); }
private void LoadColorModeData(BinaryReverseReader reader) { Debug.WriteLine("LoadColorModeData started at " + reader.BaseStream.Position.ToString()); uint paletteLength = reader.ReadUInt32(); if (paletteLength > 0) { ColorModeData = reader.ReadBytes((int)paletteLength); } }
/// <summary> /// Reads the color mode data from the reader. /// </summary> /// <param name="reader">The reader to use to read the color mode data.</param> private void LoadColorModeData(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); // Debug.Log(Time.time + "LoadColorModeData number=" + num); if (num <= 0U) { return; } ColorModeData = reader.ReadBytes((int)num); }
private void LoadImageResources(BinaryReverseReader reader) { _imageResources.Clear(); uint num = reader.ReadUInt32(); if (num <= 0U) { return; } long position = reader.BaseStream.Position; while (reader.BaseStream.Position - position < num) { ImageResource imgRes = new ImageResource(reader); switch ((ResourceIDs)imgRes.ID) { case ResourceIDs.XMLInfo: _metaData = XDocument.Load(XmlReader.Create(new MemoryStream(imgRes.Data))); IEnumerable <XElement> source = _metaData.Descendants(XName.Get("Category", "http://ns.adobe.com/photoshop/1.0/")); if (source.Any()) { _category = source.First().Value; } break; case ResourceIDs.ResolutionInfo: imgRes = new ResolutionInfo(imgRes); break; case ResourceIDs.AlphaChannelNames: imgRes = new AlphaChannels(imgRes); break; case ResourceIDs.PsCCOrignPathInfo: imgRes = new AlphaChannels(imgRes); break; case ResourceIDs.PsCCPathSelectionState: imgRes = new AlphaChannels(imgRes); break; case ResourceIDs.TransparencyIndex: Debug.Log("have transparent "); break; } _imageResources.Add(imgRes); } reader.BaseStream.Position = position + num; }
/// <summary> /// Parses either a list format or a dictionary format. Specify skipKeys=true to parse the list format /// </summary> /// <param name="r"></param> /// <param name="skipKeys"></param> /// <returns></returns> public static List <DynVal> ReadValues(BinaryReverseReader r, bool skipKeys) { int numValues = (int)r.ReadUInt32(); List <DynVal> values = new List <DynVal>(numValues); for (int i = 0; i < numValues; i++) { values.Add(ReadValue(r, skipKeys)); } return(values); }
private void LoadGlobalLayerMask(BinaryReverseReader reader) { Debug.WriteLine("LoadGlobalLayerMask started at " + reader.BaseStream.Position.ToString()); uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) { return; } GlobalLayerMaskData = reader.ReadBytes((int)maskLength); }
/// <summary> /// Initializes a new instance of the <see cref="Mask"/> class. /// </summary> /// <param name="reader">The reader to use to initialize the instance.</param> /// <param name="layer">The layer this mask belongs to.</param> internal Mask(BinaryReverseReader reader, Layer layer) { Layer = layer; uint num1 = reader.ReadUInt32(); Debug.Log("mask num1=" + num1); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; rect = new Rect(); rect.y = reader.ReadInt32(); rect.x = reader.ReadInt32(); rect.height = reader.ReadInt32() - rect.y; rect.width = reader.ReadInt32() - rect.x; DefaultColor = reader.ReadByte(); flags = new BitVector32(reader.ReadByte()); int tempNum1 = -1; int tempNum2 = -1; int tempNum3 = -1; int tempNum4 = -1; int tempNum5 = -1; int tempNum6 = -1; if ((int)num1 == 36) { tempNum1 = reader.ReadByte(); // bit vector tempNum2 = reader.ReadByte(); // ??? tempNum3 = reader.ReadInt32(); // rect Y tempNum4 = reader.ReadInt32(); // rect X tempNum5 = reader.ReadInt32(); // rect total height (actual height = this - Y) tempNum6 = reader.ReadInt32(); // rect total width (actual width = this - Y) } Debug.Log("燕茹 Mask data" + ",num1=" + num1 + ",DefaultColor=" + DefaultColor + ",flags=" + flags + ",tempNum1=" + tempNum1 + ",tempNum2=" + tempNum2 + ",tempNum3=" + tempNum3 + ",tempNum4=" + tempNum4 + ",tempNum5=" + tempNum5 + ",tempNum6=" + tempNum6 ); reader.BaseStream.Position = position + num1; }
/////////////////////////////////////////////////////////////////////////// internal Mask(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("Mask started at " + reader.BaseStream.Position.ToString()); m_layer = layer; uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) { return; } long startPosition = reader.BaseStream.Position; //----------------------------------------------------------------------- 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; m_defaultColor = reader.ReadByte(); //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- if (maskLength == 36) { BitVector32 realFlags = new BitVector32(reader.ReadByte()); byte realUserMaskBackground = reader.ReadByte(); Rectangle rect = new Rectangle(); rect.Y = reader.ReadInt32(); rect.X = reader.ReadInt32(); rect.Height = reader.ReadInt32() - m_rect.Y; rect.Width = reader.ReadInt32() - m_rect.X; } // there is other stuff following, but we will ignore this. reader.BaseStream.Position = startPosition + maskLength; }
/// <summary> /// Reads all of the layers from the reader. /// </summary> /// <param name="reader">The reader to use to read the layers.</param> private void LoadLayers(BinaryReverseReader reader) { uint num1 = reader.ReadUInt32(); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; short num2 = reader.ReadInt16(); if (num2 < 0) { AbsoluteAlpha = true; num2 = Math.Abs(num2); } Layers.Clear(); if (num2 == 0) { return; } for (int index = 0; index < (int)num2; ++index) { Layers.Add(new Layer(reader, this)); } foreach (Layer layer in Layers) { foreach (Channel channel in layer.Channels) { if (channel.ID != -2) { channel.LoadPixelData(reader); } } layer.MaskData.LoadPixelData(reader); } if (reader.BaseStream.Position % 2L == 1L) { reader.ReadByte(); } reader.BaseStream.Position = position + num1; }
private void LoadLayerAndMaskInfo(BinaryReverseReader reader) { long num = reader.ReadUInt32(); if (num <= 0U) { return; } long position = reader.BaseStream.Position; LoadLayers(reader); LoadGlobalLayerMask(reader); reader.BaseStream.Position = position + num; }
/// <summary> /// Initializes a new instance of the <see cref="AdjustmentLayerInfo"/> class. /// </summary> /// <param name="reader">The reader containing the PSD file data</param> /// <param name="layer">The layer that this adjustment info belongs to</param> public AdjustmentLayerInfo(BinaryReverseReader reader, Layer layer) { if (new string(reader.ReadChars(4)) != "8BIM") { throw new IOException("Could not read an image resource"); } Key = new string(reader.ReadChars(4)); if (Key == "lfx2" || Key == "lrFX") { layer.HasEffects = true; } uint length = reader.ReadUInt32(); Data = reader.ReadBytes((int)length); }
/// <summary> /// Initializes a new instance of the <see cref="AdjustmentLayerInfo"/> class. /// </summary> /// <param name="reader">The reader containing the PSD file data</param> /// <param name="layer">The layer that this adjustment info belongs to</param> public AdjustmentLayerInfo(BinaryReverseReader reader, Layer layer) { if (new string(reader.ReadChars(4)) != "8BIM") { throw new IOException("Could not read an image resource"); } Key = new string(reader.ReadChars(4)); if (Key == "lfx2" || Key == "lrFX") { layer.HasEffects = true; } uint length = reader.ReadUInt32(); Data = reader.ReadBytes((int)length); }
/////////////////////////////////////////////////////////////////////////// private void LoadImageResources(BinaryReverseReader reader) { Debug.WriteLine("LoadImageResources started at " + reader.BaseStream.Position.ToString()); m_imageResources.Clear(); uint imgResLength = reader.ReadUInt32(); if (imgResLength <= 0) { return; } long startPosition = reader.BaseStream.Position; while ((reader.BaseStream.Position - startPosition) < imgResLength) { ImageResource imgRes = new ImageResource(reader); ResourceIDs resID = (ResourceIDs)imgRes.ID; switch (resID) { case ResourceIDs.ResolutionInfo: imgRes = new ResolutionInfo(imgRes); break; case ResourceIDs.Thumbnail1: case ResourceIDs.Thumbnail2: imgRes = new Thumbnail(imgRes); break; case ResourceIDs.AlphaChannelNames: imgRes = new AlphaChannels(imgRes); break; } m_imageResources.Add(imgRes); } //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + imgResLength; }
public AdjustmentLayerInfo(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("AdjustmentLayerInfo started at " + reader.BaseStream.Position.ToString()); m_layer = layer; string signature = new string(reader.ReadChars(4)); if (signature != "8BIM") { throw new IOException("Could not read an image resource"); } m_key = new string(reader.ReadChars(4)); uint dataLength = reader.ReadUInt32(); m_data = reader.ReadBytes((int)dataLength); }
////////////////////////////////////////////////////////////////// public ImageResource(BinaryReverseReader reader) { m_osType = new string(reader.ReadChars(4)); if (m_osType != "8BIM" && m_osType != "MeSa") { throw new InvalidOperationException("Could not read an image resource"); } m_id = reader.ReadInt16(); m_name = reader.ReadPascalString(); uint settingLength = reader.ReadUInt32(); m_data = reader.ReadBytes((int)settingLength); if (reader.BaseStream.Position % 2 == 1) { reader.ReadByte(); } }
public AdjustmentLayerInfo(BinaryReverseReader reader, Layer layer) { // 从文档 五 - 4 - 22) 开始读取 string head = reader.ReadStringNew(4); if (head != "8BIM") { throw new IOException("Could not read an image resource"); } Key = reader.ReadStringNew(4); if (Key == "lfx2" || Key == "lrFX") { layer.HasEffects = true; } uint length = reader.ReadUInt32(); Data = reader.ReadBytes((int)length); }
internal Mask(BinaryReverseReader reader, Layer layer) { Layer = layer; // 从文档 五 - 4 - 14) uint num1 = reader.ReadUInt32(); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; _rect = new Rect(); _rect.y = reader.ReadInt32(); _rect.x = reader.ReadInt32(); _rect.height = reader.ReadInt32() - _rect.y; _rect.width = reader.ReadInt32() - _rect.x; _defaultColor = reader.ReadByte(); _flags = new BitVector32(reader.ReadByte()); int tempNum1 = -1; int tempNum2 = -1; int tempNum3 = -1; int tempNum4 = -1; int tempNum5 = -1; int tempNum6 = -1; if ((int)num1 == 36) { tempNum1 = reader.ReadByte(); // bit vector tempNum2 = reader.ReadByte(); // ??? tempNum3 = reader.ReadInt32(); // rect Y tempNum4 = reader.ReadInt32(); // rect X tempNum5 = reader.ReadInt32(); // rect total height (actual height = this - Y) tempNum6 = reader.ReadInt32(); // rect total width (actual width = this - Y) } reader.BaseStream.Position = position + num1; }
/// <summary> /// Initializes a new instance of the <see cref="AdjustmentLayerInfo"/> class. /// </summary> /// <param name="reader">The reader containing the PSD file data</param> /// <param name="layer">The layer that this adjustment info belongs to</param> public AdjustmentLayerInfo(BinaryReverseReader reader, Layer layer) { string head = reader.readStringNew(4); if (head != "8BIM") { throw new IOException("Could not read an image resource"); } Key = reader.readStringNew(4); if (Key == "lfx2" || Key == "lrFX") { layer.HasEffects = true; } //int readlength = byte.MaxValue; uint length = reader.ReadUInt32(); Data = reader.ReadBytes((int)length); //Debug.Log(Time.time + ",new AdjustmentLayerInfo key=" + Key +",strdata="+Stringdata); }
/////////////////////////////////////////////////////////////////////////// private void LoadLayers(BinaryReverseReader reader) { Debug.WriteLine("LoadLayers started at " + reader.BaseStream.Position.ToString()); uint layersInfoSectionLength = reader.ReadUInt32(); if (layersInfoSectionLength <= 0) return; long startPosition = reader.BaseStream.Position; short numberOfLayers = reader.ReadInt16(); // If <0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numberOfLayers < 0) { AbsoluteAlpha = true; numberOfLayers = Math.Abs(numberOfLayers); } m_layers.Clear(); if (numberOfLayers == 0) return; for (int i = 0; i < numberOfLayers; i++) { m_layers.Add(new Layer(reader, this)); } PrivateThreadPool threadPool = new PrivateThreadPool(); foreach (Layer layer in m_layers) { foreach (Layer.Channel channel in layer.Channels) { if (channel.ID != -2) { channel.LoadPixelData(reader); DecompressChannelContext dcc = new DecompressChannelContext(channel); WaitCallback waitCallback = new WaitCallback(dcc.DecompressChannel); threadPool.QueueUserWorkItem(waitCallback); } } layer.MaskData.LoadPixelData(reader); } threadPool.Drain(); //----------------------------------------------------------------------- if (reader.BaseStream.Position % 2 == 1) reader.ReadByte(); //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersInfoSectionLength; }
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; }
/// <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; }
/////////////////////////////////////////////////////////////////////////// private void LoadLayers(BinaryReverseReader reader) { Debug.WriteLine("LoadLayers started at " + reader.BaseStream.Position); uint layersInfoSectionLength = reader.ReadUInt32(); if (layersInfoSectionLength <= 0) return; long startPosition = reader.BaseStream.Position; short numberOfLayers = reader.ReadInt16(); // If <0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numberOfLayers < 0) { AbsoluteAlpha = true; numberOfLayers = Math.Abs(numberOfLayers); } m_layers.Clear(); if (numberOfLayers == 0) return; for (int i = 0; i < numberOfLayers; i++) { m_layers.Add(new Layer(reader, this)); } foreach (Layer layer in m_layers) { foreach (Layer.Channel channel in layer.Channels) { if (channel.ID != -2) channel.LoadPixelData(reader); } layer.MaskData.LoadPixelData(reader); } //----------------------------------------------------------------------- if (reader.BaseStream.Position%2 == 1) reader.ReadByte(); //----------------------------------------------------------------------- // make shure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersInfoSectionLength; }
/////////////////////////////////////////////////////////////////////////// private void LoadImageResources(BinaryReverseReader reader) { Debug.WriteLine("LoadImageResources started at " + reader.BaseStream.Position); m_imageResources.Clear(); uint imgResLength = reader.ReadUInt32(); if (imgResLength <= 0) return; long startPosition = reader.BaseStream.Position; while ((reader.BaseStream.Position - startPosition) < imgResLength) { var imgRes = new ImageResource(reader); var resID = (ResourceIDs)imgRes.ID; switch (resID) { case ResourceIDs.ResolutionInfo: imgRes = new ResolutionInfo(imgRes); break; case ResourceIDs.Thumbnail1: case ResourceIDs.Thumbnail2: imgRes = new Thumbnail(imgRes); break; case ResourceIDs.AlphaChannelNames: imgRes = new AlphaChannels(imgRes); break; } m_imageResources.Add(imgRes); } //----------------------------------------------------------------------- // make shure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + imgResLength; }
public Layer(BinaryReverseReader reader, PsdFile psdFile) { //从文档 五 - 4 - 1) 开始读 Children = new List <Layer>(); PsdFile = psdFile; 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; 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); } string head = reader.ReadStringNew(4); if (head != "8BIM") { throw new IOException("Layer Channelheader error!"); } string layerRecordsBlendModeKey = reader.ReadStringNew(4); Opacity = reader.ReadByte(); int Clipping = reader.ReadByte(); _flags = new BitVector32(reader.ReadByte()); int Filler = reader.ReadByte(); _imageTransparent = Convert.ToSingle(Opacity) / byte.MaxValue; //文档 五 - 4 - 13) uint num3 = reader.ReadUInt32(); long position1 = reader.BaseStream.Position; MaskData = new Mask(reader, this); _blendingRangesData = new BlendingRanges(reader); long position2 = reader.BaseStream.Position; // 文档 五 - 4 - 21) 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; 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); } else if (adjustmentLayerInfo.Key == "lclr") { BinaryReverseReader dataReader = adjustmentLayerInfo.DataReader; byte[] data = dataReader.ReadBytes(10); } } reader.BaseStream.Position = num4; int deltaL = (int)(MaskData.Rect.x - Rect.x); int deltaR = (int)(Rect.xMax - MaskData.Rect.xMax); int deltaT = (int)(MaskData.Rect.y - Rect.y); int deltaB = (int)(Rect.yMax - MaskData.Rect.yMax); int l = deltaL > 0 ? deltaL : 0; int r = deltaR > 0 ? deltaR : 0; int t = deltaT > 0 ? deltaT : 0; int b = deltaB > 0 ? deltaB : 0; //Unity Document TextureImporter.spriteBorder X=left, Y=bottom, Z=right, W=top. _border = new Vector4(l, b, r, t); //_is9Slice = SLICE_REG.Match(_name).Success; _is9Slice = _name.Contains(SLICE_HEAD); }
public static DynVal ReadValue(BinaryReverseReader r, bool skipKey) { DynVal vt = new DynVal(); if (!skipKey) { vt.Name = GetMeaningOfFourCC(ReadSpecialString(r)); } //TODO: should be assigned a sequential number? vt.Type = parseTypeString(new string(r.ReadPSDChars(4))); switch (vt.Type) { case OSType.tdta: uint unknown = r.ReadUInt32(); TdTaParser p = new TdTaParser(r); object o = p.ParseOneTree(); vt.Value = o; break; case OSType.Descriptor: vt = DynVal.ReadDescriptor(r); break; case OSType.List: vt.Children = ReadValues(r, true); break; case OSType.Double: vt.Value = r.ReadDouble(); break; case OSType.UnitFloat: //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.ReadDouble(); tst += ": " + d; vt.Value = tst; break; case OSType.Enumerated: 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 OSType.Integer: vt.Value = r.ReadInt32(); //4 byte integer break; case OSType.Boolean: vt.Value = r.ReadBoolean(); break; case OSType.String: vt.Value = r.ReadPSDUnicodeString(); break; default: throw new Exception("Unhandled type: " + vt.Type); } return(vt); }
/////////////////////////////////////////////////////////////////////////// internal Mask(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("Mask started at " + reader.BaseStream.Position); m_layer = layer; uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) { return; } long startPosition = reader.BaseStream.Position; //----------------------------------------------------------------------- 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; m_defaultColor = reader.ReadByte(); //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- if (maskLength == 36) { //var realFlags = new BitVector32(reader.ReadByte()); //var realUserMaskBackground = reader.ReadByte(); #if false var y = reader.ReadInt32(); var x = reader.ReadInt32(); var rect = new Rectangle { Y = y, X = x, Height = reader.ReadInt32() - y, Width = reader.ReadInt32() - x }; #else // this is just reading unused bytes... reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); #endif } // there is other stuff following, but we will ignore this. reader.BaseStream.Position = startPosition + maskLength; }
/// <summary> /// Reads the global layer mask from the reader. /// </summary> /// <param name="reader">The reader to use to read the global layer mask.</param> private void LoadGlobalLayerMask(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); if (num <= 0U) { return; } // read the global mask data reader.ReadBytes((int)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; }
public AdjusmentLayerInfo(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("AdjusmentLayerInfo started at " + reader.BaseStream.Position); m_layer = layer; var signature = new string(reader.ReadChars(4)); if (signature != LayerConstants.EightBimSignature) { throw new IOException("Could not read an image resource"); } m_key = new string(reader.ReadChars(4)); uint dataLength = reader.ReadUInt32(); m_data = reader.ReadBytes((int) dataLength); }
/// <summary> /// Reads the image resources from the reader. /// </summary> /// <param name="reader">The reader to use to read the image resources.</param> private void LoadImageResources(BinaryReverseReader reader) { ImageResources.Clear(); uint num = reader.ReadUInt32(); if (num <= 0U) { return; } long position = reader.BaseStream.Position; while (reader.BaseStream.Position - position < num) { ImageResource imgRes = new ImageResource(reader); switch ((ResourceIDs)imgRes.ID) { case ResourceIDs.XMLInfo: MetaData = XDocument.Load(XmlReader.Create(new MemoryStream(imgRes.Data))); IEnumerable<XElement> source = MetaData.Descendants(XName.Get("Category", "http://ns.adobe.com/photoshop/1.0/")); if (source.Any()) { Category = source.First().Value; } break; case ResourceIDs.ResolutionInfo: imgRes = new ResolutionInfo(imgRes); break; case ResourceIDs.AlphaChannelNames: imgRes = new AlphaChannels(imgRes); break; } ImageResources.Add(imgRes); } reader.BaseStream.Position = position + num; }
/// <summary> /// Reads the layer and mask information from the reader. /// </summary> /// <param name="reader">The reader to use to read the layer and mask info.</param> private void LoadLayerAndMaskInfo(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); if (num <= 0U) { return; } long position = reader.BaseStream.Position; LoadLayers(reader); LoadGlobalLayerMask(reader); reader.BaseStream.Position = position + num; }
/// <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; }
/////////////////////////////////////////////////////////////////////////// internal Mask(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("Mask started at " + reader.BaseStream.Position.ToString()); m_layer = layer; uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; long startPosition = reader.BaseStream.Position; //----------------------------------------------------------------------- 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; m_defaultColor = reader.ReadByte(); //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- if (maskLength == 36) { BitVector32 realFlags = new BitVector32(reader.ReadByte()); byte realUserMaskBackground = reader.ReadByte(); Rectangle rect = new Rectangle(); rect.Y = reader.ReadInt32(); rect.X = reader.ReadInt32(); rect.Height = reader.ReadInt32() - m_rect.Y; rect.Width = reader.ReadInt32() - m_rect.X; } // there is other stuff following, but we will ignore this. reader.BaseStream.Position = startPosition + maskLength; }
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> /// A peculiar type of ascii string frequently used throughout the Descriptor data structure. /// First 4 bytes are length (in bytes), followed by string. If length is 0, length is assumed to be 4. No idea why they did this... RLE compression? /// </summary> /// <param name="r"></param> /// <returns></returns> public static string ReadSpecialString(BinaryReverseReader r) { uint length = r.ReadUInt32(); if (length == 0) length = 4; return new string(r.ReadPSDChars((int)length)); }
////////////////////////////////////////////////////////////////// public ImageResource(BinaryReverseReader reader) { m_osType = new string(reader.ReadChars(4)); if (m_osType != "8BIM" && m_osType != "MeSa") { throw new InvalidOperationException("Could not read an image resource"); } m_id = reader.ReadInt16(); m_name = reader.ReadPascalString(); uint settingLength = reader.ReadUInt32(); m_data = reader.ReadBytes((int) settingLength); if (reader.BaseStream.Position%2 == 1) reader.ReadByte(); }
private void LoadColorModeData(BinaryReverseReader reader) { Debug.WriteLine("LoadColorModeData started at " + reader.BaseStream.Position); uint paletteLength = reader.ReadUInt32(); if (paletteLength > 0) { ColorModeData = reader.ReadBytes((int) paletteLength); } }
/// <summary> /// Reads the color mode data from the reader. /// </summary> /// <param name="reader">The reader to use to read the color mode data.</param> private void LoadColorModeData(BinaryReverseReader reader) { uint num = reader.ReadUInt32(); if (num <= 0U) { return; } ColorModeData = reader.ReadBytes((int)num); }
/////////////////////////////////////////////////////////////////////////// private void LoadLayerAndMaskInfo(BinaryReverseReader reader) { Debug.WriteLine("LoadLayerAndMaskInfo started at " + reader.BaseStream.Position); uint layersAndMaskLength = reader.ReadUInt32(); if (layersAndMaskLength <= 0) return; long startPosition = reader.BaseStream.Position; LoadLayers(reader); LoadGlobalLayerMask(reader); //----------------------------------------------------------------------- //Debug.Assert(reader.BaseStream.Position == startPosition + layersAndMaskLength, "LoadLayerAndMaskInfo"); //----------------------------------------------------------------------- // make shure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersAndMaskLength; }
/////////////////////////////////////////////////////////////////////////// private void LoadLayers(BinaryReverseReader reader) { Debug.WriteLine("LoadLayers started at " + reader.BaseStream.Position.ToString()); uint layersInfoSectionLength = reader.ReadUInt32(); if (layersInfoSectionLength <= 0) { return; } long startPosition = reader.BaseStream.Position; short numberOfLayers = reader.ReadInt16(); // If <0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numberOfLayers < 0) { AbsoluteAlpha = true; numberOfLayers = Math.Abs(numberOfLayers); } m_layers.Clear(); if (numberOfLayers == 0) { return; } for (int i = 0; i < numberOfLayers; i++) { m_layers.Add(new Layer(reader, this)); } PrivateThreadPool threadPool = new PrivateThreadPool(); foreach (Layer layer in m_layers) { foreach (Layer.Channel channel in layer.Channels) { if (channel.ID != -2) { channel.LoadPixelData(reader); DecompressChannelContext dcc = new DecompressChannelContext(channel); WaitCallback waitCallback = new WaitCallback(dcc.DecompressChannel); threadPool.QueueUserWorkItem(waitCallback); } } layer.MaskData.LoadPixelData(reader); } threadPool.Drain(); //----------------------------------------------------------------------- if (reader.BaseStream.Position % 2 == 1) { reader.ReadByte(); } //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersInfoSectionLength; }
private void LoadGlobalLayerMask(BinaryReverseReader reader) { Debug.WriteLine("LoadGlobalLayerMask started at " + reader.BaseStream.Position); uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; GlobalLayerMaskData = reader.ReadBytes((int) maskLength); }
public static DynVal ReadValue(BinaryReverseReader r, bool skipKey) { DynVal vt = new DynVal(); if (!skipKey) vt.Name = GetMeaningOfFourCC(ReadSpecialString(r)); //TODO: should be assigned a sequential number? vt.Type = parseTypeString(new string(r.ReadPSDChars(4))); switch (vt.Type) { case OSType.tdta: uint unknown = r.ReadUInt32(); TdTaParser p = new TdTaParser(r); object o = p.ParseOneTree(); vt.Value = o; break; case OSType.Descriptor: vt = DynVal.ReadDescriptor(r); break; case OSType.List: vt.Children = ReadValues(r,true); break; case OSType.Double: vt.Value = r.ReadDouble(); break; case OSType.UnitFloat: //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.ReadDouble(); tst += ": " + d; vt.Value = tst; break; case OSType.Enumerated: 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 OSType.Integer: vt.Value = r.ReadInt32(); //4 byte integer break; case OSType.Boolean: vt.Value = r.ReadBoolean(); break; case OSType.String: vt.Value = r.ReadPSDUnicodeString(); break; default: throw new Exception("Unhandled type: " + vt.Type); } return vt; }
public FontInfo(BinaryReverseReader r) { this.Mark = r.ReadUInt16(); this.FontType = r.ReadUInt32(); this.FontName = r.ReadPascalString(); this.FontFamilyName = r.ReadPascalString(); this.FontStyleName = r.ReadPascalString(); this.Script = r.ReadUInt16(); ushort NumDesignAxesVectors = r.ReadUInt16(); this.DesignVectors = new List<uint>(); for (int vectorNum = 0; vectorNum < NumDesignAxesVectors; vectorNum++) this.DesignVectors.Add(r.ReadUInt32()); }
//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; }
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; }
/// <summary> /// Reads all of the layers from the reader. /// </summary> /// <param name="reader">The reader to use to read the layers.</param> private void LoadLayers(BinaryReverseReader reader) { uint num1 = reader.ReadUInt32(); if (num1 <= 0U) { return; } long position = reader.BaseStream.Position; short num2 = reader.ReadInt16(); if (num2 < 0) { AbsoluteAlpha = true; num2 = Math.Abs(num2); } Layers.Clear(); if (num2 == 0) { return; } for (int index = 0; index < (int)num2; ++index) { Layers.Add(new Layer(reader, this)); } foreach (Layer layer in Layers) { foreach (Channel channel in layer.Channels) { if (channel.ID != -2) { channel.LoadPixelData(reader); } } layer.MaskData.LoadPixelData(reader); } if (reader.BaseStream.Position % 2L == 1L) { reader.ReadByte(); } reader.BaseStream.Position = position + num1; }
/////////////////////////////////////////////////////////////////////////// internal Mask(BinaryReverseReader reader, Layer layer) { Debug.WriteLine("Mask started at " + reader.BaseStream.Position); m_layer = layer; uint maskLength = reader.ReadUInt32(); if (maskLength <= 0) return; long startPosition = reader.BaseStream.Position; //----------------------------------------------------------------------- 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; m_defaultColor = reader.ReadByte(); //----------------------------------------------------------------------- byte flags = reader.ReadByte(); m_flags = new BitVector32(flags); //----------------------------------------------------------------------- if (maskLength == 36) { //var realFlags = new BitVector32(reader.ReadByte()); //var realUserMaskBackground = reader.ReadByte(); #if false var y = reader.ReadInt32(); var x = reader.ReadInt32(); var rect = new Rectangle { Y = y, X = x, Height = reader.ReadInt32() - y, Width = reader.ReadInt32() - x }; #else // this is just reading unused bytes... reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); #endif } // there is other stuff following, but we will ignore this. reader.BaseStream.Position = startPosition + maskLength; }
/// <summary> /// Parses either a list format or a dictionary format. Specify skipKeys=true to parse the list format /// </summary> /// <param name="r"></param> /// <param name="skipKeys"></param> /// <returns></returns> public static List<DynVal> ReadValues(BinaryReverseReader r, bool skipKeys) { int numValues = (int)r.ReadUInt32(); List<DynVal> values = new List<DynVal>(numValues); for (int i = 0; i < numValues; i++) values.Add(ReadValue(r, skipKeys)); return values; }