/*************************************************************************/
/*
 * File name: FdkHistogramMain.cpp
 * Location:  ...\Matrox Imaging\MILxxx\Examples\BoardSpecific\solios\C++\SoliosFDK
 *             \HistogramPrimitive
 *
 * Synopsis:  This example shows how to test and benchmark a custom FPGA
 *            accelerated processing function that performs a histogram
 *            on a source image. 
 */

/* Headers. */
#include <mil.h>

#define IMAGE_FILE            M_IMAGE_PATH MIL_TEXT("Cell.mim")

#define HIST_NUM_INTENSITIES  256
#define HIST_SCALE_FACTOR     8
#define HIST_X_POSITION       250
#define HIST_Y_POSITION       450

/* Master MIL functions declarations. */
void FPGAHistogram(MIL_ID SrcImageId, MIL_ID HistBufId, MIL_INT ClearFlag);

/* Main function. */
/* --------------------------------- */

int MosMain(void)
   {
   MIL_ID     MilApplication;
   MIL_ID     MilSystem     ;
   MIL_ID     MilDisplay    ;
   MIL_ID     MilImageProc  ;
   MIL_ID     MilImageDisp  ;
   MIL_ID     HistResult    ;
   MIL_ID     MilOverlayImage;
   MIL_INT    HistValues[HIST_NUM_INTENSITIES]; /* Histogram values.  */
   MIL_INT    XStart[HIST_NUM_INTENSITIES], YStart[HIST_NUM_INTENSITIES],
              XEnd[HIST_NUM_INTENSITIES],   YEnd[HIST_NUM_INTENSITIES];
   MIL_DOUBLE AnnotationColor = M_COLOR_RED;
   MIL_INT    SizeX, SizeY, BoardType, i;

   /* Allocate defaults. */
   MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay,
                                                       M_NULL, M_NULL);

   /* Check if the processing FPGA is present. */
   MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType);
   if(!(BoardType & M_PF))
      {
      MosPrintf(MIL_TEXT("Error, this example needs a processing FPGA installed on\n"));
      MosPrintf(MIL_TEXT("your board to continue.\n"));
      MosPrintf(MIL_TEXT("Press <Enter> to quit.\n"));
      MosGetch();
      MdispFree(MilDisplay);
      MsysFree(MilSystem);
      MappFree(MilApplication);
      return 0;
      }

   /* Allocate buffers and clear them.*/
   /* For FPGA acceleration, all source buffers must be in FPGA accessible memory.
      Destination buffer must be in on-baord FPGA accessible memory. This is a
      requirement of the off-chip histogram PU used by this example.
   */
   SizeX = MbufDiskInquire(IMAGE_FILE, M_SIZE_X, M_NULL);
   SizeY = MbufDiskInquire(IMAGE_FILE, M_SIZE_Y, M_NULL);
   MbufAlloc2d(MilSystem,
               SizeX,
               SizeY,
               8+M_UNSIGNED,
               M_IMAGE+M_PROC+M_FPGA_ACCESSIBLE,
               &MilImageProc);
   MbufAlloc2d(MilSystem,
               SizeX,
               SizeY,
               8+M_UNSIGNED,
               M_IMAGE+M_DISP,
               &MilImageDisp);
   MimAllocResult(MilSystem, HIST_NUM_INTENSITIES, M_HIST_LIST+M_NON_PAGED, &HistResult);

   /* Set the maximum valid pixel value. */
   MbufControl(MilImageProc, M_MAX, 255);

   /* Load the source image and display it. */
   MbufLoad(IMAGE_FILE, MilImageProc);
   MbufLoad(IMAGE_FILE, MilImageDisp);
   MdispSelect(MilDisplay, MilImageDisp);
   
   /* Enable overlay operations. */
   MdispControl(MilDisplay, M_OVERLAY, M_ENABLE);
   MdispInquire(MilDisplay, M_OVERLAY_ID, &MilOverlayImage);

   MosPrintf(MIL_TEXT("This example demonstrates how to use the Mfpga API to program\n"));
   MosPrintf(MIL_TEXT("an histogram primitive. Press <Enter> to continue.\n"));
   MosGetchar();

   /* Clear the histogram buffer and compute the histroram of the image. */
   FPGAHistogram(MilImageProc, HistResult, M_DEFAULT);

   /* Get the results. */
   MimGetResult(HistResult, M_VALUE, HistValues);

   /* Draw the histogram in the overlay. */
   MgraColor(M_DEFAULT, AnnotationColor);
   for(i=0; i<HIST_NUM_INTENSITIES; i++)
      {
      XStart[i] = i+HIST_X_POSITION+1,
      YStart[i] = HIST_Y_POSITION;
      XEnd[i]   = i+HIST_X_POSITION+1, 
      YEnd[i] = HIST_Y_POSITION-(HistValues[i]/HIST_SCALE_FACTOR);
      }
   MgraLines(M_DEFAULT, MilOverlayImage, HIST_NUM_INTENSITIES, 
                        XStart, YStart, XEnd, YEnd, M_DEFAULT);
   MosPrintf(MIL_TEXT("The histogram of the image was calculated and drawn.\n"));
   MosPrintf(MIL_TEXT("Press a key to end.\n\n"));
   MosGetchar();

   MimFree(HistResult);
   MbufFree(MilImageProc);
   MbufFree(MilImageDisp);
   MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);

   return 0;
   }