#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
#include <mutex>
#include "LJX8_IF.h"
#include "LJX8_ErrorCode.h"
#include "LJXA_ACQ.h"
#pragma comment(lib, "winmm.lib")
using namespace std;
static LJX8IF_ETHERNET_CONFIG _ethernetConfig[MAX_LJXA_DEVICENUM];
static int _highSpeedPortNo[MAX_LJXA_DEVICENUM];
static int _imageAvailable[MAX_LJXA_DEVICENUM];
static int _lastImageSizeHeight[MAX_LJXA_DEVICENUM];
static LJXA_ACQ_GETPARAM _getParam[MAX_LJXA_DEVICENUM];
static unsigned short *_heightBuf[MAX_LJXA_DEVICENUM];
static unsigned short *_luminanceBuf[MAX_LJXA_DEVICENUM];
void myCallbackFunc(LJX8IF_PROFILE_HEADER* pProfileHeaderArray, WORD* pHeightProfileArray, WORD* pLuminanceProfileArray, DWORD dwLuminanceEnable, DWORD dwProfileDataCount, DWORD dwCount, DWORD dwNotify, DWORD dwUser);
extern "C"
{
LJXA_ACQ_API int LJXA_ACQ_OpenDevice(int lDeviceId, LJX8IF_ETHERNET_CONFIG *EthernetConfig, int HighSpeedPortNo) {
int errCode = LJX8IF_EthernetOpen(lDeviceId, EthernetConfig);
_ethernetConfig[lDeviceId] = *EthernetConfig;
_highSpeedPortNo[lDeviceId] = HighSpeedPortNo;
printf("[@(LJXA_ACQ_OpenDevice) Open device](0x%x)\n", errCode);
return errCode;
}
LJXA_ACQ_API void LJXA_ACQ_CloseDevice(int lDeviceId) {
LJX8IF_FinalizeHighSpeedDataCommunication(lDeviceId);
LJX8IF_CommunicationClose(lDeviceId);
printf("[@(LJXA_ACQ_CloseDevice) Close device]\n");
}
LJXA_ACQ_API int LJXA_ACQ_Acquire(int lDeviceId, unsigned short *heightImage, unsigned short *luminanceImage, LJXA_ACQ_SETPARAM *setParam, LJXA_ACQ_GETPARAM *getParam) {
int errCode;
int yDataNum = setParam->y_linenum;
int timeout_ms = setParam->timeout_ms;
int use_external_batchStart = setParam->use_external_batchStart;
unsigned short zUnit = 0;
_heightBuf[lDeviceId] = (unsigned short*)malloc(yDataNum * MAX_LJXA_XDATANUM * 2);
if (_heightBuf[lDeviceId] == NULL) {
return LJX8IF_RC_ERR_NOMEMORY;
}
_luminanceBuf[lDeviceId] = (unsigned short*)malloc(yDataNum * MAX_LJXA_XDATANUM * 2);
if (_luminanceBuf[lDeviceId] == NULL) {
return LJX8IF_RC_ERR_NOMEMORY;
}
errCode = LJX8IF_InitializeHighSpeedDataCommunicationSimpleArray(lDeviceId, &_ethernetConfig[lDeviceId], _highSpeedPortNo[lDeviceId], &myCallbackFunc, yDataNum, lDeviceId);
printf("[@(LJXA_ACQ_Acquire) Initialize HighSpeed](0x%x)\n", errCode);
LJX8IF_HIGH_SPEED_PRE_START_REQ startReq;
startReq.bySendPosition = 2;
LJX8IF_PROFILE_INFO profileInfo;
errCode = LJX8IF_PreStartHighSpeedDataCommunication(lDeviceId, &startReq, &profileInfo);
printf("[@(LJXA_ACQ_Acquire) PreStart](0x%x)\n", errCode);
errCode = LJX8IF_GetZUnitSimpleArray(lDeviceId, &zUnit);
if (errCode != 0 || zUnit == 0)
{
printf("Failed to acquire zunit.\n");
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
return errCode;
}
_imageAvailable[lDeviceId] = 0;
_lastImageSizeHeight[lDeviceId] = 0;
errCode = LJX8IF_StartHighSpeedDataCommunication(lDeviceId);
printf("[@(LJXA_ACQ_Acquire) Start HighSpeed](0x%x)\n", errCode);
if (use_external_batchStart > 0) {
}
else {
errCode = LJX8IF_StartMeasure(lDeviceId);
printf("[@(LJXA_ACQ_Acquire) Measure Start(Batch Start)](0x%x)\n", errCode);
}
printf(" [@(LJXA_ACQ_Acquire) acquring image...]\n");
DWORD start = timeGetTime();
while (true)
{
DWORD ts = timeGetTime() - start;
if ((DWORD)timeout_ms < ts) {
break;
}
if (_imageAvailable[lDeviceId]) break;
}
if (_imageAvailable[lDeviceId] != 1) {
printf(" [@(LJXA_ACQ_Acquire) timeout]\n");
errCode = LJX8IF_StopHighSpeedDataCommunication(lDeviceId);
printf("[@(LJXA_ACQ_Acquire) Stop HighSpeed](0x%x)\n", errCode);
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
return LJX8IF_RC_ERR_TIMEOUT;
}
printf(" [@(LJXA_ACQ_Acquire) done]\n");
errCode = LJX8IF_StopHighSpeedDataCommunication(lDeviceId);
printf("[@(LJXA_ACQ_Acquire) Stop HighSpeed](0x%x)\n", errCode);
_getParam[lDeviceId].luminance_enabled = profileInfo.byLuminanceOutput;
_getParam[lDeviceId].x_pointnum = profileInfo.wProfileDataCount;
_getParam[lDeviceId].y_linenum_acquired = _lastImageSizeHeight[lDeviceId];
_getParam[lDeviceId].x_pitch_um = profileInfo.lXPitch / 100.0f;
_getParam[lDeviceId].y_pitch_um = setParam->y_pitch_um;
_getParam[lDeviceId].z_pitch_um = zUnit / 100.0f;
*getParam = _getParam[lDeviceId];
int xDataNum = _getParam[lDeviceId].x_pointnum;
unsigned short *dwHeightBuf = (unsigned short*)&_heightBuf[lDeviceId][0];
memcpy(heightImage, dwHeightBuf, xDataNum * yDataNum * 2);
if (_getParam[lDeviceId].luminance_enabled > 0) {
unsigned short *dwLuminanceBuf = (unsigned short*)&_luminanceBuf[lDeviceId][0];
memcpy(luminanceImage, dwLuminanceBuf, xDataNum * yDataNum * 2);
}
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
return LJX8IF_RC_OK;
}
LJXA_ACQ_API int LJXA_ACQ_StartAsync(int lDeviceId, LJXA_ACQ_SETPARAM *setParam) {
int errCode;
unsigned short zUnit = 0;
int yDataNum = setParam->y_linenum;
int use_external_batchStart = setParam->use_external_batchStart;
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
_heightBuf[lDeviceId] = (unsigned short*)malloc(yDataNum * MAX_LJXA_XDATANUM * 2);
_luminanceBuf[lDeviceId] = (unsigned short*)malloc(yDataNum * MAX_LJXA_XDATANUM * 2);
if (_heightBuf[lDeviceId] == NULL) {
return LJX8IF_RC_ERR_NOMEMORY;
}
if (_luminanceBuf[lDeviceId] == NULL) {
return LJX8IF_RC_ERR_NOMEMORY;
}
errCode = LJX8IF_InitializeHighSpeedDataCommunicationSimpleArray(lDeviceId, &_ethernetConfig[lDeviceId], _highSpeedPortNo[lDeviceId], &myCallbackFunc, yDataNum, lDeviceId);
printf("[@(LJXA_ACQ_StartAsync) Initialize HighSpeed](0x%x)\n", errCode);
LJX8IF_HIGH_SPEED_PRE_START_REQ startReq;
startReq.bySendPosition = 2;
LJX8IF_PROFILE_INFO profileInfo;
errCode = LJX8IF_PreStartHighSpeedDataCommunication(lDeviceId, &startReq, &profileInfo);
printf("[@(LJXA_ACQ_StartAsync) PreStart](0x%x)\n", errCode);
errCode = LJX8IF_GetZUnitSimpleArray(lDeviceId, &zUnit);
if (errCode != 0 || zUnit == 0)
{
printf("Failed to acquire zunit.\n");
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
return errCode;
}
_imageAvailable[lDeviceId] = 0;
_lastImageSizeHeight[lDeviceId] = 0;
errCode = LJX8IF_StartHighSpeedDataCommunication(lDeviceId);
printf("[@(LJXA_ACQ_StartAsync) Start HighSpeed](0x%x)\n", errCode);
if (use_external_batchStart > 0) {
}
else {
errCode = LJX8IF_StartMeasure(lDeviceId);
printf("[@(LJXA_ACQ_StartAsync) Measure Start(Batch Start)](0x%x)\n", errCode);
}
_getParam[lDeviceId].luminance_enabled = profileInfo.byLuminanceOutput;
_getParam[lDeviceId].x_pointnum = profileInfo.wProfileDataCount;
_getParam[lDeviceId].x_pitch_um = profileInfo.lXPitch / 100.0f;
_getParam[lDeviceId].y_pitch_um = setParam->y_pitch_um;
_getParam[lDeviceId].z_pitch_um = zUnit / 100.0f;
return LJX8IF_RC_OK;
}
LJXA_ACQ_API int LJXA_ACQ_AcquireAsync(int lDeviceId, unsigned short *heightImage, unsigned short *luminanceImage, LJXA_ACQ_SETPARAM *setParam, LJXA_ACQ_GETPARAM *getParam) {
int errCode;
int yDataNum = setParam->y_linenum;
if (_heightBuf[lDeviceId] == NULL || _luminanceBuf[lDeviceId] == NULL) {
return LJX8IF_RC_ERR_NOMEMORY;
}
if (_imageAvailable[lDeviceId] != 1) {
return LJX8IF_RC_ERR_TIMEOUT;
}
printf(" [@(LJXA_ACQ_AcquireAsync) done]\n");
errCode = LJX8IF_StopHighSpeedDataCommunication(lDeviceId);
printf("[@(LJXA_ACQ_AcquireAsync) Stop HighSpeed](0x%x)\n", errCode);
_getParam[lDeviceId].y_linenum_acquired = _lastImageSizeHeight[lDeviceId];
*getParam = _getParam[lDeviceId];
int xDataNum = _getParam[lDeviceId].x_pointnum;
unsigned short *dwHeightBuf = (unsigned short*)&_heightBuf[lDeviceId][0];
memcpy(heightImage, dwHeightBuf, xDataNum*yDataNum * 2);
if (_getParam[lDeviceId].luminance_enabled > 0) {
unsigned short *dwLuminanceBuf = (unsigned short*)&_luminanceBuf[lDeviceId][0];
memcpy(luminanceImage, dwLuminanceBuf, xDataNum * yDataNum * 2);
}
if (_heightBuf[lDeviceId] != NULL) {
free(_heightBuf[lDeviceId]);
}
if (_luminanceBuf[lDeviceId] != NULL) {
free(_luminanceBuf[lDeviceId]);
}
return LJX8IF_RC_OK;
}
}
mutex mtx;
void myCallbackFunc(LJX8IF_PROFILE_HEADER * pProfileHeaderArray, WORD * pHeightProfileArray, WORD * pLuminanceProfileArray, DWORD dwLuminanceEnable, DWORD dwProfileDataCount, DWORD dwCount, DWORD dwNotify, DWORD dwUser)
{
if ((dwNotify != 0) || (dwNotify & 0x10000) != 0) return;
if (dwCount == 0) return;
if (_imageAvailable[dwUser] == 1) return;
lock_guard<mutex> lock(mtx);
memcpy(&_heightBuf[dwUser][0], pHeightProfileArray, dwProfileDataCount * dwCount * 2);
if (dwLuminanceEnable == 1)
{
memcpy(&_luminanceBuf[dwUser][0], pLuminanceProfileArray, dwProfileDataCount * dwCount * 2);
}
_imageAvailable[dwUser] = 1;
_lastImageSizeHeight[dwUser] = dwCount;
}