C++ Communicating with Dll's gone wrong - c++

My current project has 2 dll's, one called Engine and another called Graphics. The Engine links to the graphics. And then the main program with links to both, but uses the Engine.
In some functions like this:
typedef const char* ce_safechar;
AssimpIntegration::GetData(ce_safechar pFile, ...
this error pops up: _pFirstBlock == pHead, just after i exited the function.
I have seen many different issues and it all seems to point at strings.
How can I avoid such behavior?
Full Function if needed:
FMESH_DATA AssimpIntegration::GetData(ce_safechar pFile, bool convLeftHanded, int maxSM)
{
// Create an instance of the Importer class
Assimp::Importer importer;
// And have it read the given file with some example post processing
// Usually - if speed is not the most important aspect for you - you'll
// probably to request more post processing than we do in this example.
int cls = 0x0;
if (convLeftHanded)
cls = aiProcess_ConvertToLeftHanded;
const aiScene* scene = importer.ReadFile( pFile, aiProcess_GenNormals | aiProcess_FindInstances | aiProcess_CalcTangentSpace | cls | aiProcess_Triangulate );
// If the import failed, report it
if (!scene)
{
char* error = (char*)importer.GetErrorString();
CE_ERROR(error, "Assimp Error");
}
// Now we can access the file's contents.
Group<MESH_STRUCT> Vertices;
Group<DWORD> indices;
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////PROCESS MESH///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
FMESH_DATA data;
if (scene->HasAnimations())
{
aiAnimation *anim = scene->mAnimations[0];
FOREACH(anim->mChannels[0]->mNumPositionKeys)
{
aiVector3D position = anim->mChannels[0]->mPositionKeys[i].mValue;
CE_ANIMATIONKEY key;
key.position = D3DXVECTOR3(position.x, position.y, position.z);
data.Keys.push_back(key);
}
}
D3DXVECTOR3 norms;
float tanx, tany, tanz;
float bitanx, bitany, bitanz;
FOREACH (scene->mNumMeshes)
{
if (i >= maxSM)
continue;
aiMesh *mesh = scene->mMeshes[i];
Vertices.group.clear();
indices.group.clear(); //dafuck?
if (mesh->HasPositions())
{
for (int v = 0; v != mesh->mNumVertices; v++)
{
norms = D3DXVECTOR3(0,0,0);
if (mesh->HasNormals())
norms = D3DXVECTOR3(mesh->mNormals[v].x,mesh->mNormals[v].y,mesh->mNormals[v].z);
tanx = tany = tanz = 0;
bitanx = bitany = bitanz = 0;
if (mesh->HasTangentsAndBitangents())
{
tanx = mesh->mTangents[v].x; tany = mesh->mTangents[v].y; tanz = mesh->mTangents[v].z;
bitanx = mesh->mBitangents[v].x; bitany = mesh->mBitangents[v].y; bitanz = mesh->mBitangents[v].z;
}
Vertices.push_back(MESH_STRUCT(
mesh->mVertices[v].x,
mesh->mVertices[v].y,
mesh->mVertices[v].z,
norms,
0,
0,
tanx, // TANGENTS
tany,
tanz
));
for (int b = 0; b < mesh->mNumBones; b++)
{
if (b > 4)
break;
float weight = 0.0f;
for ( int w = 0; w < mesh->mBones[b]->mNumWeights; w++)
if (mesh->mBones[b]->mWeights[w].mVertexId == v)
weight = mesh->mBones[b]->mWeights[w].mWeight;
Vertices.back().bWeight[b] = weight;
}
if (mesh->HasTextureCoords(0))
{
Vertices.back().U = mesh->mTextureCoords[0][v].x;
Vertices.back().V = mesh->mTextureCoords[0][v].y;
}
}
for (int f = 0; f != mesh->mNumFaces; f++)
{
for (int index = 0; index != mesh->mFaces[f].mNumIndices; index++)
{
indices.push_back(mesh->mFaces[f].mIndices[index]);
}
}
}
data.meshData.push_back(Vertices);
data.indices.push_back(indices);
// Set the required textures
const aiMaterial* pMaterial = scene->mMaterials[mesh->mMaterialIndex];
if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString Path;
if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
std::string FullPath = Path.data;
if (FullPath.find("\\") != string::npos)
FullPath = FullPath.substr(FullPath.find_last_of("\\")+1, FullPath.length() - (FullPath.length() - FullPath.find_last_of("\\")-1));
else if (FullPath.find("/") != string::npos)
FullPath = FullPath.substr(FullPath.find_last_of("/")+1, FullPath.length() - FullPath.find_last_of("/")-1);
string rFile = pFile;
string spFile = std::string(pFile);
if (spFile.find("\\") != string::npos)
rFile = spFile.substr(0, spFile.find_last_of("\\")+1);
else
rFile = spFile.substr(0, spFile.find_last_of("/")+1);
FullPath = rFile + FullPath;
data.textures.push_back(FullPath);
}
}
else
{
data.textures.push_back("");
}
}
data.scene = scene;
return data;
}

