Exemplo n.º 1
0
        public void Save(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, Layer");

            writer.Write(Rect);

            //-----------------------------------------------------------------------

            writer.Write((Int16)Channels.Count);
            foreach (var ch in Channels)
            {
                ch.Save(writer);
            }

            //-----------------------------------------------------------------------

            writer.WriteAsciiChars("8BIM");
            writer.WriteAsciiChars(BlendModeKey);
            writer.Write(Opacity);
            writer.Write(Clipping);

            writer.Write((Byte)_flags.Data);
            writer.Write((Byte)0);

            //-----------------------------------------------------------------------

            using (new PsdBlockLengthWriter(writer))
            {
                Masks.Save(writer);
                BlendingRangesData.Save(writer);

                var namePosition = writer.BaseStream.Position;

                // Legacy layer name is limited to 31 bytes.  Unicode layer name
                // can be much longer.
                writer.WritePascalString(Name, 4, 31);

                foreach (LayerInfo info in AdditionalInfo)
                {
                    info.Save(writer,
                              globalLayerInfo: false,
                              isLargeDocument: PsdFile.IsLargeDocument);
                }
            }

            Util.DebugMessage(writer.BaseStream, "Save, End, Layer, {0}", Name);
        }
Exemplo n.º 2
0
        ///////////////////////////////////////////////////////////////////////////

        private void SaveHeader(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, File header");

            string signature = "8BPS";

            writer.WriteAsciiChars(signature);
            writer.Write((Int16)Version);
            writer.Write(new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, });
            writer.Write(ChannelCount);
            writer.Write(RowCount);
            writer.Write(ColumnCount);
            writer.Write((Int16)BitDepth);
            writer.Write((Int16)ColorMode);

            Util.DebugMessage(writer.BaseStream, "Save, End, File header");
        }
Exemplo n.º 3
0
        /// <summary>
        /// Saves the layer data, excluding headers and padding.
        /// </summary>
        /// <param name="writer">The PSD writer.</param>
        internal void SaveLayersData(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, Layers");

            var numLayers = (Int16)Layers.Count;

            if (AbsoluteAlpha)
            {
                numLayers = (Int16)(-numLayers);
            }

            // Photoshop will not load files that have a layer count of 0 in the
            // compatible Layers section.  Instead, the Layers section must be
            // entirely empty.
            if (numLayers == 0)
            {
                return;
            }

            writer.Write(numLayers);

            foreach (var layer in Layers)
            {
                layer.Save(writer);
            }

            foreach (var layer in Layers)
            {
                Util.DebugMessage(writer.BaseStream,
                                  $"Save, Begin, Layer image, {layer.Name}");
                foreach (var channel in layer.Channels)
                {
                    channel.SavePixelData(writer);
                }
                Util.DebugMessage(writer.BaseStream,
                                  $"Save, End, Layer image, {layer.Name}");
            }

            // The caller is responsible for padding.  Photoshop writes padded
            // lengths for compatible layers, but unpadded lengths for Additional
            // Info layers.

            Util.DebugMessage(writer.BaseStream, "Save, End, Layers");
        }
Exemplo n.º 4
0
        internal void SavePixelData(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, Channel image");

            writer.Write((Int16)ImageCompression);
            if (ImageDataRaw == null)
            {
                return;
            }

            if (ImageCompression == ImageCompression.Rle)
            {
                RleRowLengths.Write(writer, Layer.PsdFile.IsLargeDocument);
            }
            writer.Write(ImageDataRaw);

            Util.DebugMessage(writer.BaseStream, "Save, End, Channel image, {0}",
                              ID, Layer.Name);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Write out the image resource block: header and data.
        /// </summary>
        public void Save(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, ImageResource");

            writer.WriteAsciiChars(Signature);
            writer.Write((UInt16)ID);
            writer.WritePascalString(Name, 2);

            // Length is unpadded, but data is even-padded
            var startPosition = writer.BaseStream.Position;

            using (new PsdBlockLengthWriter(writer))
            {
                WriteData(writer);
            }
            writer.WritePadding(startPosition, 2);

            Util.DebugMessage(writer.BaseStream, "Save, End, ImageResource, {0}", ID);
        }
Exemplo n.º 6
0
        public PsdBlockLengthWriter(PsdBinaryWriter writer, bool hasLongLength)
        {
            this._writer        = writer;
            this._hasLongLength = hasLongLength;

            // Store position so that we can return to it when the length is known.
            _lengthPosition = writer.BaseStream.Position;

            // Write a sentinel value as a placeholder for the length.
            writer.Write((UInt32)0xFEEDFEED);
            if (hasLongLength)
            {
                writer.Write((UInt32)0xFEEDFEED);
            }

            // Store the start position of the data block so that we can calculate
            // its length when we're done writing.
            _startPosition = writer.BaseStream.Position;
        }
Exemplo n.º 7
0
        ///////////////////////////////////////////////////////////////////////////

        private void SaveImage(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, Composite image");

            writer.Write((short)this.ImageCompression);
            if (this.ImageCompression == Memoria.PSD.ImageCompression.Rle)
            {
                foreach (var channel in this.BaseLayer.Channels)
                {
                    Util.DebugMessage(writer.BaseStream, "Save, Begin, RLE header");
                    channel.RleRowLengths.Write(writer, IsLargeDocument);
                    Util.DebugMessage(writer.BaseStream, "Save, End, RLE header");
                }
            }
            foreach (var channel in this.BaseLayer.Channels)
            {
                Util.DebugMessage(writer.BaseStream, "Save, Begin, Channel image data");
                writer.Write(channel.ImageDataRaw);
                Util.DebugMessage(writer.BaseStream, "Save, End, Channel image data");
            }

            Util.DebugMessage(writer.BaseStream, "Save, End, Composite image");
        }
Exemplo n.º 8
0
        ///////////////////////////////////////////////////////////////////////////

        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");
        }
Exemplo n.º 9
0
        /// <summary>
        /// Saves the Layers Info section, including headers and padding.
        /// </summary>
        /// <param name="writer">The PSD writer.</param>
        internal void SaveLayers(PsdBinaryWriter writer)
        {
            Util.DebugMessage(writer.BaseStream, "Save, Begin, Layers Info section");

            using (new PsdBlockLengthWriter(writer, IsLargeDocument))
            {
                var startPosition = writer.BaseStream.Position;

                // Only one set of Layers can exist in the file.  If layers will be
                // written to the Additional Info section, then the Layers section
                // must be empty to avoid conflict.
                var hasInfoLayers = AdditionalInfo.Exists(x => x is InfoLayers);
                if (!hasInfoLayers)
                {
                    SaveLayersData(writer);
                }

                // Documentation states that the Layers Info section is even-padded,
                // but it is actually padded to a multiple of 4.
                writer.WritePadding(startPosition, 4);
            }

            Util.DebugMessage(writer.BaseStream, "Save, End, Layers Info section");
        }
Exemplo n.º 10
0
 protected override void WriteData(PsdBinaryWriter writer)
 {
     PsdFile.SaveLayersData(writer);
 }
Exemplo n.º 11
0
 /// <summary>
 /// Write the data for this image resource.
 /// </summary>
 protected abstract void WriteData(PsdBinaryWriter writer);
Exemplo n.º 12
0
 public PsdBlockLengthWriter(PsdBinaryWriter writer)
     : this(writer, false)
 {
 }
Exemplo n.º 13
0
 protected override void WriteData(PsdBinaryWriter writer)
 {
     writer.Write(Data);
 }