2
0

ImagingNET.pas 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457
  1. {
  2. $Id$
  3. Vampyre Imaging Library
  4. by Marek Mauder
  5. http://imaginglib.sourceforge.net
  6. The contents of this file are used with permission, subject to the Mozilla
  7. Public License Version 1.1 (the "License"); you may not use this file except
  8. in compliance with the License. You may obtain a copy of the License at
  9. http://www.mozilla.org/MPL/MPL-1.1.html
  10. Software distributed under the License is distributed on an "AS IS" basis,
  11. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  12. the specific language governing rights and limitations under the License.
  13. Alternatively, the contents of this file may be used under the terms of the
  14. GNU Lesser General Public License (the "LGPL License"), in which case the
  15. provisions of the LGPL License are applicable instead of those above.
  16. If you wish to allow use of your version of this file only under the terms
  17. of the LGPL License and not to allow others to use your version of this file
  18. under the MPL, indicate your decision by deleting the provisions above and
  19. replace them with the notice and other provisions required by the LGPL
  20. License. If you do not delete the provisions above, a recipient may use
  21. your version of this file under either the MPL or the LGPL License.
  22. For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
  23. }
  24. { This is import wrapper for Delphi.NET. You need VampyreImaging.dll
  25. located somewhere Windows can find it. You can use functions directly
  26. imported from DLL or much more dotNET-like Imaging class members.
  27. Note that this wrapper was not tested extensively so there may be various bugs.}
  28. unit ImagingNET;
  29. {$MINENUMSIZE 4}
  30. interface
  31. uses
  32. System.Runtime.InteropServices, System.Security, System.Text, SysUtils;
  33. const
  34. ImagingVersionMajor = 0;
  35. ImagingVersionMinor = 22;
  36. ImagingVersionPatch = 0;
  37. ImagingJpegQuality = 10;
  38. ImagingJpegProgressive = 11;
  39. ImagingBitmapRLE = 12;
  40. ImagingTargaRLE = 13;
  41. ImagingDDSLoadedCubeMap = 14;
  42. ImagingDDSLoadedVolume = 15;
  43. ImagingDDSLoadedMipMapCount = 16;
  44. ImagingDDSLoadedDepth = 17;
  45. ImagingDDSSaveCubeMap = 18;
  46. ImagingDDSSaveVolume = 19;
  47. ImagingDDSSaveMipMapCount = 20;
  48. ImagingDDSSaveDepth = 21;
  49. ImagingPNGPreFilter = 25;
  50. ImagingPNGCompressLevel = 26;
  51. ImagingMNGLossyCompression = 28;
  52. ImagingMNGLossyAlpha = 29;
  53. ImagingMNGPreFilter = 30;
  54. ImagingMNGCompressLevel = 31;
  55. ImagingMNGQuality = 32;
  56. ImagingMNGProgressive = 33;
  57. ImagingJNGLossyAlpha = 40;
  58. ImagingJNGAlphaPreFilter = 41;
  59. ImagingJNGAlphaCompressLevel = 42;
  60. ImagingJNGQuality = 43;
  61. ImagingJNGProgressive = 44;
  62. ImagingColorReductionMask = 128;
  63. ImagingLoadOverrideFormat = 129;
  64. ImagingSaveOverrideFormat = 130;
  65. ImagingMipMapFilter = 131;
  66. InvalidOption = -$7FFFFFFF;
  67. ChannelBlue = 0;
  68. ChannelGreen = 1;
  69. ChannelRed = 2;
  70. ChannelAlpha = 3;
  71. type
  72. TImageFormat = (
  73. ifUnknown = 0,
  74. ifDefault = 1,
  75. // indexed formats using palette
  76. ifIndex8 = 10,
  77. // grayscale formats
  78. ifGray8 = 40,
  79. ifA8Gray8 = 41,
  80. ifGray16 = 42,
  81. ifGray32 = 43,
  82. ifGray64 = 44,
  83. ifA16Gray16 = 45,
  84. // ARGB formats
  85. ifX5R1G1B1 = 80,
  86. ifR3G3B2 = 81,
  87. ifR5G6B5 = 82,
  88. ifA1R5G5B5 = 83,
  89. ifA4R4G4B4 = 84,
  90. ifX1R5G5B5 = 85,
  91. ifX4R4G4B4 = 86,
  92. ifR8G8B8 = 87,
  93. ifA8R8G8B8 = 88,
  94. ifX8R8G8B8 = 89,
  95. ifR16G16B16 = 90,
  96. ifA16R16G16B16 = 91,
  97. ifB16G16R16 = 92,
  98. ifA16B16G16R16 = 93,
  99. // floating point formats
  100. ifR32F = 170,
  101. ifA32R32G32B32F = 171,
  102. ifA32B32G32R32F = 172,
  103. ifR16F = 173,
  104. ifA16R16G16B16F = 174,
  105. ifA16B16G16R16F = 175,
  106. // special formats
  107. ifDXT1 = 220,
  108. ifDXT3 = 221,
  109. ifDXT5 = 222);
  110. TColor32 = UInt32;
  111. TColor64 = UInt64;
  112. TPalette32 = IntPtr;
  113. TImageDataList = UInt32;
  114. [StructLayout(LayoutKind.Sequential)]
  115. TImageData = packed record
  116. Width: LongInt;
  117. Height: LongInt;
  118. Format: TImageFormat;
  119. Size: LongInt;
  120. Bits: IntPtr;
  121. Palette: TPalette32;
  122. end;
  123. [StructLayout(LayoutKind.Sequential)]
  124. TImageFormatInfo = packed record
  125. Format: TImageFormat;
  126. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
  127. Name: string;
  128. BytesPerPixel: Byte;
  129. PaletteEntries: LongInt;
  130. HasGrayChannel: Boolean;
  131. HasAlphaChannel: Boolean;
  132. IsFloatingPoint: Boolean;
  133. UsePixelFormat: Boolean;
  134. IsRBSwapped: Boolean;
  135. IsIndexed: Boolean;
  136. IsSpecial: Boolean;
  137. PixelFormat: IntPtr;
  138. GetPixelsSize: IntPtr;
  139. CheckDimensions: IntPtr;
  140. GetPixel32: IntPtr;
  141. GetPixelFP: IntPtr;
  142. SetPixel32: IntPtr;
  143. SetPixelFP: IntPtr;
  144. end;
  145. TResizeFilter = (
  146. rfNearest = 0,
  147. rfBilinear = 1,
  148. rfBicubic = 2);
  149. TColor24Rec = record;
  150. TColor32Rec = record;
  151. TColor48Rec = record;
  152. TColor64Rec = record;
  153. TColorFPRec = record;
  154. TColor24Rec = packed record
  155. public
  156. B, G, R: Byte;
  157. function SetColor(Color: TColor32): TColor24Rec; overload;
  158. function SetColor(R, G, B: Byte): TColor24Rec; overload;
  159. function SetColor(ColorRec: TColor24Rec): TColor24Rec; overload;
  160. function SetColor(ColorRec: TColor32Rec): TColor24Rec; overload;
  161. function SetColor(ColorRec: TColor48Rec): TColor24Rec; overload;
  162. function SetColor(ColorRec: TColor64Rec): TColor24Rec; overload;
  163. function SetColor(ColorRec: TColorFPRec): TColor24Rec; overload;
  164. function GetColor: TColor32;
  165. class operator Equal(const Left, Right: TColor24Rec): Boolean;
  166. class operator NotEqual(const Left, Right: TColor24Rec): Boolean;
  167. end;
  168. TColor32Rec = packed record
  169. public
  170. B, G, R, A: Byte;
  171. function SetColor(Color: TColor32): TColor32Rec; overload;
  172. function SetColor(A, R, G, B: Byte): TColor32Rec; overload;
  173. function SetColor(ColorRec: TColor24Rec): TColor32Rec; overload;
  174. function SetColor(ColorRec: TColor32Rec): TColor32Rec; overload;
  175. function SetColor(ColorRec: TColor48Rec): TColor32Rec; overload;
  176. function SetColor(ColorRec: TColor64Rec): TColor32Rec; overload;
  177. function SetColor(ColorRec: TColorFPRec): TColor32Rec; overload;
  178. function GetColor: TColor32;
  179. class operator Equal(const Left, Right: TColor32Rec): Boolean;
  180. class operator NotEqual(const Left, Right: TColor32Rec): Boolean;
  181. end;
  182. TColor48Rec = packed record
  183. public
  184. B, G, R: Word;
  185. function SetColor(Color: TColor64): TColor48Rec; overload;
  186. function SetColor(R, G, B: Word): TColor48Rec; overload;
  187. function SetColor(ColorRec: TColor24Rec): TColor48Rec; overload;
  188. function SetColor(ColorRec: TColor32Rec): TColor48Rec; overload;
  189. function SetColor(ColorRec: TColor48Rec): TColor48Rec; overload;
  190. function SetColor(ColorRec: TColor64Rec): TColor48Rec; overload;
  191. function SetColor(ColorRec: TColorFPRec): TColor48Rec; overload;
  192. function GetColor: TColor64;
  193. class operator Equal(const Left, Right: TColor48Rec): Boolean;
  194. class operator NotEqual(const Left, Right: TColor48Rec): Boolean;
  195. end;
  196. TColor64Rec = packed record
  197. public
  198. B, G, R, A: Word;
  199. function SetColor(Color: TColor64): TColor64Rec; overload;
  200. function SetColor(A, R, G, B: Word): TColor64Rec; overload;
  201. function SetColor(ColorRec: TColor24Rec): TColor64Rec; overload;
  202. function SetColor(ColorRec: TColor32Rec): TColor64Rec; overload;
  203. function SetColor(ColorRec: TColor48Rec): TColor64Rec; overload;
  204. function SetColor(ColorRec: TColor64Rec): TColor64Rec; overload;
  205. function SetColor(ColorRec: TColorFPRec): TColor64Rec; overload;
  206. function GetColor: TColor64;
  207. class operator Equal(const Left, Right: TColor64Rec): Boolean;
  208. class operator NotEqual(const Left, Right: TColor64Rec): Boolean;
  209. end;
  210. TColorFPRec = packed record
  211. public
  212. B, G, R, A: Single;
  213. function SetColor(Color: TColor64): TColorFPRec; overload;
  214. function SetColor(A, R, G, B: Single): TColorFPRec; overload;
  215. function SetColor(ColorRec: TColor24Rec): TColorFPRec; overload;
  216. function SetColor(ColorRec: TColor32Rec): TColorFPRec; overload;
  217. function SetColor(ColorRec: TColor48Rec): TColorFPRec; overload;
  218. function SetColor(ColorRec: TColor64Rec): TColorFPRec; overload;
  219. function SetColor(ColorRec: TColorFPRec): TColorFPRec; overload;
  220. function GetColor: TColor64;
  221. class operator Equal(const Left, Right: TColorFPRec): Boolean;
  222. class operator NotEqual(const Left, Right: TColorFPRec): Boolean;
  223. end;
  224. TDynImageDataArray = array of TImageData;
  225. const
  226. LibraryName = 'VampyreImaging.dll';
  227. { Low Level Imported Functions }
  228. { General Functions }
  229. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  230. procedure ImGetVersion(var Major, Minor, Patch: LongInt); external;
  231. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  232. procedure ImInitImage(var Image: TImageData); external;
  233. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  234. function ImNewImage(Width, Height: LongInt; Format: TImageFormat;
  235. var Image: TImageData): Boolean; external;
  236. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  237. function ImTestImage(const Image: TImageData): Boolean; external;
  238. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  239. function ImFreeImage(var Image: TImageData): Boolean; external;
  240. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  241. function ImDetermineFileFormat(const FileName: string; Ext: StringBuilder): Boolean; external;
  242. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  243. function ImDetermineMemoryFormat(Data: array of Byte; Size: LongInt; Ext: StringBuilder): Boolean; external;
  244. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  245. function ImIsFileFormatSupported(const FileName: string): Boolean; external;
  246. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  247. function ImEnumFileFormats(var Index: LongInt;
  248. {[out, MarshalAs(UnmanagedType.LPArray)] }Name, DefaultExt, Masks: StringBuilder; var CanSave, IsMultiImageFormat: Boolean): Boolean; external;
  249. { Image List Functions }
  250. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  251. function ImInitImageList(Size: LongInt; var ImageList: TImageDataList): Boolean; external;
  252. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  253. function ImGetImageListSize(ImageList: TImageDataList): LongInt; external;
  254. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  255. function ImGetImageListElement(ImageList: TImageDataList; Index: LongInt;
  256. var OutImage: TImageData): Boolean; external;
  257. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  258. function ImSetImageListSize(ImageList: TImageDataList; NewSize: LongInt): Boolean; external;
  259. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  260. function ImSetImageListElement(ImageList: TImageDataList; Index: LongInt;
  261. var InImage: TImageData): Boolean; external;
  262. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  263. function ImTestImagesInList(ImageList: TImageDataList): Boolean; external;
  264. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  265. function ImFreeImageList(var ImageList: TImageDataList): Boolean; external;
  266. { Loading Functions }
  267. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  268. function ImLoadImageFromFile(const FileName: string; var Image: TImageData): Boolean; external;
  269. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  270. function ImLoadImageFromMemory(const Data: array of Byte; Size: LongInt;
  271. var Image: TImageData): Boolean; external;
  272. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  273. function ImLoadMultiImageFromFile(const FileName: string; var ImageList: TImageDataList): Boolean; external;
  274. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  275. function ImLoadMultiImageFromMemory(const Data: array of Byte; Size: LongInt;
  276. var ImageList: TImageDataList): Boolean; external;
  277. { Saving Functions }
  278. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  279. function ImSaveImageToFile(const FileName: string; const Image: TImageData): Boolean; external;
  280. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  281. function ImSaveImageToMemory(const Ext: string; const Data: array of Byte; var Size: LongInt;
  282. const Image: TImageData): Boolean; external;
  283. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  284. function ImSaveMultiImageToFile(const FileName: string; ImageList: TImageDataList): Boolean; external;
  285. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  286. function ImSaveMultiImageToMemory(const Ext: string; const Data: array of Byte; var Size: LongInt;
  287. ImageList: TImageDataList): Boolean; external;
  288. { Manipulation Functions }
  289. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  290. function ImCloneImage(const Image: TImageData; var Clone: TImageData): Boolean; external;
  291. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  292. function ImConvertImage(var Image: TImageData; DestFormat: TImageFormat): Boolean; external;
  293. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  294. function ImFlipImage(var Image: TImageData): Boolean; external;
  295. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  296. function ImMirrorImage(var Image: TImageData): Boolean; external;
  297. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  298. function ImResizeImage(var Image: TImageData; NewWidth, NewHeight: LongInt; Filter: TResizeFilter): Boolean; external;
  299. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  300. function ImSwapChannels(var Image: TImageData; SrcChannel, DstChannel: LongInt): Boolean; external;
  301. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  302. function ImReduceColors(var Image: TImageData; MaxColors: LongInt): Boolean; external;
  303. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  304. function ImGenerateMipMaps(const Image: TImageData; Levels: LongInt;
  305. var MipMaps: TImageDataList): Boolean; external;
  306. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  307. function ImMapImageToPalette(var Image: TImageData; Pal: TPalette32;
  308. Entries: LongInt): Boolean; external;
  309. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  310. function ImSplitImage(var Image: TImageData; var Chunks: TImageDataList;
  311. ChunkWidth, ChunkHeight: LongInt; var XChunks, YChunks: LongInt;
  312. PreserveSize: Boolean; Fill: IntPtr): Boolean; external;
  313. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  314. function ImMakePaletteForImages(var Images: TImageDataList; Pal: TPalette32;
  315. MaxColors: LongInt; ConvertImages: Boolean): Boolean; external;
  316. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  317. function ImRotateImage(var Image: TImageData; Angle: LongInt): Boolean; external;
  318. { Drawing/Pixel functions }
  319. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  320. function ImCopyRect(const SrcImage: TImageData; SrcX, SrcY, Width, Height: LongInt;
  321. var DstImage: TImageData; DstX, DstY: LongInt): Boolean; external;
  322. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  323. function ImFillRect(var Image: TImageData; X, Y, Width, Height: LongInt;
  324. Fill: IntPtr): Boolean; external;
  325. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  326. function ImReplaceColor(var Image: TImageData; X, Y, Width, Height: LongInt;
  327. OldPixel, NewPixel: IntPtr): Boolean; external;
  328. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  329. function ImStretchRect(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,
  330. SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,
  331. DstHeight: LongInt; Filter: TResizeFilter): Boolean; external;
  332. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  333. procedure ImGetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: IntPtr); external;
  334. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  335. procedure ImSetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: IntPtr); external;
  336. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  337. function ImGetPixel32(const Image: TImageData; X, Y: LongInt): TColor32Rec; external;
  338. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  339. procedure ImSetPixel32(const Image: TImageData; X, Y: LongInt; const Color: TColor32Rec); external;
  340. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  341. function ImGetPixelFP(const Image: TImageData; X, Y: LongInt): TColorFPRec; external;
  342. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  343. procedure ImSetPixelFP(const Image: TImageData; X, Y: LongInt; const Color: TColorFPRec); external;
  344. { Palette Functions }
  345. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  346. function ImNewPalette(Entries: LongInt; var Pal: TPalette32): Boolean; external;
  347. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  348. function ImFreePalette(var Pal: TPalette32): Boolean; external;
  349. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  350. function ImCopyPalette(SrcPal, DstPal: TPalette32; SrcIdx, DstIdx, Count: LongInt): Boolean; external;
  351. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  352. function ImFindColor(Pal: TPalette32; Entries: LongInt; Color: TColor32): LongInt; external;
  353. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  354. function ImFillGrayscalePalette(Pal: TPalette32; Entries: LongInt): Boolean; external;
  355. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  356. function ImFillCustomPalette(Pal: TPalette32; Entries: LongInt; RBits, GBits,
  357. BBits: Byte; Alpha: Byte): Boolean; external;
  358. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  359. function ImSwapChannelsOfPalette(Pal: TPalette32; Entries, SrcChannel,
  360. DstChannel: LongInt): Boolean; external;
  361. { Options Functions }
  362. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  363. function ImSetOption(OptionId, Value: LongInt): Boolean; external;
  364. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  365. function ImGetOption(OptionId: LongInt): LongInt; external;
  366. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  367. function ImPushOptions: Boolean; external;
  368. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  369. function ImPopOptions: Boolean; external;
  370. { Image Format Functions }
  371. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  372. function ImGetPixelBytes(Format: TImageFormat): LongInt; external;
  373. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  374. function ImGetImageFormatInfo(Format: TImageFormat; var Info: TImageFormatInfo): Boolean; external;
  375. [SuppressUnmanagedCodeSecurity, DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
  376. function ImGetPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; external;
  377. type
  378. { Record with information about one of imag file formats supported by Imaging.}
  379. TFileFormatInfo = record
  380. Name: string;
  381. DefaultExt: string;
  382. Masks: string;
  383. CanSave: Boolean;
  384. IsMultiImageFormat: Boolean;
  385. end;
  386. { Class which encapsulates all Imaging functions without Im prefix and
  387. with dotNET friendly parameter types. There are also some dotNET only
  388. members.}
  389. Imaging = class(TObject)
  390. public
  391. class var FileFormats: array of TFileFormatInfo;
  392. class procedure BuildFileFormatList;
  393. class function EnumFileFormats(var Index: LongInt; var Name, DefaultExt, Masks: string; var CanSave, IsMultiImageFormat: Boolean): Boolean; static;
  394. class function ListToArray(List: TImageDataList; var Arr: TDynImageDataArray): Boolean; static;
  395. class function ArrayToList(const Arr: TDynImageDataArray; var List: TImageDataList): Boolean; static;
  396. public
  397. { General Functions }
  398. class procedure GetVersion(var Major, Minor, Patch: LongInt); static;
  399. class procedure InitImage(var Image: TImageData); static;
  400. class function NewImage(Width, Height: LongInt; Format: TImageFormat; var Image: TImageData): Boolean; static;
  401. class function TestImage(const Image: TImageData): Boolean; static;
  402. class function FreeImage(var Image: TImageData): Boolean; static;
  403. class function FreeImagesInArray(var Images: TDynImageDataArray): Boolean; static;
  404. class function TestImagesInArray(const Images: TDynImageDataArray): Boolean; static;
  405. class function DetermineFileFormat(const FileName: string): string; static;
  406. class function DetermineMemoryFormat(const Data: array of Byte): string; static;
  407. class function IsFileFormatSupported(const FileName: string): Boolean; static;
  408. class function GetFileFormatCount: LongInt; static;
  409. class function GetFileFormatInfo(Index: LongInt): TFileFormatInfo; static;
  410. class function GetImageFileFormatsFilter(OpenFileFilter: Boolean): string; static;
  411. { Loading Functions }
  412. class function LoadImageFromFile(const FileName: string; var Image: TImageData): Boolean; static;
  413. class function LoadImageFromMemory(const Data: array of Byte; var Image: TImageData): Boolean; static;
  414. class function LoadMultiImageFromFile(const FileName: string; var Images: TDynImageDataArray): Boolean; static;
  415. class function LoadMultiImageFromMemory(const Data: array of Byte; var Images: TDynImageDataArray): Boolean; static;
  416. { Saving Functions }
  417. class function SaveImageToFile(const FileName: string; const Image: TImageData): Boolean; static;
  418. class function SaveImageToMemory(const Ext: string; Data: array of Byte; var Size: LongInt; const Image: TImageData): Boolean; static;
  419. class function SaveMultiImageToFile(const FileName: string; const Images: TDynImageDataArray): Boolean; static;
  420. class function SaveMultiImageToMemory(const Ext: string; Data: array of Byte; var Size: LongInt; const Images: TDynImageDataArray): Boolean; static;
  421. { Manipulation Functions }
  422. class function CloneImage(const Image: TImageData; var Clone: TImageData): Boolean; static;
  423. class function ConvertImage(var Image: TImageData; DestFormat: TImageFormat): Boolean; static;
  424. class function FlipImage(var Image: TImageData): Boolean; static;
  425. class function MirrorImage(var Image: TImageData): Boolean; static;
  426. class function ResizeImage(var Image: TImageData; NewWidth, NewHeight: LongInt; Filter: TResizeFilter): Boolean; static;
  427. class function SwapChannels(var Image: TImageData; SrcChannel, DstChannel: LongInt): Boolean; static;
  428. class function ReduceColors(var Image: TImageData; MaxColors: LongInt): Boolean; static;
  429. class function GenerateMipMaps(const Image: TImageData; Levels: LongInt; var MipMaps: TDynImageDataArray): Boolean; static;
  430. class function MapImageToPalette(var Image: TImageData; Pal: TPalette32; Entries: LongInt): Boolean; static;
  431. class function SplitImage(var Image: TImageData; var Chunks: TDynImageDataArray; ChunkWidth, ChunkHeight: LongInt; var XChunks, YChunks: LongInt; PreserveSize: Boolean; Fill: TObject): Boolean; static;
  432. class function MakePaletteForImages(var Images: TDynImageDataArray; Pal: TPalette32; MaxColors: LongInt; ConvertImages: Boolean): Boolean; static;
  433. class function RotateImage(var Image: TImageData; Angle: LongInt): Boolean; static;
  434. { Drawing/Pixel functions }
  435. class function CopyRect(const SrcImage: TImageData; SrcX, SrcY, Width, Height: LongInt; var DstImage: TImageData; DstX, DstY: LongInt): Boolean; static;
  436. class function FillRect(var Image: TImageData; X, Y, Width, Height: LongInt; Fill: TObject): Boolean; static;
  437. class function ReplaceColor(var Image: TImageData; X, Y, Width, Height: LongInt; OldPixel, NewPixel: TObject): Boolean; static;
  438. class function StretchRect(const SrcImage: TImageData; SrcX, SrcY, SrcWidth, SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth, DstHeight: LongInt; Filter: TResizeFilter): Boolean; static;
  439. class procedure GetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: TObject); static;
  440. class procedure SetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: TObject); static;
  441. class function GetPixel32(const Image: TImageData; X, Y: LongInt): TColor32Rec; static;
  442. class procedure SetPixel32(const Image: TImageData; X, Y: LongInt; const Color: TColor32Rec); static;
  443. class function GetPixelFP(const Image: TImageData; X, Y: LongInt): TColorFPRec; static;
  444. class procedure SetPixelFP(const Image: TImageData; X, Y: LongInt; const Color: TColorFPRec); static;
  445. { Palette Functions }
  446. class function NewPalette(Entries: LongInt; var Pal: TPalette32): Boolean; static;
  447. class function FreePalette(var Pal: TPalette32): Boolean; static;
  448. class function CopyPalette(SrcPal, DstPal: TPalette32; SrcIdx, DstIdx, Count: LongInt): Boolean; static;
  449. class function FindColor(Pal: TPalette32; Entries: LongInt; Color: TColor32): LongInt; static;
  450. class function FillGrayscalePalette(Pal: TPalette32; Entries: LongInt): Boolean; static;
  451. class function FillCustomPalette(Pal: TPalette32; Entries: LongInt; RBits, GBits, BBits: Byte; Alpha: Byte): Boolean; static;
  452. class function SwapChannelsOfPalette(Pal: TPalette32; Entries, SrcChannel, DstChannel: LongInt): Boolean; static;
  453. { dotNET only}
  454. class function GetPaletteColor(Pal: TPalette32; Index: LongInt): TColor32; static;
  455. class procedure SetPaletteColor(Pal: TPalette32; Index: LongInt; Color: TColor32); static;
  456. { Options Functions }
  457. class function SetOption(OptionId, Value: LongInt): Boolean; static;
  458. class function GetOption(OptionId: LongInt): LongInt; static;
  459. class function PushOptions: Boolean; static;
  460. class function PopOptions: Boolean; static;
  461. { Image Format Functions }
  462. class function GetPixelBytes(Format: TImageFormat): LongInt; static;
  463. class function GetImageFormatInfo(Format: TImageFormat; var Info: TImageFormatInfo): Boolean; static;
  464. class function GetPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; static;
  465. end;
  466. implementation
  467. { Imaging private methods }
  468. class function Imaging.ListToArray(List: TImageDataList; var Arr: TDynImageDataArray): Boolean;
  469. var
  470. Img: TImageData;
  471. I, Size: LongInt;
  472. begin
  473. Result := True;
  474. Size := ImGetImageListSize(List);
  475. FreeImagesInArray(Arr);
  476. SetLength(Arr, Size);
  477. for I := 0 to Size - 1 do
  478. begin
  479. Result := Result and ImGetImageListElement(List, I, Img);
  480. Arr[I] := Img;
  481. if not Result then Break;
  482. end;
  483. end;
  484. class function Imaging.ArrayToList(const Arr: TDynImageDataArray; var List: TImageDataList): Boolean;
  485. var
  486. Img: TImageData;
  487. I, Size: LongInt;
  488. begin
  489. Size := Length(Arr);
  490. Result := ImInitImageList(Size, List);
  491. for I := 0 to Size - 1 do
  492. begin
  493. Img := Arr[I];
  494. Result := Result and ImSetImageListElement(List, I, Img);
  495. if not Result then Break;
  496. end;
  497. end;
  498. { Imaging public methods }
  499. class procedure Imaging.GetVersion(var Major, Minor, Patch: LongInt);
  500. begin
  501. ImGetVersion(Major, Minor, Patch);
  502. end;
  503. class procedure Imaging.InitImage(var Image: TImageData);
  504. begin
  505. ImInitImage(Image);
  506. end;
  507. class function Imaging.IsFileFormatSupported(const FileName: string): Boolean;
  508. begin
  509. Result := IsFileFormatSupported(FileName);
  510. end;
  511. class function Imaging.NewImage(Width, Height: LongInt; Format: TImageFormat; var Image: TImageData): Boolean;
  512. begin
  513. Result := ImNewImage(Width, Height, Format, Image);
  514. end;
  515. class function Imaging.TestImage(const Image: TImageData): Boolean;
  516. begin
  517. Result := ImTestImage(Image);
  518. end;
  519. class function Imaging.FreeImage(var Image: TImageData): Boolean;
  520. begin
  521. Result := ImFreeImage(Image);
  522. end;
  523. class function Imaging.FreeImagesInArray(var Images: TDynImageDataArray): Boolean;
  524. var
  525. I: LongInt;
  526. begin
  527. Result := True;
  528. for I := 0 to Length(Images) - 1 do
  529. Result := Result and ImFreeImage(Images[I]);
  530. end;
  531. class function Imaging.TestImagesInArray(const Images: TDynImageDataArray): Boolean;
  532. var
  533. I: LongInt;
  534. begin
  535. Result := True;
  536. for I := 0 to Length(Images) - 1 do
  537. begin
  538. Result := Result and ImTestImage(Images[I]);
  539. if not Result then Break;
  540. end;
  541. end;
  542. const
  543. ExtLen = 16;
  544. class function Imaging.DetermineFileFormat(const FileName: string): string;
  545. var
  546. Builder: StringBuilder;
  547. begin
  548. Builder := StringBuilder.Create(ExtLen);
  549. if ImDetermineFileFormat(FileName, Builder) then
  550. Result := Builder.ToString
  551. else
  552. Result := '';
  553. end;
  554. class function Imaging.DetermineMemoryFormat(const Data: array of Byte): string;
  555. var
  556. Builder: StringBuilder;
  557. begin
  558. Builder := StringBuilder.Create(ExtLen);
  559. if ImDetermineMemoryFormat(Data, Length(Data), Builder) then
  560. Result := Builder.ToString
  561. else
  562. Result := '';
  563. end;
  564. class function Imaging.EnumFileFormats(var Index: Integer; var Name, DefaultExt,
  565. Masks: string; var CanSave, IsMultiImageFormat: Boolean): Boolean;
  566. var
  567. AName, AExt, AMasks: StringBuilder;
  568. begin
  569. AName := StringBuilder.Create(128);
  570. AExt := StringBuilder.Create(ExtLen);
  571. AMasks := StringBuilder.Create(256);
  572. Result := ImEnumFileFormats(Index, AName, AExt, AMasks, CanSave, IsMultiImageFormat);
  573. // TODO: Result always is True, even if DLL function explicitly returns False. WTF?
  574. // So this check is added to ensure enumerating will end some time.
  575. Result := Result and (AName.Length > 0);
  576. Name := AName.ToString;
  577. DefaultExt := AExt.ToString;
  578. Masks := AMasks.ToString;
  579. end;
  580. class function Imaging.LoadImageFromFile(const FileName: string; var Image: TImageData): Boolean;
  581. begin
  582. Result := ImLoadImageFromFile(FileName, Image);
  583. end;
  584. class function Imaging.LoadImageFromMemory(const Data: array of Byte; var Image: TImageData): Boolean;
  585. begin
  586. Result := ImLoadImageFromMemory(Data, Length(Data), Image);
  587. end;
  588. class function Imaging.LoadMultiImageFromFile(const FileName: string; var Images: TDynImageDataArray): Boolean;
  589. var
  590. List: TImageDataList;
  591. begin
  592. Result := ImLoadMultiImageFromFile(FileName, List);
  593. if Result then
  594. begin
  595. FreeImagesInArray(Images);
  596. Result := ListToArray(List, Images);
  597. ImFreeImageList(List);
  598. end;
  599. end;
  600. class function Imaging.LoadMultiImageFromMemory(const Data: array of Byte; var Images: TDynImageDataArray): Boolean;
  601. var
  602. List: TImageDataList;
  603. begin
  604. Result := ImLoadMultiImageFromMemory(Data, Length(Data), List);
  605. if Result then
  606. begin
  607. FreeImagesInArray(Images);
  608. Result := ListToArray(List, Images);
  609. ImFreeImageList(List);
  610. end;
  611. end;
  612. class function Imaging.SaveImageToFile(const FileName: string; const Image: TImageData): Boolean;
  613. begin
  614. Result := ImSaveImageToFile(FileName, Image);
  615. end;
  616. class function Imaging.SaveImageToMemory(const Ext: string; Data: array of Byte; var Size: LongInt; const Image: TImageData): Boolean;
  617. begin
  618. Size := Length(Data);
  619. Result := ImSaveImageToMemory(Ext, Data, Size, Image);
  620. end;
  621. class function Imaging.SaveMultiImageToFile(const FileName: string; const Images: TDynImageDataArray): Boolean;
  622. var
  623. List: TImageDataList;
  624. begin
  625. Result := ArrayToList(Images, List);
  626. if Result then
  627. begin
  628. Result := ImSaveMultiImageToFile(FileName, List);
  629. ImFreeImageList(List);
  630. end;
  631. end;
  632. class function Imaging.SaveMultiImageToMemory(const Ext: string; Data: array of Byte; var Size: LongInt; const Images: TDynImageDataArray): Boolean;
  633. var
  634. List: TImageDataList;
  635. begin
  636. Result := ArrayToList(Images, List);
  637. if Result then
  638. begin
  639. Size := Length(Data);
  640. Result := ImSaveMultiImageToMemory(Ext, Data, Size, List);
  641. ImFreeImageList(List);
  642. end;
  643. end;
  644. class procedure Imaging.BuildFileFormatList;
  645. var
  646. I: LongInt;
  647. begin
  648. I := 0;
  649. SetLength(FileFormats, 1);
  650. while Imaging.EnumFileFormats(I, FileFormats[I].Name, FileFormats[I].DefaultExt,
  651. FileFormats[I].Masks, FileFormats[I].CanSave, FileFormats[I].IsMultiImageFormat) do
  652. begin
  653. SetLength(FileFormats, I + 1);
  654. end;
  655. SetLength(FileFormats, I);
  656. end;
  657. class function Imaging.CloneImage(const Image: TImageData; var Clone: TImageData): Boolean;
  658. begin
  659. Result := ImCloneImage(Image, Clone);
  660. end;
  661. class function Imaging.ConvertImage(var Image: TImageData; DestFormat: TImageFormat): Boolean;
  662. begin
  663. Result := ImConvertImage(Image, DestFormat);
  664. end;
  665. class function Imaging.FlipImage(var Image: TImageData): Boolean;
  666. begin
  667. Result := ImFlipImage(Image);
  668. end;
  669. class function Imaging.MirrorImage(var Image: TImageData): Boolean;
  670. begin
  671. Result := ImMirrorImage(Image);
  672. end;
  673. class function Imaging.ResizeImage(var Image: TImageData; NewWidth, NewHeight: LongInt; Filter: TResizeFilter): Boolean;
  674. begin
  675. Result := ImResizeImage(Image, NewWidth, NewHeight, Filter);
  676. end;
  677. class function Imaging.SwapChannels(var Image: TImageData; SrcChannel, DstChannel: LongInt): Boolean;
  678. begin
  679. Result := ImSwapChannels(Image, SrcChannel, DstChannel);
  680. end;
  681. class function Imaging.ReduceColors(var Image: TImageData; MaxColors: LongInt): Boolean;
  682. begin
  683. Result := ImReduceColors(Image, MaxColors);
  684. end;
  685. class function Imaging.GenerateMipMaps(const Image: TImageData; Levels: LongInt; var MipMaps: TDynImageDataArray): Boolean;
  686. var
  687. List: TImageDataList;
  688. begin
  689. Result := ImGenerateMipMaps(Image, Levels, List);
  690. if Result then
  691. begin
  692. FreeImagesInArray(MipMaps);
  693. Result := ListToArray(List, MipMaps);
  694. ImFreeImageList(List);
  695. end;
  696. end;
  697. class function Imaging.MapImageToPalette(var Image: TImageData; Pal: TPalette32; Entries: LongInt): Boolean;
  698. begin
  699. Result := ImMapImageToPalette(Image, Pal, Entries);
  700. end;
  701. class function Imaging.SplitImage(var Image: TImageData; var Chunks: TDynImageDataArray; ChunkWidth, ChunkHeight: LongInt; var XChunks, YChunks: LongInt; PreserveSize: Boolean; Fill: TObject): Boolean;
  702. var
  703. Ptr: IntPtr;
  704. List: TImageDataList;
  705. begin
  706. Ptr := Marshal.AllocHGlobal(Marshal.SizeOf(Fill));
  707. Marshal.StructureToPtr(Fill, Ptr, False);
  708. Result := ImSplitImage(Image, List, ChunkWidth, ChunkHeight, XChunks, YChunks,
  709. PreserveSize, Ptr);
  710. if Result then
  711. begin
  712. FreeImagesInArray(Chunks);
  713. Result := ListToArray(List, Chunks);
  714. ImFreeImageList(List);
  715. end;
  716. Marshal.FreeHGlobal(Ptr);
  717. end;
  718. class function Imaging.MakePaletteForImages(var Images: TDynImageDataArray; Pal: TPalette32; MaxColors: LongInt; ConvertImages: Boolean): Boolean;
  719. var
  720. List: TImageDataList;
  721. begin
  722. Result := ArrayToList(Images, List);
  723. if Result then
  724. begin
  725. Result := ImMakePaletteForImages(List, Pal, MaxColors, ConvertImages);
  726. Result := Result and ListToArray(List, Images);
  727. ImFreeImageList(List);
  728. end;
  729. end;
  730. class function Imaging.RotateImage(var Image: TImageData; Angle: LongInt): Boolean;
  731. begin
  732. Result := ImRotateImage(Image, Angle);
  733. end;
  734. class function Imaging.CopyRect(const SrcImage: TImageData; SrcX, SrcY, Width, Height: LongInt; var DstImage: TImageData; DstX, DstY: LongInt): Boolean;
  735. begin
  736. Result := ImCopyRect(SrcImage, SrcX, SrcY, Width, Height, DstImage, DstX, DstY);
  737. end;
  738. class function Imaging.FillRect(var Image: TImageData; X, Y, Width, Height: LongInt; Fill: TObject): Boolean;
  739. var
  740. Ptr: IntPtr;
  741. begin
  742. Ptr := Marshal.AllocHGlobal(Marshal.SizeOf(Fill));
  743. Marshal.StructureToPtr(Fill, Ptr, False);
  744. Result := ImFillRect(Image, X, Y, Width, Height, Ptr);
  745. Marshal.FreeHGlobal(Ptr);
  746. end;
  747. class function Imaging.ReplaceColor(var Image: TImageData; X, Y, Width,
  748. Height: LongInt; OldPixel, NewPixel: TObject): Boolean;
  749. var
  750. OldPtr, NewPtr: IntPtr;
  751. begin
  752. OldPtr := Marshal.AllocHGlobal(Marshal.SizeOf(OldPixel));
  753. Marshal.StructureToPtr(OldPixel, OldPtr, False);
  754. NewPtr := Marshal.AllocHGlobal(Marshal.SizeOf(NewPixel));
  755. Marshal.StructureToPtr(NewPixel, NewPtr, False);
  756. Result := ReplaceColor(Image, X, Y, Width, Height, OldPtr, NewPtr);
  757. Marshal.FreeHGlobal(OldPtr);
  758. Marshal.FreeHGlobal(NewPtr);
  759. end;
  760. class function Imaging.StretchRect(const SrcImage: TImageData; SrcX, SrcY,
  761. SrcWidth, SrcHeight: Integer; var DstImage: TImageData; DstX, DstY, DstWidth,
  762. DstHeight: Integer; Filter: TResizeFilter): Boolean;
  763. begin
  764. Result := ImStretchRect(SrcImage, SrcX, SrcY, SrcWidth, SrcHeight,
  765. DstImage, DstX, DstY, DstWidth, DstHeight, Filter);
  766. end;
  767. class procedure Imaging.GetPixelDirect(const Image: TImageData; X, Y: Integer;
  768. Pixel: TObject);
  769. var
  770. Ptr: IntPtr;
  771. begin
  772. Ptr := Marshal.AllocHGlobal(Marshal.SizeOf(Pixel));
  773. ImGetPixelDirect(Image, X, Y, Ptr);
  774. Marshal.PtrToStructure(Ptr, Pixel);
  775. Marshal.FreeHGlobal(Ptr);
  776. end;
  777. class function Imaging.GetPixel32(const Image: TImageData; X,
  778. Y: Integer): TColor32Rec;
  779. begin
  780. Result := ImGetPixel32(Image, X, Y);
  781. end;
  782. class procedure Imaging.SetPixel32(const Image: TImageData; X, Y: Integer;
  783. const Color: TColor32Rec);
  784. begin
  785. ImSetPixel32(Image, X, Y, Color);
  786. end;
  787. class function Imaging.GetPixelFP(const Image: TImageData; X,
  788. Y: Integer): TColorFPRec;
  789. begin
  790. Result := ImGetPixelFP(Image, X, Y);
  791. end;
  792. class procedure Imaging.SetPixelDirect(const Image: TImageData; X, Y: Integer;
  793. Pixel: TObject);
  794. var
  795. Ptr: IntPtr;
  796. begin
  797. Ptr := Marshal.AllocHGlobal(Marshal.SizeOf(Pixel));
  798. Marshal.StructureToPtr(Pixel, Ptr, False);
  799. ImSetPixelDirect(Image, X, Y, Ptr);
  800. Marshal.FreeHGlobal(Ptr);
  801. end;
  802. class procedure Imaging.SetPixelFP(const Image: TImageData; X, Y: Integer;
  803. const Color: TColorFPRec);
  804. begin
  805. ImSetPixelFP(Image, X, Y, Color);
  806. end;
  807. class function Imaging.NewPalette(Entries: LongInt; var Pal: TPalette32): Boolean;
  808. begin
  809. Result := ImNewPalette(Entries, Pal);
  810. end;
  811. class function Imaging.FreePalette(var Pal: TPalette32): Boolean;
  812. begin
  813. Result := ImFreePalette(Pal);
  814. end;
  815. class function Imaging.CopyPalette(SrcPal, DstPal: TPalette32; SrcIdx, DstIdx, Count: LongInt): Boolean;
  816. begin
  817. Result := ImCopyPalette(SrcPal, DstPal, SrcIdx, DstIdx, Count);
  818. end;
  819. class function Imaging.FindColor(Pal: TPalette32; Entries: LongInt; Color: TColor32): LongInt;
  820. begin
  821. Result := ImFindColor(Pal, Entries, Color);
  822. end;
  823. class function Imaging.FillGrayscalePalette(Pal: TPalette32; Entries: LongInt): Boolean;
  824. begin
  825. Result := ImFillGrayscalePalette(Pal, Entries);
  826. end;
  827. class function Imaging.FillCustomPalette(Pal: TPalette32; Entries: LongInt; RBits, GBits, BBits: Byte; Alpha: Byte): Boolean;
  828. begin
  829. Result := ImFillCustomPalette(Pal, Entries, RBits, GBits, BBits, Alpha);
  830. end;
  831. class function Imaging.SwapChannelsOfPalette(Pal: TPalette32; Entries, SrcChannel, DstChannel: LongInt): Boolean;
  832. begin
  833. Result := ImSwapChannelsOfPalette(Pal, Entries, SrcChannel, DstChannel);
  834. end;
  835. class function Imaging.GetPaletteColor(Pal: TPalette32; Index: LongInt): TColor32;
  836. begin
  837. Result := Marshal.ReadInt32(Pal, Index * SizeOf(TColor32));
  838. end;
  839. class procedure Imaging.SetPaletteColor(Pal: TPalette32; Index: LongInt; Color: TColor32);
  840. begin
  841. Marshal.WriteInt32(Pal, Index * SizeOf(TColor32), Color);
  842. end;
  843. class function Imaging.SetOption(OptionId, Value: LongInt): Boolean;
  844. begin
  845. Result := ImSetOption(OptionId, Value);
  846. end;
  847. class function Imaging.GetOption(OptionId: LongInt): LongInt;
  848. begin
  849. Result := ImGetOption(OptionId);
  850. end;
  851. class function Imaging.PushOptions: Boolean;
  852. begin
  853. Result := ImPushOptions;
  854. end;
  855. class function Imaging.PopOptions: Boolean;
  856. begin
  857. Result := ImPopOptions;
  858. end;
  859. class function Imaging.GetPixelBytes(Format: TImageFormat): LongInt;
  860. begin
  861. Result := ImGetPixelBytes(Format);
  862. end;
  863. class function Imaging.GetFileFormatCount: LongInt;
  864. begin
  865. Result := Length(FileFormats);
  866. end;
  867. class function Imaging.GetFileFormatInfo(Index: LongInt): TFileFormatInfo;
  868. begin
  869. if (Index >= Low(FileFormats)) and (Index <= High(FileFormats)) then
  870. Result := FileFormats[Index];
  871. end;
  872. class function Imaging.GetImageFileFormatsFilter(
  873. OpenFileFilter: Boolean): string;
  874. const
  875. SAllFilter = 'All Images';
  876. var
  877. I, Count: LongInt;
  878. Descriptions: string;
  879. Filters, CurFilter: string;
  880. begin
  881. Descriptions := '';
  882. Filters := '';
  883. Count := 0;
  884. for I := 0 to Length(FileFormats) - 1 do
  885. begin
  886. if not OpenFileFilter and not FileFormats[I].CanSave then
  887. Continue;
  888. CurFilter := FileFormats[I].Masks;
  889. FmtStr(Descriptions, '%s%s (%s)|%2:s', [Descriptions, FileFormats[I].Name, CurFilter]);
  890. FmtStr(Filters, '%s;%s', [Filters, CurFilter]);
  891. if I < Length(FileFormats) - 1 then
  892. Descriptions := Descriptions + '|';
  893. Inc(Count);
  894. end;
  895. if (Count > 1) and OpenFileFilter then
  896. FmtStr(Descriptions, '%s (%s)|%1:s|%s', [SAllFilter, Filters, Descriptions]);
  897. Result := Descriptions;
  898. end;
  899. class function Imaging.GetImageFormatInfo(Format: TImageFormat; var Info: TImageFormatInfo): Boolean;
  900. begin
  901. Result := ImGetImageFormatInfo(Format, Info);
  902. end;
  903. class function Imaging.GetPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;
  904. begin
  905. Result := ImGetPixelsSize(Format, Width, Height);
  906. end;
  907. { Color Records implementations }
  908. { TColor24Rec }
  909. function TColor24Rec.SetColor(Color: TColor32): TColor24Rec;
  910. begin
  911. R := (Color shr 16) and $FF;
  912. G := (Color shr 8) and $FF;
  913. B := Color and $FF;
  914. Result := Self;
  915. end;
  916. function TColor24Rec.GetColor: TColor32;
  917. begin
  918. Result := ($FF shl 24) or (R shl 16) or (G shl 8) or B;
  919. end;
  920. function TColor24Rec.SetColor(R, G, B: Byte): TColor24Rec;
  921. begin
  922. Self.R := R;
  923. Self.G := G;
  924. Self.B := B;
  925. Result := Self;
  926. end;
  927. function TColor24Rec.SetColor(ColorRec: TColorFPRec): TColor24Rec;
  928. begin
  929. Self.R := Math.Max(0, Math.Min(255, Trunc(ColorRec.R * 255)));
  930. Self.G := Math.Max(0, Math.Min(255, Trunc(ColorRec.G * 255)));
  931. Self.B := Math.Max(0, Math.Min(255, Trunc(ColorRec.B * 255)));
  932. Result := Self;
  933. end;
  934. function TColor24Rec.SetColor(ColorRec: TColor64Rec): TColor24Rec;
  935. begin
  936. Self.R := ColorRec.R shr 8;
  937. Self.G := ColorRec.G shr 8;
  938. Self.B := ColorRec.B shr 8;
  939. Result := Self;
  940. end;
  941. function TColor24Rec.SetColor(ColorRec: TColor48Rec): TColor24Rec;
  942. begin
  943. Self.R := ColorRec.R shr 8;
  944. Self.G := ColorRec.G shr 8;
  945. Self.B := ColorRec.B shr 8;
  946. Result := Self;
  947. end;
  948. function TColor24Rec.SetColor(ColorRec: TColor32Rec): TColor24Rec;
  949. begin
  950. Self.R := ColorRec.R;
  951. Self.G := ColorRec.G;
  952. Self.B := ColorRec.B;
  953. Result := Self;
  954. end;
  955. function TColor24Rec.SetColor(ColorRec: TColor24Rec): TColor24Rec;
  956. begin
  957. Self.R := ColorRec.R;
  958. Self.G := ColorRec.G;
  959. Self.B := ColorRec.B;
  960. Result := Self;
  961. end;
  962. class operator TColor24Rec.Equal(const Left, Right: TColor24Rec): Boolean;
  963. begin
  964. Result := (Left.R = Right.R) and (Left.G = Right.G) and (Left.B = Right.B);
  965. end;
  966. class operator TColor24Rec.NotEqual(const Left, Right: TColor24Rec): Boolean;
  967. begin
  968. Result := not TColor24Rec.Equals(Left, Right);
  969. end;
  970. { TColor32Rec }
  971. function TColor32Rec.SetColor(Color: TColor32): TColor32Rec;
  972. begin
  973. A := Color shr 24;
  974. R := (Color shr 16) and $FF;
  975. G := (Color shr 8) and $FF;
  976. B := Color and $FF;
  977. Result := Self;
  978. end;
  979. function TColor32Rec.GetColor: TColor32;
  980. begin
  981. Result := (A shl 24) or (R shl 16) or (G shl 8) or B;
  982. end;
  983. function TColor32Rec.SetColor(A, R, G, B: Byte): TColor32Rec;
  984. begin
  985. Self.A := A;
  986. Self.R := R;
  987. Self.G := G;
  988. Self.B := B;
  989. Result := Self;
  990. end;
  991. function TColor32Rec.SetColor(ColorRec: TColorFPRec): TColor32Rec;
  992. begin
  993. Self.A := Math.Max(0, Math.Min($FF, Trunc(ColorRec.A * $FF)));
  994. Self.R := Math.Max(0, Math.Min($FF, Trunc(ColorRec.R * $FF)));
  995. Self.G := Math.Max(0, Math.Min($FF, Trunc(ColorRec.G * $FF)));
  996. Self.B := Math.Max(0, Math.Min($FF, Trunc(ColorRec.B * $FF)));
  997. Result := Self;
  998. end;
  999. function TColor32Rec.SetColor(ColorRec: TColor64Rec): TColor32Rec;
  1000. begin
  1001. Self.A := ColorRec.A shr 8;
  1002. Self.R := ColorRec.R shr 8;
  1003. Self.G := ColorRec.G shr 8;
  1004. Self.B := ColorRec.B shr 8;
  1005. Result := Self;
  1006. end;
  1007. function TColor32Rec.SetColor(ColorRec: TColor48Rec): TColor32Rec;
  1008. begin
  1009. Self.A := $FF;
  1010. Self.R := ColorRec.R shr 8;
  1011. Self.G := ColorRec.G shr 8;
  1012. Self.B := ColorRec.B shr 8;
  1013. Result := Self;
  1014. end;
  1015. function TColor32Rec.SetColor(ColorRec: TColor32Rec): TColor32Rec;
  1016. begin
  1017. Self.A := ColorRec.A;
  1018. Self.R := ColorRec.R;
  1019. Self.G := ColorRec.G;
  1020. Self.B := ColorRec.B;
  1021. Result := Self;
  1022. end;
  1023. function TColor32Rec.SetColor(ColorRec: TColor24Rec): TColor32Rec;
  1024. begin
  1025. Self.A := $FF;
  1026. Self.R := ColorRec.R;
  1027. Self.G := ColorRec.G;
  1028. Self.B := ColorRec.B;
  1029. Result := Self;
  1030. end;
  1031. class operator TColor32Rec.Equal(const Left, Right: TColor32Rec): Boolean;
  1032. begin
  1033. Result := (Left.A = Right.A) and (Left.R = Right.R) and (Left.G = Right.G) and
  1034. (Left.B = Right.B);
  1035. end;
  1036. class operator TColor32Rec.NotEqual(const Left, Right: TColor32Rec): Boolean;
  1037. begin
  1038. Result := not TColor32Rec.Equals(Left, Right);
  1039. end;
  1040. { TColor48Rec }
  1041. function TColor48Rec.SetColor(Color: TColor64): TColor48Rec;
  1042. begin
  1043. R := (Color shr 32) and $FFFF;
  1044. G := (Color shr 16) and $FFFF;
  1045. B := Color and $FFFF;
  1046. Result := Self;
  1047. end;
  1048. function TColor48Rec.GetColor: TColor64;
  1049. begin
  1050. Result := (UInt64($FFFF) shl 48) or (UInt64(R) shl 32) or (G shl 16) or B;
  1051. end;
  1052. function TColor48Rec.SetColor(R, G, B: Word): TColor48Rec;
  1053. begin
  1054. Self.R := R;
  1055. Self.G := G;
  1056. Self.B := B;
  1057. Result := Self;
  1058. end;
  1059. function TColor48Rec.SetColor(ColorRec: TColorFPRec): TColor48Rec;
  1060. begin
  1061. Self.R := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.R * $FFFF)));
  1062. Self.G := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.G * $FFFF)));
  1063. Self.B := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.B * $FFFF)));
  1064. Result := Self;
  1065. end;
  1066. function TColor48Rec.SetColor(ColorRec: TColor64Rec): TColor48Rec;
  1067. begin
  1068. Self.R := ColorRec.R;
  1069. Self.G := ColorRec.G;
  1070. Self.B := ColorRec.B;
  1071. Result := Self;
  1072. end;
  1073. function TColor48Rec.SetColor(ColorRec: TColor48Rec): TColor48Rec;
  1074. begin
  1075. Self.R := ColorRec.R;
  1076. Self.G := ColorRec.G;
  1077. Self.B := ColorRec.B;
  1078. Result := Self;
  1079. end;
  1080. function TColor48Rec.SetColor(ColorRec: TColor32Rec): TColor48Rec;
  1081. begin
  1082. Self.R := ColorRec.R shl 8;
  1083. Self.G := ColorRec.G shl 8;
  1084. Self.B := ColorRec.B shl 8;
  1085. Result := Self;
  1086. end;
  1087. function TColor48Rec.SetColor(ColorRec: TColor24Rec): TColor48Rec;
  1088. begin
  1089. Self.R := ColorRec.R shl 8;
  1090. Self.G := ColorRec.G shl 8;
  1091. Self.B := ColorRec.B shl 8;
  1092. Result := Self;
  1093. end;
  1094. class operator TColor48Rec.Equal(const Left, Right: TColor48Rec): Boolean;
  1095. begin
  1096. Result := (Left.R = Right.R) and (Left.G = Right.G) and (Left.B = Right.B);
  1097. end;
  1098. class operator TColor48Rec.NotEqual(const Left, Right: TColor48Rec): Boolean;
  1099. begin
  1100. Result := not TColor48Rec.Equals(Left, Right);
  1101. end;
  1102. { TColor64Rec }
  1103. function TColor64Rec.SetColor(Color: TColor64): TColor64Rec;
  1104. begin
  1105. A := Color shr 48;
  1106. R := (Color shr 32) and $FFFF;
  1107. G := (Color shr 16) and $FFFF;
  1108. B := Color and $FFFF;
  1109. Result := Self;
  1110. end;
  1111. function TColor64Rec.GetColor: TColor64;
  1112. begin
  1113. Result := (UInt64(A) shl 48) or (UInt64(R) shl 32) or (G shl 16) or B;
  1114. end;
  1115. function TColor64Rec.SetColor(A, R, G, B: Word): TColor64Rec;
  1116. begin
  1117. Self.A := A;
  1118. Self.R := R;
  1119. Self.G := G;
  1120. Self.B := B;
  1121. Result := Self;
  1122. end;
  1123. function TColor64Rec.SetColor(ColorRec: TColorFPRec): TColor64Rec;
  1124. begin
  1125. Self.A := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.A * $FFFF)));
  1126. Self.R := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.R * $FFFF)));
  1127. Self.G := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.G * $FFFF)));
  1128. Self.B := Math.Max(0, Math.Min($FFFF, Trunc(ColorRec.B * $FFFF)));
  1129. Result := Self;
  1130. end;
  1131. function TColor64Rec.SetColor(ColorRec: TColor64Rec): TColor64Rec;
  1132. begin
  1133. Self.A := ColorRec.A;
  1134. Self.R := ColorRec.R;
  1135. Self.G := ColorRec.G;
  1136. Self.B := ColorRec.B;
  1137. Result := Self;
  1138. end;
  1139. function TColor64Rec.SetColor(ColorRec: TColor48Rec): TColor64Rec;
  1140. begin
  1141. Self.A := $FFFF;
  1142. Self.R := ColorRec.R;
  1143. Self.G := ColorRec.G;
  1144. Self.B := ColorRec.B;
  1145. Result := Self;
  1146. end;
  1147. function TColor64Rec.SetColor(ColorRec: TColor32Rec): TColor64Rec;
  1148. begin
  1149. Self.A := ColorRec.A shl 8;
  1150. Self.R := ColorRec.R shl 8;
  1151. Self.G := ColorRec.G shl 8;
  1152. Self.B := ColorRec.B shl 8;
  1153. Result := Self;
  1154. end;
  1155. function TColor64Rec.SetColor(ColorRec: TColor24Rec): TColor64Rec;
  1156. begin
  1157. Self.A := $FFFF;
  1158. Self.R := ColorRec.R shl 8;
  1159. Self.G := ColorRec.G shl 8;
  1160. Self.B := ColorRec.B shl 8;
  1161. Result := Self;
  1162. end;
  1163. class operator TColor64Rec.Equal(const Left, Right: TColor64Rec): Boolean;
  1164. begin
  1165. Result := (Left.A = Right.A) and (Left.R = Right.R) and (Left.G = Right.G) and
  1166. (Left.B = Right.B);
  1167. end;
  1168. class operator TColor64Rec.NotEqual(const Left, Right: TColor64Rec): Boolean;
  1169. begin
  1170. Result := not TColor64Rec.Equals(Left, Right);
  1171. end;
  1172. { TColorFRec }
  1173. function TColorFPRec.SetColor(Color: TColor64): TColorFPRec;
  1174. var
  1175. C64: TColor64Rec;
  1176. begin
  1177. C64.SetColor(Color);
  1178. Self.SetColor(C64);
  1179. Result := Self;
  1180. end;
  1181. function TColorFPRec.GetColor: TColor64;
  1182. var
  1183. C64: TColor64Rec;
  1184. begin
  1185. C64.SetColor(Self);
  1186. Result := C64.GetColor;
  1187. end;
  1188. function TColorFPRec.SetColor(A, R, G, B: Single): TColorFPRec;
  1189. begin
  1190. Self.A := A;
  1191. Self.R := R;
  1192. Self.G := G;
  1193. Self.B := B;
  1194. Result := Self;
  1195. end;
  1196. function TColorFPRec.SetColor(ColorRec: TColorFPRec): TColorFPRec;
  1197. begin
  1198. Self.A := ColorRec.A;
  1199. Self.R := ColorRec.R;
  1200. Self.G := ColorRec.G;
  1201. Self.B := ColorRec.B;
  1202. Result := Self;
  1203. end;
  1204. function TColorFPRec.SetColor(ColorRec: TColor64Rec): TColorFPRec;
  1205. begin
  1206. Self.A := ColorRec.A / $FFFF;
  1207. Self.R := ColorRec.R / $FFFF;
  1208. Self.G := ColorRec.G / $FFFF;
  1209. Self.B := ColorRec.B / $FFFF;
  1210. Result := Self;
  1211. end;
  1212. function TColorFPRec.SetColor(ColorRec: TColor48Rec): TColorFPRec;
  1213. begin
  1214. Self.A := 1.0;
  1215. Self.R := ColorRec.R / $FFFF;
  1216. Self.G := ColorRec.G / $FFFF;
  1217. Self.B := ColorRec.B / $FFFF;
  1218. Result := Self;
  1219. end;
  1220. function TColorFPRec.SetColor(ColorRec: TColor32Rec): TColorFPRec;
  1221. begin
  1222. Self.A := ColorRec.A / $FF;
  1223. Self.R := ColorRec.R / $FF;
  1224. Self.G := ColorRec.G / $FF;
  1225. Self.B := ColorRec.B / $FF;
  1226. Result := Self;
  1227. end;
  1228. function TColorFPRec.SetColor(ColorRec: TColor24Rec): TColorFPRec;
  1229. begin
  1230. Self.A := 1.0;
  1231. Self.R := ColorRec.R / $FF;
  1232. Self.G := ColorRec.G / $FF;
  1233. Self.B := ColorRec.B / $FF;
  1234. Result := Self;
  1235. end;
  1236. class operator TColorFPRec.Equal(const Left, Right: TColorFPRec): Boolean;
  1237. begin
  1238. Result := (Left.A = Right.A) and (Left.R = Right.R) and (Left.G = Right.G) and
  1239. (Left.B = Right.B);
  1240. end;
  1241. class operator TColorFPRec.NotEqual(const Left, Right: TColorFPRec): Boolean;
  1242. begin
  1243. Result := not TColorFPRec.Equals(Left, Right);
  1244. end;
  1245. initialization
  1246. Imaging.BuildFileFormatList;
  1247. {
  1248. Changes/Bug Fixes:
  1249. -- TODOS ----------------------------------------------------
  1250. - add typecast operators to color records rather than SetColor methods
  1251. - add create System.Drawing.Bitmap from TImageData function
  1252. -- 0.21 -----------------------------------------------------
  1253. - Changed out PChar parameter types of imported functions to StringBuilders
  1254. for easier conversions to System.String in Imaging class methods.
  1255. - Added GetImageFileFormatFilter method to Imaging class.
  1256. - Updated to DLL new version, some changes in Imaging class methods
  1257. that return strings.
  1258. -- 0.19 -----------------------------------------------------
  1259. - updated to DLL new version
  1260. -- 0.17 -----------------------------------------------------
  1261. - added new low level functions and their equivalents in Imaging class,
  1262. some old function headers updated
  1263. -- 0.15 -----------------------------------------------------
  1264. - changed headers of some functions because of changes in DLL
  1265. mainly related to TImageDataList parameters. Few other
  1266. "update" changes.
  1267. -- 0.13 -----------------------------------------------------
  1268. - Imaging class added
  1269. - various color records implemented
  1270. - several .NET only functions added
  1271. - unit created
  1272. }
  1273. end.