public VersionInfo(PsdBinaryReader reader, String name) : base(name) { Version = reader.ReadUInt32(); HasRealMergedData = reader.ReadBoolean(); ReaderName = reader.ReadUnicodeString(); WriterName = reader.ReadUnicodeString(); FileVersion = reader.ReadUInt32(); }
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(); }
/////////////////////////////////////////////////////////////////////////// private void LoadImageResources(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, ImageResources"); var imageResourcesLength = reader.ReadUInt32(); if (imageResourcesLength <= 0) { return; } var startPosition = reader.BaseStream.Position; var endPosition = startPosition + imageResourcesLength; while (reader.BaseStream.Position < endPosition) { var imageResource = ImageResourceFactory.CreateImageResource(reader); ImageResources.Add(imageResource); } Util.DebugMessage(reader.BaseStream, "Load, End, ImageResources"); //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + imageResourcesLength; }
public static ImageResource CreateImageResource(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, ImageResource"); var signature = reader.ReadAsciiChars(4); var resourceIdInt = reader.ReadUInt16(); var name = reader.ReadPascalString(2); var dataLength = (Int32)reader.ReadUInt32(); var dataPaddedLength = Util.RoundUp(dataLength, 2); var endPosition = reader.BaseStream.Position + dataPaddedLength; ImageResource resource = null; var resourceId = (ResourceID)resourceIdInt; switch (resourceId) { case ResourceID.ResolutionInfo: resource = new ResolutionInfo(reader, name); break; case ResourceID.AlphaChannelNames: resource = new AlphaChannelNames(reader, name, dataLength); break; case ResourceID.UnicodeAlphaNames: resource = new UnicodeAlphaNames(reader, name, dataLength); break; case ResourceID.VersionInfo: resource = new VersionInfo(reader, name); break; default: resource = new RawImageResource(reader, signature, resourceId, name, dataLength); break; } Util.DebugMessage(reader.BaseStream, "Load, End, ImageResource, {0}", resourceId); // Reposition the reader if we do not consume the full resource block. // This takes care of the even-padding, and also preserves forward- // compatibility in case a resource block is later extended with // additional properties. if (reader.BaseStream.Position < endPosition) { reader.BaseStream.Position = endPosition; } // However, overruns are definitely an error. if (reader.BaseStream.Position > endPosition) { throw new PsdInvalidException("Corruption detected in resource."); } return(resource); }
private void LoadColorModeData(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, ColorModeData"); var paletteLength = reader.ReadUInt32(); if (paletteLength > 0) { ColorModeData = reader.ReadBytes((Int32)paletteLength); } Util.DebugMessage(reader.BaseStream, "Load, End, ColorModeData"); }
/////////////////////////////////////////////////////////////////////////// private void LoadLayerAndMaskInfo(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Layer and mask info"); var layersAndMaskLength = IsLargeDocument ? reader.ReadInt64() : reader.ReadUInt32(); if (layersAndMaskLength <= 0) { return; } var startPosition = reader.BaseStream.Position; var endPosition = startPosition + layersAndMaskLength; LoadLayers(reader, true); LoadGlobalLayerMask(reader); //----------------------------------------------------------------------- // Load Additional Layer Information while (reader.BaseStream.Position < endPosition) { var info = LayerInfoFactory.Load(reader, psdFile: this, globalLayerInfo: true); AdditionalInfo.Add(info); if (info is RawLayerInfo) { var layerInfo = (RawLayerInfo)info; switch (info.Key) { case "LMsk": _globalLayerMaskData = layerInfo.Data; break; } } } Util.DebugMessage(reader.BaseStream, "Load, End, Layer and mask info"); //----------------------------------------------------------------------- // make sure we are not on a wrong offset, so set the stream position // manually reader.BaseStream.Position = startPosition + layersAndMaskLength; }
private void LoadGlobalLayerMask(PsdBinaryReader reader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, GlobalLayerMask"); var maskLength = reader.ReadUInt32(); if (maskLength <= 0) { Util.DebugMessage(reader.BaseStream, "Load, End, GlobalLayerMask"); return; } _globalLayerMaskData = reader.ReadBytes((Int32)maskLength); Util.DebugMessage(reader.BaseStream, "Load, End, GlobalLayerMask"); }
public MaskInfo(PsdBinaryReader reader, Layer layer) { Util.DebugMessage(reader.BaseStream, "Load, Begin, MaskInfo"); var maskLength = reader.ReadUInt32(); if (maskLength <= 0) { return; } var startPosition = reader.BaseStream.Position; var endPosition = startPosition + maskLength; // Read layer mask var rectangle = reader.ReadRectangle(); var backgroundColor = reader.ReadByte(); var flagsByte = reader.ReadByte(); LayerMask = new Mask(layer, rectangle, backgroundColor, new BitVector32(flagsByte)); // User mask is supplied separately when there is also a vector mask. if (maskLength == 36) { var userFlagsByte = reader.ReadByte(); var userBackgroundColor = reader.ReadByte(); var userRectangle = reader.ReadRectangle(); UserMask = new Mask(layer, userRectangle, userBackgroundColor, new BitVector32(userFlagsByte)); } // 20-byte mask data will end with padding. reader.BaseStream.Position = endPosition; Util.DebugMessage(reader.BaseStream, "Load, End, MaskInfo"); }
public Layer(PsdBinaryReader reader, PsdFile psdFile) : this(psdFile) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Layer"); Rect = reader.ReadRectangle(); //----------------------------------------------------------------------- // Read channel headers. Image data comes later, after the layer header. Int32 numberOfChannels = reader.ReadUInt16(); for (Int32 channel = 0; channel < numberOfChannels; channel++) { var ch = new Channel(reader, this); Channels.Add(ch); } //----------------------------------------------------------------------- // var signature = reader.ReadAsciiChars(4); if (signature != "8BIM") { throw (new PsdInvalidException("Invalid signature in layer header.")); } BlendModeKey = reader.ReadAsciiChars(4); Opacity = reader.ReadByte(); Clipping = reader.ReadBoolean(); var flagsByte = reader.ReadByte(); _flags = new BitVector32(flagsByte); reader.ReadByte(); //padding //----------------------------------------------------------------------- // This is the total size of the MaskData, the BlendingRangesData, the // Name and the AdjustmentLayerInfo. var extraDataSize = reader.ReadUInt32(); var extraDataStartPosition = reader.BaseStream.Position; Masks = new MaskInfo(reader, this); BlendingRangesData = new BlendingRanges(reader, this); Name = reader.ReadPascalString(4); //----------------------------------------------------------------------- // Process Additional Layer Information Int64 adjustmentLayerEndPos = extraDataStartPosition + extraDataSize; while (reader.BaseStream.Position < adjustmentLayerEndPos) { var layerInfo = LayerInfoFactory.Load(reader, psdFile: PsdFile, globalLayerInfo: false); AdditionalInfo.Add(layerInfo); } foreach (var adjustmentInfo in AdditionalInfo) { switch (adjustmentInfo.Key) { case "luni": Name = ((LayerUnicodeName)adjustmentInfo).Name; break; } } Util.DebugMessage(reader.BaseStream, "Load, End, Layer, {0}", Name); PsdFile.LoadContext.OnLoadLayerHeader(this); }
/////////////////////////////////////////////////////////////////////////// /// <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, Boolean hasHeader) { Util.DebugMessage(reader.BaseStream, "Load, Begin, Layers Info section"); Int64 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 (Int32 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"); }