[xiph-commits] r12460 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Mon Feb 12 18:01:52 PST 2007


Author: xiphmont
Date: 2007-02-12 18:01:51 -0800 (Mon, 12 Feb 2007)
New Revision: 12460

Modified:
   trunk/sushivision/panel-2d.c
Log:
Commit most of the primary fixes to discrete dimension optimizations



Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c	2007-02-12 20:25:12 UTC (rev 12459)
+++ trunk/sushivision/panel-2d.c	2007-02-13 02:01:51 UTC (rev 12460)
@@ -77,7 +77,7 @@
       }else{
 	if(val<0)val=0;
 	if(val>1)val=1;
-	c->y_map[i][j] = rint(val*65536.f);
+	c->y_map[i][j] = rint(val * (256.f*256.f*256.f));
       }
     }
   }
@@ -214,9 +214,10 @@
 }
 
 
-static int resample_helpers_init(scalespace *to, scalespace *from,
-				  int *delA, int *delB, 
-				  int *posA, int *posB){
+static float resample_helpers_init(scalespace *to, scalespace *from,
+				   unsigned char *delA, unsigned char *delB, 
+				   int *posA, int *posB,
+				   int xymul){
   int i;
   int dw = from->pixels;
   int pw = to->pixels;
@@ -226,6 +227,7 @@
   long del = scalespace_scaleoff(to,from);
   int bin = del / scaleden;
   del -= bin * scaleden; 
+  int discscale = (scaleden>scalenum?scalenum:scaleden);
 
   for(i=0;i<pw;i++){
     long del2 = del + scalenum;
@@ -237,13 +239,15 @@
       del = 0;
       del2 -= scaleden;
       sizeceil--;
-      sizefloor--;
     }
     
     if(del2 > scaleden && bin>=0 && bin<dw){
+      int total = xymul*scalenum/discscale;
 
-      delA[i] = scaleden - del;
+      delA[i] = (xymul * (scaleden - del)) / discscale;
       posA[i] = bin;
+      total -= delA[i];
+      total -= xymul*(sizeceil-2);
 
       while(bin+sizeceil>dw){
 	sizeceil--;
@@ -251,7 +255,7 @@
       }
 
       del2 %= scaleden;
-      delB[i] = del2;
+      delB[i] = total; // don't leak 
       posB[i] = bin+sizeceil;
 
     }else{
@@ -261,19 +265,35 @@
 	delB[i] = 0;
 	posB[i] = 0;
       }else{
-	delA[i] = del2 - del;
+	delA[i] = (xymul * (del2-del)) / discscale;
 	posA[i] = bin;
 	delB[i] = 0;
 	posB[i] = bin+1;
+	if(del2 == scaleden)del2=0;
       }
     }
 
     bin += sizefloor;
     del = del2;
   }
-  return scaleden;
+  return (float)discscale/scalenum;
 }
 
+static inline void l_mapping_calc( void (*m)(int,int, lcolor*), 
+				   int low,
+				   float range,
+				   int in, 
+				   int alpha, 
+				   int mul, 
+				   lcolor *outc){
+  if(mul && !isnan(in) && in>=alpha){
+    int val = rint((in - low) * range);
+    if(val<0)val=0;
+    if(val>65536)val=65536;
+    m(val,mul,outc);
+  }
+}
+
 /* the data rectangle is data width/height mapped deltas.  we render
    and subsample at the same time. */
 /* enter with no locks; only data is not replicated local storage. */
@@ -286,16 +306,15 @@
   int ph = panely.pixels;
   int dh = datay.pixels;
   int i,j;
-  int ol_alpha = rint(obj_alpha*65536.f);
+  int ol_alpha = rint(obj_alpha * (256.f*256.f*256.f));
+  int ol_low = rint(map->low * (256.f*256.f*256.f));
+  float ol_range = map->i_range * (1.f/256.f);
   if(!in_data)return;
 
   int *data = malloc(dw*dh*sizeof(*data));
   
   gdk_threads_enter ();
-  if(serialno != p2->serialno){
-    free(data);
-    goto abort;
-  }
+  if(serialno != p2->serialno) goto abort;
   memcpy(data,in_data,dw*dh*sizeof(*data));
   gdk_threads_leave ();
 