You are using STL objects as parameters and/or return types of the functions/methods you are exporting on your DLL.
Example: You return FMESH_DATA. This class/struct has STL objects inside, as we can see via line:
data.Keys.push_back(key);
The thing here is: It's not a good idea to have STL stuff being exported or imported via DLLs. It requires the caller of your DLL to use the same CRT of the objects that are created in the DLL.
But if you really wanna do that, you may change the Runtime Library of your projects (all of them) to multi-threaded (/MD). Then you will be able to use STL safely across the cliend and the DLL.

Related

Can these two methods be adjusted so that I only parse the command line once?

I have two methods that I call in InitInstance:
void CMeetingScheduleAssistantApp::DetectCommandLineSwitches()
{
LPWSTR* szArglist = nullptr;
int iNumArgs = 0;
szArglist = CommandLineToArgvW(GetCommandLine(), &iNumArgs);
if (iNumArgs > 0 && szArglist != nullptr)
{
for (int iArg = 0; iArg < iNumArgs; iArg++)
{
CString strArg(szArglist[iArg]);
int iDelim = strArg.Find(_T("="));
if (iDelim != -1)
{
CString strParamName = strArg.Left(iDelim);
CString strParamValue = strArg.Mid(iDelim + 1);
if (strParamName.CollateNoCase(_T("/lang")) == 0)
{
m_strPathLanguageResourceOverride.Format(_T("%sMeetSchedAssist%s.dll"),
(LPCTSTR)GetProgramPath(), (LPCTSTR)strParamValue.MakeUpper());
if (!PathFileExists(m_strPathLanguageResourceOverride))
m_strPathLanguageResourceOverride = _T("");
}
}
}
// Free memory allocated for CommandLineToArgvW arguments.
LocalFree(szArglist);
}
}
void CMeetingScheduleAssistantApp::DetectFileToOpenFromFileExplorer()
{
CCommandLineInfo cmdInfo;
m_bOpenFileFromFileExplorer = false;
m_strFileToOpenFromFileExplorerPath = _T("");
ParseCommandLine(cmdInfo);
if (PathFileExists(cmdInfo.m_strFileName))
{
m_bOpenFileFromFileExplorer = true;
m_strFileToOpenFromFileExplorerPath = cmdInfo.m_strFileName;
}
}
Each parses the command line in a different way:
CommandLineToArgvW / GetCommandLine
ParseCommandLine
I don't want to combine the methods as they are doing distinct tasks. But is it possible to adjust the logic so that I only parse the command line once?

C++ Libusb isn't bringing back serial number of device

