// Test.cpp : Defines the entry point for the console application.
//
#define _CRT_SECURE_NO_WARNINGS

#include <Windows.h>
#include <direct.h>

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>

#include "L_Types.h"
#include "DMPro_Types.h"
#include "QRPro_Types.h"
#include "PDF417Pro_Types.h"
#include "Az_types.h"

#include "All_Types.h"

#include "LoadBmp.cpp"

 const int maxoptcount = 10;
 struct TList
 { char symbology; // 'L' || 'D' || 'Q' || 'P' || 'A'
   int  next;
 };

 char* dir1="Samples\\";
 char* files[]={
 "UPCE_Addon.bmp"
,"20MIL_5.BMP"
,"cb_2.bmp"
,"4-1.bmp"
,"QR_v3.bmp"
,"nzp-n.BMP"
,"nzp.BMP"
,"PDF1.bmp"
,"PDF2.bmp"
,"R_A_2_.BMP"
,"R_B_7_.BMP"
,"Aztec sample.bmp"
,NULL   // last member of array must be NULL
 };

 void printLINEAR_QUALITY(LINEAR_QUALITY lq)
 {
  printf("\nGrades for the scan reflectance profile\n");
  printf("Parameter    Value   Grade          Average Grade on ten scannings\n");
  printf("Decode                 %d                     %6.2f\n",(int)lq.decode_grad,lq.decode_grad_av);
  printf("Rmax         %6.2f%%                           \n",lq.max_reflectance  );
  printf("Rmin         %6.2f%%   %d                     %6.2f\n",lq.min_reflectance  ,(int)lq.min_reflectance_grad,lq.min_reflectance_grad_av);
  printf("SC           %6.2f%%   %d                     %6.2f\n",lq.symbol_contrast  ,(int)lq.symbol_contrast_grad,lq.symbol_contrast_grad_av);
  printf("ECmin        %6.2f%%   %d                     %6.2f\n",lq.min_edge_contrast,(int)lq.min_edge_contrast_grad,lq.min_edge_contrast_grad_av);
//  printf("Rs_ECmin     %6.2f%%                         \n",lq.Rs_ECmin);
//  printf("Rb_ECmin     %6.2f%%                         \n",lq.Rb_ECmin);
  printf("MOD          %6.2f    %d                     %6.2f\n",lq.modulation       ,(int)lq.modulation_grad,lq.modulation_grad_av);
  printf("Defects      %6.2f    %d                     %6.2f\n",lq.defects          ,(int)lq.defects_grad,lq.defects_grad_av);
//  printf("ERNmax       %6.2f%%                       \n",lq.ERNmax);
  printf("Decodability %6.2f    %d                     %6.2f\n",lq.decodability     ,(int)lq.decodability_grad,lq.decodability_grad_av);
  printf("Overall Grade          %d                     %6.2f\n",                     (int)lq.overall_grade_grad,lq.overall_grade_grad_av);
  }

  void printLINEAR_SCAN_LINE(int idx_scan_line, LINEAR_SCAN_LINE* sl) {

  printf("\nResult for the ten scan reflectance profile\n");
  printf(" N start_x  start_y  end_x  end_y  q_zone  c_sum  length  data\n");
  for(int i=0; i<10; i++) {
    if(i != idx_scan_line)
      printf(" %d %6d  %7d  %5d  %5d  %6d  %5d  %5d   %s\n",i,
                                            sl[i].scan_line_start_x,
                                            sl[i].scan_line_start_y,
                                            sl[i].scan_line_end_x,
                                            sl[i].scan_line_end_y,
                                            sl[i].quietzone,
                                            sl[i].checksum,
                                            sl[i].length,
                                            sl[i].dataRes);
    else
      printf(" %d * %4d * %6d * %4d * %4d * %5d * %4d * %4d * %s\n",i,
                                            sl[i].scan_line_start_x,
                                            sl[i].scan_line_start_y,
                                            sl[i].scan_line_end_x,
                                            sl[i].scan_line_end_y,
                                            sl[i].quietzone,
                                            sl[i].checksum,
                                            sl[i].length,
                                            sl[i].dataRes);
  }
 }

//----------------------------------
void initlist(TList *listarray)
{
  memset(listarray,0,maxoptcount*sizeof(TList));
}