@@ -303,108 +322,84 @@
     /* resampled row computation */
 
     /* by column */
-    int   xdelA[pw];
-    int   xdelB[pw];
+    unsigned char   xdelA[pw];
+    unsigned char   xdelB[pw];
     int   xnumA[pw];
     int   xnumB[pw];
-    int   xnum= scalespace_scalenum(&panelx,&datax);
-    int   xden = resample_helpers_init(&panelx, &datax, xdelA, xdelB, xnumA, xnumB);
+    float xsc = resample_helpers_init(&panelx, &datax, xdelA, xdelB, xnumA, xnumB, 17);
 
     /* by row */
-    int   y_scaledel = scalespace_scaledel(&panely,&datay);
-    int   ydelA[ph];
-    int   ydelB[ph];
+    unsigned char   ydelA[ph];
+    unsigned char   ydelB[ph];
     int   ynumA[ph];
     int   ynumB[ph];
-    int   ynum= scalespace_scalenum(&panely,&datay);
-    int   yden = resample_helpers_init(&panely, &datay, ydelA, ydelB, ynumA, ynumB);
+    float ysc = resample_helpers_init(&panely, &datay, ydelA, ydelB, ynumA, ynumB, 15);
 
-    int den = xden*yden;
-    float idel = 255./(ynum*xnum);
+    float idel = ysc * xsc;
     ucolor *mix = panel;
+    int xy=0;
 
-    /* by row */
+    /* by panel row */
     for(i=0;i<ph;i++){
-      /* render is done into a temporary line because of the way alpha
-	 blending is done; the background for the blend must be taken
-	 from the original line */
 
-      int *dline_start = data + ynumA[i]*dw;
       int yend=ynumB[i];
       
-      /* by col */
+      /* by panel col */
       for(j=0;j<pw;j++){
 	
 	lcolor out = (lcolor){0,0,0,0}; 
 	int ydel = ydelA[i];
-	int *dline = dline_start;
-	
-	int x=xnumA[j];
-	int y=ynumA[i];
-	int xend=xnumB[j];
+	int y = ynumA[i];
+
+	int xstart = y*dw + xnumA[j];
+	int xend = y*dw + xnumB[j];
+	int dx = xstart;
 	int xA = xdelA[j];
 	int xB = xdelB[j];
 
-	if(y<yend){
-	  // first line
-	  if(x<xend){
-	    if(dline[x]>=ol_alpha)
-	      map->mapfunc(dline[x],ydel*xA,&out);
-	    x++;
-	    
-	    for(; x < xend-1; x++)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],ydel*xden,&out);
-	    
-	    if(x<xend)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],ydel*xB,&out);
-	  }
-	  y++;
-	  dline+=dw;
+	// first line
+	l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx++], ol_alpha, ydel*xA, &out);
 
-	  // mid lines
-	  for(;y<yend-1;y++){
-	    x = xnumA[j];
-	    if(dline[x]>=ol_alpha)
-	      map->mapfunc(dline[x],xA*yden,&out);
-	    x++;
-	    
-	    for(; x < xend-1; x++)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],den,&out);
-	    
-	    if(x<xend)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],xB*yden,&out);
+	for(; dx < xend-1; dx++)
+	  l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, ydel*17, &out);
+	
+	if(dx<xend)
+	  l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, ydel*xB, &out);
+	y++;
+	
+	// mid lines
+	for(;y<yend-1;y++){
+	  dx = xstart += dw;
+	  xend += dw;
+	  l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx++], ol_alpha, 15*xA, &out);
 
-	    dline+=dw;
-	  }
-	    
-	  // last line
-	  if(y<yend){
-	    x = xnumA[j];
-	    ydel = ydelB[i];
-	    if(dline[x]>=ol_alpha)
-	      map->mapfunc(dline[x],xA*ydel,&out);
-	    x++;
-	    
-	    for(; x < xend-1; x++)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],ydel*xden,&out);
-	    
-	    if(x<xend)
-	      if(dline[x]>=ol_alpha)
-		map->mapfunc(dline[x],xB*ydel,&out);
-	  }
+	  for(; dx < xend-1; dx++)
+	    l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, 255, &out);
+	
+	  if(dx<xend)
+	    l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, 15*xB, &out);
 	}
