#include <mil.h>
#define IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Bird.mim")
#define IMAGE_WIDTH 256L
#define IMAGE_HEIGHT 240L
#define STRING_LENGTH_MAX 40
#define STRING_POS_X 10
#define STRING_POS_Y 220
#define DRAW_RADIUS_NUMBER 5
#define DRAW_RADIUS_STEP 10
#define DRAW_CENTER_POSX 196
#define DRAW_CENTER_POSY 180
MIL_UINT32 MFTYPE TopThread(void *TPar);
MIL_UINT32 MFTYPE BotLeftThread(void *TPar);
MIL_UINT32 MFTYPE BotRightThread(void *TPar);
typedef struct ThreadParam
{
MIL_ID Id;
MIL_ID System;
MIL_ID OrgImage;
MIL_ID SrcImage;
MIL_ID DstImage;
MIL_ID DispImage;
MIL_INT DispOffsetX;
MIL_INT DispOffsetY;
MIL_ID ReadyEvent;
MIL_ID DoneEvent;
MIL_INT NumberOfIteration;
MIL_INT Radius;
MIL_INT Exit;
MIL_INT LicenseModules;
struct ThreadParam *SlaveThreadParam;
} THREAD_PARAM;
int MosMain(void)
{
MIL_ID MilApplication,
MilRemoteApplication,
MilSystem,
MilDisplay,
MilImage, MilOrgImage;
THREAD_PARAM TParTopLeft,
TParBotLeft,
TParTopRight,
TParBotRight;
MIL_DOUBLE Time, FramesPerSecond;
MIL_INT LicenseModules;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
MbufAlloc2d(MilSystem, IMAGE_WIDTH*2, IMAGE_HEIGHT*2, 8+M_UNSIGNED,
M_IMAGE+M_PROC+M_DISP, &MilImage);
MbufClear(MilImage, 0);
MdispSelect(MilDisplay,MilImage);
MdispInquire(MilDisplay, M_SELECTED, &TParTopLeft.DispImage);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8+M_UNSIGNED,
M_IMAGE+M_PROC, &MilOrgImage);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8+M_UNSIGNED, M_IMAGE+M_PROC, &TParTopLeft.SrcImage);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8+M_UNSIGNED, M_IMAGE+M_PROC, &TParBotLeft.DstImage);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8+M_UNSIGNED, M_IMAGE+M_PROC, &TParTopRight.SrcImage);
MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8+M_UNSIGNED, M_IMAGE+M_PROC, &TParBotRight.DstImage);
MthrAlloc(MilSystem, M_EVENT, M_DEFAULT, M_NULL, M_NULL, &TParTopLeft.DoneEvent);
MthrAlloc(MilSystem, M_EVENT, M_DEFAULT, M_NULL, M_NULL, &TParBotLeft.DoneEvent);
MthrAlloc(MilSystem, M_EVENT, M_DEFAULT, M_NULL, M_NULL, &TParTopRight.DoneEvent);
MthrAlloc(MilSystem, M_EVENT, M_DEFAULT, M_NULL, M_NULL, &TParBotRight.DoneEvent);
MsysInquire(MilSystem, M_OWNER_APPLICATION, &MilRemoteApplication);
MappInquire(MilRemoteApplication, M_LICENSE_MODULES, &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 = 0;
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 = 0;
MbufLoad(IMAGE_FILE, MilOrgImage);
MthrAlloc(MilSystem, M_THREAD, M_DEFAULT, &TopThread ,
&TParTopLeft, &TParTopLeft.Id);
MthrAlloc(MilSystem, M_THREAD, M_DEFAULT, &BotLeftThread ,
&TParBotLeft, &TParBotLeft.Id);
MthrAlloc(MilSystem, M_THREAD, M_DEFAULT, &TopThread ,
&TParTopRight, &TParTopRight.Id);
MthrAlloc(MilSystem, M_THREAD, M_DEFAULT, &BotRightThread,
&TParBotRight, &TParBotRight.Id);
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS, M_NULL);
MthrControl(TParTopLeft.ReadyEvent, M_EVENT_SET, M_SIGNALED);
MthrControl(TParTopRight.ReadyEvent, M_EVENT_SET, M_SIGNALED);
MosPrintf(MIL_TEXT("\nMULTI-THREADING:\n"));
MosPrintf(MIL_TEXT("----------------\n\n"));
MosPrintf(MIL_TEXT("4 threads running...\n"));
MosPrintf(MIL_TEXT("Press <Enter> to stop.\n\n"));
MosGetch();
TParTopLeft.Exit = 1;
TParTopRight.Exit = 1;
MthrWait(TParTopLeft.Id , M_THREAD_END_WAIT, M_NULL);
MthrWait(TParBotLeft.Id , M_THREAD_END_WAIT, M_NULL);
MthrWait(TParTopRight.Id, M_THREAD_END_WAIT, M_NULL);
MthrWait(TParBotRight.Id, M_THREAD_END_WAIT, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &Time);
FramesPerSecond = (TParTopLeft.NumberOfIteration + TParBotLeft.NumberOfIteration +
TParTopRight.NumberOfIteration + TParBotRight.NumberOfIteration)/Time;
MosPrintf(MIL_TEXT("Top-left iterations done: %4d.\n"),
(int)TParTopLeft.NumberOfIteration);
MosPrintf(MIL_TEXT("Bottom-left iterations done: %4d.\n"),
(int)TParBotLeft.NumberOfIteration);
MosPrintf(MIL_TEXT("Top-right iterations done: %4d.\n"),
(int)TParTopRight.NumberOfIteration);
MosPrintf(MIL_TEXT("Bottom-right iterations done: %4d.\n\n"),
(int)TParBotRight.NumberOfIteration);
MosPrintf(MIL_TEXT("Processing speed for the 4 threads: ")
MIL_TEXT("%.0f Images/Sec.\n\n"), FramesPerSecond);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
MthrFree(TParTopLeft.Id);
MthrFree(TParBotLeft.Id);
MthrFree(TParTopRight.Id);
MthrFree(TParBotRight.Id);
MthrFree(TParTopLeft.DoneEvent);
MthrFree(TParBotLeft.DoneEvent);
MthrFree(TParTopRight.DoneEvent);
MthrFree(TParBotRight.DoneEvent);
MbufFree(TParTopLeft.SrcImage);
MbufFree(TParTopRight.SrcImage);
MbufFree(TParBotLeft.DstImage);
MbufFree(TParBotRight.DstImage);
MbufFree(MilOrgImage);
MbufFree(MilImage);
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
return 0;
}
MIL_UINT32 MFTYPE TopThread(void *ThreadParameters)
{
THREAD_PARAM *TPar = (THREAD_PARAM *)ThreadParameters;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX];
while (!TPar->Exit)
{
MthrWait(TPar->ReadyEvent, M_EVENT_WAIT, M_NULL);
if ((TPar->NumberOfIteration % 192) == 0)
MbufCopy(TPar->OrgImage, TPar->SrcImage);
#if (!M_MIL_LITE)
if (TPar->LicenseModules & M_LICENSE_IM)
{
MimArith(TPar->SrcImage, 1L, TPar->DstImage, M_ADD_CONST+M_SATURATION);
}
else
#endif
{
TPar->Radius = TPar->SlaveThreadParam->Radius =
(TPar->NumberOfIteration % DRAW_RADIUS_NUMBER) * DRAW_RADIUS_STEP;
MgraColor(M_DEFAULT, 0xff);
MgraRectFill(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++;
MgraColor(M_DEFAULT, 0xFF);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d"), (int)TPar->NumberOfIteration);
MgraText(M_DEFAULT, TPar->DstImage, STRING_POS_X, STRING_POS_Y, Text);
if (TPar->DispImage)
{
MbufCopyColor2d(TPar->DstImage,
TPar->DispImage,
M_ALL_BANDS, 0, 0,
M_ALL_BANDS,
TPar->DispOffsetX,
TPar->DispOffsetY,
IMAGE_WIDTH,
IMAGE_HEIGHT);
}
MthrControl(TPar->DoneEvent, M_EVENT_SET, M_SIGNALED);
}
TPar->SlaveThreadParam->Exit = 1;
MthrControl(TPar->DoneEvent, M_EVENT_SET, M_SIGNALED);
MthrWait(TPar->System, M_THREAD_WAIT, M_NULL);
return(1L);
}
MIL_UINT32 MFTYPE BotLeftThread(void *ThreadParameters)
{
THREAD_PARAM *TPar = (THREAD_PARAM *)ThreadParameters;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX];
MIL_DOUBLE Angle = 0, AngleIncrement = 0.5;
while (!TPar->Exit)
{
MthrWait(TPar->ReadyEvent, M_EVENT_WAIT, M_NULL);
#if (!M_MIL_LITE)
if (TPar->LicenseModules & M_LICENSE_IM)
{
MimRotate(TPar->SrcImage, TPar->DstImage, Angle,
M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT,
M_NEAREST_NEIGHBOR+M_OVERSCAN_CLEAR);
Angle += AngleIncrement;
if (Angle >= 360)
{
Angle -= 360;
}
}
else
#endif
{
MbufCopy(TPar->SrcImage,TPar->DstImage);
MgraColor(M_DEFAULT, 0x80);
MgraArcFill(M_DEFAULT, TPar->DstImage, DRAW_CENTER_POSX, DRAW_CENTER_POSY,
TPar->Radius, TPar->Radius, 0, 360);
}
TPar->NumberOfIteration++;
MgraColor(M_DEFAULT, 0xFF);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d"), (int)TPar->NumberOfIteration);
MgraText(M_DEFAULT, TPar->DstImage, STRING_POS_X, STRING_POS_Y, Text);
if (TPar->DispImage)
{
MbufCopyColor2d(TPar->DstImage,
TPar->DispImage,
M_ALL_BANDS, 0, 0,
M_ALL_BANDS,
TPar->DispOffsetX,
TPar->DispOffsetY,
IMAGE_WIDTH,
IMAGE_HEIGHT);
}
MthrControl(TPar->DoneEvent, M_EVENT_SET, M_SIGNALED);
}
MthrWait(TPar->System, M_THREAD_WAIT, M_NULL);
return(1L);
}
MIL_UINT32 MFTYPE BotRightThread(void *ThreadParameters)
{
THREAD_PARAM *TPar = (THREAD_PARAM *)ThreadParameters;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX];
while (!TPar->Exit)
{
MthrWait(TPar->ReadyEvent, M_EVENT_WAIT, M_NULL);
#if (!M_MIL_LITE)
if (TPar->LicenseModules & M_LICENSE_IM)
{
MimConvolve(TPar->SrcImage, TPar->DstImage, M_EDGE_DETECT_SOBEL_FAST);
}
else
#endif
{
MbufCopy(TPar->SrcImage,TPar->DstImage);
MgraColor(M_DEFAULT, 0x40);
MgraArcFill(M_DEFAULT, TPar->DstImage, DRAW_CENTER_POSX, DRAW_CENTER_POSY,
TPar->Radius/2, TPar->Radius/2, 0, 360);
}
TPar->NumberOfIteration++;
MgraColor(M_DEFAULT, 0xFF);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d"), (int)TPar->NumberOfIteration);
MgraText(M_DEFAULT, TPar->DstImage, STRING_POS_X, STRING_POS_Y, Text);
if (TPar->DispImage)
{
MbufCopyColor2d(TPar->DstImage,
TPar->DispImage,
M_ALL_BANDS, 0, 0,
M_ALL_BANDS,
TPar->DispOffsetX,
TPar->DispOffsetY,
IMAGE_WIDTH,
IMAGE_HEIGHT);
}
MthrControl(TPar->DoneEvent, M_EVENT_SET, M_SIGNALED);
}
MthrWait(TPar->System, M_THREAD_WAIT, M_NULL);
return(1L);
}