/////////////////////////////////////////////////////////////////////////// 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 UFixed1616(reader.ReadUInt32()); this.HResDisplayUnit = (ResUnit)reader.ReadInt16(); this.WidthDisplayUnit = (Unit)reader.ReadInt16(); this.VDpi = new UFixed1616(reader.ReadUInt32()); this.VResDisplayUnit = (ResUnit)reader.ReadInt16(); this.HeightDisplayUnit = (Unit)reader.ReadInt16(); }
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, {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 + Length; ImageCompression = (ImageCompression)reader.ReadInt16(); var longDataLength = Length - 2; Util.CheckByteArrayLength(longDataLength); var dataLength = (Int32)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 = (Int32)(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"); }
/////////////////////////////////////////////////////////////////////////// /// <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"); }