Program: 26229
Project: 26229
Buggy source:
/** 
 * Apply the final transformation (multi-thread version).
 * @param intervals number of intervals in the deformation
 * @param cx x- deformation coefficients
 * @param cy y- deformation coefficients
 * @param bIsReverse flag to determine the transformation direction (target-source=FALSE or source-target=TRUE)
 * @return output images (depending on the output level)
 */
private ImagePlus applyTransformationMultiThread(final int intervals,final double[][] cx,final double[][] cy,boolean bIsReverse){
  BSplineModel auxTarget=target;
  BSplineModel auxSource=source;
  Mask auxTargetMsk=targetMsk;
  Mask auxSourceMsk=sourceMsk;
  int auxTargetWidth=this.originalTargetIP.getWidth();
  int auxTargetHeight=this.originalTargetIP.getHeight();
  ImageProcessor originalIP=this.originalSourceIP;
  if (bIsReverse) {
    auxTarget=source;
    auxSource=target;
    auxTargetMsk=sourceMsk;
    auxSourceMsk=targetMsk;
    auxTargetWidth=this.originalSourceIP.getWidth();
    auxTargetHeight=this.originalSourceIP.getHeight();
    originalIP=this.originalTargetIP;
  }
  ImagePlus output_ip=null;
  final ImageStack is=new ImageStack(auxTargetWidth,auxTargetHeight);
  final String s=bIsReverse ? new String("String_Node_Str") : new String("String_Node_Str");
  BSplineModel swx=new BSplineModel(cx);
  BSplineModel swy=new BSplineModel(cy);
  if (!(originalIP instanceof ColorProcessor)) {
    final FloatProcessor fp=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    final FloatProcessor fp_mask=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    final FloatProcessor fp_target=new FloatProcessor(auxTargetWidth,auxTargetHeight,auxTarget.getImage());
    int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetHeight / nproc;
    if (auxTargetHeight % 2 != 0)     block_height++;
    int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    FloatProcessor[] fp_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fp_mask_tile=new FloatProcessor[nThreads];
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetWidth,block_height);
      fp_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fp_mask_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      threads[i]=new Thread(new GrayscaleResultTileMaker(swx,swy,auxSource,auxTargetWidth,auxTargetHeight,auxTargetMsk,auxSourceMsk,rects[i],fp_tile[i],fp_mask_tile[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      fp.insert(fp_tile[i],rects[i].x,rects[i].y);
      fp_tile[i]=null;
      fp_mask.insert(fp_mask_tile[i],rects[i].x,rects[i].y);
      fp_mask_tile[i]=null;
      rects[i]=null;
    }
    fp.resetMinAndMax();
    is.addSlice("String_Node_Str" + s + "String_Node_Str",fp);
    is.addSlice("String_Node_Str",fp_target);
    is.addSlice("String_Node_Str",fp_mask);
  }
 else {
    BSplineModel sourceR=new BSplineModel(((ColorProcessor)originalIP).toFloat(0,null),false,1);
    sourceR.setPyramidDepth(0);
    sourceR.startPyramids();
    BSplineModel sourceG=new BSplineModel(((ColorProcessor)originalIP).toFloat(1,null),false,1);
    sourceG.setPyramidDepth(0);
    sourceG.startPyramids();
    BSplineModel sourceB=new BSplineModel(((ColorProcessor)originalIP).toFloat(2,null),false,1);
    sourceB.setPyramidDepth(0);
    sourceB.startPyramids();
    try {
      sourceR.getThread().join();
      sourceG.getThread().join();
      sourceB.getThread().join();
    }
 catch (    InterruptedException e) {
      IJ.error("String_Node_Str" + e);
    }
    ColorProcessor cp=new ColorProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpR=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpG=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpB=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    ColorProcessor cp_mask=new ColorProcessor(auxTargetWidth,auxTargetHeight);
    int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetHeight / nproc;
    if (auxTargetHeight % 2 != 0)     block_height++;
    int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    FloatProcessor[] fpR_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fpG_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fpB_tile=new FloatProcessor[nThreads];
    ColorProcessor[] cp_mask_tile=new ColorProcessor[nThreads];
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetWidth,block_height);
      fpR_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fpG_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fpB_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      cp_mask_tile[i]=new ColorProcessor(rects[i].width,rects[i].height);
      threads[i]=new Thread(new ColorResultTileMaker(swx,swy,sourceR,sourceG,sourceB,auxTargetWidth,auxTargetHeight,auxTargetMsk,auxSourceMsk,rects[i],fpR_tile[i],fpG_tile[i],fpB_tile[i],cp_mask_tile[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      fpR.insert(fpR_tile[i],rects[i].x,rects[i].y);
      fpG.insert(fpG_tile[i],rects[i].x,rects[i].y);
      fpB.insert(fpB_tile[i],rects[i].x,rects[i].y);
      fpR_tile[i]=null;
      fpG_tile[i]=null;
      fpB_tile[i]=null;
      cp_mask.insert(cp_mask_tile[i],rects[i].x,rects[i].y);
      cp_mask_tile[i]=null;
      rects[i]=null;
    }
    cp.setPixels(0,fpR);
    cp.setPixels(1,fpG);
    cp.setPixels(2,fpB);
    cp.resetMinAndMax();
    is.addSlice("String_Node_Str" + s + "String_Node_Str",cp);
    is.addSlice("String_Node_Str",bIsReverse ? this.originalSourceIP : this.originalTargetIP);
    is.addSlice("String_Node_Str",cp_mask);
  }
  if (outputLevel == 2) {
    computeDeformationVectors(intervals,cx,cy,is,bIsReverse);
    computeDeformationGrid(intervals,cx,cy,is,bIsReverse);
  }
  output_ip=new ImagePlus("String_Node_Str" + s + "String_Node_Str",is);
  output_ip.setSlice(1);
  output_ip.getProcessor().resetMinAndMax();
  return output_ip;
}

Fixed version (ground truth):
/** 
 * Apply the final transformation (multi-thread version).
 * @param intervals number of intervals in the deformation
 * @param cx x- deformation coefficients
 * @param cy y- deformation coefficients
 * @param bIsReverse flag to determine the transformation direction (target-source=FALSE or source-target=TRUE)
 * @return output images (depending on the output level)
 */
private ImagePlus applyTransformationMultiThread(final int intervals,final double[][] cx,final double[][] cy,boolean bIsReverse){
  BSplineModel auxTarget=target;
  BSplineModel auxSource=source;
  Mask auxTargetMsk=targetMsk;
  Mask auxSourceMsk=sourceMsk;
  int auxTargetWidth=this.originalTargetIP.getWidth();
  int auxTargetHeight=this.originalTargetIP.getHeight();
  ImageProcessor originalIP=this.originalSourceIP;
  if (bIsReverse) {
    auxTarget=source;
    auxSource=target;
    auxTargetMsk=sourceMsk;
    auxSourceMsk=targetMsk;
    auxTargetWidth=this.originalSourceIP.getWidth();
    auxTargetHeight=this.originalSourceIP.getHeight();
    originalIP=this.originalTargetIP;
  }
  ImagePlus output_ip=null;
  final ImageStack is=new ImageStack(auxTargetWidth,auxTargetHeight);
  final String s=bIsReverse ? new String("String_Node_Str") : new String("String_Node_Str");
  BSplineModel swx=new BSplineModel(cx);
  BSplineModel swy=new BSplineModel(cy);
  if (!(originalIP instanceof ColorProcessor)) {
    final FloatProcessor fp=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    final FloatProcessor fp_mask=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    final FloatProcessor fp_target=new FloatProcessor(auxTargetWidth,auxTargetHeight,auxTarget.getOriginalImage());
    if (auxSource.getOriginalImageWidth() > auxSource.getWidth()) {
      auxSource=new BSplineModel(originalIP,false,1);
      auxSource.setPyramidDepth(0);
      auxSource.startPyramids();
      try {
        auxSource.getThread().join();
      }
 catch (      InterruptedException e) {
        IJ.error("String_Node_Str" + e);
      }
    }
    int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetHeight / nproc;
    if (auxTargetHeight % 2 != 0)     block_height++;
    int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    FloatProcessor[] fp_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fp_mask_tile=new FloatProcessor[nThreads];
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetWidth,block_height);
      fp_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fp_mask_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      threads[i]=new Thread(new GrayscaleResultTileMaker(swx,swy,auxSource,auxTargetWidth,auxTargetHeight,auxTargetMsk,auxSourceMsk,rects[i],fp_tile[i],fp_mask_tile[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      fp.insert(fp_tile[i],rects[i].x,rects[i].y);
      fp_tile[i]=null;
      fp_mask.insert(fp_mask_tile[i],rects[i].x,rects[i].y);
      fp_mask_tile[i]=null;
      rects[i]=null;
    }
    fp.resetMinAndMax();
    is.addSlice("String_Node_Str" + s + "String_Node_Str",fp);
    is.addSlice("String_Node_Str",fp_target);
    is.addSlice("String_Node_Str",fp_mask);
  }
 else {
    BSplineModel sourceR=new BSplineModel(((ColorProcessor)originalIP).toFloat(0,null),false,1);
    sourceR.setPyramidDepth(0);
    sourceR.startPyramids();
    BSplineModel sourceG=new BSplineModel(((ColorProcessor)originalIP).toFloat(1,null),false,1);
    sourceG.setPyramidDepth(0);
    sourceG.startPyramids();
    BSplineModel sourceB=new BSplineModel(((ColorProcessor)originalIP).toFloat(2,null),false,1);
    sourceB.setPyramidDepth(0);
    sourceB.startPyramids();
    try {
      sourceR.getThread().join();
      sourceG.getThread().join();
      sourceB.getThread().join();
    }
 catch (    InterruptedException e) {
      IJ.error("String_Node_Str" + e);
    }
    ColorProcessor cp=new ColorProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpR=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpG=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    FloatProcessor fpB=new FloatProcessor(auxTargetWidth,auxTargetHeight);
    ColorProcessor cp_mask=new ColorProcessor(auxTargetWidth,auxTargetHeight);
    int nproc=Runtime.getRuntime().availableProcessors();
    int block_height=auxTargetHeight / nproc;
    if (auxTargetHeight % 2 != 0)     block_height++;
    int nThreads=nproc;
    Thread[] threads=new Thread[nThreads];
    Rectangle[] rects=new Rectangle[nThreads];
    FloatProcessor[] fpR_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fpG_tile=new FloatProcessor[nThreads];
    FloatProcessor[] fpB_tile=new FloatProcessor[nThreads];
    ColorProcessor[] cp_mask_tile=new ColorProcessor[nThreads];
    for (int i=0; i < nThreads; i++) {
      int y_start=i * block_height;
      if (nThreads - 1 == i)       block_height=auxTargetHeight - i * block_height;
      rects[i]=new Rectangle(0,y_start,auxTargetWidth,block_height);
      fpR_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fpG_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      fpB_tile[i]=new FloatProcessor(rects[i].width,rects[i].height);
      cp_mask_tile[i]=new ColorProcessor(rects[i].width,rects[i].height);
      threads[i]=new Thread(new ColorResultTileMaker(swx,swy,sourceR,sourceG,sourceB,auxTargetWidth,auxTargetHeight,auxTargetMsk,auxSourceMsk,rects[i],fpR_tile[i],fpG_tile[i],fpB_tile[i],cp_mask_tile[i]));
      threads[i].start();
    }
    for (int i=0; i < nThreads; i++) {
      try {
        threads[i].join();
        threads[i]=null;
      }
 catch (      InterruptedException e) {
        e.printStackTrace();
      }
    }
    for (int i=0; i < nThreads; i++) {
      fpR.insert(fpR_tile[i],rects[i].x,rects[i].y);
      fpG.insert(fpG_tile[i],rects[i].x,rects[i].y);
      fpB.insert(fpB_tile[i],rects[i].x,rects[i].y);
      fpR_tile[i]=null;
      fpG_tile[i]=null;
      fpB_tile[i]=null;
      cp_mask.insert(cp_mask_tile[i],rects[i].x,rects[i].y);
      cp_mask_tile[i]=null;
      rects[i]=null;
    }
    cp.setPixels(0,fpR);
    cp.setPixels(1,fpG);
    cp.setPixels(2,fpB);
    cp.resetMinAndMax();
    is.addSlice("String_Node_Str" + s + "String_Node_Str",cp);
    is.addSlice("String_Node_Str",bIsReverse ? this.originalSourceIP : this.originalTargetIP);
    is.addSlice("String_Node_Str",cp_mask);
  }
  if (outputLevel == 2) {
    computeDeformationVectors(intervals,cx,cy,is,bIsReverse);
    computeDeformationGrid(intervals,cx,cy,is,bIsReverse);
  }
  output_ip=new ImagePlus("String_Node_Str" + s + "String_Node_Str",is);
  output_ip.setSlice(1);
  output_ip.getProcessor().resetMinAndMax();
  return output_ip;
}