| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | 
							- using Android.Gms.Extensions;
 
- using Android.Graphics;
 
- using Android.Runtime;
 
- using Android.Util;
 
- using AndroidX.Camera.View.Transform;
 
- using InABox.Avalonia.Platform.Barcodes;
 
- using Java.Net;
 
- using Java.Util;
 
- using Microsoft.Maui.Graphics;
 
- using Microsoft.Maui.Storage;
 
- using Xamarin.Google.MLKit.Vision.Barcode.Common;
 
- using Xamarin.Google.MLKit.Vision.BarCode;
 
- using Xamarin.Google.MLKit.Vision.Common;
 
- using Image = Android.Media.Image;
 
- using Paint = Android.Graphics.Paint;
 
- using RectF = Microsoft.Maui.Graphics.RectF;
 
- using Size = Android.Util.Size;
 
- using ARectF = Android.Graphics.RectF;
 
- namespace InABox.Avalonia.Platform.Android.Barcodes;
 
- public static partial class Methods
 
- {
 
-     private static readonly bool neonSupported = IsNeonSupported();
 
-     private static readonly ParallelOptions parallelOptions = new()
 
-     {
 
-         MaxDegreeOfParallelism = Environment.ProcessorCount * 2
 
-     };
 
-     
 
-     public static async Task<IReadOnlySet<BarcodeResult>> ScanFromImageAsync(byte[] imageArray)
 
-         => await ProcessBitmapAsync(await BitmapFactory.DecodeByteArrayAsync(imageArray, 0, imageArray.Length));
 
-     public static async Task<IReadOnlySet<BarcodeResult>> ScanFromImageAsync(FileResult file)
 
-         => await ProcessBitmapAsync(await BitmapFactory.DecodeStreamAsync(await file.OpenReadAsync()));
 
-     public static async Task<IReadOnlySet<BarcodeResult>> ScanFromImageAsync(string url)
 
-         => await ProcessBitmapAsync(await BitmapFactory.DecodeStreamAsync(new URL(url).OpenStream()));
 
-     public static async Task<IReadOnlySet<BarcodeResult>> ScanFromImageAsync(Stream stream)
 
-         => await ProcessBitmapAsync(await BitmapFactory.DecodeStreamAsync(stream));
 
-     private static async Task<IReadOnlySet<BarcodeResult>> ProcessBitmapAsync(Bitmap? bitmap)
 
-     {
 
-         var barcodeResults = new HashSet<BarcodeResult>();
 
-         if (bitmap is null)
 
-             return barcodeResults;
 
-         
 
-         using var scanner = BarcodeScanning.GetClient(new BarcodeScannerOptions.Builder()
 
-             .SetBarcodeFormats(Barcode.FormatAllFormats)
 
-             .Build());
 
-         using var image = InputImage.FromBitmap(bitmap, 0);
 
-         using var results = await scanner.Process(image).AsAsync<Java.Lang.Object>();
 
-         ProcessBarcodeResult(results, barcodeResults);
 
-         using var invertedBitmap = Bitmap.CreateBitmap(bitmap.Height, bitmap.Width, bitmap.GetConfig());
 
-         using var canvas = new Canvas(invertedBitmap);
 
-         using var paint = new Paint();
 
-         using var matrixInvert = new ColorMatrix();
 
-         matrixInvert.Set(
 
-         [
 
-             -1.0f,  0.0f,  0.0f, 0.0f, 255.0f,
 
- 			 0.0f, -1.0f,  0.0f, 0.0f, 255.0f,
 
- 			 0.0f,  0.0f, -1.0f, 0.0f, 255.0f,
 
- 			 0.0f,  0.0f,  0.0f, 1.0f, 0.0f
 
-         ]);
 
-         using var filter = new ColorMatrixColorFilter(matrixInvert);
 
-         paint.SetColorFilter(filter);
 
-         canvas.DrawBitmap(bitmap, 0, 0, paint);
 
-         using var invertedImage = InputImage.FromBitmap(invertedBitmap, 0);
 
-         using var invertedResults = await scanner.Process(invertedImage).AsAsync<Java.Lang.Object>();
 
-         ProcessBarcodeResult(invertedResults, barcodeResults);
 
-         return barcodeResults;
 
-     }
 
-     
 
-     private static void ProcessBarcodeResult(Java.Lang.Object? inputResults, HashSet<BarcodeResult> outputResults)
 
-     {
 
-         if (inputResults is not JavaList javaList)
 
-             return;
 
-         foreach (Barcode barcode in javaList)
 
-         {
 
-             if (barcode is null)
 
-                 continue;
 
-             if (string.IsNullOrEmpty(barcode.DisplayValue) && string.IsNullOrEmpty(barcode.RawValue))
 
-                 continue;
 
-             outputResults.Add(barcode.AsBarcodeResult());
 
-         }
 
-     }
 
-     // [LibraryImport("libInvertBytes.so")]
 
-     // private static partial int InvertBytes(IntPtr data, int length);
 
-     internal static void InvertLuminance(Image image)
 
-     {
 
-         var yBuffer = image.GetPlanes()?[0].Buffer;
 
-         if (yBuffer is null)
 
-             return;
 
-         if (yBuffer.IsDirect)
 
-         {
 
-             var data = yBuffer.GetDirectBufferAddress();
 
-             var length = yBuffer.Capacity();
 
-             if (!neonSupported/* || InvertBytes(data, length) != 0*/)
 
-             {
 
-                 unsafe
 
-                 {
 
-                     var dataPtr = (ulong*)data; 
 
-                     Parallel.For(0, length >> 3, parallelOptions, (i) => dataPtr[i] = ~dataPtr[i]);
 
-                 }
 
-             }
 
-         }
 
-         else
 
-         {
 
-             using var bits = BitSet.ValueOf(yBuffer);
 
-             bits?.Flip(0, bits.Length());
 
-             yBuffer.Rewind();
 
-             yBuffer.Put(bits?.ToByteArray() ?? []);
 
-         }
 
-     }
 
-     internal static BarcodeTypes ConvertBarcodeResultTypes(int barcodeValueType)
 
-     {
 
-         return barcodeValueType switch
 
-         {
 
-             Barcode.TypeCalendarEvent => BarcodeTypes.CalendarEvent,
 
-             Barcode.TypeContactInfo => BarcodeTypes.ContactInfo,
 
-             Barcode.TypeDriverLicense => BarcodeTypes.DriversLicense,
 
-             Barcode.TypeEmail => BarcodeTypes.Email,
 
-             Barcode.TypeGeo => BarcodeTypes.GeographicCoordinates,
 
-             Barcode.TypeIsbn => BarcodeTypes.Isbn,
 
-             Barcode.TypePhone => BarcodeTypes.Phone,
 
-             Barcode.TypeProduct => BarcodeTypes.Product,
 
-             Barcode.TypeSms => BarcodeTypes.Sms,
 
-             Barcode.TypeText => BarcodeTypes.Text,
 
-             Barcode.TypeUrl => BarcodeTypes.Url,
 
-             Barcode.TypeWifi => BarcodeTypes.WiFi,
 
-             _ => BarcodeTypes.Unknown
 
-         };
 
-     }
 
-     internal static int ConvertBarcodeFormats(BarcodeFormats barcodeFormats)
 
-     {
 
-         var formats = Barcode.FormatAllFormats;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Code128))
 
