parent
071b7ae127
commit
6f1b6eb469
8 changed files with 969 additions and 21 deletions
@ -0,0 +1,88 @@ |
|||||||
|
#pragma once |
||||||
|
#ifndef CMTIMER_H |
||||||
|
#define CMTIMER_H |
||||||
|
|
||||||
|
#include "kyheader.h" |
||||||
|
|
||||||
|
class CmTimer |
||||||
|
{ |
||||||
|
public: |
||||||
|
CmTimer(CStr t):title(t) { is_started = false; start_clock = 0; cumulative_clock = 0; n_starts = 0; } |
||||||
|
|
||||||
|
~CmTimer(){ if (is_started) printf("CmTimer '%s' is started and is being destroyed.\n", title.c_str()); } |
||||||
|
|
||||||
|
inline void Start(); |
||||||
|
inline void Stop(); |
||||||
|
inline void Reset(); |
||||||
|
|
||||||
|
inline bool Report(); |
||||||
|
inline bool StopAndReport() { Stop(); return Report(); } |
||||||
|
inline float TimeInSeconds(); |
||||||
|
|
||||||
|
private: |
||||||
|
CStr title; |
||||||
|
|
||||||
|
bool is_started; |
||||||
|
clock_t start_clock; |
||||||
|
clock_t cumulative_clock; |
||||||
|
unsigned int n_starts; |
||||||
|
}; |
||||||
|
|
||||||
|
/************************************************************************/ |
||||||
|
/* Implementations */ |
||||||
|
/************************************************************************/ |
||||||
|
|
||||||
|
void CmTimer::Start() |
||||||
|
{ |
||||||
|
if (is_started){ |
||||||
|
printf("CmTimer '%s' is already started. Nothing done.\n", title.c_str()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
is_started = true; |
||||||
|
n_starts++; |
||||||
|
start_clock = clock(); |
||||||
|
} |
||||||
|
|
||||||
|
void CmTimer::Stop() |
||||||
|
{ |
||||||
|
if (!is_started){ |
||||||
|
printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
cumulative_clock += clock() - start_clock; |
||||||
|
is_started = false; |
||||||
|
} |
||||||
|
|
||||||
|
void CmTimer::Reset() |
||||||
|
{ |
||||||
|
if (is_started) { |
||||||
|
printf("CmTimer '%s'is started during reset request.\n Only reset cumulative time.\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
cumulative_clock = 0; |
||||||
|
} |
||||||
|
|
||||||
|
bool CmTimer::Report() |
||||||
|
{ |
||||||
|
if (is_started){ |
||||||
|
printf("CmTimer '%s' is started.\n Cannot provide a time report.", title.c_str()); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
float timeUsed = TimeInSeconds(); |
||||||
|
printf("[%s] CumuTime: %gs, #run: %d, AvgTime: %gs\n", title.c_str(), timeUsed, n_starts, timeUsed/n_starts); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
float CmTimer::TimeInSeconds() |
||||||
|
{ |
||||||
|
if (is_started){ |
||||||
|
printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return float(cumulative_clock) / CLOCKS_PER_SEC; |
||||||
|
} |
||||||
|
|
||||||
|
#endif // CMTIMER_H
|
@ -0,0 +1,78 @@ |
|||||||
|
#include "kyheader.h" |
||||||
|
#include "FilterTIG.h" |
||||||
|
#include "CmShow.h" |
||||||
|
|
||||||
|
|
||||||
|
void FilterTIG::update(CMat &w1f){ |
||||||
|
CV_Assert(w1f.cols * w1f.rows == D && w1f.type() == CV_32F && w1f.isContinuous()); |
||||||
|
float b[D], residuals[D]; |
||||||
|
memcpy(residuals, w1f.data, sizeof(float)*D); |
||||||
|
for (int i = 0; i < NUM_COMP; i++){ |
||||||
|
float avg = 0; |
||||||
|
for (int j = 0; j < D; j++){ |
||||||
|
b[j] = residuals[j] >= 0.0f ? 1.0f : -1.0f; |
||||||
|
avg += residuals[j] * b[j]; |
||||||
|
} |
||||||
|
avg /= D; |
||||||
|
_coeffs1[i] = avg, _coeffs2[i] = avg*2, _coeffs4[i] = avg*4, _coeffs8[i] = avg*8; |
||||||
|
for (int j = 0; j < D; j++) |
||||||
|
residuals[j] -= avg*b[j]; |
||||||
|
UINT64 tig = 0; |
||||||
|
for (int j = 0; j < D; j++) |
||||||
|
tig = (tig << 1) | (b[j] > 0 ? 1 : 0); |
||||||
|
_bTIGs[i] = tig; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void FilterTIG::reconstruct(Mat &w1f){ |
||||||
|
w1f = Mat::zeros(8, 8, CV_32F); |
||||||
|
float *weight = (float*)w1f.data; |
||||||
|
for (int i = 0; i < NUM_COMP; i++){ |
||||||
|
UINT64 tig = _bTIGs[i]; |
||||||
|
for (int j = 0; j < D; j++) |
||||||
|
weight[j] += _coeffs1[i] * (((tig >> (63-j)) & 1) ? 1 : -1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map
|
||||||
|
// Please refer to my paper for definition of the variables used in this function
|
||||||
|
Mat FilterTIG::matchTemplate(const Mat &mag1u){ |
||||||
|
const int H = mag1u.rows, W = mag1u.cols; |
||||||
|
const Size sz(W+1, H+1); // Expand original size to avoid dealing with boundary conditions
|
||||||
|
Mat_<INT64> Tig1 = Mat_<INT64>::zeros(sz), Tig2 = Mat_<INT64>::zeros(sz); |
||||||
|
Mat_<INT64> Tig4 = Mat_<INT64>::zeros(sz), Tig8 = Mat_<INT64>::zeros(sz); |
||||||
|
Mat_<byte> Row1 = Mat_<byte>::zeros(sz), Row2 = Mat_<byte>::zeros(sz); |
||||||
|
Mat_<byte> Row4 = Mat_<byte>::zeros(sz), Row8 = Mat_<byte>::zeros(sz); |
||||||
|
Mat_<float> scores(sz); |
||||||
|
for(int y = 1; y <= H; y++){ |
||||||
|
const byte* G = mag1u.ptr<byte>(y-1); |
||||||
|
INT64* T1 = Tig1.ptr<INT64>(y); // Binary TIG of current row
|
||||||
|
INT64* T2 = Tig2.ptr<INT64>(y); |
||||||
|
INT64* T4 = Tig4.ptr<INT64>(y); |
||||||
|
INT64* T8 = Tig8.ptr<INT64>(y); |
||||||
|
INT64* Tu1 = Tig1.ptr<INT64>(y-1); // Binary TIG of upper row
|
||||||
|
INT64* Tu2 = Tig2.ptr<INT64>(y-1); |
||||||
|
INT64* Tu4 = Tig4.ptr<INT64>(y-1); |
||||||
|
INT64* Tu8 = Tig8.ptr<INT64>(y-1); |
||||||
|
byte* R1 = Row1.ptr<byte>(y); |
||||||
|
byte* R2 = Row2.ptr<byte>(y); |
||||||
|
byte* R4 = Row4.ptr<byte>(y); |
||||||
|
byte* R8 = Row8.ptr<byte>(y); |
||||||
|
float *s = scores.ptr<float>(y); |
||||||
|
for (int x = 1; x <= W; x++) { |
||||||
|
byte g = G[x-1]; |
||||||
|
R1[x] = (R1[x-1] << 1) | ((g >> 4) & 1); |
||||||
|
R2[x] = (R2[x-1] << 1) | ((g >> 5) & 1); |
||||||
|
R4[x] = (R4[x-1] << 1) | ((g >> 6) & 1); |
||||||
|
R8[x] = (R8[x-1] << 1) | ((g >> 7) & 1); |
||||||
|
T1[x] = (Tu1[x] << 8) | R1[x]; |
||||||
|
T2[x] = (Tu2[x] << 8) | R2[x]; |
||||||
|
T4[x] = (Tu4[x] << 8) | R4[x]; |
||||||
|
T8[x] = (Tu8[x] << 8) | R8[x]; |
||||||
|
s[x] = dot(T1[x], T2[x], T4[x], T8[x]); |
||||||
|
} |
||||||
|
} |
||||||
|
Mat matchCost1f; |
||||||
|
scores(Rect(8, 8, W-7, H-7)).copyTo(matchCost1f); |
||||||
|
return matchCost1f; |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
#pragma once |
||||||
|
#include "kyheader.h" |
||||||
|
class FilterTIG |
||||||
|
{ |
||||||
|
public: |
||||||
|
void update(CMat &w); |
||||||
|
|
||||||
|
// For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map
|
||||||
|
Mat matchTemplate(const Mat &mag1u); |
||||||
|
|
||||||
|
inline float dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8); |
||||||
|
|
||||||
|
public: |
||||||
|
void reconstruct(Mat &w); // For illustration purpose
|
||||||
|
|
||||||
|
private: |
||||||
|
static const int NUM_COMP = 2; // Number of components
|
||||||
|
static const int D = 64; // Dimension of TIG
|
||||||
|
INT64 _bTIGs[NUM_COMP]; // Binary TIG features
|
||||||
|
float _coeffs1[NUM_COMP]; // Coefficients of binary TIG features
|
||||||
|
|
||||||
|
// For efficiently deals with different bits in CV_8U gradient map
|
||||||
|
float _coeffs2[NUM_COMP], _coeffs4[NUM_COMP], _coeffs8[NUM_COMP]; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
inline float FilterTIG::dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8) |
||||||
|
{ |
||||||
|
INT64 bcT1 = __builtin_popcountll(tig1); |
||||||
|
INT64 bcT2 = __builtin_popcountll(tig2); |
||||||
|
INT64 bcT4 = __builtin_popcountll(tig4); |
||||||
|
INT64 bcT8 = __builtin_popcountll(tig8); |
||||||
|
|
||||||
|
INT64 bc01 = (__builtin_popcountll(_bTIGs[0] & tig1) << 1) - bcT1; |
||||||
|
INT64 bc02 = ((__builtin_popcountll(_bTIGs[0] & tig2) << 1) - bcT2) << 1; |
||||||
|
INT64 bc04 = ((__builtin_popcountll(_bTIGs[0] & tig4) << 1) - bcT4) << 2; |
||||||
|
INT64 bc08 = ((__builtin_popcountll(_bTIGs[0] & tig8) << 1) - bcT8) << 3; |
||||||
|
|
||||||
|
INT64 bc11 = (__builtin_popcountll(_bTIGs[1] & tig1) << 1) - bcT1; |
||||||
|
INT64 bc12 = ((__builtin_popcountll(_bTIGs[1] & tig2) << 1) - bcT2) << 1; |
||||||
|
INT64 bc14 = ((__builtin_popcountll(_bTIGs[1] & tig4) << 1) - bcT4) << 2; |
||||||
|
INT64 bc18 = ((__builtin_popcountll(_bTIGs[1] & tig8) << 1) - bcT8) << 3; |
||||||
|
|
||||||
|
return _coeffs1[0] * (bc01 + bc02 + bc04 + bc08) + _coeffs1[1] * (bc11 + bc12 + bc14 + bc18); |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
/************************************************************************/ |
||||||
|
/* A value struct vector that supports efficient sorting */ |
||||||
|
/************************************************************************/ |
||||||
|
|
||||||
|
template<typename VT, typename ST> |
||||||
|
struct ValStructVec |
||||||
|
{ |
||||||
|
ValStructVec(){clear();} |
||||||
|
inline int size() const {return sz;} |
||||||
|
inline void clear() {sz = 0; structVals.clear(); valIdxes.clear();} |
||||||
|
inline void reserve(int resSz){clear(); structVals.reserve(resSz); valIdxes.reserve(resSz); } |
||||||
|
inline void pushBack(const VT& val, const ST& structVal) {valIdxes.push_back(make_pair(val, sz)); structVals.push_back(structVal); sz++;} |
||||||
|
|
||||||
|
inline const VT& operator ()(int i) const {return valIdxes[i].first;} // Should be called after sort
|
||||||
|
inline const ST& operator [](int i) const {return structVals[valIdxes[i].second];} // Should be called after sort
|
||||||
|
inline VT& operator ()(int i) {return valIdxes[i].first;} // Should be called after sort
|
||||||
|
inline ST& operator [](int i) {return structVals[valIdxes[i].second];} // Should be called after sort
|
||||||
|
|
||||||
|
void sort(bool descendOrder = true); |
||||||
|
const vector<ST> &getSortedStructVal(); |
||||||
|
void append(const ValStructVec<VT, ST> &newVals, int startV = 0); |
||||||
|
|
||||||
|
vector<ST> structVals; // struct values
|
||||||
|
|
||||||
|
private: |
||||||
|
int sz; // size of the value struct vector
|
||||||
|
vector<pair<VT, int>> valIdxes; // Indexes after sort
|
||||||
|
bool smaller() {return true;}; |
||||||
|
vector<ST> sortedStructVals; |
||||||
|
}; |
||||||
|
|
||||||
|
template<typename VT, typename ST> |
||||||
|
void ValStructVec<VT, ST>::append(const ValStructVec<VT, ST> &newVals, int startV) |
||||||
|
{ |
||||||
|
int sz = newVals.size(); |
||||||
|
for (int i = 0; i < sz; i++) |
||||||
|
pushBack((float)((i+300)*startV)/*newVals(i)*/, newVals[i]); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename VT, typename ST> |
||||||
|
void ValStructVec<VT, ST>::sort(bool descendOrder /* = true */) |
||||||
|
{ |
||||||
|
if (descendOrder) |
||||||
|
std::sort(valIdxes.begin(), valIdxes.end(), std::greater<pair<VT, int>>()); |
||||||
|
else |
||||||
|
std::sort(valIdxes.begin(), valIdxes.end(), std::less<pair<VT, int>>()); |
||||||
|
} |
||||||
|
|
||||||
|
template<typename VT, typename ST> |
||||||
|
const vector<ST>& ValStructVec<VT, ST>::getSortedStructVal() |
||||||
|
{ |
||||||
|
sortedStructVals.resize(sz); |
||||||
|
for (int i = 0; i < sz; i++) |
||||||
|
sortedStructVals[i] = structVals[valIdxes[i].second]; |
||||||
|
return sortedStructVals; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
void valStructVecDemo() |
||||||
|
{ |
||||||
|
ValStructVec<int, string> sVals; |
||||||
|
sVals.pushBack(3, "String 3"); |
||||||
|
sVals.pushBack(5, "String 5"); |
||||||
|
sVals.pushBack(4, "String 4"); |
||||||
|
sVals.pushBack(1, "String 1"); |
||||||
|
sVals.sort(false); |
||||||
|
for (int i = 0; i < sVals.size(); i++) |
||||||
|
printf("%d, %s\n", sVals(i), _S(sVals[i])); |
||||||
|
} |
||||||
|
*/ |
@ -0,0 +1,224 @@ |
|||||||
|
#ifndef KYHEADER_H |
||||||
|
#define KYHEADER_H |
||||||
|
|
||||||
|
#include <assert.h> |
||||||
|
#include <string> |
||||||
|
#include <vector> |
||||||
|
#include <functional> |
||||||
|
#include <list> |
||||||
|
#include <algorithm> |
||||||
|
#include <iostream> |
||||||
|
#include <cmath> |
||||||
|
#include <time.h> |
||||||
|
#include <fstream> |
||||||
|
#include <random> |
||||||
|
//#include <atlstr.h>
|
||||||
|
//#include <atltypes.h>
|
||||||
|
#include <omp.h> |
||||||
|
#include <strstream> |
||||||
|
|
||||||
|
|
||||||
|
// TODO: reference additional headers your program requires here
|
||||||
|
//#include "LibLinear/linear.h"
|
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
#include "opencv2/core.hpp" |
||||||
|
|
||||||
|
#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION) |
||||||
|
#ifdef _DEBUG |
||||||
|
#define cvLIB(name) "opencv_" name CV_VERSION_ID "d" |
||||||
|
#else |
||||||
|
#define cvLIB(name) "opencv_" name CV_VERSION_ID |
||||||
|
#endif |
||||||
|
|
||||||
|
#pragma comment( lib, cvLIB("core")) |
||||||
|
#pragma comment( lib, cvLIB("imgproc")) |
||||||
|
#pragma comment( lib, cvLIB("highgui")) |
||||||
|
using namespace cv; |
||||||
|
using namespace std; |
||||||
|
#ifdef WIN32 |
||||||
|
/* windows stuff */ |
||||||
|
#else |
||||||
|
typedef unsigned long DWORD; |
||||||
|
typedef unsigned short WORD; |
||||||
|
typedef unsigned int UNINT32; |
||||||
|
typedef bool BOOL; |
||||||
|
typedef void *HANDLE; |
||||||
|
typedef unsigned char byte; |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef std::vector<int> vecI; |
||||||
|
typedef const std::string CStr; |
||||||
|
typedef const Mat CMat; |
||||||
|
typedef std::vector<std::string> vecS; |
||||||
|
typedef std::vector<Mat> vecM; |
||||||
|
typedef std::vector<float> vecF; |
||||||
|
typedef std::vector<double> vecD; |
||||||
|
|
||||||
|
enum{CV_FLIP_BOTH = -1, CV_FLIP_VERTICAL = 0, CV_FLIP_HORIZONTAL = 1}; |
||||||
|
#define _S(str) ((str).c_str()) |
||||||
|
#define CHK_IND(p) ((p).x >= 0 && (p).x < _w && (p).y >= 0 && (p).y < _h) |
||||||
|
#define CV_Assert_(expr, args) \ |
||||||
|
{\
|
||||||
|
if(!(expr)) {\
|
||||||
|
String msg = cv::format args; \
|
||||||
|
printf("%s in %s:%d\n", msg.c_str(), __FILE__, __LINE__); \
|
||||||
|
cv::error(cv::Exception(CV_StsAssert, msg, __FUNCTION__, __FILE__, __LINE__) ); }\
|
||||||
|
} |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
// Return -1 if not in the list
|
||||||
|
template<typename T> |
||||||
|
static inline int findFromList(const T &word, const vector<T> &strList) { |
||||||
|
//TODO delete test code
|
||||||
|
//cout << "\n\n" << "word" <<" "<< word << endl;
|
||||||
|
for(int i=0; i<strList.size(); i++) { |
||||||
|
//cout <<"test word:"<< word << " " << endl;
|
||||||
|
//cout << "Size w " << word.size() << " Size L "<< strList[i].size() << endl;
|
||||||
|
} |
||||||
|
|
||||||
|
auto it = std::find(strList.begin(),strList.end(), word); |
||||||
|
if (it == strList.end()) |
||||||
|
{ |
||||||
|
return -1; |
||||||
|
} else |
||||||
|
{ |
||||||
|
auto index = std::distance(strList.begin(), it); |
||||||
|
//cout << "index" <<" "<< index << endl;
|
||||||
|
return index; |
||||||
|
} |
||||||
|
}
|
||||||
|
/*template<typename T>
|
||||||
|
static inline int findFromList(const string &word, const vector<T> &strList) { |
||||||
|
//for(int i=0; i<strList.size(); i++){
|
||||||
|
//cout <<"element: " <<strList[i]<<" "<<word << endl;
|
||||||
|
//if (std::strcmp(word.c_str(),strList[i].c_str())==0) return i;
|
||||||
|
} |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
template<typename T> inline T sqr(T x) { return x * x; } // out of range risk for T = byte, ...
|
||||||
|
template<class T, int D> inline T vecSqrDist(const Vec<T, D> &v1, const Vec<T, D> &v2) {T s = 0; for (int i=0; i<D; i++) s += sqr(v1[i] - v2[i]); return s;} // out of range risk for T = byte, ...
|
||||||
|
template<class T, int D> inline T vecDist(const Vec<T, D> &v1, const Vec<T, D> &v2) { return sqrt(vecSqrDist(v1, v2)); } // out of range risk for T = byte, ...
|
||||||
|
|
||||||
|
inline Rect Vec4i2Rect(Vec4i &v){return Rect(Point(v[0] - 1, v[1] - 1), Point(v[2], v[3])); } |
||||||
|
|
||||||
|
#ifdef __WIN32 |
||||||
|
#define INT64 long long |
||||||
|
#else |
||||||
|
#define INT64 long |
||||||
|
typedef unsigned long UINT64; |
||||||
|
#endif |
||||||
|
|
||||||
|
/////
|
||||||
|
#if (_MSC_VER >= 1500) |
||||||
|
# include <intrin.h> |
||||||
|
# define POPCNT(x) __popcnt(x) |
||||||
|
# define POPCNT64(x) __popcnt64(x) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__GNUC__) |
||||||
|
# define POPCNT(x) __builtin_popcount(x) |
||||||
|
# define POPCNT64(x) __builtin_popcountll(x) |
||||||
|
#endif |
||||||
|
|
||||||
|
inline int popcnt64(register uint64_t u) |
||||||
|
{ |
||||||
|
u = (u & 0x5555555555555555) + ((u >> 1) & 0x5555555555555555); |
||||||
|
u = (u & 0x3333333333333333) + ((u >> 2) & 0x3333333333333333); |
||||||
|
u = (u & 0x0f0f0f0f0f0f0f0f) + ((u >> 4) & 0x0f0f0f0f0f0f0f0f); |
||||||
|
u = (u & 0x00ff00ff00ff00ff) + ((u >> 8) & 0x00ff00ff00ff00ff); |
||||||
|
u = (u & 0x0000ffff0000ffff) + ((u >>16) & 0x0000ffff0000ffff); |
||||||
|
u = (u & 0x00000000ffffffff) + ((u >>32) & 0x00000000ffffffff); |
||||||
|
return u; |
||||||
|
} |
||||||
|
|
||||||
|
inline int popcnt(register uint32_t u) |
||||||
|
{ |
||||||
|
u = (u & 0x55555555) + ((u >> 1) & 0x55555555); |
||||||
|
u = (u & 0x33333333) + ((u >> 2) & 0x33333333); |
||||||
|
u = (u & 0x0f0f0f0f) + ((u >> 4) & 0x0f0f0f0f); |
||||||
|
u = (u & 0x00ff00ff) + ((u >> 8) & 0x00ff00ff); |
||||||
|
u = (u & 0x0000ffff) + ((u >>16) & 0x0000ffff); |
||||||
|
return u; |
||||||
|
} |
||||||
|
|
||||||
|
inline int popcnt64_nibble(register uint64_t u) |
||||||
|
{ |
||||||
|
static const uint8_t Table[] = { |
||||||
|
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 |
||||||
|
}; |
||||||
|
|
||||||
|
int c = 0; |
||||||
|
while (u) |
||||||
|
{ |
||||||
|
c += Table[u & 0xf]; |
||||||
|
u >>= 4; |
||||||
|
} |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
inline int popcnt_nibble(register uint32_t u) |
||||||
|
{ |
||||||
|
static const uint8_t Table[] = { |
||||||
|
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 |
||||||
|
}; |
||||||
|
|
||||||
|
int c = 0; |
||||||
|
while (u) |
||||||
|
{ |
||||||
|
c += Table[u & 0xf]; |
||||||
|
u >>= 4; |
||||||
|
} |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
inline int popcnt64_byte(register uint64_t u) |
||||||
|
{ |
||||||
|
#define B2(k) k, k+1, k+1, k+2 |
||||||
|
#define B4(k) B2(k), B2(k+1), B2(k+1), B2(k+2) |
||||||
|
#define B6(k) B4(k), B4(k+1), B4(k+1), B4(k+2) |
||||||
|
static const uint8_t Table[] = { |
||||||
|
B6(0), B6(1), B6(1), B6(2) |
||||||
|
}; |
||||||
|
#undef B6 |
||||||
|
#undef B4 |
||||||
|
#undef B2 |
||||||
|
|
||||||
|
int c = 0; |
||||||
|
while (u) |
||||||
|
{ |
||||||
|
c += Table[u & 0xff]; |
||||||
|
u >>= 8; |
||||||
|
} |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
inline int popcnt_byte(register uint32_t u) |
||||||
|
{ |
||||||
|
#define B2(k) k, k+1, k+1, k+2 |
||||||
|
#define B4(k) B2(k), B2(k+1), B2(k+1), B2(k+2) |
||||||
|
#define B6(k) B4(k), B4(k+1), B4(k+1), B4(k+2) |
||||||
|
static const uint8_t Table[] = { |
||||||
|
B6(0), B6(1), B6(1), B6(2) |
||||||
|
}; |
||||||
|
#undef B6 |
||||||
|
#undef B4 |
||||||
|
#undef B2 |
||||||
|
|
||||||
|
int c = 0; |
||||||
|
while (u) |
||||||
|
{ |
||||||
|
c += Table[u & 0xff]; |
||||||
|
u >>= 8; |
||||||
|
} |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/////
|
||||||
|
#include "CmTimer.h" |
||||||
|
#include "CmFile.h" |
||||||
|
#endif // KYHEADER_H
|
Loading…
Reference in new issue