I'm currently working on a project that involves bringing information back from devices plugged in via true usb. To solve this, I'm attempting to use libusb in my C++ project. I'm on Windows 10, using C++ and QT Creator with QT version 5.2.1. I can get the vendor ID and product ID of my device with .idVendor and idProduct. However, my serial number is returning as 0 with .iSerialNumber. I'll post my code below and hopefully someone can help me figure out what I'm missing or suggest another library for me to try. Thanks!
bool CPumpFinder::pollTrueUSB(boolean &deviceFound, Device &newDevice)
{
boolean usbFound = FALSE;
boolean accuCheckFound = FALSE;
AccuGuideCom *acc = new AccuGuideCom();
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize a library session
if(r < 0) {
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
}
ssize_t i; //for iterating through the list
for(i = 0; i < cnt; i++) {
printdev(devs[i], usbFound, accuCheckFound); //print specs of this device
if(usbFound == TRUE)
{
if(accuCheckFound == TRUE)
{
newDevice.displayName = "ACCU-CHEK GUIDE";
newDevice.type = DEVICE_ACCUCHECKGUIDE;
newDevice.vendorID = accuVID;
newDevice.productID = accuPID;
newDevice.serial = accuSerial;
}
deviceFound = TRUE;
break;
}
}
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
libusb_exit(ctx); //close the session
return deviceFound;
}
boolean CPumpFinder::printdev(libusb_device *dev, boolean &usbFound, boolean
&accuChekFound) {
libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
return usbFound;
}
uint16 vID = (uint16)desc.idVendor;
uint16 pID = (uint16)desc.idProduct; //desc.iSerialNumber
//#define ACCUCHEK_GUIDE_VENDORID (uint16)0x173A
//#define ACCUCHEK_GUIDE_PRODUCTID (uint16)0x21D5
if((vID == 5946) & (pID == 8661))
{
accuPID = pID;
accuVID = vID;
//Do serial?
accuSerial = "Test";
write_text_to_log_file("we did it");
accuChekFound = TRUE;
usbFound = TRUE;
}
if(usbFound == TRUE)
{
libusb_config_descriptor *config;
libusb_get_config_descriptor(dev, 0, &config);
const libusb_interface *inter;
const libusb_interface_descriptor *interdesc;
const libusb_endpoint_descriptor *epdesc;
for(int i=0; i<(int)config->bNumInterfaces; i++) {
inter = &config->interface[i];
for(int j=0; j<inter->num_altsetting; j++) {
interdesc = &inter->altsetting[j];
for(int k=0; k<(int)interdesc->bNumEndpoints; k++) {
epdesc = &interdesc->endpoint[k];
}
}
}
libusb_free_config_descriptor(config);
if(accuChekFound == TRUE)
{
return accuChekFound;
}
return usbFound;
}
return usbFound;
}

libusb_get_device_list seg fault

I am writing a file explorer application in Qt C++ and have a libUSB function (QList UsbDevice::getDeviceList()) which gets all attached USB devices, checks each one for my products vendor and product ID's, claims them and the returns them in an array. This all works fine and I get the device I want, however I have added a refresh button which should update the device list shown in a drop-down list (it basically calls the getDeviceList function again) but it seg faults when calling:
int numDevices = libusb_get_device_list(NULL, &usbDevices);
the second time around and I can't for the life of me see why. If someone could check over the code below and see if I have missed something stupid that would be very helpful.
QList<UsbDevice*> UsbDevice::getDeviceList()
{
unsigned char manf[256] = {'\0'};
QList<UsbDevice*> usbDeviceList;
libusb_device **usbDevices;
struct libusb_device_descriptor desc;
int numDevices = libusb_get_device_list(NULL, &usbDevices);
if(numDevices < 0)
{
libusb_free_device_list(usbDevices, 1);
return usbDeviceList;
}
QString error;
for(int i=0; i!=numDevices; ++i)
{
libusb_device *dev = usbDevices[i];
libusb_get_device_descriptor(dev, &desc);
if((desc.idVendor != VendorUsbId) && (desc.idProduct != ProductUsbId))
continue;
libusb_device_handle *handle = NULL;
libusb_config_descriptor *conf_desc = NULL;
int result = 0;
result = libusb_open(dev, &handle);
if(result < 0)
{
if(result == -3)
{
}
error = QString(libusb_error_name(result));
continue;
}
int config = 1;
if( handle == NULL)
{
continue;
}
result = libusb_set_configuration(handle, config);
if(result < 0)
{
error = QString(libusb_error_name(result));
continue;
}
result = libusb_get_config_descriptor(dev, 0, &conf_desc);
if(result < 0)
{
error = QString(libusb_error_name(result));
continue;
}
result = libusb_claim_interface(handle, 0);
if(result < 0)
{
error = QString(libusb_error_name(result));
continue;
}
result = libusb_get_string_descriptor_ascii(handle, desc.iProduct, manf, sizeof(manf));
if(result < 0)
{
error = QString(libusb_error_name(result));
continue;
}
UsbDevice *newDevice = new UsbDevice();
newDevice->setDeviceName(QString((char*)manf));
newDevice->setHandle(handle);
usbDeviceList << newDevice;
}
libusb_free_device_list(usbDevices, 1);
return usbDeviceList;
}
You are calling libusb_init() at the beginning of your program, but you are also calling libusb_exit() at the beginning : before calling a.exec().
Your first call probably happens in MainWindow constructor ?
You could instead subclass QApplication, call libusb_init() in the constructor and libusb_exit() in the destructor.

