No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ImageResource.cs 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Photoshop PSD FileType Plugin for Paint.NET
  4. // http://psdplugin.codeplex.com/
  5. //
  6. // This software is provided under the MIT License:
  7. // Copyright (c) 2006-2007 Frank Blumenberg
  8. // Copyright (c) 2010-2015 Tao Yue
  9. //
  10. // Portions of this file are provided under the BSD 3-clause License:
  11. // Copyright (c) 2006, Jonas Beckeman
  12. //
  13. // See LICENSE.txt for complete licensing and attribution information.
  14. //
  15. /////////////////////////////////////////////////////////////////////////////////
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Diagnostics;
  19. using System.Globalization;
  20. using System.IO;
  21. using System.Linq;
  22. namespace PhotoshopFile
  23. {
  24. internal enum ResourceID
  25. {
  26. Undefined = 0,
  27. MacPrintInfo = 1001,
  28. ResolutionInfo = 1005,
  29. AlphaChannelNames = 1006,
  30. DisplayInfo = 1007,
  31. Caption = 1008,
  32. BorderInfo = 1009,
  33. BackgroundColor = 1010,
  34. PrintFlags = 1011,
  35. MultichannelHalftoneInfo = 1012,
  36. ColorHalftoneInfo = 1013,
  37. DuotoneHalftoneInfo = 1014,
  38. MultichannelTransferFunctions = 1015,
  39. ColorTransferFunctions = 1016,
  40. DuotoneTransferFunctions = 1017,
  41. DuotoneImageInfo = 1018,
  42. BlackWhiteRange = 1019,
  43. EpsOptions = 1021,
  44. QuickMaskInfo = 1022,
  45. LayerStateInfo = 1024,
  46. WorkingPathUnsaved = 1025,
  47. LayersGroupInfo = 1026,
  48. IptcNaa = 1028,
  49. RawFormatImageMode = 1029,
  50. JpegQuality = 1030,
  51. GridGuidesInfo = 1032,
  52. ThumbnailBgr = 1033,
  53. CopyrightInfo = 1034,
  54. Url = 1035,
  55. ThumbnailRgb = 1036,
  56. GlobalAngle = 1037,
  57. ColorSamplersObsolete = 1038,
  58. IccProfile = 1039,
  59. Watermark = 1040,
  60. IccUntagged = 1041,
  61. EffectsVisible = 1042,
  62. SpotHalftone = 1043,
  63. DocumentSpecific = 1044,
  64. UnicodeAlphaNames = 1045,
  65. IndexedColorTableCount = 1046,
  66. TransparentIndex = 1047,
  67. GlobalAltitude = 1049,
  68. Slices = 1050,
  69. WorkflowUrl = 1051,
  70. JumpToXpep = 1052,
  71. AlphaIdentifiers = 1053,
  72. UrlList = 1054,
  73. VersionInfo = 1057,
  74. ExifData1 = 1058,
  75. ExifData3 = 1059,
  76. XmpMetadata = 1060,
  77. CaptionDigest = 1061,
  78. PrintScale = 1062,
  79. PixelAspectRatio = 1064,
  80. LayerComps = 1065,
  81. AlternateDuotoneColors = 1066,
  82. AlternateSpotColors = 1067,
  83. LayerSelectionIDs = 1069,
  84. HdrToningInfo = 1070,
  85. PrintInfo = 1071,
  86. LayerGroupsEnabled = 1072,
  87. ColorSamplers = 1073,
  88. MeasurementScale = 1074,
  89. TimelineInfo = 1075,
  90. SheetDisclosure = 1076,
  91. FloatDisplayInfo = 1077,
  92. OnionSkins = 1078,
  93. CountInfo = 1080,
  94. PrintSettingsInfo = 1082,
  95. PrintStyle = 1083,
  96. MacNSPrintInfo = 1084,
  97. WinDevMode = 1085,
  98. AutoSaveFilePath = 1086,
  99. AutoSaveFormat = 1087,
  100. PathInfo = 2000, // 2000-2999: Path Information
  101. ClippingPathName = 2999,
  102. LightroomWorkflow = 8000,
  103. PrintFlagsInfo = 10000
  104. }
  105. /// <summary>
  106. /// Abstract class for Image Resources
  107. /// </summary>
  108. internal abstract class ImageResource
  109. {
  110. private string signature;
  111. public string Signature
  112. {
  113. get { return signature; }
  114. set
  115. {
  116. if (value.Length != 4)
  117. {
  118. throw new ArgumentException(
  119. "Signature must be 4 characters in length.");
  120. }
  121. signature = value;
  122. }
  123. }
  124. public string Name { get; set; }
  125. public abstract ResourceID ID { get; }
  126. protected ImageResource(string name)
  127. {
  128. Signature = "8BIM";
  129. Name = name;
  130. }
  131. }
  132. /// <summary>
  133. /// Creates the appropriate subclass of ImageResource.
  134. /// </summary>
  135. internal static class ImageResourceFactory
  136. {
  137. public static ImageResource CreateImageResource(PsdBinaryReader reader)
  138. {
  139. Util.DebugMessage(reader.BaseStream, "Load, Begin, ImageResource");
  140. var signature = reader.ReadAsciiChars(4);
  141. var resourceIdInt = reader.ReadUInt16();
  142. var name = reader.ReadPascalString(2);
  143. var dataLength = (int)reader.ReadUInt32();
  144. var dataPaddedLength = Util.RoundUp(dataLength, 2);
  145. var endPosition = reader.BaseStream.Position + dataPaddedLength;
  146. ImageResource resource = null;
  147. var resourceId = (ResourceID)resourceIdInt;
  148. switch (resourceId)
  149. {
  150. case ResourceID.ResolutionInfo:
  151. resource = new ResolutionInfo(reader, name);
  152. break;
  153. case ResourceID.ThumbnailRgb:
  154. case ResourceID.ThumbnailBgr:
  155. resource = new Thumbnail(reader, resourceId, name, dataLength);
  156. break;
  157. case ResourceID.AlphaChannelNames:
  158. resource = new AlphaChannelNames(reader, name, dataLength);
  159. break;
  160. case ResourceID.UnicodeAlphaNames:
  161. resource = new UnicodeAlphaNames(reader, name, dataLength);
  162. break;
  163. case ResourceID.VersionInfo:
  164. resource = new VersionInfo(reader, name);
  165. break;
  166. default:
  167. resource = new RawImageResource(reader, signature, resourceId, name, dataLength);
  168. break;
  169. }
  170. Util.DebugMessage(reader.BaseStream, "Load, End, ImageResource, {0}",
  171. resourceId);
  172. // Reposition the reader if we do not consume the full resource block.
  173. // This takes care of the even-padding, and also preserves forward-
  174. // compatibility in case a resource block is later extended with
  175. // additional properties.
  176. if (reader.BaseStream.Position < endPosition)
  177. reader.BaseStream.Position = endPosition;
  178. // However, overruns are definitely an error.
  179. if (reader.BaseStream.Position > endPosition)
  180. throw new PsdInvalidException("Corruption detected in resource.");
  181. return resource;
  182. }
  183. }
  184. internal class ImageResources : List<ImageResource>
  185. {
  186. public ImageResources() : base()
  187. {
  188. }
  189. public ImageResource Get(ResourceID id)
  190. {
  191. return Find(x => x.ID == id);
  192. }
  193. public void Set(ImageResource resource)
  194. {
  195. Predicate<ImageResource> matchId = delegate(ImageResource res)
  196. {
  197. return res.ID == resource.ID;
  198. };
  199. var itemIdx = this.FindIndex(matchId);
  200. var lastItemIdx = this.FindLastIndex(matchId);
  201. if (itemIdx == -1)
  202. {
  203. Add(resource);
  204. }
  205. else if (itemIdx != lastItemIdx)
  206. {
  207. RemoveAll(matchId);
  208. Insert(itemIdx, resource);
  209. }
  210. else
  211. {
  212. this[itemIdx] = resource;
  213. }
  214. }
  215. }
  216. }