void reorderlist(TList *listarray, int &start, int pos, int count)
// assign start of list to currant pos
{
  int i;
  int curpos=start;

  if (count<=1 || pos==start)
    return;

  for (i=0;i<count;i++){
    if(listarray[curpos].next==pos){
      listarray[curpos].next = listarray[pos].next;
      listarray[pos].next = start;
      start = pos;
      break;
    }else{
      curpos = listarray[curpos].next;
    }
  }

}

void MainTask_Fn(void)
{

  int result;   int  row;
  int rowcount, colcount;
  int maxR = 4000; int maxC = 4000;
  TRow*    pdupbits;
  TRow     pdupmembits;  // Image in Memory
  TRow*    pbits;
  TRow     pmembits;  // Image in Memory
  int ResLoadBMP;
  int lq,i,j;
  char ch;

  int   count = 0;
  int   countFalse =0;
  int   csumErr=0, confErr=0, qzErr=0;
  int   countOK=0;     // count of 1D codes
  int   countDMOK=0;
  int   countQROK=0;
  int   countPDFOK=0;
	int  countAZOK = 0;
  char  dir [MAX_PATH];
  char  path[MAX_PATH];

  int optcount;
  int k;         // index of current Option
  int start = 0; // index of start Option
  int lcnt;      // counter of list position
  void*         pDecOpts[maxoptcount]; // list of pointers
  TList         optlist[maxoptcount];

  PL_Decoder    pLDecoder;
  TL_ImageInfo* pl_imageinfo;
  TL_Info*      pl_info;

  PDM_Decoder    pDMDecoder = NULL;
  TDM_ImageInfo* pdm_imageinfo;
  TDM_Info*      pdm_info;

  PQR_Decoder    pQRDecoder;
  TQR_ImageInfo* pqr_imageinfo;
  TQR_Info*      pqr_info;

  PPDF417_Decoder    pPDFDecoder;
  TPDF417_ImageInfo* ppdf_imageinfo;
  TPDF417_Info*      ppdf_info;

  PAZ_Decoder    pAZDecoder = NULL;
  PAZ_ImageInfo  pAZimageinfo;
  PAZ_Info       pAZinfo;

  bool          SymbolOK;
  int symq;
  int stat[20][5];
  HINSTANCE dllinstance;
//  WCHAR WDIR[MAX_PATH];

  TConnect_L_Decoder         PConnect_L_Decoder;
  TDisconnect_L_Decoder      PDisconnect_L_Decoder;
  TCreate_L_Options          PCreate_L_Options;
  TDelete_L_Options          PDelete_L_Options;
  TDecode_L_Bits             PDecode_L_Bits;
  TGetL_ImageInfo            PGetL_ImageInfo;
  TGetL_Info                 PGetL_Info;

  TConnect_DM_Decoder     PConnect_DM_Decoder = NULL;
  TDisconnect_DM_Decoder  PDisconnect_DM_Decoder = NULL;
  TCreate_DM_Options      PCreate_DM_Options = NULL;
  TDelete_DM_Options      PDelete_DM_Options = NULL;
  TDecodeDM_Bits          PDecodeDM_Bits = NULL;
  TGetDM_ImageInfo        PGetDM_ImageInfo = NULL;
  TGetDM_Info             PGetDM_Info = NULL;

  TConnect_QR_Decoder     PConnect_QR_Decoder;
  TDisconnect_QR_Decoder  PDisconnect_QR_Decoder;
  TCreate_QR_Options      PCreate_QR_Options;
  TDelete_QR_Options      PDelete_QR_Options;
  TDecodeQR_Bits          PDecodeQR_Bits;
  TGetQR_ImageInfo        PGetQR_ImageInfo;
  TGetQR_Info             PGetQR_Info;

  TConnect_PDF417_Decoder    PConnect_PDF_Decoder;
  TDisconnect_PDF417_Decoder PDisconnect_PDF_Decoder;
  TCreate_PDF417_Options     PCreate_PDF_Options;
  TDelete_PDF417_Options     PDelete_PDF_Options;
  TDecodePDF417_Bits         PDecodePDF_Bits;
  TGetPDF417_ImageInfo       PGetPDF_ImageInfo;
  TGetPDF417_Info            PGetPDF_Info;

	TConnect_AZ_Decoder      PConnect_AZ_Decoder;
  TDisconnect_AZ_Decoder   PDisconnect_AZ_Decoder;
  TCreate_AZ_Options       PCreate_AZ_Options;
  TDelete_AZ_Options       PDelete_AZ_Options;
  TDecode_AZ_Bits          PDecode_AZ_Bits;
  TGet_AZ_ImageInfo        PGet_AZ_ImageInfo;
  TGet_AZ_Info             PGet_AZ_Info;


  TConnect_Total_Decoder  PConnect_Total_Decoder;

#ifdef _WIN64
   dllinstance = LoadLibrary(L"All64.dll");
#else
   dllinstance = LoadLibrary(L"All.dll");
#endif

   if (dllinstance==NULL){
     printf("\ndllinstance==NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   strcpy(dir,".\\");
   strcat(dir,dir1);

   PConnect_Total_Decoder= (TConnect_Total_Decoder )GetProcAddress(dllinstance,"Connect_Total_Decoder");
   if (PConnect_Total_Decoder == NULL){
     printf("\nConnect_Total_Decoder == NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   PConnect_L_Decoder    = (TConnect_L_Decoder    )GetProcAddress(dllinstance,"Connect_L_Decoder");
   PDisconnect_L_Decoder = (TDisconnect_L_Decoder )GetProcAddress(dllinstance,"Disconnect_L_Decoder");
   PCreate_L_Options     = (TCreate_L_Options     )GetProcAddress(dllinstance,"Create_L_Options");
   PDelete_L_Options     = (TDelete_L_Options     )GetProcAddress(dllinstance,"Delete_L_Options");
   PDecode_L_Bits        = (TDecode_L_Bits        )GetProcAddress(dllinstance,"Decode_L_Bits");
   PGetL_ImageInfo       = (TGetL_ImageInfo       )GetProcAddress(dllinstance,"GetL_ImageInfo");
   PGetL_Info            = (TGetL_Info            )GetProcAddress(dllinstance,"GetL_Info");

  if (PConnect_L_Decoder == NULL){
     printf("\nConnect_L_Decoder == NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   PConnect_DM_Decoder    = (TConnect_DM_Decoder    )GetProcAddress(dllinstance,"Connect_DM_Decoder");
   PDisconnect_DM_Decoder = (TDisconnect_DM_Decoder )GetProcAddress(dllinstance,"Disconnect_DM_Decoder");
   PCreate_DM_Options     = (TCreate_DM_Options     )GetProcAddress(dllinstance,"Create_DM_Options");
   PDelete_DM_Options     = (TDelete_DM_Options     )GetProcAddress(dllinstance,"Delete_DM_Options");
   PDecodeDM_Bits         = (TDecodeDM_Bits         )GetProcAddress(dllinstance,"DecodeDM_Bits");
   PGetDM_ImageInfo       = (TGetDM_ImageInfo       )GetProcAddress(dllinstance,"GetDM_ImageInfo");
   PGetDM_Info            = (TGetDM_Info            )GetProcAddress(dllinstance,"GetDM_Info");

  if (PConnect_DM_Decoder == NULL){
     printf("\nConnect_DM_Decoder == NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   PConnect_QR_Decoder    = (TConnect_QR_Decoder    )GetProcAddress(dllinstance,"Connect_QR_Decoder");
   PDisconnect_QR_Decoder = (TDisconnect_QR_Decoder )GetProcAddress(dllinstance,"Disconnect_QR_Decoder");
   PCreate_QR_Options     = (TCreate_QR_Options     )GetProcAddress(dllinstance,"Create_QR_Options");
   PDelete_QR_Options     = (TDelete_QR_Options     )GetProcAddress(dllinstance,"Delete_QR_Options");
   PDecodeQR_Bits         = (TDecodeQR_Bits         )GetProcAddress(dllinstance,"DecodeQR_Bits");
   PGetQR_ImageInfo       = (TGetQR_ImageInfo       )GetProcAddress(dllinstance,"GetQR_ImageInfo");
   PGetQR_Info            = (TGetQR_Info            )GetProcAddress(dllinstance,"GetQR_Info");

   if (PConnect_QR_Decoder == NULL){
     printf("\nConnect_QR_Decoder == NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   PConnect_PDF_Decoder    = (TConnect_PDF417_Decoder    )GetProcAddress(dllinstance,"Connect_PDF417_Decoder");
   PDisconnect_PDF_Decoder = (TDisconnect_PDF417_Decoder )GetProcAddress(dllinstance,"Disconnect_PDF417_Decoder");
   PCreate_PDF_Options     = (TCreate_PDF417_Options     )GetProcAddress(dllinstance,"Create_PDF417_Options");
   PDelete_PDF_Options     = (TDelete_PDF417_Options     )GetProcAddress(dllinstance,"Delete_PDF417_Options");
   PDecodePDF_Bits         = (TDecodePDF417_Bits         )GetProcAddress(dllinstance,"DecodePDF417_Bits");
   PGetPDF_ImageInfo       = (TGetPDF417_ImageInfo       )GetProcAddress(dllinstance,"GetPDF417_ImageInfo");
   PGetPDF_Info            = (TGetPDF417_Info            )GetProcAddress(dllinstance,"GetPDF417_Info");
 
   if (PConnect_PDF_Decoder == NULL){
     printf("\nConnect_PDF_Decoder == NULL, print 'Enter' to exit>\n");
     scanf("%c",&ch);
     return;
   }

   PConnect_AZ_Decoder     = (TConnect_AZ_Decoder    )GetProcAddress(dllinstance, "Connect_AZ_Decoder");
   PDisconnect_AZ_Decoder  = (TDisconnect_AZ_Decoder )GetProcAddress(dllinstance, "Disconnect_AZ_Decoder");
   PCreate_AZ_Options      = (TCreate_AZ_Options     )GetProcAddress(dllinstance, "Create_AZ_Options");
   PDelete_AZ_Options      = (TDelete_AZ_Options     )GetProcAddress(dllinstance, "Delete_AZ_Options");
   PDecode_AZ_Bits         = (TDecode_AZ_Bits        )GetProcAddress(dllinstance, "Decode_AZ_Bits");
   PGet_AZ_ImageInfo       = (TGet_AZ_ImageInfo      )GetProcAddress(dllinstance, "Get_AZ_ImageInfo");
   PGet_AZ_Info            = (TGet_AZ_Info           )GetProcAddress(dllinstance, "Get_AZ_Info");

   if (PConnect_AZ_Decoder == NULL)
   {
     printf("Connect_AZ_Decoder == NULL, print 'Enter' to exit>\n");
		 scanf("%c",&ch);
     return;
   }

  PConnect_Total_Decoder();

  pDMDecoder = NULL;

  pLDecoder = PConnect_L_Decoder(maxR,maxC);
  if(pLDecoder==NULL) return ;

  pDMDecoder = PConnect_DM_Decoder(maxR,maxC);
  printf("to pDMDecoder == NULL %d\n", pDMDecoder);
  if(pDMDecoder == NULL) return ;

  pQRDecoder = PConnect_QR_Decoder(maxR,maxC);
  if(pQRDecoder==NULL) return ;

  pPDFDecoder = PConnect_PDF_Decoder(maxR,maxC);
  if(pPDFDecoder==NULL) return ;

	pAZDecoder = PConnect_AZ_Decoder(maxR, maxC);
  if(pAZDecoder == NULL) return;

  pmembits = (TRow) malloc(maxR*maxC);       //  Image in Memory
  pbits    = (TRow*) malloc(maxR*sizeof(TRow)); // pointers to ScanLines

  for (row = 0; row < maxR; row++){
      pbits[row] = &pmembits[maxC*row];
  }


  TDM_OptMode opt_DM={
                      1, // maxDMCount
                      3, // cellColor=any
                      3, // mirrorMode=any
                      DMSP_ULTIMATEPLUS, // speedMode
                      DM_QM_ALL,    // qualityMask
                      LM_ST_DOT,    // labelMode
                      0, // timeOut
                      0, // filterMode
                      0   // qzMode = normal
                     };

  TQR_OptMode opt_QR={
                      1, // maxQRCount
                      3, // cellColor=any
                      3, // mirrorMode=any
                      0, // speedMode
                      1, // quality
                      0, // labelMode
                      0, // timeOut
                      0, // filterMode
                      2, // symbology = normal + micro
                      0  // qzMode = standard
                     };

  TL_OptMode opt_L_All =
                    { 1,//10,  // int maxLcount;
                     -1,  // int typecode any;
                     // TCM_TCODE39 | TCM_TUPCEEX,
                     // TC_TNZP,
                     // TC_TSuissPost,

                      0,  // int timeout;
                      1,  // int paramq;
                      0,  // int checksum_I25;
                      0,  // int checksum_C39;
                     -1,  // int quietzone;
                       0,//1, // int smartmode
                       0, // int EC_Factor
                       0, // int pharmacodedir
                       2, //int scandir = vertical+horizontal;
                       8, //int scanstep;
                       0, // checksum_CB;
                       0, // int FullASCII_C39;
                      -1, // 250,  //int colbeg
                      -1, // 440,  //int colend      //200, 50, 440, 430
                      -1, //  50,  //int rowbeg
                      -1, // 430,  //int rowend
                      99,  // TADF_num
                      L_DEFAULT // L_WHITE
                     };
  TL_OptMode opt_RSS_All =
                    { 1,//10,  // int maxLcount;
                     //-1,  // int typecode any;
                      TCM_TRSS_ALL,
                     // TC_TNZP,
                     // TC_TSuissPost,

                      0,  // int timeout;
                      1,  // int paramq;
                      0,  // int checksum_I25;
                      0,  // int checksum_C39;
                     -1,  // int quietzone;
                       0,//1, // int smartmode
                       0, // int EC_Factor
                       0, // int pharmacodedir
                       2, //int scandir = vertical+horizontal;
                       8, //int scanstep;
                       0, // checksum_CB;
                       0, // int FullASCII_C39;
                      -1, // 250,  //int colbeg
                      -1, // 440,  //int colend      //200, 50, 440, 430
                      -1, //  50,  //int rowbeg
                      -1, // 430,  //int rowend
                      99,  // TADF_num
                      L_DEFAULT // L_WHITE
                     };

  TL_OptMode opt_NZP_W =
                    { 1,//10,  // int maxLcount;
                     //-1,  // int typecode any;
                     // TCM_TRSS_ALL,
                      TC_TNZP,
                     // TC_TSuissPost,

                      0,  // int timeout;
                      1,  // int paramq;
                      0,  // int checksum_I25;
                      0,  // int checksum_C39;
                     -1,  // int quietzone;
                       0,//1, // int smartmode
                       0, // int EC_Factor
                       0, // int pharmacodedir
                       2, //int scandir = vertical+horizontal;
                       8, //int scanstep;
                       0, // checksum_CB;
                       0, // int FullASCII_C39;
                      -1, // 250,  //int colbeg
                      -1, // 440,  //int colend      //200, 50, 440, 430
                      -1, //  50,  //int rowbeg
                      -1, // 430,  //int rowend
                      99,  // TADF_num
                      L_WHITE // L_DEFAULT
                     };

  TPDF417_OptMode opt_PDF =
  { 
	1,         //  int MaxSymbolCount;            // maximum number of decoded PDF417 labels
	SP_Robust, //  TPDF417_SpeedMode  SpeedMode;  //  SP_Fast,  SP_Robust, SP_Smart
	CG_No,     //  TPDF417_CalcGrade  CalcGrade;  //  CG_No, CG_Yes ;
	DM_All,    //  TPDF417_DirectMode DirectMode; //  DM_LeftRight, DM_Horizontal, DM_All, DM_Vertical
	0,         //  int BWFilter;                  // 0: none, +1 => BW+1,  -1 => BW-1
	0,         //  int TimeOut;                   // in milliseconds, zero - not timeout
	4          //  int ScanStep;
  };

	TAZ_OptMode    AZ_optmode;
  AZ_optmode.maxAZCount = 1;
  AZ_optmode.timeOut    = 0; // 0 ms => don't check time-out
  AZ_optmode.speedMode  = 0;
  AZ_optmode.qualityMask= 0;
  AZ_optmode.symbology  = AZ_S_NORMAL;
  AZ_optmode.filterMode = 0;
  AZ_optmode.labelMode  = 0;
  AZ_optmode.qzMode     = AZ_QZ_STANDARD;

  initlist(optlist);
  start = 0;
  pDecOpts[0] = PCreate_L_Options (pLDecoder ,opt_L_All);
//  optlist [0].symbology= 'L'; optlist [0].next = 1;
  optlist [0].symbology= 'L'; optlist [0].next = 3;
  pDecOpts[1] = PCreate_L_Options (pLDecoder ,opt_RSS_All);
  optlist [1].symbology= 'L'; optlist [1].next = 2;
  pDecOpts[2] = PCreate_L_Options (pLDecoder ,opt_NZP_W);
  optlist [2].symbology= 'L'; optlist [2].next = 5;
  pDecOpts[3] = PCreate_DM_Options (pDMDecoder ,opt_DM);
  optlist [3].symbology= 'D'; optlist [3].next = 4;
  pDecOpts[4] = PCreate_QR_Options (pQRDecoder ,opt_QR);
  optlist [4].symbology= 'Q'; optlist [4].next = 1;
  pDecOpts[5] = PCreate_PDF_Options (pPDFDecoder ,opt_PDF);
  optlist [5].symbology= 'P'; optlist [5].next = 6;
  pDecOpts[6] = PCreate_AZ_Options (pAZDecoder, AZ_optmode);
  optlist [6].symbology= 'A'; optlist [6].next = maxoptcount; // start;
  optcount = 7;

  double TotalTime = 0.0;

  for (i=0;i<20;i++){
   	memset(stat[i],0,sizeof stat[0]);
  }
  for(j=0;files[j]!=NULL; j++){
   strcpy(path,dir);
   strcat(path,files[j]);

   printf("\n");
   printf("%s ", path);
   rowcount = maxR;
   colcount = maxC;
   ResLoadBMP = LoadBMP (path , pbits ,rowcount ,colcount);

   if(ResLoadBMP != 0) {
     printf("ResLoadBMP == %d \n",ResLoadBMP);  continue;
   }//return 1;

   count++;

// 20161104
   pdupmembits = (TRow) malloc(rowcount*colcount);   //  Image in Memory
   pdupbits    = (TRow*) malloc(rowcount*sizeof(TRow)); // pointers to ScanLines

   for (row = 0; row < rowcount; row++){
     pdupbits[row] = &pdupmembits[colcount*row];
     memcpy(pdupbits[row],pbits[row],colcount);  // store original image
   }
// 20161104

LARGE_INTEGER liFreq;
LARGE_INTEGER liStart;
LARGE_INTEGER liStop;
double m_DecodeTime;
::QueryPerformanceFrequency(&liFreq);
::QueryPerformanceCounter(&liStart); // Do your processing

   k = start;
   SymbolOK = false;
   for (lcnt=0; lcnt<optcount; lcnt++){
    if (optlist[k].symbology=='L'){
     result =  PDecode_L_Bits(pDecOpts[k], rowcount,colcount,pbits);
     if (result>=0){
       pl_imageinfo = PGetL_ImageInfo(pDecOpts[k]);
       lq = pl_imageinfo->LCount;
       printf(" %d",lq);
       if (lq > 0) {
         for (i=0; i<=lq-1; i++) {
           pl_info = PGetL_Info(pDecOpts[k],i);
           printf("\n      ");
           switch (pl_info->type){
             case TC_TCODE128     : printf(" C128:   "); break;
             case TC_TCODE39      : printf(" C39:    "); break;
             case TC_TCODABAR     : printf(" Cbar:   "); break;
             case TC_TINTERLEAVED : printf(" Il 2/5: "); break;
             case TC_TEAN13       : printf(" EAN13:  "); break;
             case TC_TEAN8        : printf(" EAN8:   "); break;
             case TC_TUPCE        : printf(" UPCE:   "); break;
             case TC_TEAN13EX     : printf(" EAN13_ADDON:  "); break;
             case TC_TUPCEEX      : printf(" UPCE_ADDON:   "); break;
             case TC_TPHARMACODE  : printf(" Pharma: "); break;
             case TC_TADF  : printf(" TADF, barcount=%d   ",pl_info->add_lq->actTADFnum);break;
             default: printf(" Unknown:");
           };

           if (pl_info->pch[-3] == ']'){
             printf(" %c%c%c :", pl_info->pch[-3],pl_info->pch[-2],pl_info->pch[-1]);
           }
           printf(" %d * %s ", pl_info->pchlen,pl_info->pch);

           if( pl_imageinfo->BreakReason==L_TIMEOUT)
             printf("== TIMEOUT! ");

           if ((pl_info->type)>0){
             int bt, rr
            ,n = 0;
             bt = pl_info->type;
             if (bt<1 && bt>19)
               bt = 16; // Other
             rr = pl_info->RejectionReason;
             if (rr == L_SUCCESSFUL) n=1;
             else if (rr == L_CHECKSUM_FAILED) n=2;
             else if (rr == L_NOT_CONFIRMED  ) n=3;
             else if (rr == L_NOT_QUIET_ZONE ) n=4;
             stat[bt][n]+=1;
           }
           if( pl_info->RejectionReason==L_CHECKSUM_FAILED){
             csumErr++;
   	         printf("=CS!");
           }
           if( pl_info->RejectionReason==L_NOT_CONFIRMED ){
      	     confErr++;
   	         printf("=Nc!");
           }
           if( pl_info->RejectionReason==L_NOT_QUIET_ZONE){
             qzErr++;
   	         printf("=QZ!");
           }
           if( pl_info->RejectionReason==L_SUCCESSFUL){
             reorderlist(optlist,start,k,optcount);
             countOK++;
             printf("=OK!");
             SymbolOK = true;
             break;
           }
           k = optlist[k].next;
         };
         if (SymbolOK){
           break;
         }
      }else {  // lq==0
         k = optlist[k].next;
      }
     }else{//result<0
       k = optlist[k].next;
     }
    }else if(optlist[k].symbology=='D'){
     result =  PDecodeDM_Bits(pDecOpts[k], rowcount,colcount,pbits);
     if (result>=0){
      pdm_imageinfo = PGetDM_ImageInfo(pDecOpts[k]);
      if (pdm_imageinfo->RejectionReason == DM_RR_OK){
        reorderlist(optlist,start,k,optcount);
        symq = pdm_imageinfo->DMCount;
        printf(" ,DM count = %d",symq);
        if (symq > 0) {
          for (i=0; i<=symq-1; i++) {
            pdm_info = PGetDM_Info(pDecOpts[k],i);
            printf("\n      ");
            printf("%d * %s", pdm_info->pchlen, pdm_info->pch);
            countDMOK++;
        	printf("\nDM=OK!\n");
          }
        }
        SymbolOK = true;
        break;
       }
     }
     k = optlist[k].next;
    }else if (optlist[k].symbology=='Q'){
     result =  PDecodeQR_Bits(pDecOpts[k], rowcount,colcount,pbits);
     if (result>=0){
      pqr_imageinfo = PGetQR_ImageInfo(pDecOpts[k]);
      if (pqr_imageinfo->RejectionReason == QR_SUCCESSFUL){
        reorderlist(optlist,start,k,optcount);
        symq = pqr_imageinfo->QRCount;
        printf(" ,QR count = %d",symq);
        if (symq > 0) {
          for (i=0; i<=symq-1; i++) {
            pqr_info = PGetQR_Info(pDecOpts[k],i);
            printf("\n      ");
            printf("%d * ", pqr_info->pchlen);
            for(int m=0; m<pqr_info->pchlen; m++)
              printf("%c", char((pqr_info->pch2)[m]));

            countQROK++;
        	printf("\nQR=OK!\n");
          }
        }
        SymbolOK = true;
        break;
      }
     }
     k = optlist[k].next;
    }else if(optlist[k].symbology=='P'){
     result =  PDecodePDF_Bits(pDecOpts[k], rowcount,colcount,pbits);
     if (result>=0){
      ppdf_imageinfo = PGetPDF_ImageInfo(pDecOpts[k]);
      if (ppdf_imageinfo->RejectionReason == PDF417_OK){
        reorderlist(optlist,start,k,optcount);
        symq = ppdf_imageinfo->SymbolCount;
        printf(" ,PDF count = %d",symq);
        if (symq > 0) {
          for (i=0; i<=symq-1; i++) {
            ppdf_info = PGetPDF_Info(pDecOpts[k],i);
            printf("\n      ");
            printf("%d * %s", ppdf_info->pchlen, ppdf_info->pch);
            countPDFOK++;
        	printf("\nPDF=OK!\n");
          }
        }
        SymbolOK = true;
        break;
       }
			}
      k = optlist[k].next;
     }else if(optlist[k].symbology=='A'){
     result =  PDecode_AZ_Bits(pDecOpts[k], rowcount,colcount,pbits);
     if (result>=0){
      pAZimageinfo = PGet_AZ_ImageInfo(pDecOpts[k]);
      if (pAZimageinfo->RejectionReason == 0){
        reorderlist(optlist,start,k,optcount);
        symq = pAZimageinfo->AZCount;
        printf(" ,AZ count = %d",symq);
        if (symq > 0) {
          for (i=0; i<=symq-1; i++) {
            pAZinfo = PGet_AZ_Info(pDecOpts[k],i);
            printf("\n      ");
            printf("%d * %s", pAZinfo->pchlen, pAZinfo->pch);
            countAZOK++;
        	printf("\nAZ=OK!\n");
          }
        }
        SymbolOK = true;
        break;
       }
      
     }
     k = optlist[k].next;
    }
    if (k>=maxoptcount)
      break;
// 20161104
    for (row = 0; row < rowcount; row++){ // restore original image
      memcpy(pbits[row],pdupbits[row],colcount);
    }
// 20161104
   }
::QueryPerformanceCounter(&liStop);
LONGLONG llTimeDiff = liStop.QuadPart - liStart.QuadPart;
m_DecodeTime=(double)llTimeDiff*1000/liFreq.QuadPart;
printf(",  time=%7.2f",m_DecodeTime);
TotalTime += m_DecodeTime; // /1000

   if(result<0){
     printf(" decoder == NULL!!!!!!"); return ;
   }

// 20151104
   free(pdupbits);
   free(pdupmembits);
// 20151104

  }  // for j
  if (files[j]==NULL){
    PDisconnect_L_Decoder(pLDecoder); // and delete all Options
    PDisconnect_DM_Decoder(pDMDecoder); // and delete all Options
    PDisconnect_QR_Decoder(pQRDecoder); // and delete all Options
	 PDisconnect_PDF_Decoder(pPDFDecoder); //  -- // -- // --
	 PDisconnect_AZ_Decoder(pAZDecoder);
  }

  char ct[13];
  printf("\n\n");
  printf("1D Symbology !  OK ,  CS , Conf,  QZ \n");
  printf("-------------------------------------\n");
  for (i=1;i<=19;i++){
    switch (i){
     case 1: strcpy(ct,"CODE128     "); break;
     case 2: strcpy(ct,"CODE39      "); break;
     case 3: strcpy(ct,"CODABAR     "); break;
     case 4: strcpy(ct,"INTERLEAVED "); break;
     case 5: strcpy(ct,"EAN13       "); break;
     case 6: strcpy(ct,"EAN8        "); break;
     case 7: strcpy(ct,"UPCE        "); break;
     case 8: strcpy(ct,"POSTNET     "); break;
     case 9: strcpy(ct,"IMB         "); break;
     case 10: strcpy(ct,"PHARMACODE  "); break;
     case 11: strcpy(ct,"RSS         "); break;
     case 12: strcpy(ct,"RSS_L       "); break;
     case 13: strcpy(ct,"RSS_E       "); break;
     case 14: strcpy(ct,"EAN13 addon "); break;
     case 15: strcpy(ct,"UPCE addon  "); break;
     case 17: strcpy(ct,"TADF        "); break;
     case 18: strcpy(ct,"NZP         "); break;
     case 19: strcpy(ct,"SUISSPOST   "); break;
     default: strcpy(ct,"            "); break;
    }
    printf("%s !%4d ,%4d ,%4d ,%4d \n"
           ,ct,stat[i][1],stat[i][2],stat[i][3],stat[i][4]);
  }
  printf("\n count=%d,  1D decoded=%d  \n", count, countOK);
  printf("\n SUCCESSFUL=%d, NOT_QUIET_ZONE=%d, CHECKSUM_FAILED=%d, NOT_CONFIRMED=%d \n",
		          countOK,          qzErr,                csumErr,              confErr
		);
  printf("\n=========================================\n");
  printf("Data Matrix decoded=%d \n", countDMOK);
  printf("=========================================\n\n");
  printf("QR Code decoded=%d \n", countQROK);
  printf("=========================================\n\n");
  printf("PDF417 decoded=%d \n", countPDFOK);
  printf("=========================================\n\n");
	printf("Aztec decoded=%d \n", countAZOK);
  printf("=========================================\n\n");

  if (count>0)
    printf(",  avr. time = %8.2f\n",TotalTime/count);

  free(pbits);
  free(pmembits);

  printf("\nPrint 'Enter' to exit>\n");
  scanf("%c",&ch);

  return;
}

int main(int argc, char* argv[])
{
   MainTask_Fn();
   return 0;
}



