using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using Matrox.MatroxImagingLibrary;
namespace MThread
{
class Program
{
private const string IMAGE_FILE = MIL.M_IMAGE_PATH + "Bird.mim";
private const int IMAGE_WIDTH = 256;
private const int IMAGE_HEIGHT = 240;
private const int STRING_LENGTH_MAX = 40;
private const int STRING_POS_X = 10;
private const int STRING_POS_Y = 220;
private const int DRAW_RADIUS_NUMBER = 5;
private const int DRAW_RADIUS_STEP = 10;
private const int DRAW_CENTER_POSX = 196;
private const int DRAW_CENTER_POSY = 180;
public class THREAD_PARAM
{
public MIL_ID Id;
public MIL_ID System;
public MIL_ID OrgImage;
public MIL_ID SrcImage;
public MIL_ID DstImage;
public MIL_ID DispImage;
public MIL_INT DispOffsetX;
public MIL_INT DispOffsetY;
public MIL_ID ReadyEvent;
public MIL_ID DoneEvent;
public MIL_INT NumberOfIteration;
public MIL_INT Radius;
public MIL_INT Exit;
public MIL_INT LicenseModules;
public THREAD_PARAM SlaveThreadParam;
}
static void Main(string[] args)
{
MIL_ID MilApplication = MIL.M_NULL;
MIL_ID MilRemoteApplication = MIL.M_NULL;
MIL_ID MilSystem = MIL.M_NULL;
MIL_ID MilDisplay = MIL.M_NULL;
MIL_ID MilImage = MIL.M_NULL;
MIL_ID MilOrgImage = MIL.M_NULL;
THREAD_PARAM TParTopLeft = new THREAD_PARAM();
THREAD_PARAM TParBotLeft = new THREAD_PARAM();
THREAD_PARAM TParTopRight = new THREAD_PARAM();
THREAD_PARAM TParBotRight = new THREAD_PARAM();
double Time = 0.0;
double FramesPerSecond = 0.0;
MIL_INT LicenseModules = 0;
MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilImage);
MIL.MbufClear(MilImage, 0);
MIL.MdispSelect(MilDisplay, MilImage);
MIL.MdispInquire(MilDisplay, MIL.M_SELECTED, ref TParTopLeft.DispImage);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilOrgImage);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref TParTopLeft.SrcImage);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref TParBotLeft.DstImage);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref TParTopRight.SrcImage);
MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref TParBotRight.DstImage);
MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopLeft.DoneEvent);
MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotLeft.DoneEvent);
MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopRight.DoneEvent);
MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotRight.DoneEvent);
MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication);
MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules);
TParTopLeft.System = MilSystem;
TParTopLeft.OrgImage = MilOrgImage;
TParTopLeft.DstImage = TParTopLeft.SrcImage;
TParTopLeft.DispOffsetX = 0;
TParTopLeft.DispOffsetY = 0;
TParTopLeft.ReadyEvent = TParBotLeft.DoneEvent;
TParTopLeft.NumberOfIteration = 0;
TParTopLeft.Radius = 0;
TParTopLeft.Exit = 0;
TParTopLeft.LicenseModules = LicenseModules;
TParTopLeft.SlaveThreadParam = TParBotLeft;
TParBotLeft.System = MilSystem;
TParBotLeft.OrgImage = 0;
TParBotLeft.SrcImage = TParTopLeft.DstImage;
TParBotLeft.DispImage = TParTopLeft.DispImage;
TParBotLeft.DispOffsetX = 0;
TParBotLeft.DispOffsetY = IMAGE_HEIGHT;
TParBotLeft.ReadyEvent = TParTopLeft.DoneEvent;
TParBotLeft.NumberOfIteration = 0;
TParBotLeft.Radius = 0;
TParBotLeft.Exit = 0;
TParBotLeft.LicenseModules = LicenseModules;
TParBotLeft.SlaveThreadParam = null;
TParTopRight.System = MilSystem;
TParTopRight.OrgImage = MilOrgImage;
TParTopRight.DstImage = TParTopRight.SrcImage;
TParTopRight.DispImage = TParTopLeft.DispImage;
TParTopRight.DispOffsetX = IMAGE_WIDTH;
TParTopRight.DispOffsetY = 0;
TParTopRight.ReadyEvent = TParBotRight.DoneEvent;
TParTopRight.NumberOfIteration = 0;
TParTopRight.Radius = 0;
TParTopRight.Exit = 0;
TParTopRight.LicenseModules = LicenseModules;
TParTopRight.SlaveThreadParam = TParBotRight;
TParBotRight.System = MilSystem;
TParBotRight.OrgImage = 0;
TParBotRight.SrcImage = TParTopRight.DstImage;
TParBotRight.DispImage = TParTopLeft.DispImage;
TParBotRight.DispOffsetX = IMAGE_WIDTH;
TParBotRight.DispOffsetY = IMAGE_HEIGHT;
TParBotRight.ReadyEvent = TParTopRight.DoneEvent;
TParBotRight.NumberOfIteration = 0;
TParBotRight.Radius = 0;
TParBotRight.Exit = 0;
TParBotRight.LicenseModules = LicenseModules;
TParBotRight.SlaveThreadParam = null;
MIL.MbufLoad(IMAGE_FILE, MilOrgImage);
MIL_THREAD_FUNCTION_PTR TopThreadDelegate = new MIL_THREAD_FUNCTION_PTR(TopThread);
MIL_THREAD_FUNCTION_PTR BotLeftThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotLeftThread);
MIL_THREAD_FUNCTION_PTR BotRightThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotRightThread);
GCHandle TParTopLeftHandle = GCHandle.Alloc(TParTopLeft);
GCHandle TParBotLeftHandle = GCHandle.Alloc(TParBotLeft);
GCHandle TParTopRightHandle = GCHandle.Alloc(TParTopRight);
GCHandle TParBotRightHandle = GCHandle.Alloc(TParBotRight);
MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopLeftHandle), ref TParTopLeft.Id);
MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotLeftThreadDelegate, GCHandle.ToIntPtr(TParBotLeftHandle), ref TParBotLeft.Id);
MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopRightHandle), ref TParTopRight.Id);
MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotRightThreadDelegate, GCHandle.ToIntPtr(TParBotRightHandle), ref TParBotRight.Id);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL);
MIL.MthrControl(TParTopLeft.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
MIL.MthrControl(TParTopRight.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
Console.Write("\nMULTI-THREADING:\n");
Console.Write("----------------\n\n");
Console.Write("4 threads running...\n");
Console.Write("Press <Enter> to stop.\n\n");
Console.ReadKey();
TParTopLeft.Exit = 1;
TParTopRight.Exit = 1;
MIL.MthrWait(TParTopLeft.Id, MIL.M_THREAD_END_WAIT);
MIL.MthrWait(TParBotLeft.Id, MIL.M_THREAD_END_WAIT);
MIL.MthrWait(TParTopRight.Id, MIL.M_THREAD_END_WAIT);
MIL.MthrWait(TParBotRight.Id, MIL.M_THREAD_END_WAIT);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time);
FramesPerSecond = (TParTopLeft.NumberOfIteration + TParBotLeft.NumberOfIteration + TParTopRight.NumberOfIteration + TParBotRight.NumberOfIteration) / Time;
Console.Write("Top-left iterations done: {0,4}.\n", TParTopLeft.NumberOfIteration);
Console.Write("Bottom-left iterations done: {0,4}.\n", TParBotLeft.NumberOfIteration);
Console.Write("Top-right iterations done: {0,4}.\n", TParTopRight.NumberOfIteration);
Console.Write("Bottom-right iterations done: {0,4}.\n\n", TParBotRight.NumberOfIteration);
Console.Write("Processing speed for the 4 threads: {0:0.0} Images/Sec.\n\n", FramesPerSecond);
Console.Write("Press <Enter> to end.\n\n");
Console.ReadKey();
MIL.MthrFree(TParTopLeft.Id);
MIL.MthrFree(TParBotLeft.Id);
MIL.MthrFree(TParTopRight.Id);
MIL.MthrFree(TParBotRight.Id);
MIL.MthrFree(TParTopLeft.DoneEvent);
MIL.MthrFree(TParBotLeft.DoneEvent);
MIL.MthrFree(TParTopRight.DoneEvent);
MIL.MthrFree(TParBotRight.DoneEvent);
MIL.MbufFree(TParTopLeft.SrcImage);
MIL.MbufFree(TParTopRight.SrcImage);
MIL.MbufFree(TParBotLeft.DstImage);
MIL.MbufFree(TParBotRight.DstImage);
MIL.MbufFree(MilOrgImage);
MIL.MbufFree(MilImage);
TParTopLeftHandle.Free();
TParBotLeftHandle.Free();
TParTopRightHandle.Free();
TParBotRightHandle.Free();
MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
}
static uint TopThread(IntPtr ThreadParameters)
{
GCHandle threadParamHandle = GCHandle.FromIntPtr(ThreadParameters);
THREAD_PARAM TPar = threadParamHandle.Target as THREAD_PARAM;
while (TPar.Exit == 0)
{
MIL.MthrWait(TPar.ReadyEvent, MIL.M_EVENT_WAIT);
if ((TPar.NumberOfIteration % 192) == 0)
{
MIL.MbufCopy(TPar.OrgImage, TPar.SrcImage);
}
if ((TPar.LicenseModules & MIL.M_LICENSE_IM) != 0)
{
MIL.MimArith(TPar.SrcImage, 1L, TPar.DstImage, MIL.M_ADD_CONST + MIL.M_SATURATION);
}
else
{
TPar.Radius = TPar.SlaveThreadParam.Radius = (TPar.NumberOfIteration % DRAW_RADIUS_NUMBER) * DRAW_RADIUS_STEP;
MIL.MgraColor(MIL.M_DEFAULT, 0xff);
MIL.MgraRectFill(MIL.M_DEFAULT, TPar.DstImage, DRAW_CENTER_POSX - TPar.Radius, DRAW_CENTER_POSY - TPar.Radius, DRAW_CENTER_POSX + TPar.Radius, DRAW_CENTER_POSY + TPar.Radius);
}
TPar.NumberOfIteration++;
MIL.MgraColor(MIL.M_DEFAULT, 0xFF);
MIL.MgraText(MIL.M_DEFAULT, TPar.DstImage, STRING_POS_X, STRING_POS_Y, String.Format("{0}", TPar.NumberOfIteration));
if (TPar.DispImage != MIL.M_NULL)
{
MIL.MbufCopyColor2d(TPar.DstImage, TPar.DispImage, MIL.M_ALL_BANDS, 0, 0, MIL.M_ALL_BANDS, TPar.DispOffsetX, TPar.DispOffsetY, IMAGE_WIDTH, IMAGE_HEIGHT);
}
MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
}
TPar.SlaveThreadParam.Exit = 1;
MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
MIL.MthrWait(TPar.System, MIL.M_THREAD_WAIT, MIL.M_NULL);
return 1;
}
static uint BotLeftThread(IntPtr ThreadParameters)
{
GCHandle threadParamHandle = GCHandle.FromIntPtr(ThreadParameters);
THREAD_PARAM TPar = threadParamHandle.Target as THREAD_PARAM;
double Angle = 0.0;
double AngleIncrement = 0.5;
while (TPar.Exit == 0)
{
MIL.MthrWait(TPar.ReadyEvent, MIL.M_EVENT_WAIT);
if ((TPar.LicenseModules & MIL.M_LICENSE_IM) != 0)
{
MIL.MimRotate(TPar.SrcImage, TPar.DstImage, Angle, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_NEAREST_NEIGHBOR + MIL.M_OVERSCAN_CLEAR);
Angle += AngleIncrement;
if (Angle >= 360)
{
Angle -= 360;
}
}
else
{
MIL.MbufCopy(TPar.SrcImage, TPar.DstImage);
MIL.MgraColor(MIL.M_DEFAULT, 0x80);
MIL.MgraArcFill(MIL.M_DEFAULT, TPar.DstImage, DRAW_CENTER_POSX, DRAW_CENTER_POSY, TPar.Radius, TPar.Radius, 0, 360);
}
TPar.NumberOfIteration++;
MIL.MgraColor(MIL.M_DEFAULT, 0xFF);
MIL.MgraText(MIL.M_DEFAULT, TPar.DstImage, STRING_POS_X, STRING_POS_Y, String.Format("{0}", TPar.NumberOfIteration));
if (TPar.DispImage != MIL.M_NULL)
{
MIL.MbufCopyColor2d(TPar.DstImage, TPar.DispImage, MIL.M_ALL_BANDS, 0, 0, MIL.M_ALL_BANDS, TPar.DispOffsetX, TPar.DispOffsetY, IMAGE_WIDTH, IMAGE_HEIGHT);
}
MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
}
MIL.MthrWait(TPar.System, MIL.M_THREAD_WAIT, MIL.M_NULL);
return 1;
}
static uint BotRightThread(IntPtr ThreadParameters)
{
GCHandle threadParamHandle = GCHandle.FromIntPtr(ThreadParameters);
THREAD_PARAM TPar = threadParamHandle.Target as THREAD_PARAM;
while (TPar.Exit == 0)
{
MIL.MthrWait(TPar.ReadyEvent, MIL.M_EVENT_WAIT);
if ((TPar.LicenseModules & MIL.M_LICENSE_IM) != 0)
{
MIL.MimConvolve(TPar.SrcImage, TPar.DstImage, MIL.M_EDGE_DETECT_SOBEL_FAST);
}
else
{
MIL.MbufCopy(TPar.SrcImage, TPar.DstImage);
MIL.MgraColor(MIL.M_DEFAULT, 0x40);
MIL.MgraArcFill(MIL.M_DEFAULT, TPar.DstImage, DRAW_CENTER_POSX, DRAW_CENTER_POSY, TPar.Radius / 2, TPar.Radius / 2, 0, 360);
}
TPar.NumberOfIteration++;
MIL.MgraColor(MIL.M_DEFAULT, 0xFF);
MIL.MgraText(MIL.M_DEFAULT, TPar.DstImage, STRING_POS_X, STRING_POS_Y, String.Format("{0}", TPar.NumberOfIteration));
if (TPar.DispImage != MIL.M_NULL)
{
MIL.MbufCopyColor2d(TPar.DstImage, TPar.DispImage, MIL.M_ALL_BANDS, 0, 0, MIL.M_ALL_BANDS, TPar.DispOffsetX, TPar.DispOffsetY, IMAGE_WIDTH, IMAGE_HEIGHT);
}
MIL.MthrControl(TPar.DoneEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED);
}
MIL.MthrWait(TPar.System, MIL.M_THREAD_WAIT, MIL.M_NULL);
return 1;
}
}
}