Commit 24445249 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

modifying CLT window for shift

parent 3e7f255e
Loading
Loading
Loading
Loading
+66 −74
Original line number Diff line number Diff line
@@ -91,31 +91,43 @@ public class DttRad2 {
	//                1 - window index (0..n-1), [0] - minimal, [n-1] - max
	//                2 - sign of the C term  (-~c - d, +a -~b)
	//                3 - sign of the S term  (+~c - d, +a +~b)
	// Added for shift (+/- 0.5), using window derivative for correction:
	//                4 - window index (0..n-1), [0] - minimal, [n-1] - max (cos: same table, just different order
	//                5 - sign of derivative (to multiply by shift)
	private int [][] get_fold_indices(int x, int n){
		int n1 = n>>1;
		int [][] ind = new int[2][4];
		int [][] ind = new int[2][6];
		if (x <n1) {
			ind[0][0] = n + n1 - x - 1; // C: -cR, S: +cR
			ind[0][1] = n1     + x;
			ind[0][2] = -1;
			ind[0][3] =  1;
			ind[0][4] = n1     - x -1;
			ind[0][5] =  -1; // c - window derivative over shift is negative
			
			ind[1][0] = n + n1 + x;     // C: -d,  S: -d
			ind[1][1] = n1     - x - 1;
			ind[1][2] = -1;
			ind[1][3] = -1;

			ind[1][4] = n1     + x;
			ind[1][5] =  -1; // d - window derivative over shift is negative
		} else {
			x-=n1;
			ind[0][0] =          x;     // C: +a, S: +a
			ind[0][1] =          x;
			ind[0][2] =  1;
			ind[0][3] =  1;
			ind[0][4] =  n     - x - 1;
			ind[0][5] =  1;   // a - window derivative over shift is positive
			
			ind[1][0] = n      - x - 1; // C: -bR, S: +bR
			ind[1][1] = n      - x - 1;
			ind[1][2] = -1;
			ind[1][3] =  1;
			ind[1][4] =          x;
			ind[1][5] =  1;   // b - window derivative over shift is positive
		}
		
		return ind;
	}
	// is called when window is set
@@ -175,10 +187,8 @@ public class DttRad2 {
	public double [][][] get_fold_2d(
			int n,
			double scale_hor,
			double scale_vert
			){ // n - DCT and window size
//		if ((fold_index != null) && (fold_index.length == n*n)) return;
//		fold_index = new int[n*n][4];
			double scale_vert)
	{ // n - DCT and window size
		
			double [] hwindow_h = new double[n];
			double [] hwindow_v = new double[n];
@@ -189,7 +199,7 @@ public class DttRad2 {
				hwindow_h[i] = (ah > (Math.PI/2))? 0.0: Math.cos(ah);
				hwindow_v[i] = (av > (Math.PI/2))? 0.0: Math.cos(av);
			}
		double [][][] fold_sk = new double[2][n*n][4];
		double [][][] fold_sk = new double[4][n*n][4]; // was [2][n*n][4]
		int []    vert_ind =    new int[2];
		double [][] vert_k =    new double[2][2];
		int    [] hor_ind =     new int[2];
@@ -199,8 +209,6 @@ public class DttRad2 {
			fi = get_fold_indices(i,n);
			vert_ind[0] = fi[0][0];
			vert_ind[1] = fi[1][0];
//			vert_k[0] =   fi[0][2] * hwindow_v[fi[0][1]];
//			vert_k[1] =   fi[1][2] * hwindow_v[fi[1][1]];
			vert_k[0][0] =   fi[0][2] * hwindow_v[fi[0][1]]; // use cosine sign
			vert_k[0][1] =   fi[1][2] * hwindow_v[fi[1][1]]; // use cosine sign
			vert_k[1][0] =   fi[0][3] * hwindow_v[fi[0][1]]; // use sine sign
@@ -210,17 +218,12 @@ public class DttRad2 {
				fi = get_fold_indices(j,n);
				hor_ind[0] = fi[0][0];
				hor_ind[1] = fi[1][0];
//				hor_k[0] =   fi[0][2] * hwindow_h[fi[0][1]];
//				hor_k[1] =   fi[1][2] * hwindow_h[fi[1][1]];
				hor_k[0][0] =   fi[0][2] * hwindow_h[fi[0][1]]; // use cosine sign
				hor_k[0][1] =   fi[1][2] * hwindow_h[fi[1][1]]; // use cosine sign
				hor_k[1][0] =   fi[0][3] * hwindow_h[fi[0][1]]; // use sine sign
				hor_k[1][1] =   fi[1][3] * hwindow_h[fi[1][1]]; // use sine sign
				
				int indx = n*i + j;
//				for (int k = 0; k<4;k++) {
//					fold_sk[indx][k] =     vert_k[(k>>1) & 1] * hor_k[k & 1]; 
//				}
				
				for (int mode = 0; mode<4; mode++){
					for (int k = 0; k<4;k++) {
@@ -232,60 +235,57 @@ public class DttRad2 {
		return fold_sk;
	}

/*	
	// return index+1 and sign for 1-d imdct. x is index (0..2*n-1) of the imdct array, value is sign * (idct_index+1),
	// where idct_index (0..n-1) is index in the dct-iv array
	private int get_unfold_index_signes(int x, int n){
		int n1 = n>>1;
		int segm = x / n1;
		x = x % n1;
		switch (segm){
		case 0: return 1+ (x + n1);
		case 1: return -(n - x);
		case 2: return -(n1 - x);
		case 3: return -(1 + x);
		}
		return 0; //should never happen
	}
	private void set_unfold_2d(int n){ // n - DCT size
		if ((unfold_index != null) && (unfold_index.length == 4*n*n)) return;
		unfold_index = new int[4*n*n];
		unfold_k = new double[4][4*n*n];
		int n2 = 2*n;
		for (int i = 0; i < 2*n; i++ ){
			int index_vert = get_unfold_index(i,n);
			double k_vert = hwindow[(i < n)?i:n2 -i -1];
			if (index_vert <0 ){
				k_vert = -k_vert;
				index_vert = -index_vert;
			}
			index_vert --;
			index_vert *= n;
	// Generate (slightly - up to +/- 0.5) shifted window for standard sin window (derivative uses same table)
	public double [][][] get_shifted_fold_2d(
			int n,
			double shift_hor,
			double shift_vert)
	{ // n - DCT and window size
		
			for (int j = 0; j < 2*n; j++ ){
				int index_hor = get_unfold_index(j,n);
				double k_hor = hwindow[(j < n)?j:n2 -j -1];
				if (index_hor <0 ){
					k_hor = -k_hor;
					index_hor = -index_hor;
				}
				index_hor --; // pass 1 to next
//				unfold_index1[n2*i+j]=sgn_vert*sgn_hor*(index_vert+index_hor); // should never be 0
				unfold_index[n2*i+j]=(index_vert+index_hor);
				unfold_k[n2*i+j]=k_vert*k_hor;
		double [][][] fold_sk = new double[4][n*n][4];
		int []    vert_ind =    new int[2];
		double [][] vert_k =    new double[2][2];
		int    [] hor_ind =     new int[2];
		double [][] hor_k =     new double[2][2];
		int [][] fi;
		for (int i = 0; i < n; i++ ){
			fi = get_fold_indices(i,n);
			vert_ind[0] = fi[0][0];
			vert_ind[1] = fi[1][0];
			double vw0 = hwindow[fi[0][1]] + hwindow[fi[0][4]]*fi[0][5]* shift_vert;
			double vw1 = hwindow[fi[1][1]] + hwindow[fi[1][4]]*fi[1][5]* shift_vert;
			vert_k[0][0] =   fi[0][2] * vw0; // use cosine sign
			vert_k[0][1] =   fi[1][2] * vw1; // use cosine sign
			vert_k[1][0] =   fi[0][3] * vw0; // use sine sign
			vert_k[1][1] =   fi[1][3] * vw1; // use sine sign
			
				if (n < 8) System.out.print(String.format("%4d", unfold_index[n2*i+j]));
			for (int j = 0; j < n; j++ ){
				fi = get_fold_indices(j,n);
				hor_ind[0] = fi[0][0];
				hor_ind[1] = fi[1][0];
				double hw0 = hwindow[fi[0][1]] + hwindow[fi[0][4]]*fi[0][5]* shift_hor;
				double hw1 = hwindow[fi[1][1]] + hwindow[fi[1][4]]*fi[1][5]* shift_hor;
				
				hor_k[0][0] =   fi[0][2] * hw0; // use cosine sign
				hor_k[0][1] =   fi[1][2] * hw1; // use cosine sign
				hor_k[1][0] =   fi[0][3] * hw0; // use sine sign
				hor_k[1][1] =   fi[1][3] * hw1; // use sine sign
				
				int indx = n*i + j;
				
				for (int mode = 0; mode<4; mode++){
					for (int k = 0; k<4;k++) {
						fold_sk[mode][indx][k] =     vert_k[(mode>>1) &1][(k>>1) & 1] * hor_k[mode &1][k & 1]; 
					}
			if (n < 8) System.out.println();
				}
		if (n < 8) {
			for (int i = 0; i < 2*n; i++ ){
				System.out.println(i+"->"+get_unfold_index(i,n));
			}
		}
		return fold_sk;
	}
*/
	
	
	
	
	// return index and two signs (c,s) for 1-d imdct. x is index (0..2*n-1) of the imdct array, value is sign * (idct_index+1),
	// where idct_index (0..n-1) is index in the dct-iv array
	private int [] get_unfold_index_signs(int x, int n){
@@ -492,14 +492,6 @@ public class DttRad2 {
	}
	public double [] fold_tile(double [] x, int n, int mode) { // x should be 2n*2n
		return fold_tile(x,n, mode,this.fold_k);
//		double [] y = new double [n*n];
//		for (int i = 0; i<y.length;i++) {
//			y[i] = 0;
//			for (int k = 0; k < 4; k++){
//				y[i] += x[fold_index[i][k]] * fold_k[i][k];
//			}
//		}
//		return y;
	}

	public double [] fold_tile(
+23 −2
Original line number Diff line number Diff line
@@ -723,6 +723,13 @@ public class ImageDtt {
							String [] titles = {"CC","SC","CS","SS"};
							sdfa_instance.showArrays(clt_data[chn][tileY][tileX],  transform_size, transform_size, true, "pre-shifted_x"+tileX+"_y"+tileY, titles);
						}
						
						if ((globalDebugLevel > -1) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
								(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)) {
							System.out.println("clt_aberrations(): color="+chn+", tileX="+tileX+", tileY="+tileY+
									" fract_shiftXY[0]="+fract_shiftXY[0]+" fract_shiftXY[1]="+fract_shiftXY[1]);
						}
						
						if (!no_fract_shift) {
							// apply residual shift
							fract_shift(    // fractional shift in transform domain. Currently uses sin/cos - change to tables with 2? rotations
@@ -730,7 +737,9 @@ public class ImageDtt {
									transform_size,
									fract_shiftXY[0],            // double        shiftX,
									fract_shiftXY[1],            // double        shiftY,
									(globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
//									(globalDebugLevel > 0) && (tileX == debug_tileX) && (tileY == debug_tileY)); // external tile compare
									((globalDebugLevel > 0) && (chn==0) && (tileX >= debug_tileX - 2) && (tileX <= debug_tileX + 2) &&
											(tileY >= debug_tileY - 2) && (tileY <= debug_tileY+2)));									
							if ((globalDebugLevel > -1) && (debug_tileX == tileX) && (debug_tileY == tileY)) {
								showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
								String [] titles = {"CC","SC","CS","SS"};
@@ -1699,8 +1708,20 @@ public class ImageDtt {
			}			
		}
		// Fold and transform
		double [][][] fold_coeff = null;
		if (!dbg_transpose){
			fold_coeff = dtt.get_shifted_fold_2d(
					transform_size,
					residual_shift[0]*Math.PI/16,
					residual_shift[1]*Math.PI/16);
		}
		
		for (int dct_mode = 0; dct_mode <4; dct_mode++) {
			if (fold_coeff != null){
				clt_tile[dct_mode] = dtt.fold_tile (tile_in, transform_size, dct_mode, fold_coeff); // DCCT, DSCT, DCST, DSST
			} else {
				clt_tile[dct_mode] = dtt.fold_tile (tile_in, transform_size, dct_mode); // DCCT, DSCT, DCST, DSST
			}
			clt_tile[dct_mode] = dtt.dttt_iv   (clt_tile[dct_mode], dct_mode, transform_size);
		}
		if (bdebug) {