///Max filter imgSrc with current settings and store result in imgDst void DMaxFilter::filterImage_(DImage &imgDst, const DImage &imgSrc, bool fAlreadyPadded, DProgress *pProg){ DMaxFiltType filtType; DImage *pImgPad; int wKern, hKern; int numKernPxls; int wUnpad, hUnpad; #ifndef D_NOTHREADS MAX_HUANG_8_THREAD_PARAMS_T rgParms[MAX_MAXFILT_THREADS]; pthread_t rgThreadID[MAX_MAXFILT_THREADS]; #endif filtType = _maxFiltType; pImgPad = (DImage*)&imgSrc; if(!fAlreadyPadded){ pImgPad = new DImage(); imgSrc.padEdges_(*pImgPad, _radiusX, _radiusX, _radiusY, _radiusY, DImage::DImagePadReplicate); } wUnpad = pImgPad->width()-(_radiusX*2); hUnpad = pImgPad->height()-(_radiusY*2); wKern = _radiusX * 2 + 1; hKern = _radiusY * 2 + 1; if(NULL == rgKern){ rgKern = (unsigned char*)malloc(sizeof(unsigned char) * wKern * hKern); if(!rgKern){ fprintf(stderr, "DMaxFilter::filterImage_() out of memory\n"); exit(1); } rgRightEdge = (int*)malloc(sizeof(int)*hKern); if(!rgRightEdge){ fprintf(stderr, "DMaxFilter::filterImage_() out of memory\n"); exit(1); } if(DMaxFilt_circle == filtType){ fill_circle_kern_offsets(_radiusX, _radiusY, rgKern, rgRightEdge, &numKernPxls); } else{ fill_square_kern_offsets(_radiusX, _radiusY, rgKern, rgRightEdge, &numKernPxls); } } switch(imgSrc.getImageType()){ case DImage::DImage_u8: { imgDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1, imgSrc.getAllocMethod()); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ rgParms[tnum].pImgDst = &imgDst; rgParms[tnum].pImgSrc = pImgPad; rgParms[tnum].radiusX = _radiusX; rgParms[tnum].radiusY = _radiusY; rgParms[tnum].wKern = wKern; rgParms[tnum].hKern = hKern; rgParms[tnum].rgKern = rgKern; rgParms[tnum].numKernPxls = numKernPxls; rgParms[tnum].rgRightEdge = rgRightEdge; rgParms[tnum].pProg = NULL; rgParms[tnum].progStart = 0; rgParms[tnum].progMax = 1; rgParms[tnum].threadNumber = tnum; rgParms[tnum].numThreads = _numThreads; if(0 != pthread_create(&rgThreadID[tnum], NULL, DMaxFilter::DMaxFilter_Huang8threadWrap, &rgParms[tnum])){ fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn " "thread #%d. Exiting.\n", tnum); exit(1); } } #endif maxFiltHuang_u8(imgDst, *pImgPad, _radiusX, _radiusY, wKern, hKern, rgKern, numKernPxls, rgRightEdge, pProg, 0, hUnpad+1, 0, _numThreads); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ if(pthread_join(rgThreadID[tnum],NULL)) fprintf(stderr, "DMaxFilter::filterImage_() failed to join " "thread %d\n", tnum); } #endif if(NULL != pProg){ pProg->reportStatus(hUnpad+1, 0, hUnpad+1);//report progress complete } } break; case DImage::DImage_RGB: { DImage imgR, imgG, imgB; DImage imgRDst, imgGDst, imgBDst; imgRDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1, imgSrc.getAllocMethod()); imgGDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1, imgSrc.getAllocMethod()); imgBDst.create(wUnpad, hUnpad, DImage::DImage_u8, 1, imgSrc.getAllocMethod()); pImgPad->splitRGB(imgR, imgG, imgB); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ rgParms[tnum].pImgDst = &imgRDst; rgParms[tnum].pImgSrc = &imgR; rgParms[tnum].radiusX = _radiusX; rgParms[tnum].radiusY = _radiusY; rgParms[tnum].wKern = wKern; rgParms[tnum].hKern = hKern; rgParms[tnum].rgKern = rgKern; rgParms[tnum].numKernPxls = numKernPxls; rgParms[tnum].rgRightEdge = rgRightEdge; rgParms[tnum].pProg = NULL; rgParms[tnum].progStart = 0; rgParms[tnum].progMax = 1; rgParms[tnum].threadNumber = tnum; rgParms[tnum].numThreads = _numThreads; if(0 != pthread_create(&rgThreadID[tnum], NULL, DMaxFilter::DMaxFilter_Huang8threadWrap, &rgParms[tnum])){ fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn " "thread #%d. Exiting.\n",tnum); exit(1); } } #endif maxFiltHuang_u8(imgRDst, imgR, _radiusX, _radiusY, wKern, hKern, rgKern, numKernPxls, rgRightEdge, pProg, 0, 3 * hUnpad); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ if(pthread_join(rgThreadID[tnum],NULL)) fprintf(stderr, "DMaxFilter::filterImage_() failed to join " "thread %d\n", tnum); } for(int tnum = 1; tnum < _numThreads; ++tnum){ rgParms[tnum].pImgDst = &imgGDst; rgParms[tnum].pImgSrc = &imgG; if(0 != pthread_create(&rgThreadID[tnum], NULL, DMaxFilter::DMaxFilter_Huang8threadWrap, &rgParms[tnum])){ fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn " "thread #%d. Exiting.\n",tnum); exit(1); } } #endif maxFiltHuang_u8(imgGDst, imgG, _radiusX, _radiusY, wKern, hKern, rgKern, numKernPxls, rgRightEdge, pProg, hUnpad, 3 * hUnpad); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ if(pthread_join(rgThreadID[tnum],NULL)) fprintf(stderr, "DMaxFilter::filterImage_() failed to join " "thread %d\n", tnum); } for(int tnum = 1; tnum < _numThreads; ++tnum){ rgParms[tnum].pImgDst = &imgBDst; rgParms[tnum].pImgSrc = &imgB; if(0 != pthread_create(&rgThreadID[tnum], NULL, DMaxFilter::DMaxFilter_Huang8threadWrap, &rgParms[tnum])){ fprintf(stderr, "DMaxFilter::filterImage_() failed to spawn " "thread #%d. Exiting.\n",tnum); exit(1); } } #endif maxFiltHuang_u8(imgBDst, imgB, _radiusX, _radiusY, wKern, hKern, rgKern, numKernPxls, rgRightEdge, pProg, 2 * hUnpad, 3 * hUnpad+1); #ifndef D_NOTHREADS for(int tnum = 1; tnum < _numThreads; ++tnum){ if(pthread_join(rgThreadID[tnum],NULL)) fprintf(stderr, "DMaxFilter::filterImage_() failed to join " "thread %d\n", tnum); } #endif if(NULL != pProg){ pProg->reportStatus(3*hUnpad+1,0,3*hUnpad+1);//report complete } imgDst.combineRGB(imgRDst, imgGDst, imgBDst); } break; case DImage::DImage_dbl_multi: { int w, h, wm1, hm1; // width, height of padded image double *pDst; double *pPad; double *rgWindowBuff; fprintf(stderr, "DMaxFilter::filterImage_() performing brute-force " "(slow) max filter on double image... NOT YET IMPLEMENTED!\n"); exit(1); // w = pImgPad->width(); // h = pImgPad->height(); // wm1=w-1; // hm1 = h-1; // imgDst.create(wUnpad, hUnpad, DImage::DImage_dbl_multi, // imgSrc.numChannels(), imgSrc.getAllocMethod()); // rgWindowBuff = (double*)malloc(sizeof(double)*wKern*hKern); // D_CHECKPTR(rgWindowBuff); // for(int chan = 0; chan < imgSrc.numChannels(); ++chan){ // pDst = imgDst.dataPointer_dbl(chan); // pPad = pImgPad->dataPointer_dbl(chan); // for(int y = 0, idxDst = 0; y < hUnpad; ++y){ // int idxPad; // idxPad = (y+_radiusY)*w+_radiusX; // for(int x=0; x < wUnpad; ++x, ++idxDst, ++idxPad){ // int count; // count = 0; // for(int dy = -_radiusY; dy <= _radiusY; ++dy){ // for(int dx = -_radiusX; dx <= _radiusX; ++dx){ // rgWindowBuff[count] = pPad[idxPad+(dy*w)+dx]; // ++count; // } // } // // find max // qsort((void*)rgWindowBuff, count, sizeof(double),compareDoubles); // pDst[idxDst] = rgWindowBuff[count / 2]; // }//end for(x... // }//end for(y... // }//end for(chan... // free(rgWindowBuff); }//end block in case DImage_dbl_multi break; default: //TODO: finish implementing this fprintf(stderr, "DMaxFilter::filterImage_() not yet implemented for " "some image types\n"); exit(1); break; } if(!fAlreadyPadded){ delete pImgPad; pImgPad = NULL; } }