/////////////////////////////////////////////////////////////////////////// private void LoadHeader(PsdBinaryReader reader) { Debug.WriteLine("LoadHeader started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); var signature = reader.ReadAsciiChars(4); if (signature != "8BPS") { throw new PsdInvalidException("The given stream is not a valid PSD file"); } Version = reader.ReadInt16(); if (Version != 1) { throw new PsdInvalidException("The PSD file has an unknown version"); } //6 bytes reserved reader.BaseStream.Position += 6; this.ChannelCount = reader.ReadInt16(); this.RowCount = reader.ReadInt32(); this.ColumnCount = reader.ReadInt32(); BitDepth = reader.ReadInt16(); ColorMode = (PsdColorMode)reader.ReadInt16(); }
/////////////////////////////////////////////////////////////////////////// private void LoadHeader(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, File header"); var signature = reader.ReadAsciiChars(4); if (signature != "8BPS") { throw new PsdInvalidException("The given stream is not a valid PSD file"); } Version = (PsdFileVersion)reader.ReadInt16(); Util.DebugMessage(reader.BaseStream, "Load, Info, Version {0}", (int)Version); if ((Version != PsdFileVersion.Psd) && (Version != PsdFileVersion.PsbLargeDocument)) { throw new PsdInvalidException("The PSD file has an unknown version"); } //6 bytes reserved reader.BaseStream.Position += 6; this.ChannelCount = reader.ReadInt16(); this.RowCount = reader.ReadInt32(); this.ColumnCount = reader.ReadInt32(); BitDepth = reader.ReadInt16(); ColorMode = (PsdColorMode)reader.ReadInt16(); Util.DebugMessage(reader.BaseStream, "Load, End, File header"); }
public ResolutionInfo(PsdBinaryReader reader, string name) : base(name) { this.HDpi = new UFixed16_16(reader.ReadUInt32()); this.HResDisplayUnit = (ResUnit)reader.ReadInt16(); this.WidthDisplayUnit = (Unit)reader.ReadInt16(); this.VDpi = new UFixed16_16(reader.ReadUInt32()); this.VResDisplayUnit = (ResUnit)reader.ReadInt16(); this.HeightDisplayUnit = (Unit)reader.ReadInt16(); }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// Load Layers Info section, including image data. /// </summary> /// <param name="reader">PSD reader.</param> /// <param name="hasHeader">Whether the Layers Info section has a length header.</param> private void LoadLayers(PsdBinaryReader reader, bool hasHeader) { UInt32 sectionLength = 0; if (hasHeader) { sectionLength = reader.ReadUInt32(); if (sectionLength <= 0) { return; } } var startPosition = reader.BaseStream.Position; var numLayers = reader.ReadInt16(); // If numLayers < 0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numLayers < 0) { AbsoluteAlpha = true; numLayers = Math.Abs(numLayers); } if (numLayers == 0) { return; } for (int i = 0; i < numLayers; i++) { var layer = new Layer(reader, this); Layers.Add(layer); } //----------------------------------------------------------------------- // Load image data for all channels. foreach (var layer in Layers) { foreach (var channel in layer.Channels) { channel.LoadPixelData(reader); } } // Length is set to 0 when called on higher bitdepth layers. if (sectionLength > 0) { // Layers Info section is documented to be even-padded, but Photoshop // actually pads to 4 bytes. var endPosition = startPosition + sectionLength; var positionOffset = reader.BaseStream.Position - endPosition; if (reader.BaseStream.Position < endPosition) { reader.BaseStream.Position = endPosition; } } }
////////////////////////////////////////////////////////////////// internal void LoadPixelData(PsdBinaryReader reader) { Debug.WriteLine("Channel.LoadPixelData started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); var endPosition = reader.BaseStream.Position + this.Length; ImageCompression = (ImageCompression)reader.ReadInt16(); imageDataCompressed = true; var dataLength = this.Length - 2; switch (ImageCompression) { case ImageCompression.Raw: ImageData = reader.ReadBytes(dataLength); break; case ImageCompression.Rle: // RLE row lengths RleHeader = reader.ReadBytes(2 * Rect.Height); var rleDataLength = dataLength - 2 * Rect.Height; // The PSD specification states that rows are padded to even sizes. // However, PSD files generated by Photoshop CS4 do not actually // follow this stipulation. Data = reader.ReadBytes(rleDataLength); break; case ImageCompression.Zip: case ImageCompression.ZipPrediction: Data = reader.ReadBytes(dataLength); break; } Debug.Assert(reader.BaseStream.Position == endPosition, "Pixel data successfully read in."); }
////////////////////////////////////////////////////////////////// internal void LoadPixelData(PsdBinaryReader reader) { var endPosition = reader.BaseStream.Position + this.Length; ImageCompression = (ImageCompression)reader.ReadInt16(); var dataLength = this.Length - 2; switch (ImageCompression) { case ImageCompression.Raw: ImageDataRaw = reader.ReadBytes(dataLength); break; case ImageCompression.Rle: // RLE row lengths RleRowLengths = new RleRowLengths(reader, (int)Rect.height); var rleDataLength = (int)(endPosition - reader.BaseStream.Position); // The PSD specification states that rows are padded to even sizes. // However, Photoshop doesn't actually do this. RLE rows can have // odd lengths in the header, and there is no padding between rows. ImageDataRaw = reader.ReadBytes(rleDataLength); break; case ImageCompression.Zip: case ImageCompression.ZipPrediction: ImageDataRaw = reader.ReadBytes(dataLength); break; } }
internal Channel(PsdBinaryReader reader, Layer layer) { Debug.WriteLine("Channel started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); ID = reader.ReadInt16(); Length = reader.ReadInt32(); Layer = layer; }
/////////////////////////////////////////////////////////////////////////// #endregion /////////////////////////////////////////////////////////////////////////// #region ImageData /////////////////////////////////////////////////////////////////////////// private void LoadImage(PsdBinaryReader reader) { Debug.WriteLine("LoadImage started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); BaseLayer.Rect = new Rectangle(0, 0, ColumnCount, RowCount); ImageCompression = (ImageCompression)reader.ReadInt16(); switch (ImageCompression) { case ImageCompression.Raw: var length = this.RowCount * Util.BytesPerRow(BaseLayer.Rect, BitDepth); for (Int16 i = 0; i < ChannelCount; i++) { var channel = new Channel(i, this.BaseLayer); channel.ImageCompression = ImageCompression; channel.Length = length; channel.ImageData = reader.ReadBytes(length); BaseLayer.Channels.Add(channel); } break; case ImageCompression.Rle: // Store RLE data length for (Int16 i = 0; i < ChannelCount; i++) { var channel = new Channel(i, this.BaseLayer); channel.RleHeader = reader.ReadBytes(2 * RowCount); int totalRleLength = 0; using (var memoryStream = new MemoryStream(channel.RleHeader)) using (var memoryReader = new PsdBinaryReader(memoryStream, Encoding.ASCII)) { for (int j = 0; j < RowCount; j++) { totalRleLength += memoryReader.ReadUInt16(); } } channel.ImageCompression = this.ImageCompression; channel.Length = (int)totalRleLength; this.BaseLayer.Channels.Add(channel); } foreach (var channel in this.BaseLayer.Channels) { channel.Data = reader.ReadBytes(channel.Length); } break; } // If there is one more channel than we need, then it is the alpha channel if (ChannelCount == ColorMode.ChannelCount() + 1) { var alphaChannel = BaseLayer.Channels.Last(); alphaChannel.ID = -1; } }
public LayerTypeToolInfo(PsdBinaryReader reader) { Version = reader.ReadInt16(); xx = reader.ReadDouble(); xy = reader.ReadDouble(); yx = reader.ReadDouble(); yy = reader.ReadDouble(); tx = reader.ReadDouble(); ty = reader.ReadDouble(); TextVersion = reader.ReadInt16(); TextDescriptorVestion = reader.ReadInt32(); TextData = new DescriptorStructure(reader); WarpVersion = reader.ReadInt16(); WarpDescriptorVestion = reader.ReadInt32(); WarpData = new DescriptorStructure(reader); left = reader.ReadInt32(); top = reader.ReadInt32(); right = reader.ReadInt32(); bottom = reader.ReadInt32(); }
internal Channel(PsdBinaryReader reader, Layer layer) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Channel"); ID = reader.ReadInt16(); Length = (layer.PsdFile.IsLargeDocument) ? reader.ReadInt64() : reader.ReadInt32(); Layer = layer; Util.DebugMessage(reader.BaseStream, $"Load, End, Channel, {ID}"); }
//internal void Save(PsdBinaryWriter writer) //{ // Util.DebugMessage(writer.BaseStream, "Save, Begin, Channel"); // writer.Write(ID); // if (Layer.PsdFile.IsLargeDocument) // { // writer.Write(Length); // } // else // { // writer.Write((Int32)Length); // } // Util.DebugMessage(writer.BaseStream, "Save, End, Channel, {0}", ID); //} ////////////////////////////////////////////////////////////////// internal void LoadPixelData(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Channel image"); if (Length == 0) { ImageCompression = ImageCompression.Raw; ImageDataRaw = new byte[0]; return; } var endPosition = reader.BaseStream.Position + this.Length; ImageCompression = (ImageCompression)reader.ReadInt16(); var longDataLength = this.Length - 2; Util.CheckByteArrayLength(longDataLength); var dataLength = (int)longDataLength; switch (ImageCompression) { case ImageCompression.Raw: ImageDataRaw = reader.ReadBytes(dataLength); break; case ImageCompression.Rle: // RLE row lengths RleRowLengths = new RleRowLengths(reader, Rect.Height, Layer.PsdFile.IsLargeDocument); var rleDataLength = (int)(endPosition - reader.BaseStream.Position); Debug.Assert(rleDataLength == RleRowLengths.Total, "RLE row lengths do not sum to length of channel image data."); // The PSD specification states that rows are padded to even sizes. // However, Photoshop doesn't actually do this. RLE rows can have // odd lengths in the header, and there is no padding between rows. ImageDataRaw = reader.ReadBytes(rleDataLength); break; case ImageCompression.Zip: case ImageCompression.ZipPrediction: ImageDataRaw = reader.ReadBytes(dataLength); break; } Util.DebugMessage(reader.BaseStream, "Load, End, Channel image, {0}", ID, Layer.Name); Debug.Assert(reader.BaseStream.Position == endPosition, "Pixel data was not fully read in."); }
private void LoadImage(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Composite image"); ImageCompression = (ImageCompression)reader.ReadInt16(); // Create channels for (Int16 i = 0; i < ChannelCount; i++) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Channel image data"); var channel = new Channel(i, this.BaseLayer); channel.ImageCompression = ImageCompression; channel.Length = this.RowCount * Util.BytesPerRow(BaseLayer.Rect.Size, BitDepth); // The composite image stores all RLE headers up-front, rather than // with each channel. if (ImageCompression == ImageCompression.Rle) { channel.RleRowLengths = new RleRowLengths(reader, RowCount, IsLargeDocument); channel.Length = channel.RleRowLengths.Total; } BaseLayer.Channels.Add(channel); Util.DebugMessage(reader.BaseStream, "Load, End, Channel image data"); } foreach (var channel in this.BaseLayer.Channels) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Channel image data"); Util.CheckByteArrayLength(channel.Length); channel.ImageDataRaw = reader.ReadBytes((int)channel.Length); Util.DebugMessage(reader.BaseStream, "Load, End, Channel image data"); } // If there is exactly one more channel than we need, then it is the // alpha channel. if ((ColorMode != PsdColorMode.Multichannel) && (ChannelCount == ColorMode.MinChannelCount() + 1)) { var alphaChannel = BaseLayer.Channels.Last(); alphaChannel.ID = -1; } Util.DebugMessage(reader.BaseStream, "Load, End, Composite image"); }
internal Channel(PsdBinaryReader reader, Layer layer) { ID = reader.ReadInt16(); Length = reader.ReadInt32(); Layer = layer; }
/////////////////////////////////////////////////////////////////////////// private void LoadHeader(PsdBinaryReader reader) { var signature = reader.ReadAsciiChars(4); if (signature != "8BPS") throw new PsdInvalidException("The given stream is not a valid PSD file"); Version = reader.ReadInt16(); if (Version != 1) throw new PsdInvalidException("The PSD file has an unknown version"); //6 bytes reserved reader.BaseStream.Position += 6; this.ChannelCount = reader.ReadInt16(); this.RowCount = reader.ReadInt32(); this.ColumnCount = reader.ReadInt32(); BitDepth = reader.ReadInt16(); ColorMode = (PsdColorMode)reader.ReadInt16(); }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// Load Layers Info section, including image data. /// </summary> /// <param name="reader">PSD reader.</param> /// <param name="hasHeader">Whether the Layers Info section has a length header.</param> private void LoadLayers(PsdBinaryReader reader, bool hasHeader) { UInt32 sectionLength = 0; if (hasHeader) { sectionLength = reader.ReadUInt32(); if (sectionLength <= 0) return; } var startPosition = reader.BaseStream.Position; var numLayers = reader.ReadInt16(); // If numLayers < 0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numLayers < 0) { AbsoluteAlpha = true; numLayers = Math.Abs(numLayers); } if (numLayers == 0) return; for (int i = 0; i < numLayers; i++) { var layer = new Layer(reader, this); Layers.Add(layer); } //----------------------------------------------------------------------- // Load image data for all channels. foreach (var layer in Layers) { foreach (var channel in layer.Channels) { channel.LoadPixelData(reader); } } // Length is set to 0 when called on higher bitdepth layers. if (sectionLength > 0) { // Layers Info section is documented to be even-padded, but Photoshop // actually pads to 4 bytes. var endPosition = startPosition + sectionLength; var positionOffset = reader.BaseStream.Position - endPosition; if (reader.BaseStream.Position < endPosition) reader.BaseStream.Position = endPosition; } }
/////////////////////////////////////////////////////////////////////////// //private void SaveLayerAndMaskInfo(PsdBinaryWriter writer) //{ // Util.DebugMessage(writer.BaseStream, "Save, Begin, Layer and mask info"); // using (new PsdBlockLengthWriter(writer, IsLargeDocument)) // { // var startPosition = writer.BaseStream.Position; // SaveLayers(writer); // SaveGlobalLayerMask(writer); // foreach (var info in AdditionalInfo) // { // info.Save(writer, // globalLayerInfo: true, // isLargeDocument: IsLargeDocument); // } // writer.WritePadding(startPosition, 2); // } // Util.DebugMessage(writer.BaseStream, "Save, End, Layer and mask info"); //} /////////////////////////////////////////////////////////////////////////// /// <summary> /// Load Layers Info section, including image data. /// </summary> /// <param name="reader">PSD reader.</param> /// <param name="hasHeader">Whether the Layers Info section has a length header.</param> internal void LoadLayers(PsdBinaryReader reader, bool hasHeader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Layers Info section"); long sectionLength = 0; if (hasHeader) { sectionLength = IsLargeDocument ? reader.ReadInt64() : reader.ReadUInt32(); if (sectionLength <= 0) { // The callback may take action when there are 0 layers, so it must // be called even though the Layers Info section is empty. LoadContext.OnLoadLayersHeader(this); Util.DebugMessage(reader.BaseStream, "Load, End, Layers Info section"); return; } } var startPosition = reader.BaseStream.Position; var numLayers = reader.ReadInt16(); // If numLayers < 0, then number of layers is absolute value, // and the first alpha channel contains the transparency data for // the merged result. if (numLayers < 0) { AbsoluteAlpha = true; numLayers = Math.Abs(numLayers); } for (int i = 0; i < numLayers; i++) { var layer = new Layer(reader, this); Layers.Add(layer); } // Header is complete just before loading pixel data LoadContext.OnLoadLayersHeader(this); //----------------------------------------------------------------------- // Load image data for all channels. foreach (var layer in Layers) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Layer image, layer.Name"); foreach (var channel in layer.Channels) { channel.LoadPixelData(reader); } Util.DebugMessage(reader.BaseStream, "Load, End, Layer image, layer.Name"); } // Length is set to 0 when called on higher bitdepth layers. if (sectionLength > 0) { // Layers Info section is documented to be even-padded, but Photoshop // actually pads to 4 bytes. var endPosition = startPosition + sectionLength; var positionOffset = reader.BaseStream.Position - endPosition; Debug.Assert(positionOffset > -4, "LoadLayers did not read the full length of the Layers Info section."); Debug.Assert(positionOffset <= 0, "LoadLayers read past the end of the Layers Info section."); if (reader.BaseStream.Position < endPosition) { reader.BaseStream.Position = endPosition; } } Util.DebugMessage(reader.BaseStream, "Load, End, Layers"); }
/////////////////////////////////////////////////////////////////////////// #endregion /////////////////////////////////////////////////////////////////////////// #region ImageData /////////////////////////////////////////////////////////////////////////// private void LoadImage(PsdBinaryReader reader) { ImageCompression = (ImageCompression)reader.ReadInt16(); // Create channels for (Int16 i = 0; i < ChannelCount; i++) { var channel = new Channel(i, this.BaseLayer); channel.ImageCompression = ImageCompression; channel.Length = this.RowCount * Util.BytesPerRow(BaseLayer.Rect, BitDepth); // The composite image stores all RLE headers up-front, rather than // with each channel. if (ImageCompression == ImageCompression.Rle) { channel.RleRowLengths = new RleRowLengths(reader, RowCount); channel.Length = channel.RleRowLengths.Total; } BaseLayer.Channels.Add(channel); } foreach (var channel in this.BaseLayer.Channels) { channel.ImageDataRaw = reader.ReadBytes(channel.Length); } // If there is exactly one more channel than we need, then it is the // alpha channel. if ((ColorMode != PsdColorMode.Multichannel) && (ChannelCount == ColorMode.MinChannelCount() + 1)) { var alphaChannel = BaseLayer.Channels.Last(); alphaChannel.ID = -1; } }
/////////////////////////////////////////////////////////////////////////// private void LoadImage(PsdBinaryReader reader) { Debug.WriteLine("LoadImage started at " + reader.BaseStream.Position.ToString(CultureInfo.InvariantCulture)); BaseLayer.Rect = new Rectangle(0, 0, ColumnCount, RowCount); ImageCompression = (ImageCompression)reader.ReadInt16(); switch (ImageCompression) { case ImageCompression.Raw: var length = this.RowCount * Util.BytesPerRow(BaseLayer.Rect, BitDepth); for (Int16 i = 0; i < ChannelCount; i++) { var channel = new Channel(i, this.BaseLayer); channel.ImageCompression = ImageCompression; channel.Length = length; channel.ImageData = reader.ReadBytes(length); BaseLayer.Channels.Add(channel); } break; case ImageCompression.Rle: // Store RLE data length for (Int16 i = 0; i < ChannelCount; i++) { var channel = new Channel(i, this.BaseLayer); channel.RleHeader = reader.ReadBytes(2 * RowCount); int totalRleLength = 0; using (var memoryStream = new MemoryStream(channel.RleHeader)) using (var memoryReader = new PsdBinaryReader(memoryStream, Encoding.ASCII)) { for (int j = 0; j < RowCount; j++) totalRleLength += memoryReader.ReadUInt16(); } channel.ImageCompression = this.ImageCompression; channel.Length = (int)totalRleLength; this.BaseLayer.Channels.Add(channel); } foreach (var channel in this.BaseLayer.Channels) { channel.Data = reader.ReadBytes(channel.Length); } break; } // If there is one more channel than we need, then it is the alpha channel if (ChannelCount == ColorMode.ChannelCount() + 1) { var alphaChannel = BaseLayer.Channels.Last(); alphaChannel.ID = -1; } }