ZXingCpp.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*
  2. * Copyright 2024 Axel Waggershauser
  3. */
  4. // SPDX-License-Identifier: Apache-2.0
  5. namespace ZXingCpp {
  6. using System;
  7. #if NETSTANDARD
  8. using System.Text;
  9. #endif
  10. using System.Runtime.InteropServices;
  11. using System.Collections.Generic;
  12. using static Dll;
  13. using BarcodeFormat = BarcodeFormats;
  14. internal class Dll
  15. {
  16. private const string DllName = "ZXing";
  17. [DllImport(DllName)] public static extern IntPtr ZXing_ReaderOptions_new();
  18. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_delete(IntPtr opts);
  19. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setTryHarder(IntPtr opts, bool tryHarder);
  20. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getTryHarder(IntPtr opts);
  21. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setTryRotate(IntPtr opts, bool tryRotate);
  22. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getTryRotate(IntPtr opts);
  23. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setTryInvert(IntPtr opts, bool tryInvert);
  24. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getTryInvert(IntPtr opts);
  25. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setTryDownscale(IntPtr opts, bool tryDownscale);
  26. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getTryDownscale(IntPtr opts);
  27. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getIsPure(IntPtr opts);
  28. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setIsPure(IntPtr opts, bool isPure);
  29. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setReturnErrors(IntPtr opts, bool returnErrors);
  30. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_ReaderOptions_getReturnErrors(IntPtr opts);
  31. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setFormats(IntPtr opts, BarcodeFormats formats);
  32. [DllImport(DllName)] public static extern BarcodeFormats ZXing_ReaderOptions_getFormats(IntPtr opts);
  33. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setBinarizer(IntPtr opts, Binarizer binarizer);
  34. [DllImport(DllName)] public static extern Binarizer ZXing_ReaderOptions_getBinarizer(IntPtr opts);
  35. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setEanAddOnSymbol(IntPtr opts, EanAddOnSymbol eanAddOnSymbol);
  36. [DllImport(DllName)] public static extern EanAddOnSymbol ZXing_ReaderOptions_getEanAddOnSymbol(IntPtr opts);
  37. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setTextMode(IntPtr opts, TextMode textMode);
  38. [DllImport(DllName)] public static extern TextMode ZXing_ReaderOptions_getTextMode(IntPtr opts);
  39. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setMinLineCount(IntPtr opts, int n);
  40. [DllImport(DllName)] public static extern int ZXing_ReaderOptions_getMinLineCount(IntPtr opts);
  41. [DllImport(DllName)] public static extern void ZXing_ReaderOptions_setMaxNumberOfSymbols(IntPtr opts, int n);
  42. [DllImport(DllName)] public static extern int ZXing_ReaderOptions_getMaxNumberOfSymbols(IntPtr opts);
  43. [DllImport(DllName)] public static extern IntPtr ZXing_PositionToString(Position position);
  44. [DllImport(DllName)] public static extern BarcodeFormat ZXing_BarcodeFormatFromString(string str);
  45. [DllImport(DllName)] public static extern BarcodeFormats ZXing_BarcodeFormatsFromString(string str);
  46. [DllImport(DllName)] public static extern IntPtr ZXing_ImageView_new(IntPtr data, int width, int height, ImageFormat format, int rowStride, int pixStride);
  47. [DllImport(DllName)] public static extern IntPtr ZXing_ImageView_new_checked(byte[] data, int size, int width, int height, ImageFormat format, int rowStride, int pixStride);
  48. [DllImport(DllName)] public static extern void ZXing_ImageView_delete(IntPtr iv);
  49. [DllImport(DllName)] public static extern void ZXing_Image_delete(IntPtr img);
  50. [DllImport(DllName)] public static extern IntPtr ZXing_Image_data(IntPtr img);
  51. [DllImport(DllName)] public static extern int ZXing_Image_width(IntPtr img);
  52. [DllImport(DllName)] public static extern int ZXing_Image_height(IntPtr img);
  53. [DllImport(DllName)] public static extern ImageFormat ZXing_Image_format(IntPtr img);
  54. [DllImport(DllName)] public static extern IntPtr ZXing_ReadBarcodes(IntPtr iv, IntPtr opts);
  55. [DllImport(DllName)] public static extern void ZXing_Barcode_delete(IntPtr barcode);
  56. [DllImport(DllName)] public static extern void ZXing_Barcodes_delete(IntPtr barcodes);
  57. [DllImport(DllName)] public static extern int ZXing_Barcodes_size(IntPtr barcodes);
  58. [DllImport(DllName)] public static extern IntPtr ZXing_Barcodes_move(IntPtr barcodes, int i);
  59. [DllImport(DllName)] public static extern IntPtr ZXing_CreatorOptions_new(BarcodeFormat format);
  60. [DllImport(DllName)] public static extern void ZXing_CreatorOptions_delete(IntPtr opts);
  61. [DllImport(DllName)] public static extern void ZXing_CreatorOptions_setFormat(IntPtr opts, BarcodeFormat format);
  62. [DllImport(DllName)] public static extern BarcodeFormat ZXing_CreatorOptions_getFormat(IntPtr opts);
  63. [DllImport(DllName)] public static extern void ZXing_CreatorOptions_setReaderInit(IntPtr opts, bool readerInit);
  64. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_CreatorOptions_getReaderInit(IntPtr opts);
  65. [DllImport(DllName)] public static extern void ZXing_CreatorOptions_setForceSquareDataMatrix(IntPtr opts, bool forceSquareDataMatrix);
  66. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_CreatorOptions_getForceSquareDataMatrix(IntPtr opts);
  67. [DllImport(DllName)] public static extern void ZXing_CreatorOptions_setEcLevel(IntPtr opts, string ecLevel);
  68. [DllImport(DllName)] public static extern IntPtr ZXing_CreatorOptions_getEcLevel(IntPtr opts);
  69. [DllImport(DllName)] public static extern IntPtr ZXing_WriterOptions_new();
  70. [DllImport(DllName)] public static extern void ZXing_WriterOptions_delete(IntPtr opts);
  71. [DllImport(DllName)] public static extern void ZXing_WriterOptions_setScale(IntPtr opts, int scale);
  72. [DllImport(DllName)] public static extern int ZXing_WriterOptions_getScale(IntPtr opts);
  73. [DllImport(DllName)] public static extern void ZXing_WriterOptions_setSizeHint(IntPtr opts, int sizeHint);
  74. [DllImport(DllName)] public static extern int ZXing_WriterOptions_getSizeHint(IntPtr opts);
  75. [DllImport(DllName)] public static extern void ZXing_WriterOptions_setRotate(IntPtr opts, int rotate);
  76. [DllImport(DllName)] public static extern int ZXing_WriterOptions_getRotate(IntPtr opts);
  77. [DllImport(DllName)] public static extern void ZXing_WriterOptions_setWithHRT(IntPtr opts, bool withHRT);
  78. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_WriterOptions_getWithHRT(IntPtr opts);
  79. [DllImport(DllName)] public static extern void ZXing_WriterOptions_setWithQuietZones(IntPtr opts, bool withQuietZones);
  80. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_WriterOptions_getWithQuietZones(IntPtr opts);
  81. [DllImport(DllName)] public static extern IntPtr ZXing_CreateBarcodeFromText(string data, int size, IntPtr opts);
  82. [DllImport(DllName)] public static extern IntPtr ZXing_CreateBarcodeFromBytes(byte[] data, int size, IntPtr opts);
  83. [DllImport(DllName)] public static extern IntPtr ZXing_WriteBarcodeToSVG(IntPtr barcode, IntPtr opts);
  84. [DllImport(DllName)] public static extern IntPtr ZXing_WriteBarcodeToImage(IntPtr barcode, IntPtr opts);
  85. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_Barcode_isValid(IntPtr barcode);
  86. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_errorMsg(IntPtr barcode);
  87. [DllImport(DllName)] public static extern ErrorType ZXing_Barcode_errorType(IntPtr barcode);
  88. [DllImport(DllName)] public static extern BarcodeFormat ZXing_Barcode_format(IntPtr barcode);
  89. [DllImport(DllName)] public static extern ContentType ZXing_Barcode_contentType(IntPtr barcode);
  90. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_bytes(IntPtr barcode, out int len);
  91. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_bytesECI(IntPtr barcode, out int len);
  92. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_text(IntPtr barcode);
  93. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_ecLevel(IntPtr barcode);
  94. [DllImport(DllName)] public static extern IntPtr ZXing_Barcode_symbologyIdentifier(IntPtr barcode);
  95. [DllImport(DllName)] public static extern Position ZXing_Barcode_position(IntPtr barcode);
  96. [DllImport(DllName)] public static extern int ZXing_Barcode_orientation(IntPtr barcode);
  97. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_Barcode_hasECI(IntPtr barcode);
  98. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_Barcode_isInverted(IntPtr barcode);
  99. [DllImport(DllName)] [return:MarshalAs(UnmanagedType.I1)] public static extern bool ZXing_Barcode_isMirrored(IntPtr barcode);
  100. [DllImport(DllName)] public static extern int ZXing_Barcode_lineCount(IntPtr barcode);
  101. [DllImport(DllName)] public static extern void ZXing_free(IntPtr opts);
  102. [DllImport(DllName)] public static extern IntPtr ZXing_LastErrorMsg();
  103. public static IntPtr CheckError(IntPtr ptr, string? msg = null)
  104. {
  105. if (ptr == IntPtr.Zero)
  106. throw new Exception(msg ?? MarshalAsString(ZXing_LastErrorMsg()));
  107. return ptr;
  108. }
  109. public static string MarshalAsString(IntPtr ptr)
  110. {
  111. ptr = CheckError(ptr, "ZXing C-API returned a NULL char*.");
  112. #if NET
  113. string res = Marshal.PtrToStringUTF8(ptr) ?? "";
  114. #else
  115. string res;
  116. unsafe
  117. {
  118. int length = 0;
  119. for (byte* i = (byte*)ptr; *i != 0; i++, length++);
  120. res = Encoding.UTF8.GetString((byte*)ptr, length);
  121. }
  122. #endif
  123. ZXing_free(ptr);
  124. return res;
  125. }
  126. public delegate IntPtr RetBytesFunc(IntPtr ptr, out int len);
  127. public static byte[] MarshalAsBytes(RetBytesFunc func, IntPtr d)
  128. {
  129. IntPtr ptr = CheckError(func(d, out int len), "ZXing C-API returned a NULL byte*.");
  130. byte[] res = new byte[len];
  131. Marshal.Copy(ptr, res, 0, len);
  132. ZXing_free(ptr);
  133. return res;
  134. }
  135. }
  136. [Flags]
  137. public enum BarcodeFormats
  138. {
  139. None = 0, ///< Used as a return value if no valid barcode has been detected
  140. Aztec = (1 << 0), ///< Aztec
  141. Codabar = (1 << 1), ///< Codabar
  142. Code39 = (1 << 2), ///< Code39
  143. Code93 = (1 << 3), ///< Code93
  144. Code128 = (1 << 4), ///< Code128
  145. DataBar = (1 << 5), ///< GS1 DataBar, formerly known as RSS 14
  146. DataBarExpanded = (1 << 6), ///< GS1 DataBar Expanded, formerly known as RSS EXPANDED
  147. DataMatrix = (1 << 7), ///< DataMatrix
  148. EAN8 = (1 << 8), ///< EAN-8
  149. EAN13 = (1 << 9), ///< EAN-13
  150. ITF = (1 << 10), ///< ITF (Interleaved Two of Five)
  151. MaxiCode = (1 << 11), ///< MaxiCode
  152. PDF417 = (1 << 12), ///< PDF417
  153. QRCode = (1 << 13), ///< QR Code
  154. UPCA = (1 << 14), ///< UPC-A
  155. UPCE = (1 << 15), ///< UPC-E
  156. MicroQRCode = (1 << 16), ///< Micro QR Code
  157. RMQRCode = (1 << 17), ///< Rectangular Micro QR Code
  158. DXFilmEdge = (1 << 18), ///< DX Film Edge Barcode
  159. DataBarLimited = (1 << 19), ///< GS1 DataBar Limited
  160. LinearCodes = Codabar | Code39 | Code93 | Code128 | EAN8 | EAN13 | ITF | DataBar | DataBarExpanded | DataBarLimited | DXFilmEdge | UPCA | UPCE,
  161. MatrixCodes = Aztec | DataMatrix | MaxiCode | PDF417 | QRCode | MicroQRCode | RMQRCode,
  162. Any = LinearCodes | MatrixCodes,
  163. };
  164. public enum Binarizer
  165. {
  166. LocalAverage, ///< T = average of neighboring pixels for matrix and GlobalHistogram for linear (HybridBinarizer)
  167. GlobalHistogram, ///< T = valley between the 2 largest peaks in the histogram (per line in linear case)
  168. FixedThreshold, ///< T = 127
  169. BoolCast, ///< T = 0, fastest possible
  170. };
  171. public enum EanAddOnSymbol
  172. {
  173. Ignore, ///< Ignore any Add-On symbol during read/scan
  174. Read, ///< Read EAN-2/EAN-5 Add-On symbol if found
  175. Require, ///< Require EAN-2/EAN-5 Add-On symbol to be present
  176. };
  177. public enum TextMode
  178. {
  179. Plain, ///< bytes() transcoded to unicode based on ECI info or guessed charset (the default mode prior to 2.0)
  180. ECI, ///< standard content following the ECI protocol with every character set ECI segment transcoded to unicode
  181. HRI, ///< Human Readable Interpretation (dependent on the ContentType)
  182. Hex, ///< bytes() transcoded to ASCII string of HEX values
  183. Escaped, ///< Use the EscapeNonGraphical() function (e.g. ASCII 29 will be transcoded to "<GS>")
  184. };
  185. public enum ContentType { Text, Binary, Mixed, GS1, ISO15434, UnknownECI };
  186. public enum ErrorType { None, Format, Checksum, Unsupported };
  187. public enum ImageFormat {
  188. None = 0,
  189. Lum = 0x01000000,
  190. LumA = 0x02000000,
  191. RGB = 0x03000102,
  192. BGR = 0x03020100,
  193. RGBA = 0x04000102,
  194. ARGB = 0x04010203,
  195. BGRA = 0x04020100,
  196. ABGR = 0x04030201,
  197. };
  198. public struct PointI
  199. {
  200. public int X, Y;
  201. };
  202. public struct Position
  203. {
  204. public PointI TopLeft, TopRight, BottomRight, BottomLeft;
  205. public override string ToString() => MarshalAsString(ZXing_PositionToString(this));
  206. };
  207. public class ImageView
  208. {
  209. internal IntPtr _d;
  210. public ImageView(byte[] data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0)
  211. => _d = CheckError(ZXing_ImageView_new_checked(data, data.Length, width, height, format, rowStride, pixStride));
  212. public ImageView(IntPtr data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0)
  213. => _d = CheckError(ZXing_ImageView_new(data, width, height, format, rowStride, pixStride));
  214. ~ImageView() => ZXing_ImageView_delete(_d);
  215. }
  216. public class Image : IDisposable
  217. {
  218. internal IntPtr _d;
  219. internal Image(IntPtr d) => _d = d;
  220. ~Image() => Dispose();
  221. public void Dispose()
  222. {
  223. ZXing_Image_delete(_d);
  224. _d = IntPtr.Zero;
  225. GC.SuppressFinalize(this);
  226. }
  227. public IntPtr Data => ZXing_Image_data(_d);
  228. public int Width => ZXing_Image_width(_d);
  229. public int Height => ZXing_Image_height(_d);
  230. public ImageFormat Format => ZXing_Image_format(_d);
  231. public byte[] ToArray()
  232. {
  233. IntPtr ptr = ZXing_Image_data(_d);
  234. if (ptr == IntPtr.Zero)
  235. return new byte[0];
  236. int len = Width * Height;
  237. byte[] res = new byte[len];
  238. Marshal.Copy(ptr, res, 0, len);
  239. return res;
  240. }
  241. }
  242. public class ReaderOptions
  243. {
  244. internal IntPtr _d;
  245. public ReaderOptions() => _d = CheckError(ZXing_ReaderOptions_new(), "Failed to create ReaderOptions.");
  246. ~ReaderOptions() => ZXing_ReaderOptions_delete(_d);
  247. public bool TryHarder
  248. {
  249. get => ZXing_ReaderOptions_getTryHarder(_d);
  250. set => ZXing_ReaderOptions_setTryHarder(_d, value);
  251. }
  252. public bool TryRotate
  253. {
  254. get => ZXing_ReaderOptions_getTryRotate(_d);
  255. set => ZXing_ReaderOptions_setTryRotate(_d, value);
  256. }
  257. public bool TryInvert
  258. {
  259. get => ZXing_ReaderOptions_getTryInvert(_d);
  260. set => ZXing_ReaderOptions_setTryInvert(_d, value);
  261. }
  262. public bool TryDownscale
  263. {
  264. get => ZXing_ReaderOptions_getTryDownscale(_d);
  265. set => ZXing_ReaderOptions_setTryDownscale(_d, value);
  266. }
  267. public bool IsPure
  268. {
  269. get => ZXing_ReaderOptions_getIsPure(_d);
  270. set => ZXing_ReaderOptions_setIsPure(_d, value);
  271. }
  272. public bool ReturnErrors
  273. {
  274. get => ZXing_ReaderOptions_getReturnErrors(_d);
  275. set => ZXing_ReaderOptions_setReturnErrors(_d, value);
  276. }
  277. public BarcodeFormats Formats
  278. {
  279. get => ZXing_ReaderOptions_getFormats(_d);
  280. set => ZXing_ReaderOptions_setFormats(_d, value);
  281. }
  282. public Binarizer Binarizer
  283. {
  284. get => ZXing_ReaderOptions_getBinarizer(_d);
  285. set => ZXing_ReaderOptions_setBinarizer(_d, value);
  286. }
  287. public EanAddOnSymbol EanAddOnSymbol
  288. {
  289. get => ZXing_ReaderOptions_getEanAddOnSymbol(_d);
  290. set => ZXing_ReaderOptions_setEanAddOnSymbol(_d, value);
  291. }
  292. public TextMode TextMode
  293. {
  294. get => ZXing_ReaderOptions_getTextMode(_d);
  295. set => ZXing_ReaderOptions_setTextMode(_d, value);
  296. }
  297. public int MinLineCount
  298. {
  299. get => ZXing_ReaderOptions_getMinLineCount(_d);
  300. set => ZXing_ReaderOptions_setMinLineCount(_d, value);
  301. }
  302. public int MaxNumberOfSymbols
  303. {
  304. get => ZXing_ReaderOptions_getMaxNumberOfSymbols(_d);
  305. set => ZXing_ReaderOptions_setMaxNumberOfSymbols(_d, value);
  306. }
  307. }
  308. public class CreatorOptions
  309. {
  310. internal IntPtr _d;
  311. public CreatorOptions(BarcodeFormat format)
  312. => _d = CheckError(ZXing_CreatorOptions_new(format), "Failed to create CreatorOptions.");
  313. public static implicit operator CreatorOptions(BarcodeFormat f) => new CreatorOptions(f);
  314. ~CreatorOptions() => ZXing_CreatorOptions_delete(_d);
  315. public bool ReaderInit
  316. {
  317. get => ZXing_CreatorOptions_getReaderInit(_d);
  318. set => ZXing_CreatorOptions_setReaderInit(_d, value);
  319. }
  320. public bool ForceSquareDataMatrix
  321. {
  322. get => ZXing_CreatorOptions_getForceSquareDataMatrix(_d);
  323. set => ZXing_CreatorOptions_setForceSquareDataMatrix(_d, value);
  324. }
  325. public String ECLevel
  326. {
  327. get => MarshalAsString(ZXing_CreatorOptions_getEcLevel(_d));
  328. set => ZXing_CreatorOptions_setEcLevel(_d, value);
  329. }
  330. }
  331. public class WriterOptions
  332. {
  333. internal IntPtr _d;
  334. public WriterOptions() => _d = CheckError(ZXing_WriterOptions_new(), "Failed to create WriterOptions.");
  335. ~WriterOptions() => ZXing_WriterOptions_delete(_d);
  336. public int Scale
  337. {
  338. get => ZXing_WriterOptions_getScale(_d);
  339. set => ZXing_WriterOptions_setScale(_d, value);
  340. }
  341. public int SizeHint
  342. {
  343. get => ZXing_WriterOptions_getSizeHint(_d);
  344. set => ZXing_WriterOptions_setSizeHint(_d, value);
  345. }
  346. public int Rotate
  347. {
  348. get => ZXing_WriterOptions_getRotate(_d);
  349. set => ZXing_WriterOptions_setRotate(_d, value);
  350. }
  351. public bool WithHRT
  352. {
  353. get => ZXing_WriterOptions_getWithHRT(_d);
  354. set => ZXing_WriterOptions_setWithHRT(_d, value);
  355. }
  356. public bool WithQuietZones
  357. {
  358. get => ZXing_WriterOptions_getWithQuietZones(_d);
  359. set => ZXing_WriterOptions_setWithQuietZones(_d, value);
  360. }
  361. }
  362. public class Barcode
  363. {
  364. internal IntPtr _d;
  365. internal Barcode(IntPtr d) => _d = d;
  366. ~Barcode() => ZXing_Barcode_delete(_d);
  367. public Barcode(string data, CreatorOptions opts)
  368. => _d = CheckError(ZXing_CreateBarcodeFromText(data, data.Length, opts._d));
  369. public Barcode(byte[] data, CreatorOptions opts)
  370. => _d = CheckError(ZXing_CreateBarcodeFromBytes(data, data.Length, opts._d));
  371. public bool IsValid => ZXing_Barcode_isValid(_d);
  372. public BarcodeFormat Format => ZXing_Barcode_format(_d);
  373. public ContentType ContentType => ZXing_Barcode_contentType(_d);
  374. public string Text => MarshalAsString(ZXing_Barcode_text(_d));
  375. public byte[] Bytes => MarshalAsBytes(ZXing_Barcode_bytes, _d);
  376. public byte[] BytesECI => MarshalAsBytes(ZXing_Barcode_bytesECI, _d);
  377. public string ECLevel => MarshalAsString(ZXing_Barcode_ecLevel(_d));
  378. public string SymbologyIdentifier => MarshalAsString(ZXing_Barcode_symbologyIdentifier(_d));
  379. public string ErrorMsg => MarshalAsString(ZXing_Barcode_errorMsg(_d));
  380. public ErrorType ErrorType => ZXing_Barcode_errorType(_d);
  381. public Position Position => ZXing_Barcode_position(_d);
  382. public int Orientation => ZXing_Barcode_orientation(_d);
  383. public bool HasECI => ZXing_Barcode_hasECI(_d);
  384. public bool IsInverted => ZXing_Barcode_isInverted(_d);
  385. public bool IsMirrored => ZXing_Barcode_isMirrored(_d);
  386. public int LineCount => ZXing_Barcode_lineCount(_d);
  387. public string ToSVG(WriterOptions? opts = null)
  388. => MarshalAsString(CheckError(ZXing_WriteBarcodeToSVG(_d, opts?._d ?? IntPtr.Zero)));
  389. public Image ToImage(WriterOptions? opts = null)
  390. => new Image(CheckError(ZXing_WriteBarcodeToImage(_d, opts?._d ?? IntPtr.Zero)));
  391. public static BarcodeFormat FormatFromString(string str)
  392. {
  393. var res = ZXing_BarcodeFormatFromString(str);
  394. if ((int)res == -1) // see ZXing_BarcodeFormat_Invalid
  395. throw new Exception(MarshalAsString(ZXing_LastErrorMsg()));
  396. return res;
  397. }
  398. public static BarcodeFormats FormatsFromString(string str)
  399. {
  400. var res = ZXing_BarcodeFormatsFromString(str);
  401. if ((int)res == -1) // see ZXing_BarcodeFormat_Invalid
  402. throw new Exception(MarshalAsString(ZXing_LastErrorMsg()));
  403. return res;
  404. }
  405. }
  406. public class BarcodeReader : ReaderOptions
  407. {
  408. public static Barcode[] Read(ImageView iv, ReaderOptions? opts = null)
  409. {
  410. var ptr = CheckError(ZXing_ReadBarcodes(iv._d, opts?._d ?? IntPtr.Zero));
  411. // return static empty array if no Barcodes are found, avoiding any managed heap allocation
  412. var res = Array.Empty<Barcode>();
  413. var size = ZXing_Barcodes_size(ptr);
  414. if (size > 0) {
  415. res = new Barcode[size];
  416. for (int i = 0; i < size; ++i)
  417. res[i] = new Barcode(ZXing_Barcodes_move(ptr, i));
  418. }
  419. ZXing_Barcodes_delete(ptr);
  420. return res;
  421. }
  422. public Barcode[] From(ImageView iv) => Read(iv, this);
  423. }
  424. public class BarcodeCreator : CreatorOptions
  425. {
  426. public BarcodeCreator(BarcodeFormat format) : base(format) {}
  427. public Barcode From(string data) => new Barcode(data, this);
  428. public Barcode From(byte[] data) => new Barcode(data, this);
  429. }
  430. }