Esempio n. 1
0
int table_printf(BlockInfo* pRoot)
{
  MY_PRINTF("\n");
  if (pRoot == NULL) return 0;

  BlockInfo* pCur = pRoot;
  int count = 0;
  for (; pCur != NULL; pCur = element_child(pCur)) {
    MY_PRINTF("+%2x(%3lx)   ", element_key(pCur), element_size(pCur));
    count++;
  }
  MY_PRINTF("\n");
  count += table_printf(element_sibling(pRoot));
  return count;
}
Esempio n. 2
0
element* table_remove(BlockInfo* pRoot, BlockInfo* pBlock) {
  MY_PRINTF("  table remove\n");
  element* pCur = pRoot;
  MY_ASSERT(table_search(pRoot, element_size(pBlock)) != NULL);
  if (pCur == pBlock) {
    //pCur->child
    //pSib
    if (element_child(pCur)) {
      element* pSib = element_sibling(pCur);
      pCur = element_child(pCur);
      element_sibling(pCur) = pSib;
    }
    else {
      pCur = element_sibling(pCur);
    }
  }
  else if (element_size(pCur) == element_size(pBlock)) {
    MY_ASSERT(pCur != pBlock);
    MY_ASSERT(element_child(pCur) != NULL);
    element_child(pCur) = child_remove(element_child(pCur), pBlock);
  }
  else if (element_size(pCur) < element_size(pBlock)) {
    MY_ASSERT(element_sibling(pCur) != NULL);
    element_sibling(pCur) = table_remove(element_sibling(pCur), pBlock);
  }
  else {
    MY_ASSERT(element_size(pCur) > element_size(pBlock));
    MY_ASSERT(0);
  }
  return pCur;
};
Esempio n. 3
0
/*
 * Use an inline function here just to test '__textcoal_nt' sections on darwin.
 */
