Click here to show toolbars of the Web Online Help System: show toolbars |
/*******************************************************************************/ /* * File name: MIL.MbufPointerAccess.cs * Location: See Matrox Example Launcher in the MIL Control Center * * * Synopsis: This program shows how to use the pointer of a * MIL buffer in order to directly access its data. * * Note: This program does not support Distributed MIL (DMIL). * * Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. * All Rights Reserved * */ using System; using System.Collections.Generic; using System.Text; using Matrox.MatroxImagingLibrary; namespace MBufPointerAccess { class Program { /* Target image size. */ private const int IMAGE_SIZE_X = 512; private const int IMAGE_SIZE_Y = 512; static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); /* Pointer access example for a monochrome buffer */ MonoBufferPointerAccessExample(MilSystem, MilDisplay); /* Pointer access example for a color packed buffer. */ ColorPackedBufferPointerAccessExample(MilSystem, MilDisplay); /* Pointer access example for a color planar buffer. */ ColorPlanarBufferPointerAccessExample(MilSystem, MilDisplay); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); } /* Pointer access example for a monochrome buffer. */ /* ------------------------------------------------*/ /* Pixel value calculation parameters. */ private const double X_REF1 = -0.500; private const double Y_REF1 = +0.001; private const double DIM1 = +3.200; static void MonoBufferPointerAccessExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; /* Image buffer identifier. */ MIL_INT MilImagePtr = MIL.M_NULL; /* Image pointer. */ MIL_INT MilImagePitch = MIL.M_NULL; /* Image pitch. */ MIL_INT x, y; /* Buffer access variables. */ MIL_UINT Value; /* Value to write. */ Console.Write("- The data of a 8bits monochrome MIL buffer is modified\n"); Console.Write(" using its pointer to directly access the memory.\n\n"); /* Allocate a monochrome buffer. */ MIL.MbufAlloc2d(MilSystem, IMAGE_SIZE_X, IMAGE_SIZE_Y, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilImage); /* Lock buffer for direct access. */ MIL.MbufControl(MilImage, MIL.M_LOCK, MIL.M_DEFAULT); /* Retrieving buffer data pointer and pitch information. */ MIL.MbufInquire(MilImage, MIL.M_HOST_ADDRESS, ref MilImagePtr); MIL.MbufInquire(MilImage, MIL.M_PITCH, ref MilImagePitch); /* Direct Access to the buffer's data. */ if (MilImagePtr != MIL.M_NULL) { unsafe // Unsafe code block to allow manipulating memory addresses { // Convert the address inquired from MIL to a fixed size pointer. // The MIL_INT type cannot be converted to a byte * so use the // IntPtr portable type // IntPtr MilImagePtrIntPtr = MilImagePtr; byte* MilImageAddr = (byte*)MilImagePtrIntPtr; /* For each row. */ for (y = 0; y < IMAGE_SIZE_Y; y++) { /* For each column. */ for (x = 0; x < IMAGE_SIZE_X; x++) { /* Calculate the pixel value. */ Value = Mandelbrot(x, y, X_REF1, Y_REF1, DIM1); /* Write the pixel using its pointer. */ MilImageAddr[x] = (byte)(Value); } /* Move pointer to the next line taking into account the image's pitch. */ MilImageAddr += MilImagePitch; } /* Signals MIL that the buffer data has been updated. */ MIL.MbufControl(MilImage, MIL.M_MODIFIED, MIL.M_DEFAULT); /* Unlock buffer. */ MIL.MbufControl(MilImage, MIL.M_UNLOCK, MIL.M_DEFAULT); /* Select to display. */ MIL.MdispSelect(MilDisplay, MilImage); } } else { Console.Write("The source buffer has no accessible memory\n"); Console.Write("address on this specific system. Try changing\n"); Console.Write("the system in the MIL Config utility.\n\n"); } /* Print a message and wait for a key. */ Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); /* Free allocation. */ MIL.MbufFree(MilImage); } /* Pointer access example for a color packed buffer. */ /* --------------------------------------------------*/ /* Pixel value calculation parameters. */ private const double X_REF2 = -1.1355; private const double Y_REF2 = -0.2510; private const double DIM2 = +0.1500; /* Utility to pack B,G,R values into 32 bits integer. */ static uint PackToBGR32(Byte b, Byte g, Byte r) { return ((uint)b | (uint)(g << 8) | (uint)(r << 16)); } static void ColorPackedBufferPointerAccessExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; /* Image buffer identifier. */ MIL_INT MilImagePtr = MIL.M_NULL; /* Image pointer. */ MIL_INT MilImagePitch = MIL.M_NULL; /* Image pitch. */ MIL_INT x, y, NbBand = 3; /* Buffer access variables. */ MIL_UINT Value; /* Value to write. */ uint Value_BGR32; /* Value to write. */ Console.Write("- The data of a 32bits color packed MIL buffer is modified\n"); Console.Write(" using its pointer to directly access the memory.\n\n"); /* Allocate a monochrome buffer. */ MIL.MbufAllocColor(MilSystem, NbBand, IMAGE_SIZE_X, IMAGE_SIZE_Y, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP + MIL.M_BGR32 + MIL.M_PACKED, ref MilImage); /* Lock buffer for direct access. */ MIL.MbufControl(MilImage, MIL.M_LOCK, MIL.M_DEFAULT); /* Retrieving buffer data pointer and pitch information. */ MIL.MbufInquire(MilImage, MIL.M_HOST_ADDRESS, ref MilImagePtr); MIL.MbufInquire(MilImage, MIL.M_PITCH, ref MilImagePitch); /* Direct Access to the buffer's data. */ if (MilImagePtr != MIL.M_NULL) { unsafe // Unsafe code block to allow manipulating memory addresses { // Convert the address inquired from MIL to a fixed size pointer. // The MIL_INT type cannot be converted to a byte * so use the // IntPtr portable type // IntPtr MilImagePtrIntPtr = MilImagePtr; uint* MilImageAddr = (uint*)MilImagePtrIntPtr; /* For each row. */ for (y = 0; y < IMAGE_SIZE_Y; y++) { /* For each column. */ for (x = 0; x < IMAGE_SIZE_X; x++) { /* Calculate the pixel value. */ Value = Mandelbrot(x, y, X_REF2, Y_REF2, DIM2); Value_BGR32 = PackToBGR32( (byte)GetColorFromIndex(MIL.M_BLUE, (MIL_INT)Value, 255), (byte)GetColorFromIndex(MIL.M_GREEN, (MIL_INT)Value, 255), (byte)GetColorFromIndex(MIL.M_RED, (MIL_INT)Value, 255) ); /* Write the pixel using its pointer. */ MilImageAddr[x] = (uint)Value_BGR32; } /* Move pointer to the next line taking into account the image's pitch. */ MilImageAddr += MilImagePitch; } /* Signals MIL that the buffer data has been updated. */ MIL.MbufControl(MilImage, MIL.M_MODIFIED, MIL.M_DEFAULT); /* Unlock buffer. */ MIL.MbufControl(MilImage, MIL.M_UNLOCK, MIL.M_DEFAULT); /* Select to display. */ MIL.MdispSelect(MilDisplay, MilImage); } } else { Console.Write("The source buffer has no accessible memory\n"); Console.Write("address on this specific system. Try changing\n"); Console.Write("the system in the MIL Config utility.\n\n"); } /* Print a message and wait for a key. */ Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); /* Free allocation. */ MIL.MbufFree(MilImage); } /* Pointer access example for a color planar buffer. */ /* ------------------------------------------------*/ /* Pixel value calculation parameters. */ private const double X_REF3 = -0.7453; private const double Y_REF3 = +0.1127; private const double DIM3 = +0.0060; static void ColorPlanarBufferPointerAccessExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; /* Image buffer identifier. */ MIL_ID MilImageBand = MIL.M_NULL; /* Image band identifier. */ MIL_INT MilImageBandPtr = MIL.M_NULL; /* Image pointer. */ MIL_INT MilImagePitch = MIL.M_NULL; /* Image pitch. */ MIL_INT x, y, i, NbBand = 3; /* Buffer access variables. */ MIL_UINT Value; /* Value to write. */ MIL_INT[] ColorBand = new MIL_INT[] { MIL.M_RED, MIL.M_GREEN, MIL.M_BLUE }; Console.Write("- The data of a 24bits color planar MIL buffer is modified using\n"); Console.Write(" each color band pointer's to directly access the memory.\n\n"); /* Allocate a monochrome buffer. */ MIL.MbufAllocColor(MilSystem, NbBand, IMAGE_SIZE_X, IMAGE_SIZE_Y, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP + MIL.M_PLANAR, ref MilImage); /* Retrieving buffer pitch information. */ MIL.MbufInquire(MilImage, MIL.M_PITCH, ref MilImagePitch); /* Lock buffer for direct access. */ MIL.MbufControl(MilImage, MIL.M_LOCK, MIL.M_DEFAULT); /* Verifying the buffer has a host address. */ MIL.MbufChildColor(MilImage, MIL.M_RED, ref MilImageBand); MIL.MbufInquire(MilImageBand, MIL.M_HOST_ADDRESS, ref MilImageBandPtr); MIL.MbufFree(MilImageBand); if (MilImageBandPtr != MIL.M_NULL) { unsafe // Unsafe code block to allow manipulating memory addresses { /* For each color band. */ for (i = 0; i < NbBand; i++) { /* Retrieving buffer color band pointer. */ MIL.MbufChildColor(MilImage, (MIL_INT)ColorBand[i], ref MilImageBand); MIL.MbufInquire(MilImageBand, MIL.M_HOST_ADDRESS, ref MilImageBandPtr); // Convert the address inquired from MIL to a fixed size pointer. // The MIL_INT type cannot be converted to a byte * so use the // IntPtr portable type // IntPtr MilImageBandPtrIntPtr = MilImageBandPtr; byte* MilImageBandAddr = (byte*)MilImageBandPtrIntPtr; /* For each row. */ for (y = 0; y < IMAGE_SIZE_Y; y++) { /* For each column. */ for (x = 0; x < IMAGE_SIZE_X; x++) { /* Calculate the pixel value. */ Value = Mandelbrot(x, y, X_REF3, Y_REF3, DIM3); /* Write the pixel using its pointer. */ MilImageBandAddr[x] = (byte)GetColorFromIndex(ColorBand[i], (MIL_INT)Value, 255); } /* Move pointer to the next line taking into account the image's pitch. */ MilImageBandAddr += MilImagePitch; } MIL.MbufFree(MilImageBand); } } /* Signals MIL that the buffer data has been updated. */ MIL.MbufControl(MilImage, MIL.M_MODIFIED, MIL.M_DEFAULT); /* Unlock buffer. */ MIL.MbufControl(MilImage, MIL.M_UNLOCK, MIL.M_DEFAULT); /* Select to display. */ MIL.MdispSelect(MilDisplay, MilImage); } else { Console.Write("The source buffer has no accessible memory\n"); Console.Write("address on this specific system. Try changing\n"); Console.Write("the system in the MIL Config utility.\n\n"); } /* Print a message and wait for a key. */ Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); /* Free allocation. */ MIL.MbufFree(MilImage); } /* Mandelbrot fractal utility functions. */ static double Remap(double pos, double size, double min, double max) { return ((((max) - (min)) / (size)) * (pos) + (min)); } static MIL_UINT Mandelbrot(MIL_INT PosX, MIL_INT PosY, double RefX, double RefY, double Dim) { const int maxIter = 256; double xMin = RefX - 0.5 * Dim; double xMax = RefX + 0.5 * Dim; double yMin = RefY - 0.5 * Dim; double yMax = RefY + 0.5 * Dim; double x0 = Remap((double)PosX, (double)IMAGE_SIZE_X, xMin, xMax); double y0 = Remap((double)PosY, (double)IMAGE_SIZE_Y, yMin, yMax); double x = 0.0; double y = 0.0; MIL_UINT Iter = 0; while ((x * x + y * y < 4) && (Iter < maxIter)) { double Temp = x * x - y * y + x0; y = 2 * x * y + y0; x = Temp; Iter++; } if (Iter > 255) return 255; else return Iter; } /* Calculate color from index. */ static MIL_INT GetColorFromIndex(MIL_INT Band, MIL_INT Index, MIL_INT MaxIndex) { MIL_INT[] Segments = { }; MIL_INT[] SegmentsR = { 0, 0, 0, 255, 255, 128 }; MIL_INT[] SegmentsG = { 0, 0, 255, 255, 0, 0 }; MIL_INT[] SegmentsB = { 128, 255, 255, 0, 0, 0 }; switch ((int)Band) { case MIL.M_RED: Segments = SegmentsR; break; case MIL.M_GREEN: Segments = SegmentsG; break; case MIL.M_BLUE: Segments = SegmentsB; break; } double RemapedIndex = Index * MaxIndex / 256.0; MIL_INT SegmentIndex = (MIL_INT)(RemapedIndex * 5.0 / 256.0); double Slope = (Segments[SegmentIndex + 1] - Segments[SegmentIndex]) / (256.0 / 5.0); double Offset = (Segments[SegmentIndex] - Slope * SegmentIndex * 256.0 / 5.0); MIL_INT Value = (MIL_INT)(Slope * RemapedIndex + Offset + 0.5); return Value; } } }