123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization.Formatters.Binary;
- namespace PaintDotNet.SystemLayer
- {
- /// <summary>
- /// Re-implements System.Drawing.PropertyItem so that the data is serializable.
- /// </summary>
- [Serializable]
- internal sealed class PropertyItem2
- {
- private const string piElementName = "exif";
- private const string idPropertyName = "id";
- private const string lenPropertyName = "len";
- private const string typePropertyName = "type";
- private const string valuePropertyName = "value";
- private int id;
- private int len;
- private short type;
- private byte[] value;
- public int Id
- {
- get
- {
- return id;
- }
- }
- public int Len
- {
- get
- {
- return len;
- }
- }
- public short Type
- {
- get
- {
- return type;
- }
- }
- public byte[] Value
- {
- get
- {
- return (byte[])value.Clone();
- }
- }
- public PropertyItem2(int id, int len, short type, byte[] value)
- {
- this.id = id;
- this.len = len;
- this.type = type;
- if (value == null)
- {
- this.value = new byte[0];
- }
- else
- {
- this.value = (byte[])value.Clone();
- }
- if (len != this.value.Length)
- {
- Tracing.Ping("len != value.Length: id=" + id + ", type=" + type);
- }
- }
- public string ToBlob()
- {
- string blob = string.Format("<{0} {1}=\"{2}\" {3}=\"{4}\" {5}=\"{6}\" {7}=\"{8}\" />",
- piElementName,
- idPropertyName, this.id.ToString(CultureInfo.InvariantCulture),
- lenPropertyName, this.len.ToString(CultureInfo.InvariantCulture),
- typePropertyName, this.type.ToString(CultureInfo.InvariantCulture),
- valuePropertyName, Convert.ToBase64String(this.value));
- return blob;
- }
- [MethodImpl(MethodImplOptions.Synchronized)]
- public PropertyItem ToPropertyItem()
- {
- PropertyItem pi = GetPropertyItem();
- pi.Id = this.Id;
- pi.Len = this.Len;
- pi.Type = this.Type;
- pi.Value = this.Value;
- return pi;
- }
- public static PropertyItem2 FromPropertyItem(PropertyItem pi)
- {
- return new PropertyItem2(pi.Id, pi.Len, pi.Type, pi.Value);
- }
- private static string GetProperty(string blob, string propertyName)
- {
- string findMe = propertyName + "=\"";
- int startIndex = blob.IndexOf(findMe) + findMe.Length;
- int endIndex = blob.IndexOf("\"", startIndex);
- string propertyValue = blob.Substring(startIndex, endIndex - startIndex);
- return propertyValue;
- }
- public static PropertyItem2 FromBlob(string blob)
- {
- PropertyItem2 pi2;
- if (blob.Length > 0 && blob[0] == '<')
- {
- string idStr = GetProperty(blob, idPropertyName);
- string lenStr = GetProperty(blob, lenPropertyName);
- string typeStr = GetProperty(blob, typePropertyName);
- string valueStr = GetProperty(blob, valuePropertyName);
- int id = int.Parse(idStr, CultureInfo.InvariantCulture);
- int len = int.Parse(lenStr, CultureInfo.InvariantCulture);
- short type = short.Parse(typeStr, CultureInfo.InvariantCulture);
- byte[] value = Convert.FromBase64String(valueStr);
- pi2 = new PropertyItem2(id, len, type, value);
- }
- else
- {
- // Old way of serializing: .NET serialized!
- byte[] bytes = Convert.FromBase64String(blob);
- MemoryStream ms = new MemoryStream(bytes);
- BinaryFormatter bf = new BinaryFormatter();
- SerializationFallbackBinder sfb = new SerializationFallbackBinder();
- sfb.AddAssembly(Assembly.GetExecutingAssembly());
- bf.Binder = sfb;
- pi2 = (PropertyItem2)bf.Deserialize(ms);
- }
- return pi2;
- }
- // System.Drawing.Imaging.PropertyItem does not have a public constructor
- // So, as per the documentation, we have to "steal" one.
- // Quite ridiculous.
- // This depends on PropertyItem.png being an embedded resource in this assembly.
- private static Image propertyItemImage;
- [MethodImpl(MethodImplOptions.Synchronized)]
- private static PropertyItem GetPropertyItem()
- {
- if (propertyItemImage == null)
- {
- Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PaintDotNet.SystemLayer.PropertyItem.png");
- propertyItemImage = Image.FromStream(stream);
- }
- PropertyItem pi = propertyItemImage.PropertyItems[0];
- pi.Id = 0;
- pi.Len = 0;
- pi.Type = 0;
- pi.Value = new byte[0];
- return pi;
- }
- }
- }
|