inline int MyDisasm(uintptr_t CodeIndex, PDISCPUSTATE pCpu, uint32_t *pcb)
{
    uint32_t cb;
    int rc = DISInstrWithReader(CodeIndex, DISCPUMODE_32BIT, DisasmTest1ReadCode, 0, pCpu, &cb);
    *pcb = cb;
    MY_PRINTF(("DISCoreOneEx -> rc=%d cb=%d  Cpu: bOpCode=%#x pCurInstr=%p (42=%d)\n", \
               rc, cb, pCpu->bOpCode, pCpu->pCurInstr, 42)); \
    return rc;
}
Esempio n. 4
0
extern "C" DECLEXPORT(int) DisasmTest1(void)
{
    DISCPUSTATE Cpu;
    uintptr_t CodeIndex = 0;
    uint32_t cb;
    int rc;
    MY_PRINTF(("DisasmTest1: %p\n", &DisasmTest1));

    memset(&Cpu, 0, sizeof(Cpu));

#define DISAS_AND_CHECK(cbInstr, enmOp) \
        do { \
            rc = MyDisasm(CodeIndex, &Cpu, &cb); \
            if (RT_FAILURE(rc)) \
                return CodeIndex | 0xf000; \
            if (Cpu.pCurInstr->uOpcode != (enmOp)) \
                return CodeIndex| 0xe000; \
            if (cb != (cbInstr)) \
                return CodeIndex | 0xd000; \
            CodeIndex += cb; \
        } while (0)

    DISAS_AND_CHECK(1, OP_PUSH);
    DISAS_AND_CHECK(2, OP_MOV);
    DISAS_AND_CHECK(3, OP_MOV);
    DISAS_AND_CHECK(6, OP_CMP);
    DISAS_AND_CHECK(2, OP_JNE);
    DISAS_AND_CHECK(3, OP_MOV);
    DISAS_AND_CHECK(4, OP_CMP);
    DISAS_AND_CHECK(2, OP_JNE);
    DISAS_AND_CHECK(5, OP_MOV);
    DISAS_AND_CHECK(2, OP_JMP);
    DISAS_AND_CHECK(2, OP_XOR);
    DISAS_AND_CHECK(2, OP_JNE);
    DISAS_AND_CHECK(3, OP_MOV);
    DISAS_AND_CHECK(1, OP_PUSH);
    DISAS_AND_CHECK(3, OP_MOV);
    DISAS_AND_CHECK(3, OP_MOV);
    DISAS_AND_CHECK(3, OP_CALL);
    DISAS_AND_CHECK(3, OP_ADD);
    DISAS_AND_CHECK(1, OP_POP);
    DISAS_AND_CHECK(1, OP_RETN);
    DISAS_AND_CHECK(1, OP_INT3);

    return rc;
}
Esempio n. 5
0
element* child_remove(BlockInfo* pFirst, BlockInfo* pBlock) {
  MY_PRINTF("  child remove %p %lx %p %lx\n", pFirst, element_size(pFirst), pBlock, element_size(pBlock));
  BlockInfo* pPrev = NULL;
  BlockInfo* pCur;
  for (pCur = pFirst; pCur != NULL; pCur = element_child(pCur)) {
    if (pCur == pBlock) {
      break;
    }
    pPrev = pCur;
  }
  MY_ASSERT(pCur != NULL);
  if (pPrev != NULL) {
    MY_ASSERT(pBlock != pFirst);
    element_child(pPrev) = element_child(pCur);
    return pFirst;
  }
  MY_ASSERT(pBlock == pFirst);
  return element_child(pCur);
}
void reconstruct_video(nTupleVolume<T>* imgVol, nTupleVolume<T>* occVol,
        nTupleVolume<T>* dispField, float sigmaColour, int useAllPatches, int reconstructionType)
{
	/*decalarations*/
    int xSize, ySize, tSize, nTupleSize; //img Size
    int i,j,k;                           //3-D index
    int iMin,iMax,jMin,jMax,kMin,kMax;   //Boundary of index Volume
    int ii,jj,kk, weightInd;
    int xDisp, yDisp, tDisp,xDispShift,yDispShift,tDispShift;
    int shiftI,shiftJ,shiftK;
    int hPatchSizeX,hPatchSizeY,hPatchSizeT; //half patchsize
    int hI,hJ,hK,doubleII,doubleJJ,doubleKK;
    int nbNeighbours;
    int correctInfo;
    float alpha, adaptiveSigma;
    float *weights,sumWeights, avgColourR, avgColourG, avgColourB, *colours;

	/*get image volume sizes*/
	xSize = imgVol->xSize;
	ySize = imgVol->ySize;
	tSize = imgVol->tSize;
	nTupleSize = imgVol->nTupleSize;

    hPatchSizeX = imgVol->hPatchSizeX;          //half patchsize
    hPatchSizeY = imgVol->hPatchSizeY;
    hPatchSizeT = imgVol->hPatchSizeT;
    
    /*allocate the (maximum) memory for the weights*/
    nbNeighbours = (imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); //number of neighbor
    weights = (float*)malloc((size_t)(nbNeighbours*sizeof(float)));
    colours = (float*)malloc((size_t)(NCHANNELS*nbNeighbours*sizeof(float)));
    
	/*check certain parameters*/
	if( (imgVol->patchSizeX != (imgVol->patchSizeX)) || (imgVol->patchSizeY != (imgVol->patchSizeY)) ||
        (imgVol->patchSizeT != (imgVol->patchSizeT))  )	/*check that the patch sizes are equal*/ //what is this for?
	{
		MY_PRINTF("Error in estimate_colour, the size of the patches are not equal in the two image volumes.");
		return;
	}
	if ( ( imgVol->patchSizeX > imgVol->xSize) || ( imgVol->patchSizeY > imgVol->ySize) || ( imgVol->patchSizeT > imgVol->tSize) )	/*check that the patch size is less or equal to each dimension in the images*/
	{
		MY_PRINTF("Error in estimate_colour, the patch size is to large for one or more of the dimensions of the image volume.");
		return;
	}

    for (k=0; k<(occVol->tSize); k++)       //run all over occVolume, t dimension
        for (j=0; j<(occVol->ySize); j++)   // y dimension
            for (i=0; i<(occVol->xSize); i++)//x dimension
            {    
                if ( ((occVol->get_value(i,j,k,0)) == 0) || ((occVol->get_value(i,j,k,0) == 2) )  )     //do not inpaint
                    continue;
                else    /*an occluded pixel (therefore to be modified)*/
                {
                    if (reconstructionType == NEAREST_NEIGHBOUR_RECONSTRUCTION )    //nearest neighbor reconstruction
                    {
                        xDisp = i + (int)dispField->get_value(i,j,k,0);             // x Displacement
                        yDisp = j + (int)dispField->get_value(i,j,k,1);             // y Displacement
                        tDisp = k + (int)dispField->get_value(i,j,k,2);             // t displacement

                        ////if pure replacing of pixels
                        copy_pixel_values_nTuple_volume(imgVol, imgVol,xDisp, yDisp, tDisp, i, j, k); //copy pixel value of ANN to occluded pixel.
                        ///set_value_nTuple_volume(occVol,i,j,k,2,0);
                        ///set_value_nTuple_volume(imgVol,i,j,k,0,0);
                        continue;
                    }
                     
                    // init array weight and colours
                    for (ii=0;ii<(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); ii++) //all the pixel in a patch
					{
                        weights[ii] = (float)-1; //weight for all pixel in patch
                        colours[ii] = (float)-1; //red
                        colours[ii + nbNeighbours] = (float)-1;//green chanel
                        colours[ii + 2*nbNeighbours] = (float)-1; //blue chanel
					}

                    sumWeights = 0.0;
                    alpha = FLT_MAX;
                    correctInfo = 0;
                    avgColourR = 0.0;
                    avgColourG = 0.0;
                    avgColourB = 0.0;
                    
                    //boudary for each patch
                    iMin = max_int(i - hPatchSizeX,0);
                    iMax = min_int(i + hPatchSizeX,(imgVol->xSize)-1 );
                    jMin = max_int(j - hPatchSizeY,0);
                    jMax = min_int(j + hPatchSizeY,(imgVol->ySize)-1 );
                    kMin = max_int(k - hPatchSizeT,0);
                    kMax = min_int(k + hPatchSizeT,(imgVol->tSize)-1 );
                    
                    /*
                    MY_PRINTF("iMin : %d, iMax : %d\n",iMin,iMax);
                    MY_PRINTF("jMin : %d, jMax : %d\n",jMin,jMax);
                    MY_PRINTF("kMin : %d, kMax : %d\n",kMin,kMax);*/
                    /*first calculate the weights*/
                    //run for each patch, calculate the spatial temporal neighbor of the patch
                    for (kk=kMin; kk<=kMax;kk++) //t dimension
                        for (jj=jMin; jj<=jMax;jj++)//y dimension
                            for (ii=iMin; ii<=iMax;ii++) //x dimension
                            {
                                /*get ssd similarity*/
                                xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); //get value dispX for pixel in the patch
                                yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                /*(spatio-temporally) shifted values of the covering patches*/
                                xDispShift = xDisp - (ii-i); //i + dispField (dispField for pixel (ii,jj,kk))
                                yDispShift = yDisp - (jj-j);
                                tDispShift = tDisp - (kk-k);
                        
                                 if (useAllPatches == 1)    // if use all patches
                                 {
                                     
                                    alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); //get min SSD and assign to alpha
                                    //transform matrice indice to array indice.
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    weights[weightInd] = dispField->get_value(ii,jj,kk,3); //weight is an array, SSD error of patch
                                    
                                    //colours is an array
                                    colours[weightInd] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,0)); //red
                                    colours[weightInd + nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,1));//green
                                    colours[weightInd + 2*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,2)); //blue
                                    correctInfo = 1;
                                 }
                                 else   /*only use some of the patches*/
                                 {
                                     if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1))
                                     {
                                        alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); 
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = dispField->get_value(ii,jj,kk,3);
                                        
                                        colours[weightInd] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,0));
                                        colours[weightInd + nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,1));
                                        colours[weightInd + 2*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,2));
                                        correctInfo = 1;
                                     }
                                     else
                                     {
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = -1;
                                         
                                        colours[weightInd] = -1;
                                        colours[weightInd + nbNeighbours] = -1;
                                        colours[weightInd + 2*nbNeighbours] = -1;
                                        continue;
                                     }
                                 }
                            }
                    
                    alpha = max_float(alpha,1);
                    if (correctInfo == 0)
                        continue;
                    
                    if (reconstructionType == BEST_PATCH_RECONSTRUCTION)
                    {
                        estimate_best_colour(imgVol,imgVol, weights, nbNeighbours, colours, sigmaColour, i, j, k);
                        continue;
                    }
                    //get the 75th percentile of the distances for setting the adaptive sigma
                    adaptiveSigma = get_adaptive_sigma(weights,(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT),sigmaColour);
					adaptiveSigma = max_float(adaptiveSigma,(float)0.1);
                    
                    /* ///MY_PRINTF("alpha : %f\n",alpha);
                    //adjust the weights : note, the indices which are outside the image boundaries
                    //will have no influence on the final weights (they are initialised to 0)  */
                    for (kk=kMin; kk<=kMax;kk++)
                        for (jj=jMin; jj<=jMax;jj++)
                            for (ii=iMin; ii<=iMax;ii++)
                            {
                                if (useAllPatches)
                                {
                                    /*weights = exp( -weights/(2*sigma�*alpha))*/
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/
                                    //
                                    sumWeights = (float)(sumWeights+weights[weightInd]);
                                }
                                else   /*only use some of the patches*/
                                {
                                     if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1))
                                     {
                                        /*weights = exp( -weights/(2*sigma�*alpha))*/
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/
                                        //
                                        sumWeights = (float)(sumWeights+weights[weightInd]);
                                     }
                                     else
                                         continue;
                                }
                            }

                    /*now calculate the pixel value(s)*/
                    for (kk=kMin; kk<=kMax;kk++)
                        for (jj=jMin; jj<=jMax;jj++)
                            for (ii=iMin; ii<=iMax;ii++)
                            {
                                if (useAllPatches)
                                {
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    /*get ssd similarity*/
                                    xDisp = ii + (int)dispField->get_value(ii,jj,kk,0);
                                    yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                    tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                    /*(spatio-temporally) shifted values of the covering patches*/
                                    xDispShift = xDisp - (ii-i);
                                    yDispShift = yDisp - (jj-j);
                                    tDispShift = tDisp - (kk-k);
                                    avgColourR = avgColourR + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,0));
                                    avgColourG = avgColourG + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,1));
                                    avgColourB = avgColourB + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,2));
                                }
                                else
                                {
                                     if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1))
                                     {
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        /*get ssd similarity*/
                                        xDisp = ii + (int)dispField->get_value(ii,jj,kk,0);
                                        yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                        tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                        /*(spatio-temporally) shifted values of the covering patches*/
                                        xDispShift = xDisp - (ii-i);
                                        yDispShift = yDisp - (jj-j);
                                        tDispShift = tDisp - (kk-k);
                                        avgColourR = avgColourR + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,0));
                                        avgColourG = avgColourG + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,1));
                                        avgColourB = avgColourB + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,2));
                                     }
                                     else
                                         continue;
                                }
                            }
                         /*MY_PRINTF("SumWeights : %f\n",sumWeights);*/
                    imgVol->set_value(i,j,k,0,(T)(avgColourR/(sumWeights)));
                    imgVol->set_value(i,j,k,1,(T)(avgColourG/(sumWeights)));
                    imgVol->set_value(i,j,k,2,(T)(avgColourB/(sumWeights)));
                    /*set_value_nTuple_volume(occVol,i,j,k,0,0);*/
                }
            }

        free(weights);
        free(colours);
        return;
}
/*this function calculates a nearest neighbour field, from imgVolA to imgVolB*/
void reconstruct_image_and_features(nTupleVolume* imgVol, nTupleVolume* occVol,
        nTupleVolume *normGradXvol, nTupleVolume *normGradYvol,
        nTupleVolume* dispField, float sigmaColour, int reconstructionType, bool initialisation)
{
	int useAllPatches = 0;
	if (initialisation==true)
		useAllPatches = 0;
	else
		useAllPatches = 1;
	
	/*decalarations*/
    int iMin,iMax,jMin,jMax,kMin,kMax;
    int weightInd;
    int xDisp, yDisp, tDisp,xDispShift,yDispShift,tDispShift;
    int hPatchSizeX,hPatchSizeY,hPatchSizeT;
    int nbNeighbours;
    int correctInfo;
    float alpha, adaptiveSigma;
    float *weights,sumWeights, *colours, *avgColours;
    float avgNormGradX,avgNormGradY;

    hPatchSizeX = imgVol->hPatchSizeX;
    hPatchSizeY = imgVol->hPatchSizeY;
    hPatchSizeT = imgVol->hPatchSizeT;
    
    /*allocate the (maximum) memory for the weights*/
    nbNeighbours = (imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT);
    weights = new float[nbNeighbours];
    colours = new float[(imgVol->nTupleSize)*nbNeighbours];
    avgColours = new float[imgVol->nTupleSize];
    
	/*check certain parameters*/
	if( (imgVol->patchSizeX != (imgVol->patchSizeX)) || (imgVol->patchSizeY != (imgVol->patchSizeY)) ||
		(imgVol->patchSizeT != (imgVol->patchSizeT))  )	/*check that the patch sizes are equal*/
	{
		MY_PRINTF("Error in estimate_colour, the size of the patches are not equal in the two image volumes.");
		return;
	}
	if ( ( imgVol->patchSizeX > imgVol->xSize) || ( imgVol->patchSizeY > imgVol->ySize) || ( imgVol->patchSizeT > imgVol->tSize) )	/*check that the patch size is less or equal to each dimension in the images*/
	{
		MY_PRINTF("Error in estimate_colour, the patch size is to large for one or more of the dimensions of the image volume.");
		return;
	}

    for (int k=0; k<(occVol->tSize); k++)
        for (int j=0; j<(occVol->ySize); j++)
            for (int i=0; i<(occVol->xSize); i++)
            {    
                if ( ((occVol->get_value(i,j,k,0)) == 0) || ((occVol->get_value(i,j,k,0) == 2) )  )
                    continue;
                else    /*an occluded pixel (therefore to be modified)*/
                {
                    if (reconstructionType == 1 )
                    {
                        xDisp = i + (int)dispField->get_value(i,j,k,0);
                        yDisp = j + (int)dispField->get_value(i,j,k,1);
                        tDisp = k + (int)dispField->get_value(i,j,k,2);

                        ////if pure replacing of pixels
                        copy_pixel_values_nTuple_volume(imgVol, imgVol,xDisp, yDisp, tDisp, i, j, k);
                        ///set_value_nTuple_volume(occVol,i,j,k,2,0);
                        ///set_value_nTuple_volume(imgVol,i,j,k,0,0);
                        continue;
                    }
                     
                    //initialisation of the weight and colour vectors
                    for (int ii=0;ii<(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); ii++)
					{
						weights[ii] = (float)-1;
						for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
						{
							colours[ii + colourInd*nbNeighbours] = (float)-1;
						}
					}
					for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
					{
						avgColours[colourInd] = (float)0.0;
					}

                    sumWeights = 0.0;
                    alpha = FLT_MAX;
                    correctInfo = 0;
                    
                    avgNormGradX = 0.0;
                    avgNormGradY = 0.0;
                    
                    iMin = max_int(i - hPatchSizeX,0);
                    iMax = min_int(i + hPatchSizeX,(imgVol->xSize)-1 );
                    jMin = max_int(j - hPatchSizeY,0);
                    jMax = min_int(j + hPatchSizeY,(imgVol->ySize)-1 );
                    kMin = max_int(k - hPatchSizeT,0);
                    kMax = min_int(k + hPatchSizeT,(imgVol->tSize)-1 );
                    
                    /*
                    MY_PRINTF("iMin : %d, iMax : %d\n",iMin,iMax);
                    MY_PRINTF("jMin : %d, jMax : %d\n",jMin,jMax);
                    MY_PRINTF("kMin : %d, kMax : %d\n",kMin,kMax);*/
                    /*first calculate the weights*/
                    for (int kk=kMin; kk<=kMax;kk++)
                        for (int jj=jMin; jj<=jMax;jj++)
                            for (int ii=iMin; ii<=iMax;ii++)
                            {
                                /*get ssd similarity*/
                                xDisp = ii + (int)dispField->get_value(ii,jj,kk,0);
                                yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                /*(spatio-temporally) shifted values of the covering patches*/
                                xDispShift = xDisp - (ii-i);
                                yDispShift = yDisp - (jj-j);
                                tDispShift = tDisp - (kk-k);
                        
                                 if (useAllPatches == 1)
                                 {
                                     
                                    alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); 
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    weights[weightInd] = dispField->get_value(ii,jj,kk,3);
                                    
                                    
                                    for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
									{
										colours[weightInd + colourInd*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd));
									}
                                    correctInfo = 1;
                                 }
                                 else   /*only use some of the patches*/
                                 {
                                     if ((occVol->get_value(ii,jj,kk,0)) == 0)
                                     {
                                        alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); 
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = dispField->get_value(ii,jj,kk,3);
                                        
                                        for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
										{
											colours[weightInd + colourInd*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd));
										}
                                        correctInfo = 1;
                                     }
                                     else
                                     {
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = -1;
                                        
                                        for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
										{
											colours[weightInd + colourInd*nbNeighbours] = (float)-1;
										}
                                        continue;
                                     }
                                 }
                            }
                    
                    alpha = max_float(alpha,1);
                    if (correctInfo == 0)
                        continue;
                    
                    if (reconstructionType == 3)
                    {
                        estimate_best_colour(imgVol, weights, nbNeighbours, colours, i, j, k);
                        continue;
                    }
                    //get the 75th percentile of the distances for setting the adaptive sigma
                    adaptiveSigma = get_adaptive_sigma(weights,(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT),sigmaColour);
					adaptiveSigma = max_float(adaptiveSigma,(float)0.1);
                    
                    /* ///MY_PRINTF("alpha : %f\n",alpha);
                    //adjust the weights : note, the indices which are outside the image boundaries
                    //will have no influence on the final weights (they are initialised to 0)  */
                    for (int kk=kMin; kk<=kMax;kk++)
                        for (int jj=jMin; jj<=jMax;jj++)
                            for (int ii=iMin; ii<=iMax;ii++)
                            {
                                if (useAllPatches)
                                {
                                    /*weights = exp( -weights/(2*sigma*alpha))*/
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/
                                    //
                                    sumWeights = (float)(sumWeights+weights[weightInd]);
                                }
                                else   /*only use some of the patches*/
                                {
                                     if ((occVol->get_value(ii,jj,kk,0)) == 0)
                                     {
                                        /*weights = exp( -weights/(2*sigma*alpha))*/
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/
                                        //
                                        sumWeights = (float)(sumWeights+weights[weightInd]);
                                     }
                                     else
                                         continue;
                                }
                            }

                    /*now calculate the pixel value(s)*/
                    for (int kk=kMin; kk<=kMax;kk++)
                        for (int jj=jMin; jj<=jMax;jj++)
                            for (int ii=iMin; ii<=iMax;ii++)
                            {
                                if (useAllPatches)
                                {
                                    weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                    /*get ssd similarity*/
                                    xDisp = ii + (int)dispField->get_value(ii,jj,kk,0);
                                    yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                    tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                    /*(spatio-temporally) shifted values of the covering patches*/
                                    xDispShift = xDisp - (ii-i);
                                    yDispShift = yDisp - (jj-j);
                                    tDispShift = tDisp - (kk-k);
                                    
                                    for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
									{
										avgColours[colourInd] = avgColours[colourInd] + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd));
									}

                                    avgNormGradX = avgNormGradX + (float)(weights[weightInd])*(normGradXvol->get_value(xDispShift,yDispShift,tDispShift,0));
                                    avgNormGradY = avgNormGradY + (float)(weights[weightInd])*(normGradYvol->get_value(xDispShift,yDispShift,tDispShift,0));
                                }
                                else
                                {
                                     if ((occVol->get_value(ii,jj,kk,0)) == 0)
                                     {
                                        weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin);
                                        /*get ssd similarity*/
                                        xDisp = ii + (int)dispField->get_value(ii,jj,kk,0);
                                        yDisp = jj + (int)dispField->get_value(ii,jj,kk,1);
                                        tDisp = kk + (int)dispField->get_value(ii,jj,kk,2);
                                        /*(spatio-temporally) shifted values of the covering patches*/
                                        xDispShift = xDisp - (ii-i);
                                        yDispShift = yDisp - (jj-j);
                                        tDispShift = tDisp - (kk-k);
                                        for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
										{
											avgColours[colourInd] = avgColours[colourInd] + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd));
										}

                                        avgNormGradX = avgNormGradX + (float)(weights[weightInd])*(normGradXvol->get_value(xDispShift,yDispShift,tDispShift,0));
                                        avgNormGradY = avgNormGradY + (float)(weights[weightInd])*(normGradYvol->get_value(xDispShift,yDispShift,tDispShift,0));
                                     }
                                     else
                                         continue;
                                }
                            }
                         /*MY_PRINTF("SumWeights : %f\n",sumWeights);*/
					for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++)
					{
						imgVol->set_value(i,j,k,colourInd,(imageDataType)((avgColours[colourInd])/(sumWeights)));
					}

                    normGradXvol->set_value(i,j,k,0,(imageDataType)(avgNormGradX/(sumWeights)));
                    normGradYvol->set_value(i,j,k,0,(imageDataType)(avgNormGradY/(sumWeights)));
                    /*set_value_nTuple_volume(occVol,i,j,k,0,0);*/
                }
            }

        delete weights;
        delete colours;
        delete avgColours;
        return;
}
nTupleVolume * inpaint_image( nTupleVolume *imgVolIn, nTupleVolume *occVolIn,
patchMatchParameterStruct *patchMatchParams, inpaintingParameterStruct *inpaintingParams)
{
	
	// ******************************************************************** //
	// **** AUTOMATICALLY DETERMINE NUMBER OF LEVELS, IF NOT SPECIFIED **** //
	// ******************************************************************** //
	if (inpaintingParams->nLevels == -1)
	{
		inpaintingParams->nLevels =
			determine_multiscale_level_number(occVolIn,imgVolIn->patchSizeX,imgVolIn->patchSizeY);
	}
	display_inpainting_parameters(inpaintingParams);
	display_patch_match_parameters(patchMatchParams);
	
	nTupleVolume *imgVolOut;

	// ************************** //
	// **** CREATE PYRDAMIDS **** //
	// ************************** //
	nTupleVolumePyramid imgVolPyramid = create_nTupleVolume_pyramid(imgVolIn, inpaintingParams->nLevels);
	nTupleVolumePyramid occVolPyramid = create_nTupleVolume_pyramid_binary(occVolIn, inpaintingParams->nLevels);
	featurePyramid featuresVolPyramid;
	if (inpaintingParams->useFeatures == true)
	{
		double t1 = clock();
		featuresVolPyramid = create_feature_pyramid(imgVolIn, occVolIn, inpaintingParams->nLevels);
		MY_PRINTF("\n\nFeatures calculation time: %f\n",((double)(clock()-t1)) / CLOCKS_PER_SEC);
	}
	else
	{
		featuresVolPyramid.normGradX = NULL;
        featuresVolPyramid.normGradY = NULL;
        featuresVolPyramid.nLevels = -1;
	}

	//create structuring element
	nTupleVolume *structElDilate = create_structuring_element("rectangle", imgVolIn->patchSizeX, imgVolIn->patchSizeY);
	
	//show_patch_match_parameters(patchMatchParams);
	
	// ****************************************** //
	// ************* START INPAINTING *********** //
	// ****************************************** //
	
	nTupleVolume *imgVol,*normGradXvol,*normGradYvol;
	nTupleVolume *shiftVol=NULL;
	for (int level=( (inpaintingParams->nLevels)-1); level>=0; level--)
	{
		printf("Current pyramid level : %d\n",level);
		nTupleVolume *imgVolPrevious,*occVol,*occVolDilate;

		if (patchMatchParams->maxShiftDistance != -1)		
			patchMatchParams->maxShiftDistance =
			(float)( (patchMatchParams->maxShiftDistance)/( pow((float)SUBSAMPLE_FACTOR,(float)level) ));
		
		imgVol = copy_image_nTuple(imgVolPyramid[level]);
		occVol = copy_image_nTuple(occVolPyramid[level]);
		//create dilated occlusion
		occVolDilate = imdilate(occVol, structElDilate);
		
		if (featuresVolPyramid.nLevels >= 0)
		{
			normGradXvol = copy_image_nTuple((featuresVolPyramid.normGradX)[level]);
			normGradYvol = copy_image_nTuple((featuresVolPyramid.normGradY)[level]);
			//attach features to patchMatch parameters
			patchMatchParams->normGradX = normGradXvol;
			patchMatchParams->normGradY = normGradYvol;
		}
					
		//initialise solution
		if (level == ((inpaintingParams->nLevels)-1))
		{
			shiftVol = new nTupleVolume(4,imgVol->xSize,imgVol->ySize,imgVol->patchSizeX,imgVol->patchSizeY,IMAGE_INDEXING);
			shiftVol->set_all_image_values(0);
			printf("\nInitialisation started\n\n\n");
			initialise_inpainting(imgVol,occVol,featuresVolPyramid,shiftVol,patchMatchParams);
			patchMatchParams->partialComparison = 0;
			printf("\nInitialisation finished\n\n\n");
			
			if (featuresVolPyramid.nLevels >= 0)	//retrieve features from the pointers in the patchMatch parameters
			{
				normGradXvol = patchMatchParams->normGradX;
				normGradYvol = patchMatchParams->normGradY;
			}
		}
		else	//reconstruct current solution
		{
			if (featuresVolPyramid.nLevels >= 0)
			{
				reconstruct_image_and_features(imgVol, occVol,
				normGradXvol, normGradYvol,
				shiftVol, SIGMA_COLOUR);
			}
			else
			{
				reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR);
				//write_shift_map(shiftVol,fileOut);
			}
		}
		
		calclulate_patch_distances(imgVol,imgVol,shiftVol,occVolDilate,patchMatchParams);
		
		//iterate ANN search and reconstruction
		int iterationNb = 0;
		imageDataType residual = FLT_MAX;
		while( (residual > (inpaintingParams->residualThreshold) ) && (iterationNb < (inpaintingParams->maxIterations) ) )
		{
			//copy current imgVol
			imgVolPrevious = copy_image_nTuple(imgVol);
			patch_match_ANN(imgVol,imgVol,shiftVol,occVolDilate,occVolDilate,patchMatchParams);
			if (featuresVolPyramid.nLevels >= 0)
			{
				reconstruct_image_and_features(imgVol, occVol,
        			normGradXvol, normGradYvol,
        			shiftVol, SIGMA_COLOUR);
			}
			else
				reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR);
			residual = calculate_residual(imgVol,imgVolPrevious,occVol);
			if (patchMatchParams->verboseMode == true)
				printf("Iteration number %d, residual = %f\n",iterationNb,residual);
			iterationNb++;
		}
		//upsample shift volume, if we are not on the finest level
		if (level >0)
		{	
			nTupleVolume * shiftVolTemp = up_sample_image(shiftVol, SUBSAMPLE_FACTOR,imgVolPyramid[level-1]);
			delete(shiftVol);
			shiftVol = copy_image_nTuple(shiftVolTemp);
			shiftVol->multiply((imageDataType)SUBSAMPLE_FACTOR);
			delete(shiftVolTemp);
		}
		else
		{
			reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR,3);
			imgVolOut = new nTupleVolume(imgVol);
		}
		//destroy structures
		delete(imgVol);
		delete(imgVolPrevious);
		delete(occVol);
		delete(occVolDilate);
		if (featuresVolPyramid.nLevels >= 0)
		{
			delete normGradXvol;
			delete normGradYvol;
		}
	}
	
	// ************************** //
	// **** DELETE STRUCTURES *** //
	// ************************** //
	for (int i=0; i< (inpaintingParams->nLevels); i++)
	{
		delete(imgVolPyramid[i]);
		delete(occVolPyramid[i]);
	}
	delete(imgVolPyramid);
	delete(occVolPyramid);
	delete(shiftVol);
	delete_feature_pyramid(featuresVolPyramid);
	delete(patchMatchParams);
	
	printf("Inpainting finished !\n");

	return(imgVolOut);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
        nTupleVolume<float> *imgVol, *occVol, 
                *gradXvol, *gradYvol, *normGradXvol, *normGradYvol, *dispField;
        int * imgVolSizes, *dispFieldSizes;
        float sigmaColour;
        float *dispFieldTemp;
        int numDimsImgVol, numDimsDispField;
        int useAllPatches, reconstructionType;
        parameterStruct *patchMatchParams;
        mwSize resultSize[4];
        
        if (nrhs < (SIGMA_COLOUR_INPUT+1))
        {
            mexErrMsgTxt("Error. A minimum of 10 parameters are needed in the spatio-temporal patch match mexfunction.\n");
            return;
        }

        ASSERT ( (mxGetClassID(prhs[IMG_VOL_INPUT]) == mxSINGLE_CLASS) & (mxGetClassID(prhs[OCC_VOL_INPUT]) == mxSINGLE_CLASS)
                 & (mxGetClassID(prhs[DISP_FIELD_INPUT]) == mxSINGLE_CLASS));

        /* Get sizes of variables*/
        imgVolSizes = (int*)mxGetDimensions(prhs[IMG_VOL_INPUT]);  /* sizes of imgVol*/
        numDimsImgVol = (int)mxGetNumberOfDimensions(prhs[IMG_VOL_INPUT]);  /*length of sizes of imgVolA*/
        dispFieldSizes = (int*)mxGetDimensions(prhs[DISP_FIELD_INPUT]);  /*sizes of imgVolB*/
        numDimsDispField = (int)mxGetNumberOfDimensions(prhs[DISP_FIELD_INPUT]);  /* length of sizes of dispField*/
        
        if ((numDimsImgVol != 4) || (numDimsDispField != 4))
        {
            mexPrintf("Number of dimensions :\n imgVol : %d\nimgVolFine : %d\nDispField : %d\n",numDimsImgVol,numDimsDispField);
            mexErrMsgTxt("Error, the number of array dimensions must be 4 (x,y,t,multivalue).");
			plhs[0] = mxCreateNumericMatrix((mwSize)1,(mwSize)1, mxINT32_CLASS, (mxComplexity)0);
            dispFieldTemp = (float*)mxGetPr(plhs[0]);
            *dispFieldTemp = -1;
            return;
        }
		
        //get the patchMatch parameters
        ASSERT(mxIsStruct(prhs[PATCH_MATCH_PARAMS_INPUT]) );
        patchMatchParams = (parameterStruct*)new parameterStruct;
        parse_patch_match_parameters(prhs[PATCH_MATCH_PARAMS_INPUT],patchMatchParams);
        /* sigma colour*/
        sigmaColour = (float)(*mxGetPr(prhs[SIGMA_COLOUR_INPUT]));  
        
        if ( (imgVolSizes[2] < patchMatchParams->patchSizeX) || (imgVolSizes[1] < patchMatchParams->patchSizeY) || (imgVolSizes[3] < patchMatchParams->patchSizeT) )
        {
            MY_PRINTF("Image sizes :\n x : %d, y : %d, t : %d\n",(int)imgVolSizes[2],(int)imgVolSizes[1],(int)imgVolSizes[3]);
            MY_PRINTF("Patch sizes :\n x : %d, y : %d, t : %d\n",(int)patchMatchParams->patchSizeX,(int)patchMatchParams->patchSizeY,(int)patchMatchParams->patchSizeT);
            mexErrMsgTxt("Error, the patch sizes are too large for the image.");
			plhs[0] = mxCreateNumericMatrix((mwSize)1,(mwSize)1, mxINT32_CLASS, (mxComplexity)0);
            dispFieldTemp = (float*)mxGetPr(plhs[0]);
            *dispFieldTemp = -1;
            return;
        }
        
        
        if (nrhs >= (USE_ALL_PATCHES_INPUT+1))
            useAllPatches = (int)(*mxGetPr(prhs[USE_ALL_PATCHES_INPUT]));  /* if we want to use all surrounding patches or not*/
        else
            useAllPatches = 1;
        
        if (nrhs >= (RECONSTRUCTION_TYPE_INPUT+1))
            reconstructionType = (int)(*mxGetPr(prhs[RECONSTRUCTION_TYPE_INPUT]));  /* the manner in which we want to reconstruct the image*/
        else
            reconstructionType = 0;

        
        int imageIndexing = 1;
        //input image volumes
        imgVol = new nTupleVolume<float>(3, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
            (float*)mxGetPr(prhs[IMG_VOL_INPUT]));
        occVol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
                (float*)mxGetPr(prhs[OCC_VOL_INPUT]));
        
        //shift volume
        dispField = new nTupleVolume<float>(4, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
            (float*)mxGetPr(prhs[DISP_FIELD_INPUT]));
        
        //features
        gradXvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
                (float*)patchMatchParams->gradX);
        gradYvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
                (float*)patchMatchParams->gradY);
        normGradXvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
                (float*)patchMatchParams->normGradX);
        normGradYvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3],
                patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing,
                (float*)patchMatchParams->normGradY);
        
        /*colour estimation*/
        reconstruct_videos(imgVol, occVol,
            gradXvol, gradYvol, normGradXvol, normGradYvol,
            dispField, (float)sigmaColour, useAllPatches, reconstructionType);
        
        /*OUTPUT*/
        /* Create output matrix*/
        resultSize[0] = (int)(imgVolSizes[0]);
        resultSize[1] = (int)(imgVolSizes[1]);
        resultSize[2] = (int)(imgVolSizes[2]);
        resultSize[3] = (int)(imgVolSizes[3]);
        plhs[0] = mxCreateNumericArray((mwSize)4,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0);
        float *imgVolOutTemp = (float*)mxGetPr(plhs[0]);
        memcpy(imgVolOutTemp,imgVol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*resultSize[3]*sizeof(float));
        
        
        //create other output matrices
        resultSize[0] = (int)(imgVolSizes[1]);
        resultSize[1] = (int)(imgVolSizes[2]);
        resultSize[2] = (int)(imgVolSizes[3]);
        
        plhs[1] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0);
        float* gradXoutTemp = (float*)mxGetPr(plhs[1]);
        memcpy(gradXoutTemp,gradXvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float));
        
        plhs[2] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0);
        float* gradYoutTemp = (float*)mxGetPr(plhs[2]);
        memcpy(gradYoutTemp,gradYvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float));
        
        plhs[3] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0);
        float* normGradXoutTemp = (float*)mxGetPr(plhs[3]);
        memcpy(normGradXoutTemp,normGradXvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float));
        
        plhs[4] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0);
        float* normGradYoutTemp = (float*)mxGetPr(plhs[4]);
        memcpy(normGradYoutTemp,normGradYvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float));
        
        delete imgVol;
        delete gradXvol;
        delete gradYvol;
        delete normGradXvol;
        delete normGradYvol;
        delete patchMatchParams;
        
        return;
}