+	
+	// last line
+	if(y<yend){
+	  dx = xstart += dw;
+	  xend += dw;
+	  ydel = ydelB[i];
+	  l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx++], ol_alpha, ydel*xA, &out);
+	  
+	  for(; dx < xend-1; dx++)
+	    l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, ydel*17, &out);
+	  
+	  if(dx<xend)
+	    l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx], ol_alpha, ydel*xB, &out);
+	}
 
-	*mix = map->mixfunc( (ucolor)(((u_int32_t)(out.a*idel)<<24) +
-				      ((u_int32_t)(out.r*idel)<<16) +
-				      ((u_int32_t)(out.g*idel)<<8) +
-				      ((u_int32_t)(out.b*idel))),
-			     *mix);
-	mix++;
+	mix[xy] = map->mixfunc( (ucolor)(((u_int32_t)(out.a*idel)<<24) +
+					 ((u_int32_t)(out.r*idel)<<16) +
+					 ((u_int32_t)(out.g*idel)<<8) +
+					 ((u_int32_t)(out.b*idel))),
+				mix[xy]);
+	xy++;
 
       }
     }
@@ -414,17 +409,16 @@
       int *dline = data+i*dw;
       
       for(j=0;j<pw;j++){
-	if(dline[j]>=ol_alpha){
-	  lcolor out = (lcolor){0,0,0,0};
-	  map->mapfunc(dline[j],255,&out);
+	lcolor out = (lcolor){0,0,0,0};
+	l_mapping_calc(map->mapfunc, ol_low, ol_range, dline[j], ol_alpha, 255, &out);
 	
-	  *panel = map->mixfunc((ucolor)(((u_int32_t)(out.a)<<24) +
-					 ((u_int32_t)(out.r)<<16) +
-					 ((u_int32_t)(out.g)<<8) +
-					 ((u_int32_t)(out.b))),
-				*panel);
-	  panel++;
-	}
+	*panel = map->mixfunc((ucolor)(((u_int32_t)(out.a)<<24) +
+				       ((u_int32_t)(out.r)<<16) +
+				       ((u_int32_t)(out.g)<<8) +
+				       ((u_int32_t)(out.b))),
+			      *panel);
+	panel++;
+
       }
     }
   }
@@ -432,6 +426,7 @@
   return;
  abort:
   gdk_threads_leave ();
+  if(data)free(data);
 }
 
 static void _sushiv_panel2d_remap(sushiv_panel_t *p){
@@ -689,13 +684,13 @@
 }
 
 // assumes data is locked
-static void fast_scale_x(float *data, 
+static void fast_scale_x(int *data, 
 			 int w,
 			 int h,
 			 scalespace new,
 			 scalespace old){
   int x,y;
-  float work[w];
+  int work[w];
   int mapbase[w];
   float mapdel[w];
 
@@ -724,19 +719,19 @@
   }
 
   for(y=0;y<h;y++){
-    float *data_line = data+y*w;
+    int *data_line = data+y*w;
     for(x=0;x<w;x++){
       if(mapbase[x]<0 || mapbase[x]>=(w-1)){
-	work[x]=NAN;
+	work[x]=-1;
       }else{
 	int base = mapbase[x];
 	float del = mapdel[x];
-	float A = data_line[base];
-	float B = data_line[base+1];
-	if(isnan(A) || isnan(B))
-	  work[x]=NAN;
+	int A = data_line[base];
+	int B = data_line[base+1];
+	if(A<0 || B<0)
+	  work[x]=-1;
 	else
-	  work[x]= A + (B - A)*del;
+	  work[x]= A + rint((B - A)*del);
 	
       }
     }
@@ -744,13 +739,13 @@
   }   
 }
 
-static void fast_scale_y(float *data, 
+static void fast_scale_y(int *data, 
 			 int w,
 			 int h,
 			 scalespace new,
 			 scalespace old){
   int x,y;
-  float work[h];
+  int work[h];
   int mapbase[h];
   float mapdel[h];
 
@@ -780,20 +775,20 @@
   }
   
   for(x=0;x<w;x++){
-    float *data_column = data+x;
+    int *data_column = data+x;
     int stride = w;
     for(y=0;y<h;y++){
       if(mapbase[y]<0 || mapbase[y]>=(h-1)){
-	work[y]=NAN;
+	work[y]=-1;
       }else{
 	int base = mapbase[y]*stride;
 	float del = mapdel[y];
-	float A = data_column[base];
-	float B = data_column[base+stride];
-	if(isnan(A) || isnan(B))
-	  work[y]=NAN;
+	int A = data_column[base];
+	int B = data_column[base+stride];
+	if(A<0 || B<0)
+	  work[y]=-1;
 	else
-	  work[y]= A + (B-A)*del;
+	  work[y]= A + rint((B-A)*del);
 	
       }
     }
@@ -804,10 +799,10 @@
   }   
 }
 
