#include <mil.h>
const long COLORMAP_SIZE = 256;
const long COLOR_SAMPLE_SIZE = 32;
const long COLOR_OVERVIEW_MAP_SIZE = 64;
const long DISPLAY_TEXT_SIZE = 20;
const long OVERVIEW_COLMAP_NUMBER = 8;
const long INIT_LUMINANCE_VALUE = 128;
void InitHSLColormap(MIL_ID MilHSLColormapID);
MIL_INT GetOverviewColormapOffset(MIL_INT Luminance);
void GenColormap(MIL_ID MilHSLColormap,
MIL_ID ColprmapImage,
MIL_ID Luminance);
void RestoreColorContext(MIL_ID MilSystem,
MIL_ID &MilColContext,
MIL_ID MilDispImage);
#define STRING_LENGTH_MAX 128
#define MosMin(a, b) (((a) < (b)) ? (a) : (b))
#define MosMax(a, b) (((a) > (b)) ? (a) : (b))
#define EXAMPLE_IMAGE_PATH M_IMAGE_PATH MIL_TEXT("FoodInspectionMango/")
static MIL_CONST_TEXT_PTR COLOR_CONTEXT_PATH = EXAMPLE_IMAGE_PATH MIL_TEXT("MangoColor.mcol");
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDispImage,
MilOverlay,
MilHSLColormap,
MilColormapChild,
MilColorResChild,
MilColContext,
MilColResult,
MilColSample,
MilBlobContext,
MilBlobResult,
MilDisplay;
MIL_INT Luminance = INIT_LUMINANCE_VALUE,
Offset, SizeX, SizeY,
NbSamples,
Index, Ch;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX];
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("UtilMatchColormap\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This example allows you to easily restore a color matching context and\n")
MIL_TEXT("interactively display a colormap with the corresponding matched areas.\n")
MIL_TEXT("The colormap is provided for a given luminance value which you can\n")
MIL_TEXT("interactively change using the keyboard.\n\n"));
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay);
SizeX = 2 * COLORMAP_SIZE + 1;
SizeY = 2 * DISPLAY_TEXT_SIZE + COLOR_SAMPLE_SIZE + COLORMAP_SIZE + 2 * COLOR_OVERVIEW_MAP_SIZE + 3;
MbufAllocColor(MilSystem, 3, SizeX, SizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_PROC, &MilDispImage);
MbufClear(MilDispImage, 0);
MbufChild2d(MilDispImage, 0, COLOR_SAMPLE_SIZE + 2 * DISPLAY_TEXT_SIZE, COLORMAP_SIZE, COLORMAP_SIZE, &MilColormapChild);
MbufChild2d(MilDispImage, COLORMAP_SIZE + 1, COLOR_SAMPLE_SIZE + 2 * DISPLAY_TEXT_SIZE, COLORMAP_SIZE, COLORMAP_SIZE, &MilColorResChild);
MbufAllocColor(MilSystem, 3, COLORMAP_SIZE, COLORMAP_SIZE, 8 + M_UNSIGNED, M_IMAGE + M_PLANAR + M_PROC, &MilHSLColormap);
InitHSLColormap(MilHSLColormap);
McolAllocResult(MilSystem, M_DEFAULT, M_DEFAULT, &MilColResult);
RestoreColorContext(MilSystem, MilColContext, MilDispImage);
McolInquire(MilColContext, M_CONTEXT, M_NUMBER_OF_SAMPLES + M_TYPE_MIL_INT, &NbSamples);
MdispSelect(MilDisplay, MilDispImage);
MdispControl(MilDisplay, M_OVERLAY, M_ENABLE);
MdispInquire(MilDisplay, M_OVERLAY_ID, &MilOverlay);
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MgraColor(M_DEFAULT, M_COLOR_WHITE);
MgraText(M_DEFAULT, MilDispImage, 0, 2, MIL_TEXT("Context samples average colors:"));
MgraText(M_DEFAULT, MilDispImage, 0, COLOR_SAMPLE_SIZE + DISPLAY_TEXT_SIZE + 2, MIL_TEXT("Luminance = "));
MbufAlloc2d(MilSystem, COLORMAP_SIZE, COLORMAP_SIZE, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &MilColSample);
MblobAlloc(MilSystem, M_DEFAULT, M_DEFAULT, &MilBlobContext);
MblobAllocResult(MilSystem, M_DEFAULT, M_DEFAULT, &MilBlobResult);
MblobControl(MilBlobContext, M_SAVE_RUNS, M_ENABLE);
MosPrintf(MIL_TEXT("To interact with the utility, press the:\n"));
MosPrintf(MIL_TEXT(". Left or Down key, which decreases the luminance value.\n"));
MosPrintf(MIL_TEXT(". Right or Up key, which increases the luminance value.\n"));
MosPrintf(MIL_TEXT(". 'N' or 'n' key, which restores a new color matching context.\n"));
MosPrintf(MIL_TEXT(". <Enter> key, which terminates the program.\n\n"));
Ch = 0;
while (Ch != '\r')
{
switch (Ch)
{
case 0x4B:
case 0x50:
{ Luminance -= 1; break; }
case 0x4D:
case 0x48:
{ Luminance += 1; break; }
case 'N':
case 'n':
{
McolFree(MilColContext);
RestoreColorContext(MilSystem, MilColContext, MilDispImage);
McolInquire(MilColContext, M_CONTEXT, M_NUMBER_OF_SAMPLES + M_TYPE_MIL_INT, &NbSamples);
Luminance = INIT_LUMINANCE_VALUE;
}
}
Luminance = MosMin(Luminance, 255);
Luminance = MosMax(Luminance, 0);
MgraColor(M_DEFAULT, M_COLOR_WHITE);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d "), (int)Luminance);
MgraText(M_DEFAULT, MilDispImage, 100, COLOR_SAMPLE_SIZE + DISPLAY_TEXT_SIZE + 2, Text);
GenColormap(MilHSLColormap, MilColormapChild, Luminance);
McolMatch(MilColContext, MilColormapChild, M_DEFAULT, M_NULL, MilColResult, M_DEFAULT);
McolDraw(M_DEFAULT, MilColResult, MilColorResChild, M_DRAW_PIXEL_MATCH_USING_COLOR, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MgraColor(M_DEFAULT, M_COLOR_WHITE);
for (Index = 0; Index<NbSamples; Index++)
{
MbufClear(MilColSample, 0);
McolDraw(M_DEFAULT, MilColResult, MilColSample, M_DRAW_PIXEL_MATCH_USING_LABEL, M_DEFAULT, M_SAMPLE_INDEX(Index), M_DEFAULT);
MblobCalculate(MilBlobContext, MilColSample, M_NULL, MilBlobResult);
MblobDraw(M_DEFAULT, MilBlobResult, MilColormapChild, M_DRAW_BLOBS_CONTOUR, M_DEFAULT, M_DEFAULT);
}
MgraColor(M_DEFAULT, M_COLOR_WHITE);
Offset = GetOverviewColormapOffset(Luminance);
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MgraRect(M_DEFAULT, MilOverlay,
Offset, COLOR_SAMPLE_SIZE + 2 * DISPLAY_TEXT_SIZE + COLORMAP_SIZE + 1,
Offset + (2 * COLORMAP_SIZE) / OVERVIEW_COLMAP_NUMBER - 1,
COLOR_SAMPLE_SIZE + 2 * DISPLAY_TEXT_SIZE + COLORMAP_SIZE + 2 * COLOR_OVERVIEW_MAP_SIZE + 1);
if ((Ch = MosGetch()) == 0xE0)
Ch = MosGetch();
}
MbufFree(MilColormapChild);
MbufFree(MilColorResChild);
MbufFree(MilDispImage);
MbufFree(MilHSLColormap);
MbufFree(MilColSample);
McolFree(MilColContext);
McolFree(MilColResult);
MblobFree(MilBlobContext);
MblobFree(MilBlobResult);
MdispFree(MilDisplay);
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
return 0;
};
void RestoreColorContext(MIL_ID MilSystem,
MIL_ID &MilColContext,
MIL_ID MilDispImage)
{
MIL_ID MilColBuffer,
MilColResult,
MilHSLColormap,
MilUtilChild,
MilOverviewMap;
MIL_INT Luminance,
NbSamples,
Offset,
SizePerSample,
Index;
MIL_INT Rvalue,
Gvalue,
Bvalue;
MIL_TEXT_CHAR MyChar = ' ';
MosPrintf(MIL_TEXT("Press 'D' to restore a default context, or\n")
MIL_TEXT("press another key to select a new context.\n\n"));
MyChar = (MIL_TEXT_CHAR)MosGetch();
if (MyChar == 'd' || MyChar == 'D')
{
McolRestore(COLOR_CONTEXT_PATH, MilSystem, M_DEFAULT, &MilColContext);
}
else
{
MosPrintf(MIL_TEXT("Select a new color matching context to restore.\n")
MIL_TEXT("<Cancel> will restore a default context.\n\n"));
MappControl(M_ERROR, M_PRINT_DISABLE);
McolRestore(M_INTERACTIVE, MilSystem, M_DEFAULT, &MilColContext);
MappControl(M_ERROR, M_PRINT_ENABLE);
if (MilColContext == M_NULL)
McolRestore(COLOR_CONTEXT_PATH, MilSystem, M_DEFAULT, &MilColContext);
}
McolControl(MilColContext, M_DEFAULT, M_OUTLIER_DRAW_COLOR, 0);
McolPreprocess(MilColContext, M_DEFAULT);
McolInquire(MilColContext, M_CONTEXT, M_NUMBER_OF_SAMPLES + M_TYPE_MIL_INT, &NbSamples);
SizePerSample = (2 * COLORMAP_SIZE) / NbSamples;
MgraColor(M_DEFAULT, M_COLOR_BLACK);
for (Index = 0; Index<NbSamples; Index++)
{
McolInquire(MilColContext, M_SAMPLE_INDEX(Index), M_SAMPLE_8BIT_AVERAGE_COLOR_BAND_0 + M_TYPE_MIL_INT, &Rvalue);
McolInquire(MilColContext, M_SAMPLE_INDEX(Index), M_SAMPLE_8BIT_AVERAGE_COLOR_BAND_1 + M_TYPE_MIL_INT, &Gvalue);
McolInquire(MilColContext, M_SAMPLE_INDEX(Index), M_SAMPLE_8BIT_AVERAGE_COLOR_BAND_2 + M_TYPE_MIL_INT, &Bvalue);
MbufChild2d(MilDispImage, Index * SizePerSample, DISPLAY_TEXT_SIZE, SizePerSample, COLOR_SAMPLE_SIZE, &MilUtilChild);
MbufClear(MilUtilChild, M_RGB888(Rvalue, Gvalue, Bvalue));
MgraLine(M_DEFAULT, MilDispImage, Index * SizePerSample, DISPLAY_TEXT_SIZE, Index * SizePerSample, DISPLAY_TEXT_SIZE + COLOR_SAMPLE_SIZE);
MbufFree(MilUtilChild);
}
McolAllocResult(MilSystem, M_DEFAULT, M_DEFAULT, &MilColResult);
MbufAllocColor(MilSystem, 3, 2 * COLORMAP_SIZE + 1, 2 * COLOR_OVERVIEW_MAP_SIZE, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &MilOverviewMap);
MbufAllocColor(MilSystem, 3, COLORMAP_SIZE, COLORMAP_SIZE, 8 + M_UNSIGNED, M_IMAGE + M_PLANAR + M_PROC, &MilHSLColormap);
MbufAllocColor(MilSystem, 3, COLORMAP_SIZE, COLORMAP_SIZE, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &MilColBuffer);
MbufClear(MilOverviewMap, M_COLOR_BLACK);
InitHSLColormap(MilHSLColormap);
for (Index = 0; Index<OVERVIEW_COLMAP_NUMBER; Index++)
{
Luminance = (MIL_INT)((Index + 0.5) * 255 / OVERVIEW_COLMAP_NUMBER);
Offset = GetOverviewColormapOffset(Luminance);
GenColormap(MilHSLColormap, MilColBuffer, Luminance);
MbufChild2d(MilOverviewMap, Offset, 0, (2 * COLORMAP_SIZE) / OVERVIEW_COLMAP_NUMBER, COLOR_OVERVIEW_MAP_SIZE, &MilUtilChild);
MimResize(MilColBuffer, MilUtilChild, M_FILL_DESTINATION, M_FILL_DESTINATION, M_DEFAULT);
MbufFree(MilUtilChild);
McolMatch(MilColContext, MilColBuffer, M_DEFAULT, M_NULL, MilColResult, M_DEFAULT);
McolDraw(M_DEFAULT, MilColResult, MilColBuffer, M_DRAW_PIXEL_MATCH_USING_COLOR, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MbufChild2d(MilOverviewMap, Offset, COLOR_OVERVIEW_MAP_SIZE, (2 * COLORMAP_SIZE) / OVERVIEW_COLMAP_NUMBER, COLOR_OVERVIEW_MAP_SIZE, &MilUtilChild);
MimResize(MilColBuffer, MilUtilChild, M_FILL_DESTINATION, M_FILL_DESTINATION, M_DEFAULT);
MbufFree(MilUtilChild);
MbufCopyColor2d(MilOverviewMap, MilDispImage, M_ALL_BANDS, 0, 0, M_ALL_BANDS, 0, 2 * DISPLAY_TEXT_SIZE + COLOR_SAMPLE_SIZE + COLORMAP_SIZE + 2, 2 * COLORMAP_SIZE + 1, 2 * COLOR_OVERVIEW_MAP_SIZE -1);
}
MbufFree(MilColBuffer);
MbufFree(MilHSLColormap);
MbufFree(MilOverviewMap);
McolFree(MilColResult);
};
void InitHSLColormap(MIL_ID MilHSLColormapID)
{
MIL_INT i, j;
MIL_UINT8 pData[COLORMAP_SIZE][COLORMAP_SIZE];
for (j = 0; j < COLORMAP_SIZE; j++)
for (i = 0; i < COLORMAP_SIZE; i++)
pData[i][j] = (MIL_UINT8)(j);
MbufPutColor(MilHSLColormapID, M_PLANAR, M_RED, pData);
for (j = 0; j < COLORMAP_SIZE; j++)
for (i = 0; i < COLORMAP_SIZE; i++)
pData[i][j] = (MIL_UINT8)(i);
MbufPutColor(MilHSLColormapID, M_PLANAR, M_GREEN, pData);
};
void GenColormap(MIL_ID MilHSLColormap, MIL_ID ColormapImage, MIL_ID Luminance)
{
MIL_ID BlueBand;
MbufChildColor(MilHSLColormap, M_BLUE, &BlueBand);
MbufClear(BlueBand, (MIL_DOUBLE)Luminance);
MbufFree(BlueBand);
MimConvert(MilHSLColormap, ColormapImage, M_HSL_TO_RGB);
};
MIL_INT GetOverviewColormapOffset(MIL_INT Luminance)
{
MIL_INT Index = (MIL_INT)(Luminance*OVERVIEW_COLMAP_NUMBER / 256);
return Index * ((2 * COLORMAP_SIZE) / OVERVIEW_COLMAP_NUMBER);
};