//---------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include <Windows.h>

#include "DMPro_Types.h"

#include "LoadBmp.cpp"

//#define LibName L"DM_EP_64.dll"
#define LibName L"DM_EP_32.dll"

const int   // the images maximum dimensions
  maxrowQ = 5000,
  maxcolQ = 8192;

int main(int argc, char **argv)
{
   TRow*    pbits;
   TRow     pmembits;  // Image in Memory

   char*   files[] =
   {
     "samples\\1.bmp",
     "samples\\2.bmp",
     "samples\\3.bmp",
     "samples\\4.bmp",
     "samples\\5.bmp",
     "samples\\6.bmp",
     "samples\\7.bmp",
     "samples\\8.bmp",
     NULL
   };
   int 	   ResLoadBMP;
   int	    rowcount, colcount,  row, result;
   int     i;
   int     j, k;
   int     rr;

   PDM_Decoder pDecoder;

   PDM_Options dec1;

   TDM_OptMode opt;
   TDM_ImageInfo* pdm_imageinfo;
   TDM_Info* pdm_info;

   int fn;
   int dmq;
   int welldec;

   char endrun;

   char Symbology_Identifier[4];

   HINSTANCE dllinstance;

   TConnect_DM_Decoder     Connect_DM_Decoder;
   TDisconnect_DM_Decoder  Disconnect_DM_Decoder;
   TCreate_DM_Options      Create_DM_Options;
   TDelete_DM_Options      Delete_DM_Options;
   TDecodeDM_Bits          DecodeDM_Bits;
   TGetDM_ImageInfo        GetDM_ImageInfo;
   TGetDM_Info             GetDM_Info;

   dllinstance = LoadLibrary(LibName);
   if (dllinstance==NULL)
     goto doExit1;
   
   Connect_DM_Decoder    = (TConnect_DM_Decoder    )GetProcAddress(dllinstance,"Connect_DM_Decoder");
   Disconnect_DM_Decoder = (TDisconnect_DM_Decoder )GetProcAddress(dllinstance,"Disconnect_DM_Decoder");
   Create_DM_Options     = (TCreate_DM_Options     )GetProcAddress(dllinstance,"Create_DM_Options");
   Delete_DM_Options     = (TDelete_DM_Options     )GetProcAddress(dllinstance,"Delete_DM_Options");
   DecodeDM_Bits         = (TDecodeBitsF           )GetProcAddress(dllinstance,"DecodeDM_Bits");
   GetDM_ImageInfo       = (TGetDM_ImageInfo       )GetProcAddress(dllinstance,"GetDM_ImageInfo");
   GetDM_Info            = (TGetDM_Info            )GetProcAddress(dllinstance,"GetDM_Info");

   pmembits = (TRow ) malloc(maxrowQ*maxcolQ);      //  Image in Memory
   pbits    = (TRow*) malloc(maxrowQ*sizeof(TRow)); // pointers to ScanLines
   for (row = 0; row < maxrowQ; row++){
     pbits[row] = &pmembits[maxcolQ*row];
   }
   welldec = 0;
   if (Connect_DM_Decoder==NULL)
     goto doExit;
   pDecoder = Connect_DM_Decoder(maxcolQ,maxrowQ);
   if (pDecoder != NULL){

     opt.maxDMCount = 100;
     opt.cellColor  = CL_ANY; // equal to default value
     opt.mirrorMode = MM_ANY;
     opt.speedMode  = DMSP_ULTIMATEPLUS; // DMSP_REGULAR;
     opt.qualityMask = DM_QM_ALL;
     opt.labelMode  = LM_ST_DOT;
     opt.timeOut    = 0;//107;
     opt.filterMode = FM_NON;
     opt.qzMode     = DMQZ_NORMAL; 

     dec1 = Create_DM_Options(pDecoder,opt);

     for(int j=0;files[j]!=NULL; j++){
       if (files[j] == NULL)
         break; 
       printf("\n\n");
       printf("%s ", files[j]);

       rowcount = maxrowQ;
       colcount = maxcolQ;
       ResLoadBMP = LoadBMP (files[j] ,pbits ,rowcount ,colcount);
       if (ResLoadBMP == 0){

         result = DecodeDM_Bits(dec1,rowcount, colcount, pbits);

//         printf("\n result = %4d ",result);
         pdm_imageinfo = GetDM_ImageInfo(dec1);
         dmq = pdm_imageinfo->DMCount;
         printf("\n DM count = %4d",dmq);
         rr  = pdm_imageinfo->RejectionReason;
         if (dmq>0){
           for (i=0;i<=dmq-1;i++){
             pdm_info = GetDM_Info(dec1,i);
//             printf("\n RSErr = %4d",pdm_info->RSErr);
			 printf("\n rowcols: ");
             for (k=0;k<4;k++){
               printf("(%4d,%4d),   ", int(pdm_info->rowcols[2*k])
                                 , int(pdm_info->rowcols[2*k+1]));
             }
             printf("\n");
             if (pdm_info->pchlen>0){
               welldec++;
               printf("\n Decoded array: %s",pdm_info->pch);
    	       strncpy(Symbology_Identifier,(char*)&(pdm_info->pch[-3]),3);
               Symbology_Identifier[3] = 0;
    	       printf("\n Symbology_Id = %s,  RSErr = %4d",Symbology_Identifier,pdm_info->RSErr);
             }
             printf("\n Dimensions: %4d * %4d",
                    pdm_info->VDim, pdm_info->HDim);
             printf("\n axial_nonuniformity (grade)  = %7.2f  (%d)"
                      ,pdm_info->quality.axial_nonuniformity
                      ,int(pdm_info->quality.axial_nonuniformity_grade));
             printf("\n grid_nonuniformity  (grade)  = %7.2f  (%d)"
                      ,pdm_info->quality.grid_nonuniformity
                      ,int(pdm_info->quality.grid_nonuniformity_grade));
             printf("\n symbol_contrast     (grade)  = %7.2f  (%d)"
                  ,pdm_info->quality.symbol_contrast
                  ,int(pdm_info->quality.symbol_contrast_grade));
             printf("\n unused_error_corr.  (grade)  = %7.2f  (%d)"
                 , pdm_info->quality.unused_error_correction
                 , int(pdm_info->quality.unused_error_correction_grade));
             printf("\n vert. & horiz. print_growth  = %7.2f,%7.2f"
                     ,pdm_info->quality.vertical_print_growth
                     ,pdm_info->quality.horizontal_print_growth);
             printf("\n fixed_patt_damage.  (grade)  = %7.2f  (%d)"
                     , pdm_info->quality.fixed_pattern_damage
                     , int(pdm_info->quality.fixed_pattern_damage_grade));
             printf("\n (modulation grade)           =          (%d)"
                      ,int(pdm_info->quality.modulation_grade));
             printf("\n (decode grade)               =          (%d)"
                      ,int(pdm_info->quality.decode_grade));
             printf("\n (overall grade)              =          (%d)"
                      ,int(pdm_info->quality.overall_grade));
 
           }
         }
         fn++;

        }else{
          printf("\n\nLoadBMP !=0\n");
       }
     }
     Delete_DM_Options(dec1);
     Disconnect_DM_Decoder(pDecoder);
   }

 doExit:
   free(pbits);
   free(pmembits);

 doExit1:
   printf("\n\n  Matrices OK: %d",welldec);
   printf("\nPush 'Enter' to exit>");
   scanf("%c",&endrun);

   return 0;
}
