Exif.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. using PaintDotNet.SystemLayer;
  2. using System;
  3. using System.Drawing.Imaging;
  4. namespace PaintDotNet
  5. {
  6. public sealed class Exif
  7. {
  8. private Exif()
  9. {
  10. }
  11. public static PropertyItem CreatePropertyItem(ExifTagID id, ExifTagType type, byte[] data)
  12. {
  13. return CreatePropertyItem((short)id, type, data);
  14. }
  15. public static PropertyItem CreatePropertyItem(short id, ExifTagType type, byte[] data)
  16. {
  17. PropertyItem pi = PdnGraphics.CreatePropertyItem();
  18. pi.Id = id;
  19. pi.Type = (short)type;
  20. pi.Len = data.Length;
  21. pi.Value = (byte[])data.Clone();
  22. return pi;
  23. }
  24. public static string DecodeAsciiValue(PropertyItem pi)
  25. {
  26. if (pi.Type != (short)ExifTagType.Ascii)
  27. {
  28. throw new ArgumentException("pi.Type != ExifTagType.Ascii");
  29. }
  30. string data = System.Text.Encoding.ASCII.GetString(pi.Value);
  31. if (data[data.Length - 1] == '\0')
  32. {
  33. data = data.Substring(0, data.Length - 1);
  34. }
  35. return data;
  36. }
  37. public static PropertyItem CreateAscii(ExifTagID id, string value)
  38. {
  39. return CreateAscii((short)id, value);
  40. }
  41. public static PropertyItem CreateAscii(short id, string value)
  42. {
  43. return CreatePropertyItem(id, ExifTagType.Ascii, EncodeAsciiValue(value + "\0"));
  44. }
  45. public static byte[] EncodeAsciiValue(string value)
  46. {
  47. return System.Text.Encoding.ASCII.GetBytes(value);
  48. }
  49. public static byte DecodeByteValue(PropertyItem pi)
  50. {
  51. if (pi.Type != (short)ExifTagType.Byte)
  52. {
  53. throw new ArgumentException("pi.Type != ExifTagType.Byte");
  54. }
  55. if (pi.Value.Length != 1)
  56. {
  57. throw new ArgumentException("pi.Value.Length != 1");
  58. }
  59. if (pi.Len != 1)
  60. {
  61. throw new ArgumentException("pi.Length != 1");
  62. }
  63. return pi.Value[0];
  64. }
  65. public static PropertyItem CreateByte(ExifTagID id, byte value)
  66. {
  67. return CreateByte((short)id, value);
  68. }
  69. public static PropertyItem CreateByte(short id, byte value)
  70. {
  71. return CreatePropertyItem(id, ExifTagType.Byte, EncodeByteValue(value));
  72. }
  73. public static byte[] EncodeByteValue(byte value)
  74. {
  75. return new byte[] { value };
  76. }
  77. public static ushort DecodeShortValue(PropertyItem pi)
  78. {
  79. if (pi.Type != (short)ExifTagType.Short)
  80. {
  81. throw new ArgumentException("pi.Type != ExifTagType.Short");
  82. }
  83. if (pi.Value.Length != 2)
  84. {
  85. throw new ArgumentException("pi.Value.Length != 2");
  86. }
  87. if (pi.Len != 2)
  88. {
  89. throw new ArgumentException("pi.Length != 2");
  90. }
  91. return (ushort)(pi.Value[0] + (pi.Value[1] << 8));
  92. }
  93. public static PropertyItem CreateShort(ExifTagID id, ushort value)
  94. {
  95. return CreateShort((short)id, value);
  96. }
  97. public static PropertyItem CreateShort(short id, ushort value)
  98. {
  99. return CreatePropertyItem(id, ExifTagType.Short, EncodeShortValue(value));
  100. }
  101. public static byte[] EncodeShortValue(ushort value)
  102. {
  103. return new byte[] {
  104. (byte)(value & 0xff),
  105. (byte)((value >> 8) & 0xff)
  106. };
  107. }
  108. public static uint DecodeLongValue(PropertyItem pi)
  109. {
  110. if (pi.Type != (short)ExifTagType.Long)
  111. {
  112. throw new ArgumentException("pi.Type != ExifTagType.Long");
  113. }
  114. if (pi.Value.Length != 4)
  115. {
  116. throw new ArgumentException("pi.Value.Length != 4");
  117. }
  118. if (pi.Len != 4)
  119. {
  120. throw new ArgumentException("pi.Length != 4");
  121. }
  122. return (uint)pi.Value[0] + ((uint)pi.Value[1] << 8) + ((uint)pi.Value[2] << 16) + ((uint)pi.Value[3] << 24);
  123. }
  124. public static PropertyItem CreateLong(ExifTagID id, uint value)
  125. {
  126. return CreateLong((short)id, value);
  127. }
  128. public static PropertyItem CreateLong(short id, uint value)
  129. {
  130. return CreatePropertyItem(id, ExifTagType.Long, EncodeLongValue(value));
  131. }
  132. public static byte[] EncodeLongValue(uint value)
  133. {
  134. return new byte[] {
  135. (byte)(value & 0xff),
  136. (byte)((value >> 8) & 0xff),
  137. (byte)((value >> 16) & 0xff),
  138. (byte)((value >> 24) & 0xff)
  139. };
  140. }
  141. public static void DecodeRationalValue(PropertyItem pi, out uint numerator, out uint denominator)
  142. {
  143. if (pi.Type != (short)ExifTagType.Rational)
  144. {
  145. throw new ArgumentException("pi.Type != ExifTagType.Rational");
  146. }
  147. if (pi.Value.Length != 8)
  148. {
  149. throw new ArgumentException("pi.Value.Length != 8");
  150. }
  151. if (pi.Len != 8)
  152. {
  153. throw new ArgumentException("pi.Length != 8");
  154. }
  155. numerator = (uint)pi.Value[0] + ((uint)pi.Value[1] << 8) + ((uint)pi.Value[2] << 16) + ((uint)pi.Value[3] << 24);
  156. denominator = (uint)pi.Value[4] + ((uint)pi.Value[5] << 8) + ((uint)pi.Value[6] << 16) + ((uint)pi.Value[7] << 24);
  157. }
  158. public static PropertyItem CreateRational(ExifTagID id, uint numerator, uint denominator)
  159. {
  160. return CreateRational((short)id, numerator, denominator);
  161. }
  162. public static PropertyItem CreateRational(short id, uint numerator, uint denominator)
  163. {
  164. return CreatePropertyItem(id, ExifTagType.Rational, EncodeRationalValue(numerator, denominator));
  165. }
  166. public static byte[] EncodeRationalValue(uint numerator, uint denominator)
  167. {
  168. return new byte[] {
  169. (byte)(numerator & 0xff),
  170. (byte)((numerator >> 8) & 0xff),
  171. (byte)((numerator >> 16) & 0xff),
  172. (byte)((numerator >> 24) & 0xff),
  173. (byte)(denominator & 0xff),
  174. (byte)((denominator >> 8) & 0xff),
  175. (byte)((denominator >> 16) & 0xff),
  176. (byte)((denominator >> 24) & 0xff)
  177. };
  178. }
  179. public static byte DecodeUndefinedValue(PropertyItem pi)
  180. {
  181. if (pi.Type != (short)ExifTagType.Undefined)
  182. {
  183. throw new ArgumentException("pi.Type != ExifTagType.Undefined");
  184. }
  185. if (pi.Value.Length != 1)
  186. {
  187. throw new ArgumentException("pi.Value.Length != 1");
  188. }
  189. if (pi.Len != 1)
  190. {
  191. throw new ArgumentException("pi.Length != 1");
  192. }
  193. return pi.Value[0];
  194. }
  195. public static PropertyItem CreateUndefined(ExifTagID id, byte value)
  196. {
  197. return CreateUndefined((short)id, value);
  198. }
  199. public static PropertyItem CreateUndefined(short id, byte value)
  200. {
  201. return CreatePropertyItem(id, ExifTagType.Undefined, EncodeUndefinedValue(value));
  202. }
  203. public static byte[] EncodeUndefinedValue(byte value)
  204. {
  205. return new byte[] { value };
  206. }
  207. public static int DecodeSLongValue(PropertyItem pi)
  208. {
  209. if (pi.Type != (short)ExifTagType.SLong)
  210. {
  211. throw new ArgumentException("pi.Type != ExifTagType.SLong");
  212. }
  213. if (pi.Value.Length != 4)
  214. {
  215. throw new ArgumentException("pi.Value.Length != 4");
  216. }
  217. if (pi.Len != 4)
  218. {
  219. throw new ArgumentException("pi.Length != 4");
  220. }
  221. return pi.Value[0] + (pi.Value[1] << 8) + (pi.Value[2] << 16) + (pi.Value[3] << 24);
  222. }
  223. public static PropertyItem CreateSLong(ExifTagID id, int value)
  224. {
  225. return CreateSLong((short)id, value);
  226. }
  227. public static PropertyItem CreateSLong(short id, int value)
  228. {
  229. return CreatePropertyItem(id, ExifTagType.SLong, EncodeSLongValue(value));
  230. }
  231. public static byte[] EncodeSLongValue(int value)
  232. {
  233. return new byte[] {
  234. (byte)(value & 0xff),
  235. (byte)((value >> 8) & 0xff),
  236. (byte)((value >> 16) & 0xff),
  237. (byte)((value >> 24) & 0xff)
  238. };
  239. }
  240. public static void DecodeRationalValue(PropertyItem pi, out int numerator, out int denominator)
  241. {
  242. if (pi.Type != (short)ExifTagType.SRational)
  243. {
  244. throw new ArgumentException("pi.Type != ExifTagType.SRational");
  245. }
  246. if (pi.Value.Length != 8)
  247. {
  248. throw new ArgumentException("pi.Value.Length != 8");
  249. }
  250. if (pi.Len != 8)
  251. {
  252. throw new ArgumentException("pi.Length != 8");
  253. }
  254. numerator = pi.Value[0] + (pi.Value[1] << 8) + (pi.Value[2] << 16) + (pi.Value[3] << 24);
  255. denominator = pi.Value[4] + (pi.Value[5] << 8) + (pi.Value[6] << 16) + (pi.Value[7] << 24);
  256. }
  257. public static PropertyItem CreateSRational(ExifTagID id, int numerator, int denominator)
  258. {
  259. return CreateSRational((short)id, numerator, denominator);
  260. }
  261. public static PropertyItem CreateSRational(short id, int numerator, int denominator)
  262. {
  263. return CreatePropertyItem(id, ExifTagType.SRational, EncodeSRationalValue(numerator, denominator));
  264. }
  265. public static byte[] EncodeSRationalValue(int numerator, int denominator)
  266. {
  267. return new byte[] {
  268. (byte)(numerator & 0xff),
  269. (byte)((numerator >> 8) & 0xff),
  270. (byte)((numerator >> 16) & 0xff),
  271. (byte)((numerator >> 24) & 0xff),
  272. (byte)(denominator & 0xff),
  273. (byte)((denominator >> 8) & 0xff),
  274. (byte)((denominator >> 16) & 0xff),
  275. (byte)((denominator >> 24) & 0xff)
  276. };
  277. }
  278. }
  279. }