Open file from memory buffer using minizip

I am searching how to open archive from memory buffer using minizip.
I found ioapi_mem_c.zip from their page http://www.winimage.com/zLibDll/minizip.html.
I can't understand how to use it. Can some one give me an example?
I solved my problem for unziping:
I added this function to unzip.c
extern unzFile ZEXPORT unzOpenBuffer (const void* buffer, uLong size)
{
char path[16] = {0};
zlib_filefunc64_32_def memory_file;
uLong base = (uLong)buffer;
sprintf(path, "%x+%x", base, size);
fill_memory_filefunc64_32(&memory_file);
return unzOpenInternal(path, &memory_file, 0);
}
And made some changes in ioapi_mem.c:
void fill_memory_filefunc64_32 (pzlib_filefunc_def)
zlib_filefunc64_32_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen32_file = fopen_mem_func;
pzlib_filefunc_def->zfile_func64.zopen64_file = fopen_mem_func;
pzlib_filefunc_def->zfile_func64.zread_file = fread_mem_func;
pzlib_filefunc_def->zfile_func64.zwrite_file = fwrite_mem_func;
pzlib_filefunc_def->ztell32_file = ftell_mem_func;
pzlib_filefunc_def->zseek32_file = fseek_mem_func;
pzlib_filefunc_def->zfile_func64.zseek64_file = NULL;
pzlib_filefunc_def->zfile_func64.zclose_file = fclose_mem_func;
pzlib_filefunc_def->zfile_func64.zerror_file = ferror_mem_func;
pzlib_filefunc_def->zfile_func64.opaque = NULL;
}
I hope this will help someone who will have the same problem.
And Here is simple class implementation how to use it:
void ZipArchiveImpl::OpenArchive()
{
ASSERT(!mInited, "Already opened.");
if ((mFileMode == FM_READ))
{
if (mArchiveName.size() == 0)
{
u32 sz = mFile->GetFileSize();
mUnzBlock.Resize(sz);
mFile->SetPosition(0);
mFile->Read(mUnzBlock.Data(), mUnzBlock.GetSizeInBytes());
mUnzHandle = unzOpenBuffer(mUnzBlock.Data(), mUnzBlock.GetSizeInBytes());
}
else
{
mUnzHandle = unzOpen(mArchiveName.c_str());
}
if (!mUnzHandle) return;
FillMap();
}
else if (mFileMode == FM_WRITE)
{
ASSERT0(mArchiveName.size());
mZipHandle = zipOpen(mArchiveName.c_str(), 0);
if (!mZipHandle) return;
}
mInited = true;
}
IFile* ZipArchiveImpl::OpenRead(const std::string& name)
{
if (IsExist(name))
{
ZipFileInfo info = mFileMap.find(name)->second;
MemoryBlock block(1);
block.Resize(info.uncompressedSize);
int res = unzGoToFilePos(mUnzHandle, &info.filePosInfo);
if (UNZ_OK != res)
{
return false;
}
// open the current file with optional password
if (mArchivePassword != "")
{
res = unzOpenCurrentFilePassword(info.zipFileHandle, mArchivePassword.c_str());
}
else
{
res = unzOpenCurrentFile(info.zipFileHandle);
}
if (UNZ_OK != res)
{
return false;
}
// read uncompressed data
int readResult = unzReadCurrentFile(info.zipFileHandle, block.Data(), info.uncompressedSize);
// close the file
res = unzCloseCurrentFile(info.zipFileHandle);
if (UNZ_OK != res)
{
return false;
}
if (info.uncompressedSize == readResult)
{
return ROBE_NEW MemoryFile(block.Data(), info.uncompressedSize);
}
else
{
return NULL;
}
}
else
{
return NULL;
}
}
IFile* ZipArchiveImpl::OpenRead(u32 id)
{
ASSERT0(mFileNames.size() > id);
if (IsExist(mFileNames[id]))
{
return OpenRead(mFileNames[id]);
}
else
{
return NULL;
}
}
void ZipArchiveImpl::FillMap()
{
s32 walkRes = unzGoToFirstFile(mUnzHandle);
unz_file_info info;
while (UNZ_OK == walkRes)
{
// get info about current file
char currentFileName[512];
s32 fileInfoRes = unzGetCurrentFileInfo(mUnzHandle, &info, currentFileName, sizeof(currentFileName), 0, 0, 0, 0);
std::string name = std::string(currentFileName);
mFileNames.push_back(name);
InitInfo(name, &info);
walkRes = unzGoToNextFile(mUnzHandle);
}
OpenRead(0);
if (UNZ_END_OF_LIST_OF_FILE != walkRes)
{
}
}
void ZipArchiveImpl::InitInfo(const std::string& name, unz_file_info* info)
{
ZipFileInfo zfi;
mFileMap.insert(std::pair<std::string, ZipFileInfo>(name, zfi));
mFileMap[name].zipFileHandle = mUnzHandle;
int res = unzGetFilePos(mFileMap[name].zipFileHandle, &mFileMap[name].filePosInfo);
mFileMap[name].uncompressedSize = info->uncompressed_size;
char lastsymbol = name[name.size() - 1];
if (lastsymbol == '/' || lastsymbol == '\\')
{
mFileMap[name].type = ZFT_DIR;
}
else
{
mFileMap[name].type = ZFT_FILE;
}
}
ZipArchiveImpl::~ZipArchiveImpl()
{
if (mInited)
{
if (mUnzHandle) unzClose(mUnzHandle);
if (mZipHandle) zipClose(mZipHandle, 0);
}
}
bool ZipArchiveImpl::IsExist(const std::string& name)
{
return (mFileMap.find(name) != mFileMap.end());
}
void ZipArchiveImpl::SaveFileToZip(const std::string& path, IFile* file)
{
const u32 DefaultFileAttribute = 32;
MemoryBlock block(1);
block.Resize(file->GetFileSize());
file->Read(block.Data(), block.GetSizeInBytes());
zip_fileinfo zinfo;
memset(&zinfo, 0, sizeof(zinfo));
zinfo.internal_fa = 0;
zinfo.external_fa = DefaultFileAttribute;
::boost::posix_time::ptime pt = ::boost::posix_time::from_time_t(time(0));
std::tm ptm = ::boost::posix_time::to_tm(pt);
zinfo.dosDate = 0;
zinfo.tmz_date.tm_year = ptm.tm_year;
zinfo.tmz_date.tm_mon = ptm.tm_mon;
zinfo.tmz_date.tm_mday = ptm.tm_mday;
zinfo.tmz_date.tm_hour = ptm.tm_hour;
zinfo.tmz_date.tm_min = ptm.tm_min;
zinfo.tmz_date.tm_sec = ptm.tm_sec;
zipOpenNewFileInZip(mZipHandle, path.c_str(), &zinfo, 0, 0, 0, 0, 0, Z_DEFLATED, Z_BEST_SPEED);
zipWriteInFileInZip(mZipHandle, block.Data(), block.GetSizeInBytes());
zipCloseFileInZip(mZipHandle);
}
unsigned long ZipArchiveImpl::GetFileAttributes(const std::string& filePath)
{
unsigned long attrib = 0;
#ifdef WIN32
attrib = ::GetFileAttributes(filePath.c_str());
#else
struct stat path_stat;
if (::stat(filePath.c_str(), &path_stat) == 0)
{
attrib = path_stat.st_mode;
}
#endif
return attrib;
}
added this function to unzip.c
extern unzFile ZEXPORT unzOpenBuffer(const void* buffer, uLong size)
{
zlib_filefunc_def filefunc32 = { 0 };
ourmemory_t *punzmem = (ourmemory_t*)malloc(sizeof(ourmemory_t));
punzmem->size = size;
punzmem->base = (char *)malloc(punzmem->size);
memcpy(punzmem->base, buffer, punzmem->size);
punzmem->grow = 0;
punzmem->cur_offset = 0;
punzmem->limit = 0;
fill_memory_filefunc(&filefunc32, punzmem);
return unzOpen2(NULL, &filefunc32);
}
Looking at the code in the link, there is no obvious way to pass a memory buffer. Save your memory buffer as a file, unzip it.
Or you could implement your own zlib_filefunc_def variant that operates on a lump of memory instead of a file. I don't think that is very hard to do.
Checkout the nmoinvaz fork of minizip: To unzip from a zip file in memory use fill_memory_filefunc and supply a proper ourmemory_t structure
zlib_filefunc_def filefunc32 = {0};
ourmemory_t unzmem = {0};
unzmem.size = bufsize;
unzmem.base = (char *)malloc(unzmem.size);
memcpy(unzmem.base, buffer, unzmem.size);
fill_memory_filefunc(&filefunc32, &unzmem);
unzOpen2("__notused__", &filefunc32);