-static void fast_scale(float *newdata, 
+static void fast_scale(int *newdata, 
 		       scalespace xnew,
 		       scalespace ynew,
-		       float *olddata,
+		       int *olddata,
 		       scalespace xold,
 		       scalespace yold){
   int y;
@@ -821,8 +816,8 @@
     if(new_h > old_h){
       // copy image to new, scale there
       for(y=0;y<old_h;y++){
-	float *new_line = newdata+y*new_w;
-	float *old_line = olddata+y*old_w;
+	int *new_line = newdata+y*new_w;
+	int *old_line = olddata+y*old_w;
 	memcpy(new_line,old_line,old_w*(sizeof*new_line));
       }
       fast_scale_x(newdata,new_w,new_h,xnew,xold);
@@ -831,8 +826,8 @@
       // scale y in old pane, copy to new, scale x 
       fast_scale_y(olddata,old_w,old_h,ynew,yold);
       for(y=0;y<new_h;y++){
-	float *new_line = newdata+y*new_w;
-	float *old_line = olddata+y*old_w;
+	int *new_line = newdata+y*new_w;
+	int *old_line = olddata+y*old_w;
 	memcpy(new_line,old_line,old_w*(sizeof*new_line));
       }
       fast_scale_x(newdata,new_w,new_h,xnew,xold);
@@ -842,8 +837,8 @@
       // scale x in old pane, o=copy to new, scale y
       fast_scale_x(olddata,old_w,old_h,xnew,xold);
       for(y=0;y<old_h;y++){
-	float *new_line = newdata+y*new_w;
-	float *old_line = olddata+y*old_w;
+	int *new_line = newdata+y*new_w;
+	int *old_line = olddata+y*old_w;
 	memcpy(new_line,old_line,new_w*(sizeof*new_line));
       }
       fast_scale_y(newdata,new_w,new_h,ynew,yold);
@@ -854,8 +849,8 @@
       fast_scale_y(olddata,old_w,old_h,ynew,yold);
       if(olddata != newdata){
 	for(y=0;y<new_h;y++){
-	  float *new_line = newdata+y*new_w;
-	  float *old_line = olddata+y*old_w;
+	  int *new_line = newdata+y*new_w;
+	  int *old_line = olddata+y*old_w;
 	  memcpy(new_line,old_line,new_w*(sizeof*new_line));
 	}
       }
@@ -1103,7 +1098,7 @@
     plot->y = sy;
 
     p2->last_line++;
-    serialno = ++p2->serialno; // we're about to free the old data rectangles
+    ++p2->serialno; // we're about to free the old data rectangles
     
     if(memcmp(&sx_v,&old_xv,sizeof(sx_v)) || memcmp(&sy_v,&old_yv,sizeof(sy_v))){
       p2->scaling_in_progress = 1;
@@ -1122,27 +1117,19 @@
 	  newmap[j]=-1;
 	
 	// zoom scale data in map planes as placeholder for render
-	/* come back once converted to fixed point
 	if(oldmap){
 	  fast_scale(newmap, sx_v, sy_v,
 		     oldmap,old_xv, old_yv);
 	  free(oldmap);
 	}
-	*/
 
-	//gdk_threads_enter ();
-	//if(p2->serialno != serialno){
-	//  gdk_threads_leave();
-	//  return 1;
-	//}
 	p2->y_map[i] = newmap; 
       }
       
       p2->scaling_in_progress = 0;
+      _sushiv_panel2d_map_redraw(p);
       gdk_threads_leave ();
-      _sushiv_panel_dirty_map_throttled(p);
       _sushiv_wake_workers();   
-      //_sushiv_panel2d_remap(p);
       plot_draw_scales(plot);
 
     }else



More information about the commits mailing list