#define _WIN32_DCOM
#include <SDKDDKVer.h>
#include <direct.h>
#include <thr/threads.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <tchar.h>
#include <io.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "..\..\lib\libcii\cii11\include\libcii.h"
#include "algo.h" extern TCHAR tcLogFile[];
//
#ifdef UNICODE
#define __FILET__ __FILEW__
#define __FUNCTIONT__ __FUNCTIONW__
#else
#define __FILET__ __FILE__
#define __FUNCTIONT__ __FUNCTION__
#endif
#define TRACE_OUT(out ,fmt,...) do{TCHAR tcDate[24],tcTime[24];_tstrdate_s(tcDate),_tstrtime_s(tcTime);\
_ftprintf_s(out, _T(" %s %s - FILE:%s - FUN:%s - LINE:%d \r\n MESSAGE: ") fmt _T("\r\n")\
,tcDate,tcTime,__FILET__,__FUNCTIONT__,__LINE__, ##__VA_ARGS__); } while ()
//
#define TRACE_LOG(fmt,...) do{ FILE* stream ; TRACE_OUT(stderr, fmt , ##__VA_ARGS__); \
if( != _tfopen_s(&stream,tcLogFile,_T("a"))) break; \
TRACE_OUT(stream, fmt , ##__VA_ARGS__); \
fclose(stream); \
} while() #import <IsVision_9007\ISCFaceRecognize.dll> no_namespace
#import <IsVision_9007\ISCFaceDetect.dll> no_namespace
#import <IsVision_9007\ISCFaceRectify.dll> no_namespace
#import <IsVision_9007\ISCFaceTools.dll> no_namespace
#import <IsVision_9007\ISCFaceTracking.dll> no_namespace
#import <IsVision_9007\ISCImageProc.dll> no_namespace
#import <IsVision_9007\ISCImageQuality.dll> no_namespace
#import <IsVision_9007\ISXImage.dll> no_namespace
#import <IsVision_9007\ISCFaceMedia.dll> no_namespace #ifdef __cplusplus
typedef struct Algo_T * LpAlgo_T;
typedef struct Args_T * LpArgs_T;
typedef struct Pipe_T * LpPipe_T;
typedef struct Item_T * LpItem_T;
#define T LpAlgo_T
#define R LpArgs_T
#define P LpPipe_T
#define I LpItem_T
#else
#define T Arena_T
#define R Args_T
#define P Pipe_T
typedef struct Algo_T *Algo_T;
typedef struct Args_T *Args_T;
typedef struct Pipe_T *Pipe_T;
#endif #define _CT_FileName_ 0x01
#define _CT_FileData_ 0x02
#define _CT_ImageRgb_ 0x03 #define _IRecognize 0x0001
#define _ITransImage 0x0002
#define _IFaceDetect 0x0004
#define _IFaceRectify 0x0008
#define _IFaceTool 0x0010
#define _IFaceTrack 0x0020
#define _IImageProc 0x0040
#define _IImageQuality 0x0080
#define _IVisionImage 0x0100
#define _IPosition 0x0200
#define _IComImageAll 0x01FF #ifndef _THR_THREADS_H
#define mtx_init(mtx, typ) InitializeSRWLock(mtx)
#define mtx_destroy(mtx) __noop
#define mtx_lock(mtx) AcquireSRWLockExclusive (mtx)
#define mtx_unlock(mtx) ReleaseSRWLockExclusive (mtx);
#define cnd_init(cnd) InitializeConditionVariable(cnd);
#define cnd_destroy(cnd) __noop
#define cnd_signal(cnd) WakeConditionVariable(cnd)
#define cnd_wait(cnd, mtx) SleepConditionVariableSRW(cnd, mtx, INFINITE, 0)
#define mtx_t_ SRWLOCK
#define cnd_t_ CONDITION_VARIABLE
#else
#define mtx_t_ mtx_t
#define cnd_t_ cnd_t
#endif
#define NUMBER_ALGO 7
#define NUMBER_ITEM 7 struct Global_T
{
long nNumberCpu;
};
static volatile struct Global_T _global;
TCHAR tcLogFile[];
struct Args_T
{
enumTemplateType eTemplateType;
PTP_WORK pwkNewTemplate;
_TCHAR tcIniFile[];
_TCHAR tcSN[];
_TCHAR tcLicense[];
long lTemplateSize; int iNetLogin;
int used;
int total;
T* algo;
SRWLOCK srw_;
static mtx_t_ mtx_;
static long once;
static long count_ref;
};
mtx_t_ Args_T::mtx_;
long Args_T::once = 0L;
long Args_T::count_ref = 0L;
//
struct Algo_T
{
IRecognizePtr m_IRecognize;
ITransImagePtr m_ITransImage;
IDetectPtr m_pIDetect;
IFaceRectifyPtr m_pFaceRectify;
IFaceToolsPtr m_pIFaceTool;
IFaceTrackingPtr m_pIFaceTrack;
IImageProcPtr m_pIImageProc;
IImageQualityPtr m_pIImageQuality;
IVisionImagePtr m_pIVisionImage;
IPositionPtr m_pIPosition;
unsigned long nIptrFlag;
R m_lpArgs;
};
typedef struct Data_T *LpData_T;
typedef struct Pipe_T
{
LpData_T* ptr;
size_t length;
size_t used;
size_t iget;
size_t iput;
mtx_t_ _mtx;
cnd_t_ _cndr;
cnd_t_ _cndw;
}* LpPipe_T;
enum eOptType{ eNewTemplate, eNewTemplate2, eCmprTemplate ,eNullOpt };
struct Item_T
{
T cl;
eOptType opt;
HANDLE event;
LpPipe_T pipe;
LpPipe_T pipe2;
long ref_count;
long ref_signal;
long num_thread;
long seq;
bool result;
static long ref_selfbuf;
static I selfbuf[NUMBER_ITEM];
//
union
{
struct
{
const char* srcpath;
const char* wildcard;
const char* dstfile;
}ready;
struct
{
unsigned char** img;
long* length;
long size;
long size2;
const char* imgtype;
unsigned char** tmp;
}ready2;
};
void* pvResult;
LpList_T list;
SRWLOCK mtx_;
};
long Item_T::ref_selfbuf;
I Item_T::selfbuf[NUMBER_ITEM];
struct Data_T
{
union
{
struct
{
char* file;
}result;
struct
{
unsigned char** img;
long* length;
long size;
const char* imgtype;
long pos;
}result2;
};
void* pvResult;
struct
{
double simi;
long seq;
long size;
}vTemplate;
eOptType opt;
};
static P Pipe_new(size_t length)
{
P pi = (P)malloc(sizeof *pi);
assert(pi);
mtx_init(&pi->_mtx, _Mtx_plain);
cnd_init(&pi->_cndr);
cnd_init(&pi->_cndw);
pi->ptr = (LpData_T*)calloc(length, sizeof LpData_T );
assert(pi->ptr);
pi->length = length;
pi->used = ;
pi->iget = ;
pi->iput = ;
return pi;
}
static void Pipe_put(P pi, LpData_T ptr)
{
assert(pi);
mtx_lock(&pi->_mtx);
while (pi->used >= pi->length)
{
cnd_wait(&pi->_cndr, &pi->_mtx);
}
pi->ptr[pi->iput++] = ptr;
++pi->used;
if (pi->iput >= pi->length)
{
pi->iput = ;
}
cnd_signal(&pi->_cndw);
mtx_unlock(&pi->_mtx);
}
static void Pipe_get(P pi, LpData_T* ptr)
{
assert(pi);
mtx_lock(&pi->_mtx);
while (pi->used <= )
{
cnd_wait(&pi->_cndw, &pi->_mtx);
}
--pi->used;
*ptr = pi->ptr[pi->iget++];
if (pi->iget >= pi->length)
{
pi->iget = ;
}
cnd_signal(&pi->_cndr);
mtx_unlock(&pi->_mtx);
}
static void Pipe_free(P* pi)
{
assert(pi && *pi);
assert((*pi)->ptr);
free((*pi)->ptr);
mtx_destroy(&(*pi)->_mtx);
cnd_destroy(&(*pi)->_cndr);
cnd_destroy(&(*pi)->_cndw);
free(*pi);
(*pi) = nullptr;
}
static R Args_new()
{
static R ag = nullptr;
if ( == InterlockedCompareExchange(&ag->once, 1L, 0L))
{
ag = (R)malloc( sizeof *ag );
ag->count_ref = 0L;
ag->pwkNewTemplate = nullptr;// CreateThreadpoolWork(__ThreadCreateTemplate, ag, NULL);
InitializeSRWLock(&ag->srw_);
mtx_init(&ag->mtx_, _Mtx_plain);
{
TCHAR tcFileName[], tcModuleFile[MAX_PATH];
SYSTEM_INFO _syInfo;
GetSystemInfo(&_syInfo);
_global.nNumberCpu = _syInfo.dwNumberOfProcessors;
GetModuleFileName(NULL, tcModuleFile, MAX_PATH);
_tsplitpath_s(tcModuleFile, NULL, , NULL, , tcFileName, , NULL, );
_tmakepath_s(ag->tcIniFile, , NULL, NULL, tcFileName, _T("ini"));
_tmakepath_s(tcLogFile, , NULL, NULL, tcFileName, _T("log"));
if (_taccess_s(ag->tcIniFile, 0x04) == )
{
GetPrivateProfileString(_T("Register"), _T("sn"), _T(""), ag->tcSN, _countof(ag->tcSN), ag->tcIniFile);
GetPrivateProfileString(_T("Register"), _T("license"), _T(""), ag->tcLicense, _countof(ag->tcLicense), ag->tcIniFile);
ag->iNetLogin = GetPrivateProfileInt(_T("Register"), _T("netlogin"), , ag->tcIniFile);
ag->eTemplateType = (enumTemplateType)GetPrivateProfileInt(_T("Parameters"), _T("TemplateType"), , ag->tcIniFile);
}
else
{
ag->iNetLogin = ;
ag->eTemplateType = (enumTemplateType);
_tcscpy_s(ag->tcSN, _T(""));
_tcscpy_s(ag->tcLicense, _T(""));
}
}
ag->total = _global.nNumberCpu;
ag->used = ;
ag->algo = (T*)malloc(ag->total * sizeof T);
_tprintf(_T("+++++++++++++++++++++++++++++++++++++++++++++++++++++++Args_new.\r\n"));
}
InterlockedIncrement(&ag->count_ref);
return ag;
}
static T Algo_get(R ag)
{
T al;
mtx_lock(&ag->mtx_);
if (ag->used > )
al = ag->algo[--ag->used];
else
al = nullptr;
mtx_unlock(&ag->mtx_);
return al;
}
static bool Algo_put(T al)
{
R ag = al->m_lpArgs;
mtx_lock(&ag->mtx_);
if (ag->used < ag->total && ag->count_ref > )
ag->algo[ag->used++] = al;
else
al = nullptr;
mtx_unlock(&ag->mtx_);
return al != nullptr;
}
static I Item_get()
{
I im = nullptr;
mtx_lock(&Args_T::mtx_);
if (Item_T::ref_selfbuf > )
{
im = Item_T::selfbuf[--Item_T::ref_selfbuf];
im->ref_count = ;
im->seq = ;
im->cl = nullptr;
im->result = false;
im->pipe->used = ;
im->pipe->iget = ;
im->pipe->iput = ;
im->pipe2->used = ;
im->pipe2->iget = ;
im->pipe2->iput = ;
}
else
im = nullptr;
mtx_unlock(&Args_T::mtx_);
return im;
}
static bool Item_put(I im)
{
mtx_lock(&Args_T::mtx_);
if (Item_T::ref_selfbuf < NUMBER_ITEM && Args_T::count_ref > )
Item_T::selfbuf[Item_T::ref_selfbuf++] = im;
else
im = nullptr;
mtx_unlock(&Args_T::mtx_);
return im != nullptr;
}
static void Item_free(I *im)
{
assert(im && *im);
if (!Item_put(*im))
{
CloseHandle((*im)->event);
Pipe_free(&(*im)->pipe);
Pipe_free(&(*im)->pipe2);
free(*im);
(*im) = nullptr;
}
}
static I Item_new()
{
I im = Item_get();
if (nullptr == im)
{
im = (I)malloc(sizeof *im);
im->ref_count = ;
im->seq = ;
im->cl = nullptr;
im->result = false;
InitializeSRWLock(&im->mtx_);
im->pipe = Pipe_new();
im->pipe2 = Pipe_new();
im->event = CreateEvent(NULL, FALSE, FALSE, NULL);
}
return im;
}
static void Args_free(R* ag)
{
long ref;
assert(ag && *ag);
ref = InterlockedDecrement(&(*ag)->count_ref);
if (ref == )
{
T al;// this code is not excute
I im;
assert(ref == );
InterlockedExchange(&(*ag)->once, 0L);
while (al = Algo_get(*ag))
{
Algo_free(&al);
}
while (im = Item_get())
{
Item_free(&im);
}
mtx_destroy(&(*ag)->mtx_);
free((*ag)->algo);
free(*ag);
(*ag) = nullptr;
_tprintf(_T("-------------------------------------------------------Args_free.\r\n"));
}
}
T Algo_new()
{
R ag = Args_new();
T al = Algo_get(ag);
if (!al)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_SPEED_OVER_MEMORY);
al = new Algo_T;
al->nIptrFlag = 0UL;
al->m_lpArgs = ag;
}
assert(al);
return al;
}
static bool NewTemplateFile( const char* filename)
{
size_t len;
if ( == _access(filename, 0x06))
{
return true;
}
if ( < (len = strlen(filename)))
{
char* tmpbuf, *p, c;
tmpbuf = (char*)malloc(len + );
strcpy_s(tmpbuf, len + , filename);
for (p = tmpbuf; *p; ++p)
{
if ('\\' != *p && '/' != *p)
{
continue;
}
c = *++p;
*p = '\0';
if ((_access(tmpbuf, )) != )
{
if ( != _mkdir(tmpbuf))
{
break;
}
}
*p = c;
}
{
bool bret;
FILE* file;
bret = ( == _tfopen_s(&file, tmpbuf, _T("a")));
free(tmpbuf);
fclose(file);
return bret;
}
}
else
return false;
}
static bool IsMatched(CONST TCHAR* p, CONST TCHAR* q)
{
CONST TCHAR *r, *z, *x = _T("");
for (r = p; *p; ++p)
if (*p == '\\')
r = p + ;
else if (*p == '.')
x = p;
z = r;
while (*q)
{
while (*q == '|')q++;
if (*q == '*')
{
r = x;
while (*++q != '.' && *q);
}
while (tolower(*q) == tolower(*r) && *r) r++, q++;
if (*q == '*' || !*r && (!*q || *q == '|'))
{
return true;
}
while (*q != '|' && *q)++q;
r = z;
}
return false;
}
static void FetchFile(TCHAR* tcFile, size_t nChars, CONST TCHAR* tcWard, P pi)
{
_tfinddata_t _tfddt;
intptr_t intptr = _tfindfirst(tcFile, &_tfddt);
if (- == intptr)
{
return;
}
do
{
tcFile[nChars] = '\0';
if (_tfddt.attrib & _A_SUBDIR )
{
if (_tfddt.name[] != '.')
{
_tcscat_s(tcFile, MAX_PATH, _tfddt.name);
_tcscat_s(tcFile, MAX_PATH, _T("\\"));
_tcscat_s(tcFile, MAX_PATH, _T("*.*"));
FetchFile(tcFile, nChars + + _tcslen(_tfddt.name), tcWard, pi);
}
}
else if (IsMatched(_tfddt.name, tcWard))
{
LpData_T ptr = (LpData_T)malloc(sizeof(*ptr));
size_t length = nChars + _tcslen(_tfddt.name) + ;
ptr->result.file = new char[length];// (_TCHAR*)malloc( length * sizeof _TCHAR);
_tcscat_s(tcFile, MAX_PATH, _tfddt.name);
_tcscpy_s(ptr->result.file, length, tcFile);
ptr->opt = eNewTemplate;
Pipe_put(pi, ptr);
}
} while ( == _tfindnext(intptr, &_tfddt));
_findclose(intptr);
}
static void GetSubDir(CONST TCHAR* tcFile, CONST TCHAR *tcWard, P pi)
{
TCHAR tcFileName[MAX_PATH], *pEnd;
//if (_taccess_s(ag->tcIniFile, 0x04) == 0)
//
struct stat s_buf;
stat(tcFile, &s_buf); /*判断输入的文件路径是否目录,若是目录,则往下执行,分析目录下的文件*/
if ( s_buf.st_mode&_S_IFDIR)
{
_tcscpy_s(tcFileName, tcFile);
(pEnd = _tcsrchr(tcFileName, '\\'))[] = '\0';
_tcscat_s(tcFileName, _T("*.*"));
FetchFile(tcFileName, pEnd - tcFileName + , tcWard, pi);
}
else if (s_buf.st_mode&_S_IFREG)
{
TCHAR tcFileExt[];
_tsplitpath_s(tcFile, NULL, , NULL, , tcFileName, MAX_PATH, tcFileExt, );
_tmakepath_s(tcFileName, MAX_PATH, NULL, NULL, tcFileName, tcFileExt);
if (IsMatched(tcFileName, tcWard))
{
LpData_T ptr = (LpData_T)malloc(sizeof(*ptr));
ptr->result.file = new char[MAX_PATH];
_tcscpy_s(ptr->result.file, MAX_PATH, tcFile);
ptr->opt = eNewTemplate;
Pipe_put(pi, ptr);
}
}
Pipe_put(pi, nullptr);
}
static void ComObjectInstance(T al, unsigned long nIptrFlag)
{
HRESULT hr;
assert(al);
if ((nIptrFlag & _IRecognize) && !(_IRecognize & al->nIptrFlag))
{
al->nIptrFlag &= ~_IRecognize;
if (FAILED(hr = al->m_IRecognize.CreateInstance(__uuidof(Recognize))))
{
TRACE_LOG(_T("_IRecognize接口创建失败:%#08x"), hr);
}
else if (FAILED(hr = al->m_IRecognize->SetModelType((enumFrameModelType)al->m_lpArgs->eTemplateType)))
{
TRACE_LOG(_T("_IRecognize::SetModelType:ErrCode = %d"), al->m_IRecognize->GetLastError());
}
else
{
if (al->m_lpArgs->iNetLogin && al->m_IRecognize->Initialize(VARIANT_TRUE) == VARIANT_TRUE
|| !al->m_lpArgs->iNetLogin
&& ((( == _tcslen(al->m_lpArgs->tcSN) || == _tcslen(al->m_lpArgs->tcLicense))
&& al->m_IRecognize->Initialize(VARIANT_FALSE) == VARIANT_TRUE) || al->m_IRecognize->SetRegisteredInfo(_bstr_t(al->m_lpArgs->tcSN), _bstr_t(al->m_lpArgs->tcLicense)) == VARIANT_TRUE))
{
al->nIptrFlag |= _IRecognize;
al->m_lpArgs->lTemplateSize = al->m_IRecognize->GetTemplateSize(al->m_lpArgs->eTemplateType);
TRACE_LOG(_T("_IRecognize:GetVersion() = %s,_IRecognize::GetTemplateSize() = %d"), (const char*)al->m_IRecognize->GetVersion(), al->m_lpArgs->lTemplateSize);
}
else
{
TRACE_LOG(_T("_IRecognize接口初始化失败:ErrCode = %d"), al->m_IRecognize->GetLastError());
}
}
}
if ((nIptrFlag & _ITransImage) && !(_ITransImage & al->nIptrFlag))
{
if (FAILED(hr = al->m_ITransImage.CreateInstance(__uuidof(TransImage))))
{
TRACE_LOG(_T("_ITransImage接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_ITransImage;
}
else
{
al->nIptrFlag |= _ITransImage;
TRACE_LOG(_T("_ITransImage:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IFaceDetect) && !(_IFaceDetect & al->nIptrFlag))
{
al->nIptrFlag &= ~_IFaceDetect;
if (FAILED(hr = al->m_pIDetect.CreateInstance(__uuidof(Detect))))
{
TRACE_LOG(_T("_IFaceDetect接口创建失败:%#08x"), hr);
}
else
{
if (al->m_lpArgs->iNetLogin && al->m_pIDetect->Initialize(VARIANT_TRUE) == VARIANT_TRUE
|| !al->m_lpArgs->iNetLogin
&& ((( == _tcslen(al->m_lpArgs->tcSN) || == _tcslen(al->m_lpArgs->tcLicense))
&& al->m_pIDetect->Initialize(VARIANT_FALSE) == VARIANT_TRUE) || al->m_pIDetect->SetRegisteredInfo(_bstr_t(al->m_lpArgs->tcSN), _bstr_t(al->m_lpArgs->tcLicense)) == VARIANT_TRUE))
{
al->nIptrFlag |= _IFaceDetect;
TRACE_LOG(_T("_IFaceDetect:GetVersion() = %s"), (const char*)al->m_pIDetect->GetVersion());
}
else
{
TRACE_LOG(_T("_IFaceDetect接口初始化失败:ErrCode = %d"), al->m_pIDetect->GetLastError());
}
}
}
if ((nIptrFlag & _IFaceRectify) && !(_IFaceRectify & al->nIptrFlag))
{
if (FAILED(hr = al->m_pFaceRectify.CreateInstance(__uuidof(FaceRectify))))
{
TRACE_LOG(_T("_IFaceRectify接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IFaceRectify;
}
else
{
al->nIptrFlag |= _IFaceRectify;
TRACE_LOG(_T("_IFaceRectify:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IFaceTool) && !(_IFaceTool & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIFaceTool.CreateInstance(__uuidof(FaceTools))))
{
TRACE_LOG(_T("_IFaceTool接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IFaceTool;
}
else
{
al->nIptrFlag |= _IFaceTool;
TRACE_LOG(_T("_IFaceTool:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IFaceTrack) && !(_IFaceTrack & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIFaceTrack.CreateInstance(__uuidof(FaceTracking))))
{
TRACE_LOG(_T("_IFaceTrack接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IFaceTrack;
}
else
{
al->nIptrFlag |= _IFaceTrack;
TRACE_LOG(_T("_IFaceTrack:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IImageProc) && !(_IImageProc & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIImageProc.CreateInstance(__uuidof(ImageProc))))
{
TRACE_LOG(_T("_IImageProc接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IImageProc;
}
else
{
al->nIptrFlag |= _IImageProc;
TRACE_LOG(_T("_IImageProc:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IImageQuality) && !(_IImageQuality & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIImageQuality.CreateInstance(__uuidof(ImageQuality))))
{
TRACE_LOG(_T("_IImageQuality接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IImageQuality;
}
else
{
al->nIptrFlag |= _IImageQuality;
TRACE_LOG(_T("_IImageQuality:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IVisionImage) && !(_IVisionImage & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIVisionImage.CreateInstance(__uuidof(VisionImage))))
{
TRACE_LOG(_T("_IFaceTrack接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IVisionImage;
}
else
{
al->nIptrFlag |= _IVisionImage;
TRACE_LOG(_T("_IFaceTrack:CreateInstance Finished."));
}
}
if ((nIptrFlag & _IPosition) && !(_IPosition & al->nIptrFlag))
{
if (FAILED(hr = al->m_pIPosition.CreateInstance(__uuidof(Position))))
{
TRACE_LOG(_T("_IPosition接口创建失败:%#08x"), hr);
al->nIptrFlag &= ~_IPosition;
}
else
{
al->nIptrFlag |= _IPosition;
}
}
}
static void ComObjectRelease(T al, unsigned long nIptrFlag)
{
if ((nIptrFlag & _IRecognize) && (_IRecognize & al->nIptrFlag))
{
al->m_IRecognize->Uninitialize();
al->m_IRecognize.Release();
al->nIptrFlag &= ~_IRecognize;
}
if ((nIptrFlag & _ITransImage) && (_ITransImage & al->nIptrFlag))
{
al->m_ITransImage.Release();
al->nIptrFlag &= ~_ITransImage;
}
if ((nIptrFlag & _IFaceDetect) && (_ITransImage & al->nIptrFlag))
{
al->m_pIDetect->Uninitialize();
al->m_pIDetect.Release();
al->nIptrFlag &= ~_IFaceDetect;
}
if ((nIptrFlag & _IFaceRectify) && (_ITransImage & al->nIptrFlag))
{
al->m_pFaceRectify.Release();
al->nIptrFlag &= ~_IFaceRectify;
}
if ((nIptrFlag & _IFaceTool) && (_ITransImage & al->nIptrFlag))
{
al->m_pIFaceTool->Uninitialize();
al->m_pIFaceTool.Release();
al->nIptrFlag &= ~_IFaceTool;
}
if ((nIptrFlag & _IFaceTrack) && (_ITransImage & al->nIptrFlag))
{
al->m_pIFaceTrack.Release();
al->nIptrFlag &= ~_IFaceTrack;
}
if ((nIptrFlag & _IImageProc) && (_ITransImage & al->nIptrFlag))
{
al->m_pIImageProc.Release();
al->nIptrFlag &= ~_IImageProc;
}
if ((nIptrFlag & _IImageQuality) && (_ITransImage & al->nIptrFlag))
{
al->m_pIImageQuality->Uninitialize();
al->m_pIImageQuality.Release();
al->nIptrFlag &= ~_IImageQuality;
}
if ((nIptrFlag & _IVisionImage) && (_ITransImage & al->nIptrFlag))
{
al->m_pIVisionImage.Release();
al->nIptrFlag &= ~_IVisionImage;
}
if ((nIptrFlag & _IPosition) && (_IPosition & al->nIptrFlag))
{
al->m_pIPosition.Release();
al->nIptrFlag &= ~_IPosition;
}
}
static long Algo_create_template(T al, char* lpData, unsigned char** ppTemplate, int *iTemplateSize, int DataType, long Datalength)
{
unsigned char* pTemplate;
assert(al && lpData && ppTemplate);
if (!(al->nIptrFlag & _ITransImage))
{
ComObjectInstance(al, _ITransImage);
}
if (!(al->nIptrFlag & _ITransImage))
{
return (-);
}
if (!(al->nIptrFlag & _IFaceDetect))
{
ComObjectInstance(al, _IFaceDetect);
}
if (!(al->nIptrFlag & _IFaceDetect))
{
return (-);
}
if (!(al->nIptrFlag & _IPosition))
{
ComObjectInstance(al, _IPosition);
}
if (!(al->nIptrFlag & _IPosition))
{
return (-);
}
switch (DataType)
{
case _CT_FileName_:
if (VARIANT_TRUE != al->m_ITransImage->ReadImageFile(_bstr_t(lpData), enumFileType::TRANS_FILE_TYPE_UNKNOWN))
{
TRACE_LOG(_T("加载图像文件失败, ErrCode = %d"), GetLastError());
return (-);
}
break;
case _CT_FileData_:
if (VARIANT_TRUE != al->m_ITransImage->ReadImageData((unsigned char*)lpData, Datalength, enumFileType::TRANS_FILE_TYPE_UNKNOWN))
{
TRACE_LOG(_T("加载图像文件失败, ErrCode = %d"), GetLastError());
return (-);
}
break;
case _CT_ImageRgb_:
default:
TRACE_LOG(_T("建模数据源类型不明确!"));
return (-);
}
al->m_pIPosition->Clear();
if (VARIANT_TRUE != al->m_pIDetect->FindFace(al->m_ITransImage, al->m_pIPosition))
{
TRACE_LOG(_T("检测人脸失败, ErrCode = %d"), al->m_pIDetect->GetLastError());
return (-);
}
*iTemplateSize = Algo_template_size(al);
if (*iTemplateSize < )
{
return (-);
}
pTemplate = new unsigned char[*iTemplateSize * al->m_pIPosition->GetlFaceNum()];
if (VARIANT_TRUE != al->m_IRecognize->CreateTemplate(al->m_ITransImage, al->m_pIPosition
, enumTemplateType::TEMPLATE_TYPE_GENERAL, al->m_pIPosition->GetlFaceNum(), pTemplate))
{
TRACE_LOG(_T("创建模版失败, ErrCode = %d"), al->m_IRecognize->GetLastError());
delete[] pTemplate;
return (-);
}
*ppTemplate = pTemplate;
return al->m_pIPosition->GetlFaceNum();
}
static long Algo_create_template(T al, const char* lpFile, unsigned char** ppTemplate, int *iTemplateSize)
{
return Algo_create_template(al, const_cast<char*>(lpFile), ppTemplate, iTemplateSize, _CT_FileName_, );
}
//#define _tprintf
static void __stdcall __TrySubmitCompareTemplate(
PTP_CALLBACK_INSTANCE instance,
PVOID pvctx)
{
I im = (I)pvctx;
T al = Algo_new();
R ag = al->m_lpArgs;
P in = im->pipe;
P out = im->pipe2;
LpData_T ptr = nullptr;
LpData_T ptr2 = nullptr;
eOptType eOpt = im->opt;
PSRWLOCK mtx_ = &im->cl->m_lpArgs->srw_;
unsigned char *pTemplate = nullptr;
unsigned char **tmpbuf, **vtmp, *tmp, **vtmp2;
double *simibuf;
long i, j, k, size, size2, pos, *length;
bool result = im->result;
long seq = InterlockedIncrement(&im->seq);
CallbackMayRunLong(instance);
for (;;)
{
Pipe_get(in, &ptr);
if (ptr == nullptr)
{
Pipe_put(in, nullptr); //_tprintf(_T("ptr %d == nullptr\r\n"),i);
if (result)
{
Pipe_put(out, nullptr);
}
break;
}
vtmp = ptr->result2.img;
vtmp2 = im->ready2.tmp;
size = ptr->result2.size;
size2 = im->ready2.size2;
pos = ptr->result2.pos;
simibuf = &((double*)im->pvResult)[pos];
for (i = , k = ; i < size; ++i)
{
tmpbuf = &vtmp[pos + i];
pTemplate = tmpbuf[];
for (j = ; j < size2; ++j, ++k)
{
tmp = vtmp2[j];
simibuf[k] = k;
#ifndef _DEBUG
al->m_IRecognize->CompareTemplate(pTemplate, tmp, );
#endif
// printf("simibuf[%d]= %f\r\n",k+pos, simibuf[k]);
}
}
if (result)
{ }
else
{ free(ptr);
}
}
Algo_free(&al);
assert(im->ref_signal >= );
if (InterlockedDecrement(&im->ref_signal) == )
{
SetEventWhenCallbackReturns(instance, im->event);
//_tprintf(_T("%s: SetEventWhenCallbackReturns\r\n"), __FUNCTION__);
}
//_tprintf(_T("%s[%d] - Type[%d] :Exit\r\n"), __FUNCTION__,seq, im->opt);
}
static void __stdcall __TrySubmitCreateTemplate(
PTP_CALLBACK_INSTANCE instance,
PVOID pvctx)
{
I im = (I)pvctx;
T al = Algo_new();
R ag = al->m_lpArgs;
P in = im->pipe, out = im->pipe2;
LpData_T ptr = nullptr;
LpData_T ptr2 = nullptr;
eOptType eOpt = im->opt;
PSRWLOCK mtx_ = &ag->srw_;
unsigned char *pTemplate = nullptr;
int iTemplateSize = ;
bool result = im->result;
long seq = InterlockedIncrement(&im->seq);
CallbackMayRunLong(instance);
for (;;)
{
Pipe_get(in, &ptr);
if (ptr == nullptr)
{
Pipe_put(in, nullptr); //_tprintf(_T("ptr %d == nullptr\r\n"),i);
if (result)
{
Pipe_put(out, nullptr);
}
break;
}
switch (eOpt)
{
case eNewTemplate:
{
LpList_T *list = &im->list;
char* file = ptr->result.file;
#ifndef _DEBUG
Algo_create_template(al,file , &pTemplate, &iTemplateSize);
#else
_tprintf(_T(" %s iTemplateSize %d\r\n"), file,iTemplateSize);
pTemplate = (unsigned char *)ptr->result.file;
#endif
if (result)
{
ptr->pvResult = pTemplate;
Pipe_put(out, ptr);
}
else
{
AcquireSRWLockExclusive(mtx_);
*list = List_push(*list, pTemplate);
*list = List_push(*list, file);
ReleaseSRWLockExclusive(mtx_);
free(ptr);
}
}
break;
case eNewTemplate2:
{
unsigned char **r_pvbuf, **pvTemplate, **img = ptr->result2.img;
const char* imgtype = ptr->result2.imgtype;
long* length = ptr->result2.length, size = ptr->result2.size;
long pos = ptr->result2.pos, i = ;
pvTemplate = &((unsigned char **)im->pvResult)[pos];
for (; i < size; ++i)
{
r_pvbuf = &img[i];
#ifndef _DEBUG
Algo_create_template(al, (char *)r_pvbuf[],&pTemplate, &iTemplateSize, _CT_FileData_, length[i]);
#else
pTemplate = r_pvbuf[];
#endif
pvTemplate[i] = pTemplate;
}
if (result)
{
ptr->vTemplate.seq = pos;
ptr->vTemplate.size = size;
ptr->pvResult = pvTemplate;
Pipe_put(out, ptr);
}
else
{
free(ptr);
}
}
default:
break;
}//switch
}// for
assert(im->ref_signal >= );
Algo_free(&al);
if (InterlockedDecrement(&im->ref_signal) == )
{
SetEventWhenCallbackReturns(instance, im->event);
// _tprintf(_T("______________________ SetEventWhenCallbackReturns[%d]:Exit\r\n"),seq);
}
// _tprintf(_T("__ThreadCreateTemplate[%d]:Exit\r\n"), seq);
}
static void __stdcall __TrySubmitResultThread(
PTP_CALLBACK_INSTANCE instance,
PVOID pvctx)
{
I im = (I)pvctx;
P pi = im->pipe2;
T al = im->cl;
eOptType eOpt = im->opt;
LpData_T ptr = nullptr;
PSRWLOCK mtx_ = &al->m_lpArgs->srw_;
unsigned char *pTemplate = nullptr;
long seq = InterlockedIncrement(&im->seq);
CallbackMayRunLong(instance);
switch (seq)
{
case :
for (;;)
{
Pipe_get(pi, &ptr);
if (ptr == nullptr)
{
Pipe_put(pi, nullptr);
break;
}
switch (eOpt)
{
case eNewTemplate:
{
LpList_T *list = &im->list;
AcquireSRWLockExclusive(mtx_);
*list = List_push(*list, ptr->pvResult);
*list = List_push(*list, ptr->result.file);
ReleaseSRWLockExclusive(mtx_);
}break;
case eNewTemplate2:
{
unsigned char **pvTemplate = (unsigned char **)im->pvResult;
//
}break;
case eCmprTemplate:
{
double *vsimi = (double *)im->pvResult;
vsimi[ptr->vTemplate.seq] = ptr->vTemplate.simi;
}
default:
break;
} // switch
free(ptr);
} // for
default:
break;
} // switch
assert(im->ref_signal >= );
if (InterlockedDecrement(&im->ref_signal) == )
{
SetEventWhenCallbackReturns(instance, im->event);
// _tprintf(_T("+++++++++++++SetEventWhenCallbackReturns[%d]:Exit\r\n"), seq);
}
//_tprintf(_T("__TrySubmitThread[%d] - Type[%d] :Exit\r\n"), seq, im->opt);
}
static void ReaySubmitThread(I im, PTP_SIMPLE_CALLBACK __pfTrySubmit)
{
T al = (T)im->cl;
P out = im->pipe;
eOptType eOpt = im->opt;
long i, block, size, *length = nullptr;
long nThrd = ;
im->num_thread = ;
im->ref_signal = im->num_thread;
if (im->result)
{
++nThrd;
TrySubmitThreadpoolCallback(__TrySubmitResultThread, im, NULL);
// _tprintf(_T("__TrySubmitResultThread :Start\r\n"));
}
for (; nThrd < im->ref_signal; ++nThrd)
{
TrySubmitThreadpoolCallback(__pfTrySubmit, im, NULL);
// _tprintf(_T("__TrySubmitCreateTemplate :Start\r\n"));
}
switch (eOpt)
{
case eNewTemplate:
GetSubDir(im->ready.srcpath, im->ready.wildcard, out);
break;
case eNewTemplate2:
length = im->ready2.length;
case eCmprTemplate:
{
unsigned char** img = im->ready2.img;
const char* imgtype = im->ready2.imgtype;
size = im->ready2.size;
block = size / max(, nThrd);
i = ;
if (block >= nThrd)
{
for (; i < nThrd; ++i)
{
LpData_T ptr = (LpData_T)malloc(sizeof(*ptr));
ptr->opt = eOpt;
ptr->result2.imgtype = imgtype;
ptr->result2.size = block;
ptr->result2.length = eCmprTemplate != eOpt ? &length[i] : nullptr;
ptr->result2.pos = block * i;
ptr->result2.img = &img[block * i];
Pipe_put(out, ptr);
}
size = im->ready2.size % max(, nThrd);
i = block * i;
size += i;
img = &img[i];
}
for (; i < size; ++i)
{
LpData_T ptr = (LpData_T)malloc(sizeof(*ptr));
ptr->opt = eOpt;
ptr->result2.imgtype = imgtype;
ptr->result2.size = ;
ptr->result2.pos = i;
ptr->result2.length = length ? &length[i] : nullptr;
ptr->result2.img = &img[i];
Pipe_put(out, ptr);
}
Pipe_put(out, nullptr);
}
default:
break;
}
WaitForSingleObject(im->event, INFINITE);
// _tprintf(_T("ReaySubmitThread :End\r\n"));
//_tprintf(_T("CloseHandle()[%d]\r\n"), InterlockedDecrement(&watch_1));
//IdleCpu_put(nThreadNum);
}
void Algo_free(T *al)
{
R ag = (*al)->m_lpArgs;
if (!Algo_put(*al))
{
ComObjectRelease(*al, _IComImageAll);
delete (*al);
(*al) = nullptr;
CoUninitialize();
}
Args_free(&ag);
}
long Algo_template_size(T al)
{
assert(al);
if (!(al->nIptrFlag & _IRecognize))
{
ComObjectInstance(al, _IRecognize);
}
if (!(al->nIptrFlag & _IRecognize))
{
return (-);
}
return al->m_lpArgs->lTemplateSize;
}
long Algo_template_type(T al, long type)
{
R ag;
HRESULT hr;
enumTemplateType etype;
assert(al);
if (!(al->nIptrFlag & _IRecognize))
{
ComObjectInstance(al, _IRecognize);
}
if (!(al->nIptrFlag & _IRecognize))
{
return (-);
}
ag = al->m_lpArgs;
assert(ag);
switch (type) {
case : etype = TEMPLATE_TYPE_SIMPLE; break;
case : etype = TEMPLATE_TYPE_GENERAL; break;
case : etype = TEMPLATE_TYPE_COMPLEX; break;
default:
return (-);
}
if (FAILED(hr = al->m_IRecognize->SetModelType((enumFrameModelType)etype)))
{
TRACE_LOG(_T("_IRecognize::SetModelType:ErrCode = %d"), al->m_IRecognize->GetLastError());
}
else
{
enumTemplateType retv = ag->eTemplateType;
ag->eTemplateType = etype;
switch (retv) {
case TEMPLATE_TYPE_SIMPLE : return ;
case TEMPLATE_TYPE_GENERAL : return ;
case TEMPLATE_TYPE_COMPLEX : return ;
default:
return (-);
}
}
}
unsigned char** Algo_create_template(T al, const char* path,long* size, const char* file, const char *ward )
{
I im = Item_new();
unsigned char** pvTemplate;
assert(al);
im->ready.srcpath = path;// lpPath;
im->ready.wildcard = ward;
im->ready.dstfile = file;
im->opt = eNewTemplate;
im->cl = al;
im->list = nullptr;
im->result = file && file[] != '\0';
ReaySubmitThread(im, __TrySubmitCreateTemplate);
AcquireSRWLockExclusive(&al->m_lpArgs->srw_);
*size = List_length(im->list) / ;
pvTemplate = (unsigned char**)List_toArray(im->list, nullptr);
List_free(&im->list);
ReleaseSRWLockExclusive(&al->m_lpArgs->srw_);
Item_free(&im);
return pvTemplate;
}
unsigned char** Algo_create_template(T al, unsigned char* img[], long length[], long size, const char* file, const char* imgtype)
{
I im = Item_new();
unsigned char** pvTemplate;
assert(al);
pvTemplate = new unsigned char* [size];
memset(pvTemplate, , size * sizeof *pvTemplate);
im->ready2.img = img;// lpPath;
im->ready2.length = length;
im->ready2.size = size;
im->ready2.imgtype = imgtype;
im->pvResult = pvTemplate;
im->opt = eNewTemplate2;
im->cl = al;
im->result = file && file[] != '\0' ;
ReaySubmitThread(im, __TrySubmitCreateTemplate);
Item_free(&im);
// _tprintf(_T("free(lpItem)[]\r\n"));
return pvTemplate;
}
double* Algo_compare_template(T al, unsigned char* vtmp[], long size, unsigned char* vtmp2[], long size2)
{
I im = Item_new();
double * vsimi = nullptr;
assert(al && vtmp2 && vtmp);
vsimi = new double[size * size2];
memset(vsimi, , size * size2 * sizeof *vsimi);
im->ready2.img = vtmp;// lpPath;
im->ready2.length = nullptr;
im->ready2.size = size;
im->ready2.size2 = size2;
im->ready2.imgtype = "";
im->ready2.tmp = vtmp2;
im->pvResult = vsimi;
im->opt = eCmprTemplate;
im->cl = al;
ReaySubmitThread(im, __TrySubmitCompareTemplate);
Item_free(&im);
//_tprintf(_T("free(lpItem)[]\r\n"));
return vsimi;
}

windows线程池的更多相关文章

  1. 第11章 Windows线程池(2)_Win2008及以上的新线程池

    11.2 Win2008以上的新线程池 (1)传统线程池的优缺点: ①传统Windows线程池调用简单,使用方便(有时只需调用一个API即可) ②这种简单也带来负面问题,如接口过于简单,无法更多去控制 ...

  2. 第11章 Windows线程池(1)_传统的Windows线程池

    第11章 Windows线程池 11.1 传统的Windows线程池及API (1)线程池中的几种底层线程 ①可变数量的长任务线程:WT_EXECUTELONGFUNCTION ②Timer线程:调用 ...

  3. windows线程池四种情形(win核心读书笔记)

    windows线程池四种情形(win核心读书笔记) Mircosoft从Windows2000引入线程池API,并在Vista后对线程池重新构架,引入新的线程池API.以下所有线程池函数均适用于Vis ...

  4. Windows核心编程:第11章 Windows线程池

    Github https://github.com/gongluck/Windows-Core-Program.git //第11章 Windows线程池.cpp: 定义应用程序的入口点. // #i ...

  5. 《Windows核心编程系列》十一谈谈Windows线程池

    Windows线程池 上一篇博文我们介绍了IO完成端口.得知IO完成端口可以非常智能的分派线程.但是IO完成端口仅对等待它的线程进行分派,创建和销毁线程的工作仍然需要我们自己来做. 我们自己也可以创建 ...

  6. 利用 Windows 线程池定制的 4 种方式完成任务(Windows 核心编程)

    Windows 线程池 说起底层的线程操作一般都不会陌生,Windows 提供了 CreateThread 函数来创建线程,为了同步线程的操作,Windows 提供了事件内核对象.互斥量内核对象.关键 ...

  7. 第11章 Windows线程池(3)_私有的线程池

    11.3 私有的线程池 11.3.1 创建和销毁私有的线程池 (1)进程默认线程池 当调用CreateThreadpoolwork.CreateThreadpoolTimer.CreateThread ...

  8. 【转】一个windows线程池实现

    #ifndef _ThreadPool_H_ #define _ThreadPool_H_ #pragma warning(disable: 4530) #pragma warning(disable ...

  9. windows线程池之I/O完成端口(IOCP)

    对于这个学习主要参考博客 http://blog.csdn.net/neicole/article/details/7549497

随机推荐

  1. 53.CSS---CSS水平垂直居中常见方法总结

    CSS水平垂直居中常见方法总结 1.元素水平居中 当然最好使的是: margin: 0 auto; 居中不好使的原因: 1.元素没有设置宽度,没有宽度怎么居中嘛! 2.设置了宽度依然不好使,你设置的是 ...

  2. Python str byte 互相转换

  3. lua常用方法收集

    1. xlua之将c#集合转换成table -- 将c#的list转换成table local function ConvertCSListToTable(list) local t = {}; , ...

  4. [openjudge-动态规划]鸣人的影分身

    题目描述 描述 在火影忍者的世界里,令敌人捉摸不透是非常关键的.我们的主角漩涡鸣人所拥有的一个招数--多重影分身之术--就是一个很好的例子. 影分身是由鸣人身体的查克拉能量制造的,使用的查克拉越多,制 ...

  5. docker mysql 数据库乱码

    创建 mysql 时,需要加上编码,不然会乱码: docker run --name mysql01 -p : -e MYSQL_ROOT_PASSWORD=pwd123 -d mysql:5.5 - ...

  6. vscode菜单栏、工具栏不见了

    按alt可以出来菜单栏: 命令行切换出来 关键字 menu F1 or shift+ctrl+p 切换出命令行,然后输入menu 有个view:toggle Menu bar 的功能,没文档这个确实要 ...

  7. Spring 集成 Swagger UI

    <!-- Spring --> <dependency> <groupId>org.springframework.boot</groupId> < ...

  8. js 计算后样式封装

    function getStyle(obj,attr){ // 需要获取的元素 属性 if(obj.currentStyle){ return obj.currentStyle[attr]; }els ...

  9. Docker Kubernetes 创建管理 Deployment

    Docker Kubernetes YAML文件创建容器 通过创建Deployment来管理pods从而创建容器.它会同时创建容器.pod.以及Deployment ! 环境: 系统:Centos 7 ...

  10. C# Array 基本数据类型数组的基类 传参问题

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...