Пример #1
0
        ///////////////////////////////////////////////////////////////////////////

        public void PrepareSave()
        {
            foreach (var ch in Channels)
            {
                ch.CompressImageData();
            }

            // Create or update the Unicode layer name to be consistent with the
            // ANSI layer name.
            var layerUnicodeNames = AdditionalInfo.Where(x => x is LayerUnicodeName);

            if (layerUnicodeNames.Count() > 1)
            {
                throw new PsdInvalidException(
                          $"{nameof(Layer)} can only have one {nameof(LayerUnicodeName)}.");
            }

            var layerUnicodeName = (LayerUnicodeName)layerUnicodeNames.FirstOrDefault();

            if (layerUnicodeName == null)
            {
                layerUnicodeName = new LayerUnicodeName(Name);
                AdditionalInfo.Add(layerUnicodeName);
            }
            else if (layerUnicodeName.Name != Name)
            {
                layerUnicodeName.Name = Name;
            }
        }
Пример #2
0
        public static LayerInfo Load(PsdBinaryReader reader)
        {
            Debug.WriteLine("LayerInfoFactory.Load started at " + reader.BaseStream.Position);

            var signature = reader.ReadAsciiChars(4);

            if (signature != "8BIM")
            {
                throw new PsdInvalidException("Could not read LayerInfo due to signature mismatch.");
            }

            var key           = reader.ReadAsciiChars(4);
            var length        = reader.ReadInt32();
            var startPosition = reader.BaseStream.Position;

            LayerInfo result;

            switch (key)
            {
            case "lsct":
            case "lsdk":
                result = new LayerSectionInfo(reader, key, length);
                break;

            case "luni":
                result = new LayerUnicodeName(reader);
                break;

            case "TySh":
                result = new LayerText(reader, length);
                break;

            case "tySH":
                result = new LayerTextType(reader);
                break;

            default:
                result = new RawLayerInfo(reader, key, length);
                break;
            }

            // May have additional padding applied.
            var endPosition = startPosition + length;

            if (reader.BaseStream.Position < endPosition)
            {
                reader.BaseStream.Position = endPosition;
            }

            // Documentation states that the length is even-padded.  Actually:
            //   1. Most keys have 4-padded lengths.
            //   2. However, some keys (LMsk) have even-padded lengths.
            //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
            //
            // The data is always 4-padded, regardless of the stated length.

            reader.ReadPadding(startPosition, 4);

            return(result);
        }
Пример #3
0
    public static LayerInfo Load(PsdBinaryReader reader)
    {
      Debug.WriteLine("LayerInfoFactory.Load started at " + reader.BaseStream.Position);
      
      var signature = reader.ReadAsciiChars(4);
      if (signature != "8BIM")
        throw new PsdInvalidException("Could not read LayerInfo due to signature mismatch.");

      var key = reader.ReadAsciiChars(4);
      var length = reader.ReadInt32();
      var startPosition = reader.BaseStream.Position;

      LayerInfo result;
      switch (key)
      {
        case "lsct":
        case "lsdk":
          result = new LayerSectionInfo(reader, key, length);
          break;
        case "luni":
          result = new LayerUnicodeName(reader);
          break;
        default:
          result = new RawLayerInfo(reader, key, length);
          break;
      }

      // May have additional padding applied.
      var endPosition = startPosition + length;
      if (reader.BaseStream.Position < endPosition)
        reader.BaseStream.Position = endPosition;

      // Documentation states that the length is even-padded.  Actually:
      //   1. Most keys have 4-padded lengths.
      //   2. However, some keys (LMsk) have even-padded lengths.
      //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
      //
      // The data is always 4-padded, regardless of the stated length.

      reader.ReadPadding(startPosition, 4);

      return result;
    }
