Exemple #1
0
        ///////////////////////////////////////////////////////////////////////////

        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();
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        //////////////////////////////////////////////////////////////////

        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.");
        }
Exemple #5
0
        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");
        }
Exemple #6
0
        ///////////////////////////////////////////////////////////////////////////

        /// <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");
        }