int main(int argc, const char* argv[])
{
	// Parse command
	__int64 llFormat = (OneD|QR_CODE);
	const char * pszImageFile = NULL;
	int iMaxCount = 0x7FFFFFFF;
	int iIndex = 0;
	ReaderOptions ro = {0};
	int iRet = -1;
	char * pszTemp = NULL;
	char * pszTemp1 = NULL;
	unsigned __int64 ullTimeBegin = 0;
	unsigned __int64 ullTimeEnd = 0;
	
	if (argc <= 1)
	{
		PrintHelp();
		return 1;
	}

	for (iIndex = 1; iIndex < argc; iIndex ++)
	{
		if (strcmpi(argv[iIndex], "-help") == 0)
		{
			PrintHelp();
			return 0;
		}

		if (strcmpi(argv[iIndex], "-f") == 0)
		{// parse format
			iIndex ++;
			if (iIndex >= argc)
			{
				printf("The syntax of the command is incorrect.\r\n");
				return 1;
			}
			llFormat = GetFormat(argv[iIndex]);
			if (llFormat == 0)
			{
				printf("The syntax of the command is incorrect.\r\n");
				return 1;
			}
			continue;
		}

		if (strcmpi(argv[iIndex], "-n") == 0)
		{// parse format
			iIndex ++;
			if (iIndex >= argc)
			{
				printf("The syntax of the command is incorrect.\r\n");
				return 1;
			}
			iMaxCount = atoi(argv[iIndex]);
			continue;
		}

		if (NULL == pszImageFile)
			pszImageFile = argv[iIndex];
	}

	if (NULL == pszImageFile)
	{
		printf("The syntax of the command is incorrect.\r\n");
		return 1;
	}

	// Set license
	CBarcodeReader reader;
	reader.InitLicense("<Put your license key here>");

	// Read barcode
	ullTimeBegin = GetTickCount();
	ro.llBarcodeFormat = llFormat;
	ro.iMaxBarcodesNumPerPage = iMaxCount;
	reader.SetReaderOptions(ro);
	iRet = reader.DecodeFile(pszImageFile);
	ullTimeEnd = GetTickCount();
		
	// Output barcode result
	pszTemp = (char*)malloc(4096);
	if (iRet != DBR_OK)
	{
		sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet));
		printf(pszTemp);
		free(pszTemp);
		return 1;
	}

	pBarcodeResultArray paryResult = NULL;
	reader.GetBarcodes(&paryResult);
	
	if (paryResult->iBarcodeCount == 0)
	{
		sprintf(pszTemp, "No barcode found. Total time spent: %.3f seconds.\r\n", ((float)(ullTimeEnd - ullTimeBegin)/1000));
		printf(pszTemp);
		free(pszTemp);
		reader.FreeBarcodeResults(&paryResult);
		return 0;
	}
	
	sprintf(pszTemp, "Total barcode(s) found: %d. Total time spent: %.3f seconds\r\n\r\n", paryResult->iBarcodeCount, ((float)(ullTimeEnd - ullTimeBegin)/1000));
	printf(pszTemp);
	for (iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++)
	{
		sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1);
		printf(pszTemp);
		sprintf(pszTemp, "    Page: %d\r\n", paryResult->ppBarcodes[iIndex]->iPageNum);
		printf(pszTemp);
		sprintf(pszTemp, "    Type: %s\r\n", GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat));
		printf(pszTemp);
		pszTemp1 = (char*)malloc(paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
		memset(pszTemp1, 0, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
		memcpy(pszTemp1, paryResult->ppBarcodes[iIndex]->pBarcodeData, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength);
		sprintf(pszTemp, "    Value: %s\r\n", pszTemp1);
		printf(pszTemp);
		free(pszTemp1);
		sprintf(pszTemp, "    Region: {Left: %d, Top: %d, Width: %d, Height: %d}\r\n\r\n", 
			paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop, 
			paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight);
		printf(pszTemp);
	}	

	free(pszTemp);
	reader.FreeBarcodeResults(&paryResult);

	return 0;
}
VALUE decode(const char *pszImageFile)
{
	VALUE ary = rb_ary_new();

	__int64 llFormat = (OneD |QR_CODE);
	int iMaxCount = 0x7FFFFFFF;
	int iIndex = 0;
	ReaderOptions ro = {0};
	pBarcodeResultArray paryResult = NULL;
	int iRet = -1;
	char * pszTemp = NULL;
	char * pszTemp1 = NULL;
	struct timeval begin, end;

	if (NULL == pszImageFile)
	{
		printf("The syntax of the command is incorrect.\n");
		return 1;
	}

	// Set license
	DBR_InitLicense("B8DF4560D0953299D5454C71A38D1FEB");

	// Read barcode
	gettimeofday(&begin, NULL);
	ro.llBarcodeFormat = llFormat;
	ro.iMaxBarcodesNumPerPage = iMaxCount;
	iRet = DBR_DecodeFile(pszImageFile, &ro, &paryResult);
	gettimeofday(&end, NULL);

	// Output barcode result
	pszTemp = (char*)malloc(4096);
	if (iRet != DBR_OK)
	{
		sprintf(pszTemp, "Failed to read barcode: %s\r\n", DBR_GetErrorString(iRet));
		printf("%s", pszTemp);
		free(pszTemp);
		return 1;
	}

	if (paryResult->iBarcodeCount == 0)
	{
		sprintf(pszTemp, "No barcode found. Total time spent: %.3f seconds.\r\n",
					((float)((end.tv_sec * 1000 * 1000 +  end.tv_usec) - (begin.tv_sec * 1000 * 1000 + begin.tv_usec))/(1000 * 1000)));
		printf("%s", pszTemp);
		DBR_FreeBarcodeResults(&paryResult);
		return 0;
	}

	sprintf(pszTemp, "Total barcode(s) found: %d. Total time spent: %.3f seconds\r\n\r\n", paryResult->iBarcodeCount,
					((float)((end.tv_sec * 1000 * 1000 +  end.tv_usec) - (begin.tv_sec * 1000 * 1000 + begin.tv_usec))/(1000 * 1000)));
	printf("%s", pszTemp);
	for (iIndex = 0; iIndex < paryResult->iBarcodeCount; iIndex++)
	{
		sprintf(pszTemp, "Barcode %d:\r\n", iIndex + 1);
		// printf("%s", pszTemp);
		sprintf(pszTemp, "%s    Page: %d\r\n", pszTemp, paryResult->ppBarcodes[iIndex]->iPageNum);
		// printf("%s", pszTemp);
		sprintf(pszTemp, "%s    Type: %s\r\n", pszTemp, GetFormatStr(paryResult->ppBarcodes[iIndex]->llFormat));
		// printf("%s", pszTemp);
		pszTemp1 = (char*)malloc(paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
		memset(pszTemp1, 0, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength + 1);
		memcpy(pszTemp1, paryResult->ppBarcodes[iIndex]->pBarcodeData, paryResult->ppBarcodes[iIndex]->iBarcodeDataLength);
		sprintf(pszTemp, "%s    Value: %s\r\n", pszTemp, pszTemp1);
		// printf("%s", pszTemp);
		free(pszTemp1);
		// sprintf(pszTemp, "    Region: {Left: %d, Top: %d, Width: %d, Height: %d}\r\n\r\n",
		// 	paryResult->ppBarcodes[iIndex]->iLeft, paryResult->ppBarcodes[iIndex]->iTop,
		// 	paryResult->ppBarcodes[iIndex]->iWidth, paryResult->ppBarcodes[iIndex]->iHeight);
		// printf("%s", pszTemp);
		rb_ary_push(ary, rb_str_new_cstr(pszTemp));
	}

	free(pszTemp);
	DBR_FreeBarcodeResults(&paryResult);

	return ary;
}