Пример #4
0
        /// <summary>
        /// Loads the next LayerInfo record.
        /// </summary>
        /// <param name="reader">The file reader</param>
        /// <param name="psdFile">The PSD file.</param>
        /// <param name="globalLayerInfo">True if the LayerInfo record is being
        ///   loaded from the end of the Layer and Mask Information section;
        ///   false if it is being loaded from the end of a Layer record.</param>
        public static LayerInfo Load(PsdBinaryReader reader, PsdFile psdFile,
                                     bool globalLayerInfo, long fileEndPos)
        {
            Util.DebugMessage(reader.BaseStream, "Load, Begin, LayerInfo");

            // Some keys use a signature of 8B64, but the identity of these keys
            // is undocumented.  We will therefore accept either signature.
            var signature = reader.ReadAsciiChars(4);

            if ((signature != "8BIM") && (signature != "8B64"))
            {
                throw new PsdInvalidException(
                          "LayerInfo signature invalid, must be 8BIM or 8B64.");
            }

            var       key           = reader.ReadAsciiChars(4);
            var       hasLongLength = LayerInfoUtil.HasLongLength(key, psdFile.IsLargeDocument);
            LayerInfo result        = new RawLayerInfo("dummy");
            bool      breakFromLoop = false;

            while (!breakFromLoop)
            {
                var baseStartPosition = reader.BaseStream.Position;
                var length            = hasLongLength
                    ? reader.ReadInt64()
                    : reader.ReadInt32();
                var startPosition = reader.BaseStream.Position;


                switch (key)
                {
                case "Layr":
                case "Lr16":
                case "Lr32":
                    result = new InfoLayers(reader, psdFile, key, length);
                    break;

                case "lsct":
                case "lsdk":
                    result = new LayerSectionInfo(reader, key, (int)length);
                    break;

                case "luni":
                    result = new LayerUnicodeName(reader);
                    break;

                case "lyid":
                    result = new LayerId(reader, key, length);
                    break;

                default:
                    result = new RawLayerInfo(reader, signature, key, length);
                    break;
                }

                // May have additional padding applied.
                var endPosition = startPosition + length;
                if (reader.BaseStream.Position < endPosition)
                {
                    reader.BaseStream.Position = endPosition;
                }

                // Documentation states that the length is even-padded.  Actually:
                //   1. Most keys have 4-padded lengths.
                //   2. However, some keys (LMsk) have even-padded lengths.
                //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
                //
                // Photoshop writes data that is always 4-padded, even when the stated
                // length is not a multiple of 4.  The length mismatch seems to occur
                // only on global layer info.  We do not read extra padding in other
                // cases because third-party programs are likely to follow the spec.

                if (globalLayerInfo)
                {
                    reader.ReadPadding(startPosition, 4);
                }

                //try if we can read the next signature
                if (reader.BaseStream.Position < fileEndPos)
                {
                    var nowPosition = reader.BaseStream.Position;
                    signature = reader.ReadAsciiChars(4);
                    if ((signature != "8BIM") && (signature != "8B64"))
                    {
                        hasLongLength = true;
                        reader.BaseStream.Position = baseStartPosition;
                    }
                    else
                    {
                        reader.BaseStream.Position = nowPosition;
                        breakFromLoop = true;
                    }
                }
                else
                {
                    breakFromLoop = true;
                }
            }


            Util.DebugMessage(reader.BaseStream, "Load, End, LayerInfo, {0}, {1}",
                              result.Signature, result.Key);
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Loads the next LayerInfo record.
        /// </summary>
        /// <param name="reader">The file reader</param>
        /// <param name="psdFile">The PSD file.</param>
        /// <param name="globalLayerInfo">True if the LayerInfo record is being
        ///   loaded from the end of the Layer and Mask Information section;
        ///   false if it is being loaded from the end of a Layer record.</param>
        /// <returns>LayerInfo object if it was successfully read, or null if
        ///   padding was found.</returns>
        private static LayerInfo Load(PsdBinaryReader reader, PsdFile psdFile,
                                      bool globalLayerInfo)
        {
            Util.DebugMessage(reader.BaseStream, "Load, Begin, LayerInfo");

            // Most keys have undocumented signatures, so we always accept either one.
            var signature = reader.ReadAsciiChars(4);

            if ((signature != "8BIM") && (signature != "8B64"))
            {
                throw new PsdInvalidException(
                          $"{nameof(LayerInfo)} signature invalid, must be 8BIM or 8B64.");
            }

            var key           = reader.ReadAsciiChars(4);
            var hasLongLength = LayerInfoUtil.HasLongLength(signature, key, psdFile.IsLargeDocument);
            var length        = hasLongLength
        ? reader.ReadInt64()
        : reader.ReadInt32();
            var startPosition = reader.BaseStream.Position;

            LayerInfo result;

            switch (key)
            {
            case "Layr":
            case "Lr16":
            case "Lr32":
                result = new InfoLayers(reader, psdFile, key, length);
                break;

            case "lsct":
            case "lsdk":
                result = new LayerSectionInfo(reader, key, (int)length);
                break;

            case "luni":
                result = new LayerUnicodeName(reader);
                break;

            default:
                result = new RawLayerInfo(reader, signature, key, length);
                break;
            }

            // May have additional padding applied.
            var endPosition = startPosition + length;

            if (reader.BaseStream.Position < endPosition)
            {
                reader.BaseStream.Position = endPosition;
            }

            // Documentation states that the length is even-padded.  Actually:
            //   1. Most keys have 4-padded lengths.
            //   2. However, some keys (LMsk) have even-padded lengths.
            //   3. Other keys (Txt2, Lr16, Lr32) have unpadded lengths.
            //
            // Photoshop writes data that is always 4-padded, even when the stated
            // length is not a multiple of 4.  The length mismatch seems to occur
            // only on global layer info.  We do not read extra padding in other
            // cases because third-party programs are likely to follow the spec.

            if (globalLayerInfo)
            {
                reader.ReadPadding(startPosition, 4);
            }

            Util.DebugMessage(reader.BaseStream,
                              $"Load, End, LayerInfo, {result.Signature}, {result.Key}");
            return(result);
        }
Пример #6
0
    ///////////////////////////////////////////////////////////////////////////

    public void PrepareSave()
    {
      foreach (var ch in Channels)
      {
        ch.CompressImageData();
      }

      // Create or update the Unicode layer name to be consistent with the
      // ANSI layer name.
      var layerUnicodeNames = AdditionalInfo.Where(x => x is LayerUnicodeName);
      if (layerUnicodeNames.Count() > 1)
        throw new PsdInvalidException("Layer has more than one LayerUnicodeName.");

      var layerUnicodeName = (LayerUnicodeName) layerUnicodeNames.FirstOrDefault();
      if (layerUnicodeName == null)
      {
        layerUnicodeName = new LayerUnicodeName(Name);
        AdditionalInfo.Add(layerUnicodeName);
      }
      else if (layerUnicodeName.Name != Name)
      {
        layerUnicodeName.Name = Name;
      }
    }