Example #1
0
///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;
  }

}