-             formats |= Barcode.FormatCode128;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Code39))
 
-             formats |= Barcode.FormatCode39;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Code93))
 
-             formats |= Barcode.FormatCode93;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.CodaBar))
 
-             formats |= Barcode.FormatCodabar;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.DataMatrix))
 
-             formats |= Barcode.FormatDataMatrix;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Ean13))
 
-             formats |= Barcode.FormatEan13;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Ean8))
 
-             formats |= Barcode.FormatEan8;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Itf))
 
-             formats |= Barcode.FormatItf;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.QRCode))
 
-             formats |= Barcode.FormatQrCode;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Upca))
 
-             formats |= Barcode.FormatUpcA;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Upce))
 
-             formats |= Barcode.FormatUpcE;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Pdf417))
 
-             formats |= Barcode.FormatPdf417;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.Aztec))
 
-             formats |= Barcode.FormatAztec;
 
-         if (barcodeFormats.HasFlag(BarcodeFormats.All))
 
-             formats = Barcode.FormatAllFormats;
 
-         return formats;
 
-     }
 
-     internal static Size TargetResolution(CaptureQuality? captureQuality)
 
-     {
 
-         return captureQuality switch
 
-         {
 
-             CaptureQuality.Low => new Size(854, 480),
 
-             CaptureQuality.Medium => new Size(1280, 720),
 
-             CaptureQuality.High => new Size(1920, 1080),
 
-             CaptureQuality.Highest => new Size(3840, 2160),
 
-             _ => new Size(1280, 720)
 
-         };
 
-     }
 
-     private static bool IsNeonSupported()
 
-     {
 
-         try
 
-         {
 
-             var info = File.ReadAllText("/proc/cpuinfo");
 
-             return info.Contains("neon") || info.Contains("asimd");
 
-         }
 
-         catch (Exception)
 
-         {
 
-             return false;
 
-         }
 
-     }
 
-     internal static RectF AsRectangleF(this ARectF rect)
 
-     {
 
-         return new(rect.Left, rect.Top, rect.Width(), rect.Height());
 
-     }
 
-     internal static BarcodeResult AsBarcodeResult(this Barcode barcode, CoordinateTransform? coordinateTransform = null)
 
-     {
 
-         RectF imageRect, previewRect;
 
-         if (barcode.BoundingBox is null)
 
-         {
 
-             imageRect = RectF.Zero;
 
-             previewRect = RectF.Zero;
 
-         }
 
-         else
 
-         {
 
-             using var barcodeBox = new ARectF(barcode.BoundingBox);
 
-             imageRect = barcodeBox.AsRectangleF();
 
-             if (coordinateTransform is null)
 
-             {
 
-                 previewRect = new();
 
-             }
 
-             else
 
-             {
 
-                 coordinateTransform.MapRect(barcodeBox);
 
-                 previewRect = barcodeBox.AsRectangleF();
 
-             }
 
-         }
 
-         return new BarcodeResult()
 
-         {
 
-             BarcodeType = Methods.ConvertBarcodeResultTypes(barcode.ValueType),
 
-             BarcodeFormat = (BarcodeFormats)barcode.Format,
 
-             DisplayValue = barcode.DisplayValue ?? string.Empty,
 
-             RawValue = barcode.RawValue ?? string.Empty,
 
-             RawBytes = barcode.GetRawBytes() ?? [],
 
-             PreviewBoundingBox = previewRect,
 
-             ImageBoundingBox = imageRect
 
-         };
 
-     }
 
- }
 
 
  |