Exception in displaying the depth and Rgb Image through OpenNI in C++

I am new to openNI and Kinect as a beginner I tried implementing OpenNI SimpleViewer through the Tutorial in OpenNI.org at this link : http://openni.org/docs2/Tutorial/smpl_simple_view.html
I have implemented the code as described in this tutorial but I am still facing problem as The program is throwing exception and it is not showing any output.
I have linked all the libraries and installed the kinect properly. I have also included the OpenCV library with openNI.
Here is My C++ Code that I have Implemented :
int main()
{
rc = context.InitFromXmlFile(XML_PATH,&errors);
if(rc == XN_STATUS_NO_NODE_PRESENT)
{
XnChar strError[1024];
errors.ToString(strError,1024);
printf("%s\n",strError);
return(rc);
}
else if(rc != XN_STATUS_OK)
{
printf("Open failed : %s\n", xnGetStatusString(rc));
return(rc);
}
rc = context.FindExistingNode(XN_NODE_TYPE_DEPTH,depth);
if(rc != XN_STATUS_OK)
{
printf("No Depth Node Found. Check XML!\n");
return -1;
}
depth.GetMetaData(depthMD);
image.GetMetaData(imageMD);
if(imageMD.FullXRes() != depthMD.FullXRes() || imageMD.FullYRes() != depthMD.FullYRes())
{
printf("The device depth and image resolution must be equal\n");
return -1;
}
if(imageMD.PixelFormat() != XN_PIXEL_FORMAT_RGB24)
{
printf("The Device Image Format must be RGB24\n");
return -1;
}
unsigned short textMapX = (((unsigned short)(depthMD.FullXRes() - 1)/512) + 1 * 512);
unsigned short textMapY = (((unsigned short)(depthMD.FullYRes() - 1)/512) + 1 * 512);
XnRGB24Pixel* pTextMap = (XnRGB24Pixel*) malloc(textMapX * textMapY * sizeof(XnRGB24Pixel));
rc = context.WaitOneUpdateAll(depth);
depth.GetMetaData(depthMD);
image.GetMetaData(imageMD);
const XnDepthPixel* pDepth = depthMD.Data();
const XnUInt8* pImage = imageMD.Data();
unsigned int imageScale = GL_WIN_SIZE_X/depthMD.FullXRes();
xnOSMemSet(depthHist,0,MAX * sizeof(float));
unsigned int numberOfPoints = 0;
for(XnUInt y = 0; y < depthMD.YRes(); ++ y)
{
for(XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth);
{
if(*pDepth != 0)
{
depthHist[*pDepth]++;
numberOfPoints++;
}
}
}
for(int index = 1; index < MAX; index++)
{
depthHist[index] += depthHist[index - 1];
}
if(numberOfPoints)
{
for(int index = 1; index < MAX; index++)
{
depthHist[index] = (unsigned int)(256 * (1.0f - (depthHist[index]/numberOfPoints)));
}
}
return 0;
}
I am also facing problem understanding the later part of the code.