Exemplo n.º 1
0
int mark_track_c(ClientData clientData, Tcl_Interp* interp, int argc, const char** argv) 
/* draws crosses for detected points in a displayed image */
{
  char  seq_name[4][128];
  int   i_img, i_seq, h, intx, inty;

  cr_sz = atoi(Tcl_GetVar2(interp, "mp", "pcrossize",  TCL_GLOBAL_ONLY));

  fpp = fopen_r ("parameters/sequence.par");
  for (i_img=0; i_img<4; i_img++) 
    { 
      fscanf (fpp, "%s\n", seq_name[i_img]); 
    }
  /* name of sequence */
  fscanf (fpp,"%d\n", &seq_first);
  fscanf (fpp,"%d\n", &seq_last);
  fclose (fpp);
  
  sprintf (buf, "Show detected particles "); puts (buf);
  Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 2");
  Tcl_Eval(interp, ".text insert 2 $tbuf");
  
  /* track sequence */
  for (i_seq=seq_first; i_seq<=seq_last; i_seq++)
    {
      read_ascii_data(i_seq);
      /* treat the cameras one after the other */
      for (i_img=0; i_img<n_img; i_img++)
	{
	  for (h=0; h<nt4[3][i_img]; h++)
	    {
	      if ( ( fabs(t4[3][i_img][h].x-zoom_x[i_img]) < imx/(2*zoom_f[i_img]))
		   && ( fabs(t4[3][i_img][h].y-zoom_y[i_img]) < imy/(2*zoom_f[i_img])) )
		{		    
		  intx = (int)(imx/2+zoom_f[i_img]*(t4[3][i_img][h].x-zoom_x[i_img]));
		  inty = (int)(imy/2+zoom_f[i_img]*(t4[3][i_img][h].y-zoom_y[i_img]));		  
		  if (t4[3][i_img][h].tnr>-1)
		    { 
		      drawcross ( interp, intx, inty, cr_sz+1, i_img, "green");
		      if (zoom_f[i_img] >= 6) {
		      draw_pnr ( interp, intx, inty+10, i_seq, i_img, "orange");
		      draw_pnr ( interp, intx, inty, t4[3][i_img][h].tnr, i_img, "green");
		      }
		    } else { drawcross ( interp, intx, inty, cr_sz, i_img, "blue"); }
		}
	    }
	  Tcl_Eval(interp, "update idletasks");	      
	}
    }

  sprintf(val, "...done");
  Tcl_SetVar(interp, "tbuf", val, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 3");
  Tcl_Eval(interp, ".text insert 3 $tbuf");

  return TCL_OK;  
}
Exemplo n.º 2
0
Arquivo: tools.c Projeto: 3dptv/3dptv
int kill_in_list (Tcl_Interp* interp, int nr, int num, int ms_x, int ms_y)
{
	int 	i, imin = 9999, intx, inty;
	double	x, y, d, dmin = 9999;

	if (zoom_f[nr] > 1)
	{
		sprintf (buf, "cannot delete point from zoomed image");
		Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
		Tcl_Eval(interp, ".text delete 3");
		Tcl_Eval(interp, ".text insert 3 $tbuf");
		return (0);
	}

	for (i=0; i<num; i++)
	{
		x = (double) ms_x - pix[nr][i].x;
		y = (double) ms_y - pix[nr][i].y;
		d = sqrt (x*x + y*y);
		if (d < dmin)
		{
			dmin = d; imin = i;
		}
	}
	if (dmin > 10)	  return (-1);				 /*  limit: 10 pixel  */
	intx = (int) pix[nr][imin].x;
	inty = (int) pix[nr][imin].y;

	drawcross (interp, intx, inty, cr_sz+1, nr, "magenta");
	for (i=imin; i<num; i++)  
		pix[nr][i] = pix[nr][i+1];

	return (imin);
}
Exemplo n.º 3
0
//实现图形的旋转和速度的控制
void ksdraw12129::draw5cross()
{
    drawcross();
    ofRotate(45);
    drawcross();
    ofRotate(-45);
    
    ofScale(0.85f,0.85f,0);
    float a2 = ofGetElapsedTimef()*(-Speed2);
    ofRotate(a2);
    drawcross();
    
    ofRotate(22.5f);
    
    drawcross();
    ofRotate(-a2);
    
    ofScale(0.6f,0.6f,0);
    float a1 = ofGetElapsedTimef()*Speed1;
    ofRotate(a1);
    drawcross();
    
}
Exemplo n.º 4
0
void mark_correspondences (Tcl_Interp* interp, int nr)
/* draws crosses and numbers for corresponding points in a displayed window */
{
  int  	i,j, pnr, lim, sum, intx, inty;
  double  x, y;
  
  if (match == 0) return;
  
  lim = imx/(2*zoom_f[nr]);
  
  for (i=0; i<match; i++)
    {
      pnr = geo[nr][con[i].p[nr]].pnr;
      if (pnr < 0 || con[i].p[nr] < 0)	continue;
      
      x = pix[nr][pnr].x;  y = pix[nr][pnr].y;
      if ((fabs (x-zoom_x[nr]) < lim) && (fabs (y-zoom_y[nr]) < lim))
	{
	  intx = (int) ( imx/2 + zoom_f[nr] * (x-zoom_x[nr]));
	  inty = (int) ( imy/2 + zoom_f[nr] * (y-zoom_y[nr]));
	  
	  /* check whether quadruplet, triplet or pair -> select color */
	  for (j=0, sum=0; j<4; j++)	if (con[i].p[j] > 0) sum++; 
	  if ( sum == 2 ) sprintf(buf ,"yellow");
	  if ( sum == 3 ) sprintf(buf ,"green");
	  if ( sum == 4 ) sprintf(buf ,"red");

	  drawcross (interp, intx, inty, cr_sz, nr, buf);

	  /* draw point number */
	  if ( examine  && zoom_f[nr] > 2 )
	    {
	      /* number of established correspondence */
	      /*
	      draw_pnr (interp, intx+3 , inty+3, i, nr, "white"); 
	      */
	       } 
	}
    }
}
Exemplo n.º 5
0
void mark_detections (Tcl_Interp* interp, int nr)
/* draws crosses for detected points in a displayed image */
{
  int  	i,limx, limy, intx, inty;
  
  if (num[nr] == 0)
    {
      printf ("No points detected");  return;
    }
  limy = imy/(2*zoom_f[nr]);
  limx = imx/(2*zoom_f[nr]);
  for (i=0; i<num[nr]; i++)
    {
      if (   (fabs(pix[nr][i].x-zoom_x[nr]) < limx)
	     && (fabs(pix[nr][i].y-zoom_y[nr]) < limy))
	{
	  intx = (int)(imx/2+zoom_f[nr]*(pix[nr][i].x-zoom_x[nr]));
	  inty = (int)(imy/2+zoom_f[nr]*(pix[nr][i].y-zoom_y[nr]));
	  drawcross (interp, intx, inty, cr_sz , nr, "blue");
	}
    }
}
Exemplo n.º 6
0
Arquivo: svg.c Projeto: D3cryptor/uTox
void svg_draw(void)
{
    bm_scroll_bits = malloc(SCROLL_WIDTH * SCROLL_WIDTH);
    drawcircle(bm_scroll_bits, SCROLL_WIDTH);

    bm_statusarea = malloc(BM_STATUSAREA_WIDTH * BM_STATUSAREA_HEIGHT);
    drawrectrounded(bm_statusarea, BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT, SCALE * 2);

    bm_add = malloc(BM_ADD_WIDTH * BM_ADD_WIDTH);
    drawcross(bm_add, BM_ADD_WIDTH);

    int s = BM_ADD_WIDTH * BM_ADD_WIDTH;
    bm_groups = calloc(1, s);
    drawgroup(bm_groups, BM_ADD_WIDTH);

    bm_transfer = calloc(1, s);
    drawline(bm_transfer, BM_ADD_WIDTH, BM_ADD_WIDTH, SCALE * 3, SCALE * 3, SCALE * 5, 0.75 * SCALE);
    drawline(bm_transfer, BM_ADD_WIDTH, BM_ADD_WIDTH, SCALE * 6, SCALE * 6, SCALE * 5, 0.75 * SCALE);
    drawtri(bm_transfer, BM_ADD_WIDTH, BM_ADD_WIDTH, 6 * SCALE, 0, 4 * SCALE, 0);
    drawtri(bm_transfer, BM_ADD_WIDTH, BM_ADD_WIDTH, 3 * SCALE, 9 * SCALE, 4 * SCALE, 1);

    bm_settings = malloc(s);
    drawcross(bm_settings, BM_ADD_WIDTH);
    drawxcross(bm_settings, BM_ADD_WIDTH, BM_ADD_WIDTH, BM_ADD_WIDTH);
    drawnewcircle(bm_settings, BM_ADD_WIDTH, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 8 * SCALE);
    drawsubcircle(bm_settings, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 4 * SCALE);

    s = BM_CONTACT_WIDTH * BM_CONTACT_WIDTH;
    bm_contact = calloc(1, s);
    drawnewcircle(bm_contact, BM_CONTACT_WIDTH, 18 * SCALE, 10 * SCALE, 18 * SCALE, 15 * SCALE);
    drawsubcircle(bm_contact, BM_CONTACT_WIDTH, 10 * SCALE, 10 * SCALE, 7 * SCALE);
    drawhead(bm_contact, BM_CONTACT_WIDTH, 10 * SCALE, 6 * SCALE, 8 * SCALE);

    bm_group = calloc(1, s);
    drawgroup(bm_group, BM_CONTACT_WIDTH);

    s = BM_LBICON_WIDTH * BM_LBICON_HEIGHT;
    bm_file = malloc(s);
    convert(bm_file, bm_file_bits, s);

    bm_call = malloc(s);
    convert(bm_call, bm_call_bits, s);

    #define S (BM_STATUS_WIDTH * BM_STATUS_WIDTH)
    bm_status_bits = malloc(S * 4);
    drawcircle(bm_status_bits, BM_STATUS_WIDTH);
    drawcircle(bm_status_bits + S, BM_STATUS_WIDTH);
    drawcircle(bm_status_bits + S * 2, BM_STATUS_WIDTH);
    drawcircle(bm_status_bits + S * 3, BM_STATUS_WIDTH);
    drawsubcircle(bm_status_bits + S * 3, BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 4 * SCALE);
    #undef S

    bm_lbutton = malloc(BM_LBUTTON_WIDTH * BM_LBUTTON_HEIGHT);
    drawrectrounded(bm_lbutton, BM_LBUTTON_WIDTH, BM_LBUTTON_HEIGHT, SCALE * 2);

    bm_sbutton = malloc(BM_SBUTTON_WIDTH * BM_SBUTTON_HEIGHT);
    drawrectrounded(bm_sbutton, BM_SBUTTON_WIDTH, BM_SBUTTON_HEIGHT, SCALE);

    bm_ft = malloc(BM_FT_WIDTH * BM_FT_HEIGHT);
    drawrectrounded(bm_ft, BM_FT_WIDTH, BM_FT_HEIGHT, SCALE * 2);

    bm_ftm = malloc(BM_FTM_WIDTH * BM_FT_HEIGHT);
    drawrectroundedex(bm_ftm, BM_FTM_WIDTH, BM_FT_HEIGHT, SCALE * 2, 13);

    bm_ftb = malloc(BM_FTB_WIDTH * (BM_FTB_HEIGHT + SCALE) + BM_FTB_WIDTH * BM_FTB_HEIGHT);
    drawrectroundedex(bm_ftb, BM_FTB_WIDTH, BM_FTB_HEIGHT + SCALE, SCALE * 2, 6);
    drawrectroundedex(bm_ftb + BM_FTB_WIDTH * (BM_FTB_HEIGHT + SCALE), BM_FTB_WIDTH, BM_FTB_HEIGHT, SCALE * 2, 10);

    s = BM_FB_WIDTH * BM_FB_HEIGHT;
    bm_no = calloc(1, s);
    drawxcross(bm_no, BM_FB_WIDTH, BM_FB_HEIGHT, BM_FB_HEIGHT);
    bm_pause = calloc(1, s);
    drawlinevert(bm_pause, BM_FB_WIDTH, BM_FB_HEIGHT, 0.75 * SCALE, 1.25 * SCALE);
    drawlinevert(bm_pause, BM_FB_WIDTH, BM_FB_HEIGHT, 4.25 * SCALE, 1.25 * SCALE);

    bm_yes = calloc(1, s);
    drawline(bm_yes, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 3.75, SCALE * 2.75, SCALE * 4, 0.5 * SCALE);
    drawlinedown(bm_yes, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 1.9, SCALE * 3.25, SCALE * 2.5, 0.5 * SCALE);

}
Exemplo n.º 7
0
int flow_demo_c (ClientData clientData, Tcl_Interp* interp, int argc, const char** argv)
{
  int i, i_seq, nr, j,pft_version=3,num_points,dumy;
  char	        name[128];
  unsigned char	*imgf;
  Tk_PhotoHandle img_handle;
  Tk_PhotoImageBlock img_block;

  nr = atoi(argv[1]);

  fpp = fopen_r ("parameters/sequence.par");
  for (i=0; i<4; i++)
    fscanf (fpp, "%s\n", seq_name[i]);     /* name of sequence */
  fscanf (fpp,"%d\n", &seq_first);
  fscanf (fpp,"%d\n", &seq_last);
  fclose (fpp);


  /* allocate memory */
  imgf = (unsigned char *) calloc (imgsize, 1);

  fpp = fopen ("parameters/pft_version.par", "r");
  if (fpp){
      fscanf (fpp, "%d\n", &pft_version);
	  pft_version=pft_version+3;
      fclose (fpp);
  }
  else{
	  fpp = fopen ("parameters/pft_version.par", "w");
      fprintf(fpp,"%d\n", 0);
	  fclose(fpp);
  }

  /* load and display images */
  for (i_seq=seq_first; i_seq<=seq_last; i_seq++){
      compose_name_plus_nr (seq_name[nr], "", i_seq, name);
      fp1 = fopen_r (name);	if (! fp1)	return TCL_OK;
      sprintf (buf, "display camera %d, image %d", nr+1, i_seq);
      Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
      Tcl_Eval(interp, ".text delete 2");
      Tcl_Eval(interp, ".text insert 2 $tbuf");

      read_image (interp, name, imgf);
      fclose (fp1);

      img_handle = Tk_FindPhoto( interp, "temp");
      Tk_PhotoGetImage (img_handle, &img_block);

      sprintf(buf, "newimage %d", nr+1);
      Tcl_Eval(interp, buf);

      
	  if(pft_version==4){
         sprintf (filename, "%s%s", name,"_targets");
	      /* read targets of camera nr*/
	     nt4[3][nr]=0;

	     fp1= fopen (filename, "r");
	     if (! fp1) printf("Can't open ascii file: %s\n", filename);

         fscanf (fp1, "%d\n", &nt4[3][nr]);
         for (j=0; j<nt4[3][nr]; j++){
	          fscanf (fp1, "%4d %lf %lf %d %d %d %d %d\n",
		      &pix[nr][j].pnr, &pix[nr][j].x,
		      &pix[nr][j].y, &pix[nr][j].n ,
		      &pix[nr][j].nx ,&pix[nr][j].ny,
		      &pix[nr][j].sumg, &pix[nr][j].tnr);
	     }
         fclose (fp1);
         num[nr] = nt4[3][nr];
		 if (display){
	         for (j=0; j<num[nr]; j++){
	             drawcross (interp, (int) pix[nr][j].x, (int) pix[nr][j].y,cr_sz, nr, "blue");
	         }
			 printf ("drawing %d 2d ", num[nr]);
		 }

         sprintf (filename, "res/rt_is.%d", i_seq);
		 fp1= fopen (filename, "r");
  if (fp1){
         fscanf (fp1, "%d\n", &num_points);
         for (j=0; j<num_points; j++){
	         if (n_img==4){
		        fscanf(fp1, "%d %lf %lf %lf %d %d %d %d\n",
	            &dumy, &fix[j].x, &fix[j].y, &fix[j].z,
	            &geo[0][j].pnr, &geo[1][j].pnr, &geo[2][j].pnr, &geo[3][j].pnr);
		     }
		     if (n_img==3){
		        fscanf(fp1, "%d %lf %lf %lf %d %d %d %d\n",
	            &dumy, &fix[j].x, &fix[j].y, &fix[j].z,
	            &geo[0][j].pnr, &geo[1][j].pnr, &geo[2][j].pnr);
		     }
		     if (n_img==2){ // Alex's patch. 24.09.09. Working on Wesleyan data of 2 cameras only
		        fscanf(fp1, "%d %lf %lf %lf %d %d %d %d\n",
	            &dumy, &fix[j].x, &fix[j].y, &fix[j].z,
	            &geo[0][j].pnr, &geo[1][j].pnr);
	         }
		 }
         fclose (fp1);
		 if (display){
	         for (j=0; j<num_points; j++){
				 img_coord (fix[j].x,fix[j].y,fix[j].z, Ex[nr], I[nr], G[nr], ap[nr], mmp, &pix[nr][j].x,&pix[nr][j].y);
				 metric_to_pixel (pix[nr][j].x,pix[nr][j].y, imx,imy, pix_x,pix_y, &pix[nr][j].x,&pix[nr][j].y, chfield);
				 //if(geo[nr][j].pnr>-1){
	             //    drawcross (interp, (int) pix[nr][geo[nr][j].pnr].x, (int) pix[nr][geo[nr][j].pnr].y,cr_sz, nr, "yellow");
				 //}
				 drawcross (interp, (int) pix[nr][j].x, (int) pix[nr][j].y,cr_sz, nr, "red");
		     }
			 printf ("and %d corresponding 3d positions for frame %d\n", num_points,i_seq);
		 }
  }	
	  }
      Tcl_Eval(interp, "update idletasks");
    }
    printf ("done\n\n");

  free (imgf);
  return TCL_OK;
}
Exemplo n.º 8
0
int trajectories_c(ClientData clientData, Tcl_Interp* interp, int argc, const char** argv) 
/* draws crosses for detected points in a displayed image */
{
  int   k, intx1, inty1, intx2, inty2;
  int i, anz1, anz2, m, j;
  FILE *fp1;
  char val[256];
  vector *line1, *line2;
  double color;
  coord_2d p1[4], p2[4];

  cr_sz = atoi(Tcl_GetVar2(interp, "mp", "pcrossize",  TCL_GLOBAL_ONLY));

  fpp = fopen_r ("parameters/sequence.par");

  /* name of sequence */
  fscanf (fpp,"%d\n", &seq_first);
  fscanf (fpp,"%d\n", &seq_last);
  fclose (fpp);
  
  sprintf (buf, "Show trajectories "); puts (buf);
  Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 2");
  Tcl_Eval(interp, ".text insert 2 $tbuf");


  for (i=seq_first; i<seq_last;i++)
    {
      if (i < 10)             sprintf (val, "res/ptv_is.%1d", i);
      else if (i < 100)       sprintf (val, "res/ptv_is.%2d",  i);
      else       sprintf (val, "res/ptv_is.%3d",  i);
 
      fp1 = fopen (val, "r");
      
      color = ((double)(i-seq_first))/((double)(seq_last-2-seq_first));
      fscanf (fp1,"%d\n", &anz1);
      
      line1 = (vector *) malloc (anz1 * sizeof (vector));
      for (j=0;j<anz1;j++) {
	fscanf (fp1, "%d\n", &line1[j].p);
	fscanf (fp1, "%d\n", &line1[j].n);
	fscanf (fp1, "%lf\n", &line1[j].x1);
	fscanf (fp1, "%lf\n", &line1[j].y1);
	fscanf (fp1, "%lf\n", &line1[j].z1);
      }

      strcpy(val, "");     
      fclose (fp1);

      /* read next time step */     
      if (i+1 < 10)             sprintf (val, "res/ptv_is.%1d", i+1);
      else if (i+1 < 100)       sprintf (val, "res/ptv_is.%2d",  i+1);
      else       sprintf (val, "res/ptv_is.%3d",  i+1);
      
      fp1 = fopen (val, "r");      
      fscanf (fp1,"%d\n", &anz2);
      line2 = (vector *) calloc (anz2, sizeof (vector));
      
      for (j=0;j<anz2;j++) {
	fscanf (fp1, "%d\n", &line2[j].p);
	fscanf (fp1, "%d\n", &line2[j].n);
	fscanf (fp1, "%lf\n", &line2[j].x1);
	fscanf (fp1, "%lf\n", &line2[j].y1);
	fscanf (fp1, "%lf\n", &line2[j].z1);
      }
      fclose (fp1);
      
      for(j=0;j<anz1;j++) { 	
	m = line1[j].n;

	if (m >= 0)  {	  
	  for (k=0; k<n_img; k++)
	    {
	      img_coord (line1[j].x1, line1[j].y1, line1[j].z1, Ex[k],I[k], G[k], ap[k], mmp, &p1[k].x, &p1[k].y);
	      metric_to_pixel (p1[k].x, p1[k].y, imx,imy, pix_x,pix_y, &p1[k].x, &p1[k].y, chfield);
	      
	      img_coord (line2[m].x1, line2[m].y1, line2[m].z1, Ex[k],I[k], G[k], ap[k], mmp, &p2[k].x, &p2[k].y);
	      metric_to_pixel (p2[k].x, p2[k].y, imx,imy, pix_x,pix_y, &p2[k].x, &p2[k].y, chfield); 
	      
	      if ( fabs( p2[k].x-zoom_x[k]) < imx/(2*zoom_f[k])
		   && ( fabs(p2[k].y-zoom_y[k]) < imy/(2*zoom_f[k])) )
		{	
		  intx1 = (int)(imx/2+zoom_f[k]*(p1[k].x-zoom_x[k]));
		  inty1 = (int)(imy/2+zoom_f[k]*(p1[k].y-zoom_y[k]));
		  intx2 = (int)(imx/2+zoom_f[k]*(p2[k].x-zoom_x[k]));
		  inty2 = (int)(imy/2+zoom_f[k]*(p2[k].y-zoom_y[k]));

		  drawcross ( interp, intx1, inty1, cr_sz+1, k, "blue");	 
		  drawcross ( interp, intx2, inty2, cr_sz+1, k, "red");
		  drawvector (interp, intx1, inty1, intx2, inty2, 2, k, "green");
		}	
	    }
	}
	}
	  Tcl_Eval(interp, "update idletasks");	      


      strcpy(val, "");
      free(line1); free(line2);
    }  /* end of sequence loop */
  
  sprintf(val, "...done");
  Tcl_SetVar(interp, "tbuf", val, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 3");
  Tcl_Eval(interp, ".text insert 3 $tbuf"); 
  
  return TCL_OK;
}
Exemplo n.º 9
0
Arquivo: svg.c Projeto: Chuongv/uTox
_Bool svg_draw(_Bool needmemory) {
    int size, s;
    void *p;

    if(svg_data) {
        free(svg_data);
    }

    /* Build what we expect the size to be.
     * This section uses unnamed shortcuts, so it really serves no purpose and makes it harder to debug, it needs to be
     * fixed, without shortcuts, and proper comments... TODO FIXME */
    size = SCROLL_WIDTH * SCROLL_WIDTH + SCROLL_WIDTH * SCROLL_WIDTH /2 +
        BM_STATUSAREA_WIDTH * BM_STATUSAREA_HEIGHT +
        /* Panel buttons */
        BM_ADD_WIDTH * BM_ADD_WIDTH * 4 +
        BM_CONTACT_WIDTH * BM_CONTACT_WIDTH * 2 +
        BM_LBICON_WIDTH * BM_LBICON_HEIGHT * 2 + // call, video
        BM_FILE_WIDTH * BM_FILE_HEIGHT + BM_FILE_BIG_WIDTH * BM_FILE_BIG_HEIGHT + // file small and big
        BM_STATUS_WIDTH * BM_STATUS_WIDTH * 4 +
        BM_STATUS_NOTIFY_WIDTH * BM_STATUS_NOTIFY_WIDTH +
        BM_LBUTTON_WIDTH * BM_LBUTTON_HEIGHT +
        BM_SBUTTON_WIDTH * BM_SBUTTON_HEIGHT +
        /* File transfer */
        BM_FT_CAP_WIDTH * BM_FTB_HEIGHT +
        BM_FT_WIDTH * BM_FT_HEIGHT +
        BM_FTM_WIDTH * BM_FT_HEIGHT +
        (BM_FTB_WIDTH * (BM_FTB_HEIGHT + UTOX_SCALE(1)) + BM_FTB_WIDTH * BM_FTB_HEIGHT) +
        BM_FB_WIDTH * BM_FB_HEIGHT * 4 +
        /* Chat Buttons */
        BM_CHAT_BUTTON_WIDTH * BM_CHAT_BUTTON_HEIGHT * 2 + // Chat button 1, 2
        BM_CHAT_SEND_WIDTH   * BM_CHAT_SEND_HEIGHT +
        BM_CHAT_SEND_OVERLAY_WIDTH * BM_CHAT_SEND_OVERLAY_HEIGHT +
        BM_CHAT_BUTTON_OVERLAY_WIDTH * BM_CHAT_BUTTON_OVERLAY_HEIGHT;

    svg_data = calloc(1, size);

    if(!svg_data) {
        return 0;
    }

    p = svg_data;

    /* Scroll bars top bottom halves */
    drawcircle(p, SCROLL_WIDTH);
    loadalpha(BM_SCROLLHALFTOP, p,                                  SCROLL_WIDTH, SCROLL_WIDTH /2);
    loadalpha(BM_SCROLLHALFBOT, p + SCROLL_WIDTH * SCROLL_WIDTH /2, SCROLL_WIDTH, SCROLL_WIDTH /2);
    p += SCROLL_WIDTH * SCROLL_WIDTH;


    /* Scroll bars top bottom halves (small)*/
    drawcircle(p, SCROLL_WIDTH /2);
    loadalpha(BM_SCROLLHALFTOP_SMALL, p,                                     SCROLL_WIDTH /2, SCROLL_WIDTH /4);
    loadalpha(BM_SCROLLHALFBOT_SMALL, p + SCROLL_WIDTH /2 * SCROLL_WIDTH /4, SCROLL_WIDTH /2, SCROLL_WIDTH /4);
    p += SCROLL_WIDTH * SCROLL_WIDTH /2;

    drawrectrounded(p, BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT, UTOX_SCALE(2));
    loadalpha(BM_STATUSAREA, p, BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT);
    p += BM_STATUSAREA_WIDTH * BM_STATUSAREA_HEIGHT;

    /* Draw panel Buttons */
    drawcross(p, BM_ADD_WIDTH);
    loadalpha(BM_ADD, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += BM_ADD_WIDTH * BM_ADD_WIDTH;

    /* New group bitmap */
    drawgroup(p, BM_ADD_WIDTH);
    loadalpha(BM_GROUPS, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += BM_ADD_WIDTH * BM_ADD_WIDTH;

    drawline(p, BM_ADD_WIDTH, BM_ADD_WIDTH, UTOX_SCALE(3), UTOX_SCALE(3), UTOX_SCALE(5), UTOX_SCALE(0.75 ));
    drawline(p, BM_ADD_WIDTH, BM_ADD_WIDTH, UTOX_SCALE(6), UTOX_SCALE(6), UTOX_SCALE(5), UTOX_SCALE(0.75 ));
    drawtri(p, BM_ADD_WIDTH, BM_ADD_WIDTH, UTOX_SCALE(6 ), 0, UTOX_SCALE(4 ), 0);
    drawtri(p, BM_ADD_WIDTH, BM_ADD_WIDTH, UTOX_SCALE(3 ), UTOX_SCALE(9 ), UTOX_SCALE(4 ), 1);
    loadalpha(BM_TRANSFER, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += BM_ADD_WIDTH * BM_ADD_WIDTH;

    /* Settings gear bitmap */
    drawcross(p, BM_ADD_WIDTH);
    drawxcross(p, BM_ADD_WIDTH, BM_ADD_WIDTH, BM_ADD_WIDTH);
    drawnewcircle(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, UTOX_SCALE(7 ));
    drawsubcircle(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, UTOX_SCALE(3 ));
    loadalpha(BM_SETTINGS, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += BM_ADD_WIDTH * BM_ADD_WIDTH;

    /* Contact avatar default bitmap */
    drawnewcircle(p, BM_CONTACT_WIDTH, UTOX_SCALE(18 ), UTOX_SCALE(10 ), UTOX_SCALE(18 ), UTOX_SCALE(14 ));
    drawsubcircle(p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, UTOX_SCALE(10 ), UTOX_SCALE(10 ), UTOX_SCALE(6 ));
    drawhead(p, BM_CONTACT_WIDTH, UTOX_SCALE(10 ), UTOX_SCALE(6 ), UTOX_SCALE(8 ));
    loadalpha(BM_CONTACT, p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH);
    p += BM_CONTACT_WIDTH * BM_CONTACT_WIDTH;

    /* Group heads default bitmap */
    drawgroup(p, BM_CONTACT_WIDTH);
    loadalpha(BM_GROUP, p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH);
    p += BM_CONTACT_WIDTH * BM_CONTACT_WIDTH;

    /* Draw button icon overlays. */
    drawlineround(p, BM_FILE_WIDTH, BM_FILE_HEIGHT, UTOX_SCALE(5.5 ), UTOX_SCALE(5 ), UTOX_SCALE(1 ), UTOX_SCALE(3.85 ), UTOX_SCALE(6.6 ), 0);
    drawlineroundempty(p, BM_FILE_WIDTH, BM_FILE_HEIGHT, UTOX_SCALE(5.5 ), UTOX_SCALE(5 ), UTOX_SCALE(1 ), UTOX_SCALE(2.4 ), UTOX_SCALE(4.5 ));
    drawsubcircle(p, BM_FILE_WIDTH, BM_FILE_HEIGHT, UTOX_SCALE(6.0 ), UTOX_SCALE(8.1 ), UTOX_SCALE(2.5 ));
    drawlineround(p, BM_FILE_WIDTH, BM_FILE_HEIGHT, UTOX_SCALE(7.0 ), UTOX_SCALE(5.40 ), UTOX_SCALE(0.5 ), UTOX_SCALE(2.2 ), UTOX_SCALE(3.75 ), 1);
    drawlineroundempty(p, BM_FILE_WIDTH, BM_FILE_HEIGHT, UTOX_SCALE(7.25 ), UTOX_SCALE(5.15 ), UTOX_SCALE(0.75 ), UTOX_SCALE(0.75 ), UTOX_SCALE(1.5 ));
    loadalpha(BM_FILE, p, BM_FILE_WIDTH, BM_FILE_HEIGHT);
    p += BM_FILE_WIDTH * BM_FILE_HEIGHT;
    /* and the big one... */
    // TODO convert the *2 hack
    drawlineround(p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT, UTOX_SCALE(5.5 ) * 2, UTOX_SCALE(5 ) * 2, UTOX_SCALE(1 ) * 2, UTOX_SCALE(3.85 ) * 2, UTOX_SCALE(6.6 ) * 2, 0);
    drawlineroundempty(p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT, UTOX_SCALE(5.5 ) * 2, UTOX_SCALE(5 ) * 2, UTOX_SCALE(1 ) * 2, UTOX_SCALE(2.4 ) * 2, UTOX_SCALE(4.5 ) * 2);
    drawsubcircle(p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT, UTOX_SCALE(6.0 ) * 2, UTOX_SCALE(8.1 ) * 2, UTOX_SCALE(2.5 ) * 2);
    drawlineround(p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT, UTOX_SCALE(7.0 ) * 2, UTOX_SCALE(5.40 ) * 2, UTOX_SCALE(0.5 ) * 2, UTOX_SCALE(2.2 ) * 2, UTOX_SCALE(3.75 ) * 2, 1);
    drawlineroundempty(p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT, UTOX_SCALE(7.25 ) * 2, UTOX_SCALE(5.15 ) * 2, UTOX_SCALE(0.75 ) * 2, UTOX_SCALE(0.75 ) * 2, UTOX_SCALE(1.5 ) * 2);
    loadalpha(BM_FILE_BIG, p, BM_FILE_BIG_WIDTH, BM_FILE_BIG_HEIGHT);
    p += BM_FILE_BIG_WIDTH * BM_FILE_BIG_HEIGHT;

    drawnewcircle(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, UTOX_SCALE(1), 0, UTOX_SCALE(19 ));
    drawsubcircle(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, UTOX_SCALE(1), 0, UTOX_SCALE(15 ));
    drawnewcircle2(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, UTOX_SCALE(9 ), UTOX_SCALE(2 ), UTOX_SCALE(3 ), 0);
    drawnewcircle2(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, UTOX_SCALE(3 ), UTOX_SCALE(8 ), UTOX_SCALE(3 ), 1);
    loadalpha(BM_CALL, p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT);
    p += BM_LBICON_WIDTH * BM_LBICON_HEIGHT;

    /* Video start end bitmap */
    int x, y;
    uint8_t *data = p;
    /* left triangle lens thing */
    for(y = 0; y != BM_LBICON_HEIGHT; y++) {
        for(x = 0; x != UTOX_SCALE(4); x++) {
            double d = fabs(y - UTOX_SCALE(4.5 )) - 0.66 * (UTOX_SCALE(4) - x);
            *data++ = pixel(d);
        }
        data += BM_LBICON_WIDTH - UTOX_SCALE(4);
    }
    drawrectroundedsub(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, UTOX_SCALE(4 ), UTOX_SCALE(1), UTOX_SCALE(7 ), UTOX_SCALE(7 ), UTOX_SCALE(1));
    loadalpha(BM_VIDEO, p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT);
    p += BM_LBICON_WIDTH * BM_LBICON_HEIGHT;

    /* Draw user status Buttons */
    s = BM_STATUS_WIDTH * BM_STATUS_WIDTH;
    drawcircle(p, BM_STATUS_WIDTH);
    loadalpha(BM_ONLINE, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH / 2, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, SCALE(6));
    loadalpha(BM_AWAY, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH / 2, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, SCALE(6));
    loadalpha(BM_BUSY, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, SCALE(6));
    loadalpha(BM_OFFLINE, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_NOTIFY_WIDTH);
    drawsubcircle(p, BM_STATUS_NOTIFY_WIDTH, BM_STATUS_NOTIFY_WIDTH, 0.5 * BM_STATUS_NOTIFY_WIDTH, 0.5 * BM_STATUS_NOTIFY_WIDTH, SCALE(10));
    loadalpha(BM_STATUS_NOTIFY, p, BM_STATUS_NOTIFY_WIDTH, BM_STATUS_NOTIFY_WIDTH);
    p += BM_STATUS_NOTIFY_WIDTH * BM_STATUS_NOTIFY_WIDTH;

    drawrectrounded(p, BM_LBUTTON_WIDTH, BM_LBUTTON_HEIGHT, UTOX_SCALE(2));
    loadalpha(BM_LBUTTON, p, BM_LBUTTON_WIDTH, BM_LBUTTON_HEIGHT);
    p += BM_LBUTTON_WIDTH * BM_LBUTTON_HEIGHT;

    drawrectrounded(p, BM_SBUTTON_WIDTH, BM_SBUTTON_HEIGHT, UTOX_SCALE(2));
    loadalpha(BM_SBUTTON, p, BM_SBUTTON_WIDTH, BM_SBUTTON_HEIGHT);
    p += BM_SBUTTON_WIDTH * BM_SBUTTON_HEIGHT;

    /* Draw file transfer buttons */
    drawrectroundedex(p, BM_FT_CAP_WIDTH, BM_FTB_HEIGHT, UTOX_SCALE(2), 13);
    loadalpha(BM_FT_CAP, p, BM_FT_CAP_WIDTH, BM_FTB_HEIGHT);
    p += BM_FT_CAP_WIDTH * BM_FTB_HEIGHT;

    drawrectrounded(p, BM_FT_WIDTH, BM_FT_HEIGHT, UTOX_SCALE(2));
    loadalpha(BM_FT, p, BM_FT_WIDTH, BM_FT_HEIGHT);
    p += BM_FT_WIDTH * BM_FT_HEIGHT;

    drawrectroundedex(p, BM_FTM_WIDTH, BM_FT_HEIGHT, UTOX_SCALE(2), 13);
    loadalpha(BM_FTM, p, BM_FTM_WIDTH, BM_FT_HEIGHT);
    p += BM_FTM_WIDTH * BM_FT_HEIGHT;

    drawrectroundedex(p, BM_FTB_WIDTH, BM_FTB_HEIGHT + UTOX_SCALE(1), UTOX_SCALE(2), 0);
    loadalpha(BM_FTB1, p, BM_FTB_WIDTH, BM_FTB_HEIGHT + UTOX_SCALE(1));
    p += BM_FTB_WIDTH * (BM_FTB_HEIGHT + UTOX_SCALE(1));

    drawrectroundedex(p, BM_FTB_WIDTH, BM_FTB_HEIGHT, UTOX_SCALE(2), 14);
    loadalpha(BM_FTB2, p, BM_FTB_WIDTH, BM_FTB_HEIGHT);
    p += BM_FTB_WIDTH * BM_FTB_HEIGHT;

    s = BM_FB_WIDTH * BM_FB_HEIGHT;

    drawxcross(p, BM_FB_WIDTH, BM_FB_HEIGHT, BM_FB_HEIGHT);
    loadalpha(BM_NO, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawlinevert(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(0.75 ), UTOX_SCALE(1.25 ));
    drawlinevert(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(4.25 ), UTOX_SCALE(1.25 ));
    loadalpha(BM_PAUSE, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawline(p,     BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(1.75), UTOX_SCALE(3.5),  UTOX_SCALE(2.5), UTOX_SCALE(0.5 ));
    drawline(p,     BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(4),    UTOX_SCALE(3.5),  UTOX_SCALE(2.5), UTOX_SCALE(0.5 ));
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(1.75), UTOX_SCALE(1.75), UTOX_SCALE(2.5), UTOX_SCALE(0.5 ));
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(4),    UTOX_SCALE(1.75), UTOX_SCALE(2.5), UTOX_SCALE(0.5 ));
    loadalpha(BM_RESUME, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawline(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(3.75), UTOX_SCALE(2.75), UTOX_SCALE(4), UTOX_SCALE(0.5 ));
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, UTOX_SCALE(1.9), UTOX_SCALE(3.25), UTOX_SCALE(2.5), UTOX_SCALE(0.5 ));
    loadalpha(BM_YES, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    /* the two small chat buttons... */
    drawrectroundedex(p, BM_CHAT_BUTTON_WIDTH, BM_CHAT_BUTTON_HEIGHT, UTOX_SCALE(2), 13);
    loadalpha(BM_CHAT_BUTTON_LEFT, p, BM_CHAT_BUTTON_WIDTH, BM_CHAT_BUTTON_HEIGHT);
    p += BM_CHAT_BUTTON_WIDTH * BM_CHAT_BUTTON_HEIGHT;

    drawrectroundedex(p, BM_CHAT_BUTTON_WIDTH, BM_CHAT_BUTTON_HEIGHT, UTOX_SCALE(2), 0);
    loadalpha(BM_CHAT_BUTTON_RIGHT, p, BM_CHAT_BUTTON_WIDTH, BM_CHAT_BUTTON_HEIGHT);
    p += BM_CHAT_BUTTON_WIDTH * BM_CHAT_BUTTON_HEIGHT;


    /* Draw chat send button */
    drawrectroundedex(p, BM_CHAT_SEND_WIDTH, BM_CHAT_SEND_HEIGHT, UTOX_SCALE(4 ), 14);
    loadalpha(BM_CHAT_SEND, p, BM_CHAT_SEND_WIDTH, BM_CHAT_SEND_HEIGHT);
    p += BM_CHAT_SEND_WIDTH * BM_CHAT_SEND_HEIGHT;

    /* Draw chat send overlay */
    drawnewcircle(p, BM_CHAT_SEND_OVERLAY_WIDTH, BM_CHAT_SEND_OVERLAY_HEIGHT, UTOX_SCALE(10 ), UTOX_SCALE(7 ), UTOX_SCALE(13 ));
    drawtri(      p, BM_CHAT_SEND_OVERLAY_WIDTH, BM_CHAT_SEND_OVERLAY_HEIGHT, UTOX_SCALE(15 ), UTOX_SCALE(9 ),  UTOX_SCALE(6 ), 0);
    loadalpha(BM_CHAT_SEND_OVERLAY, p, BM_CHAT_SEND_OVERLAY_WIDTH, BM_CHAT_SEND_OVERLAY_HEIGHT);
    p += BM_CHAT_SEND_OVERLAY_WIDTH * BM_CHAT_SEND_OVERLAY_HEIGHT;

    /* screen shot button overlay */
    /* Rounded frame */
    drawrectroundedsub(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,               BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                          UTOX_SCALE(1 ),                                  UTOX_SCALE(1 ),
                          BM_CHAT_BUTTON_OVERLAY_WIDTH - (UTOX_SCALE(4 )), BM_CHAT_BUTTON_OVERLAY_HEIGHT - (UTOX_SCALE(4 )),
                          UTOX_SCALE(1 ));
    drawrectroundedneg(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,               BM_CHAT_BUTTON_OVERLAY_HEIGHT, /* width, height */
                          UTOX_SCALE(2 ),                                  UTOX_SCALE(2 ),                     /* start x, y */
                          BM_CHAT_BUTTON_OVERLAY_WIDTH - (UTOX_SCALE(6 )), BM_CHAT_BUTTON_OVERLAY_HEIGHT - (UTOX_SCALE(6 )),
                          UTOX_SCALE(1 ));
    /* camera shutter circle */
    drawnewcircle(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                     BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.75, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.75,
                     UTOX_SCALE(6  ));
    drawsubcircle(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                     BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.75, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.75,
                     UTOX_SCALE(2 ));
    /* shutter lines */
    svgdraw_line_neg(p,      BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                             BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.80, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.65,
                             UTOX_SCALE(2 ), 0.1);
    svgdraw_line_neg(p,      BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                             BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.73, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.87,
                             UTOX_SCALE(2 ), 0.1);
    svgdraw_line_down_neg(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                             BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.65, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.70,
                             UTOX_SCALE(2 ), 0.1);
    svgdraw_line_down_neg(p, BM_CHAT_BUTTON_OVERLAY_WIDTH,        BM_CHAT_BUTTON_OVERLAY_HEIGHT,
                             BM_CHAT_BUTTON_OVERLAY_WIDTH * 0.85, BM_CHAT_BUTTON_OVERLAY_HEIGHT * 0.81,
                             UTOX_SCALE(2 ), 0.1);
    loadalpha(BM_CHAT_BUTTON_OVERLAY_SCREENSHOT, p, BM_CHAT_BUTTON_OVERLAY_WIDTH, BM_CHAT_BUTTON_OVERLAY_HEIGHT);
    p += BM_CHAT_BUTTON_OVERLAY_WIDTH * BM_CHAT_BUTTON_OVERLAY_HEIGHT;

    if(p - svg_data != size) {
        debug("SVG:\tSVG data size mismatch...\n");
    }

    if(!needmemory) {
        free(svg_data);
        svg_data = NULL;
    }

    return 1;
}
Exemplo n.º 10
0
int calibration_proc_c (/*ClientData clientData, Tcl_Interp* interp,*/ int argc, const char** argv)
{
  int i, j, sel, i_img, k, n, sup;
  int intx1, inty1, intx2, inty2;
  coord_2d    	apfig1[11][11];	/* regular grid for ap figures */
  coord_2d     	apfig2[11][11];	/* ap figures */
  coord_3d     	fix4[4];       	/* object points for preorientation */
  coord_2d     	crd0[4][4];    	/* image points for preorientation */
  char	       	filename[256], val[256];
  const char *valp;

  //Tk_PhotoHandle img_handle;
  //Tk_PhotoImageBlock img_block;

  /* read support of unsharp mask */
  fp1 = fopen ("parameters/unsharp_mask.par", "r");
  if (! fp1)	sup = 12;
  else	{ fscanf (fp1, "%d\n", &sup); fclose (fp1); }

  /* Get Selection value from TclTk */

  // ChrisB: what does this do?? Set a value......
  //valp = Tcl_GetVar(interp, "sel",  TCL_GLOBAL_ONLY);
  //sel = atoi (valp);
  sel = 1;	// set a value....

  switch (sel)
    {
    case 1: /*  read calibration parameter file  */
      fp1 = fopen_r ("parameters/cal_ori.par");
      fscanf (fp1,"%s\n", fixp_name);
      for (i=0; i<4; i++)
	{
	  fscanf (fp1, "%s\n", img_name[i]);
	  fscanf (fp1, "%s\n", img_ori0[i]);
	}
      fscanf (fpp, "%d\n", &tiff_flag);
      fscanf (fp1, "%d\n", &chfield);
      fclose (fp1);

      /*  create file names  */
      for (i=0; i<n_img; i++)
	{
	  strcpy (img_ori[i], img_name[i]);
	  strcat (img_ori[i], ".ori");
	  strcpy (img_addpar0[i], img_name[i]);
	  strcat (img_addpar0[i], ".addpar0");
	  strcpy (img_addpar[i], img_name[i]);
	  strcat (img_addpar[i], ".addpar");
	  strcpy (img_hp_name[i], img_name[i]);
	  strcat (img_hp_name[i], "_hp");
	}

      for (i=0; i<n_img; i++)
	{

	  zoom_x[i] = imx/2, zoom_y[i] = imy/2, zoom_f[i] = 1;

	  read_image (/*interp,*/ img_name[i], img[i]);

	  sprintf(val, "camcanvas %d", i+1);
	  //Tcl_Eval(interp, val);

	  //img_handle = Tk_FindPhoto( interp, "temp");
	  //Tk_PhotoGetImage (img_handle, &img_block);
	  //tclimg2cimg (interp, img[i], &img_block);

	  sprintf(val, "newimage %d", i+1);
	  //Tcl_Eval(interp, val);
	}

      break;


    case 2: puts ("Detection procedure"); strcpy(val,"");

      /* Highpass Filtering */
      pre_processing_c (/*clientData, interp,*/ argc, argv);

      /* reset zoom values */
      for (i=0; i<n_img; i++)
	{
	  zoom_x[i] = imx/2; zoom_y[i] = imy/2; zoom_f[i] = 1;
	}

     /* copy images because the target recognition
	 will set greyvalues to zero */

     for (i=0; i<n_img; i++)
	{
	  copy_images (img[i], img0[i]);
	}


      /* target recognition */
      for (i=0; i<n_img; i++)
	{
	  targ_rec (/*interp,*/ img[i], img0[i], "parameters/detect_plate.par",
		    0, imx, 1, imy, pix[i], i, &num[i]);

	  sprintf (buf,"image %d: %d,  ", i+1, num[i]);
	  strcat(val, buf);

	  if (num[i] > nmax)  exit (1);
	}

      /* save pixel coord as approx. for template matching */
      if (examine)	for (i=0; i<n_img; i++)
	{
	  sprintf (filename, "%s_pix", img_name[i]);
	  fp1 = fopen (filename, "w");
	  for (j=0; j<num[i]; j++)
	    fprintf (fp1, "%4d  %8.3f  %8.3f\n",
		     pix[i][j].pnr, pix[i][j].x, pix[i][j].y);

	  fclose (fp1);
	}

      sprintf(buf,"Number of detected targets, interaction enabled");
      //Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
      //Tcl_Eval(interp, ".text delete 2");
      //Tcl_Eval(interp, ".text insert 2 $tbuf");
      //Tcl_SetVar(interp, "tbuf", val, TCL_GLOBAL_ONLY);
      //Tcl_Eval(interp, ".text delete 3");
      //Tcl_Eval(interp, ".text insert 3 $tbuf");
      break;


    case 3:	pp1=0;	pp2=0;	pp3=0;	pp4=0;

      for (i=0; i<n_img; i++)
	{
	  sprintf (buf, "%d targets remain", num[i]);
	  puts (buf);
	}
      fp1 = fopen_r ("parameters/man_ori.par");
      for (i=0; i<n_img; i++)
	{
	  fscanf (fp1, "%d %d %d %d\n", &nr[i][0], &nr[i][1], &nr[i][2], &nr[i][3]);
	}
      fclose (fp1);

      for (i=0; i<n_img; i++)
	{
	  sprintf(val, "measure %d %d %d %d %d", nr[i][0], nr[i][1], nr[i][2], nr[i][3], i+1);
	  //Tcl_Eval(interp, val);
#if 0
	  // ChrisB: do we need this?
	  valp = Tcl_GetVar(interp, "px0",  TCL_GLOBAL_ONLY);
	  pix0[i][0].x = atoi (valp);
	  valp = Tcl_GetVar(interp, "py0",  TCL_GLOBAL_ONLY);
	  pix0[i][0].y = atoi (valp);
	  valp = Tcl_GetVar(interp, "px1",  TCL_GLOBAL_ONLY);
	  pix0[i][1].x = atoi (valp);
	  valp = Tcl_GetVar(interp, "py1",  TCL_GLOBAL_ONLY);
	  pix0[i][1].y = atoi (valp);
	  valp = Tcl_GetVar(interp, "px2",  TCL_GLOBAL_ONLY);
	  pix0[i][2].x = atoi (valp);
	  valp = Tcl_GetVar(interp, "py2",  TCL_GLOBAL_ONLY);
	  pix0[i][2].y = atoi (valp);
	  valp = Tcl_GetVar(interp, "px3",  TCL_GLOBAL_ONLY);
	  pix0[i][3].x = atoi (valp);
	  valp = Tcl_GetVar(interp, "py3",  TCL_GLOBAL_ONLY);
	  pix0[i][3].y = atoi (valp);
#endif
	}

      /* write measured coordinates to file for next trial */
      fp1 = fopen ("man_ori.dat", "w");
      for (i=0; i<n_img; i++)
	for (j=0; j<4; j++)
	  fprintf (fp1, "%f %f\n", pix0[i][j].x, pix0[i][j].y);
      fclose (fp1);

      break;


    case 4: /* read pixel coordinates of older pre-orientation */

      /* read point numbers of pre-clicked points */
      fp1 = fopen_r ("parameters/man_ori.par");
      for (i=0; i<n_img; i++)
	{
	  fscanf (fp1, "%d %d %d %d\n",
		  &nr[i][0], &nr[i][1], &nr[i][2], &nr[i][3]);
	}
      fclose (fp1);

      /* read coordinates of pre-clicked points */
      fp1 = fopen ("man_ori.dat", "r");
      if (! fp1)	break;
      for (i_img=0; i_img<n_img; i_img++)	for (i=0; i<4; i++)
	{
#if 0
	  fscanf (fp1, "%lf %lf\n",
		  &pix0[i_img][i].x, &pix0[i_img][i].y);
	  drawcross (interp,  (int) pix0[i_img][i].x,
		     (int) pix0[i_img][i].y, cr_sz+2, i_img, "red");
	  draw_pnr (interp, (int) pix0[i_img][i].x, (int) pix0[i_img][i].y,
		    nr[i_img][i], i_img, "red");
#endif

	}
      fclose (fp1);

      break;


    case 5: puts ("Sort grid points");
      for (i=0; i<n_img; i++)
	{
	  /* read control point coordinates for man_ori points */
	  fp1 = fopen_r (fixp_name);
	  k = 0;
	  while ( fscanf (fp1, "%d %lf %lf %lf", &fix[k].pnr,
			  &fix[k].x, &fix[k].y, &fix[k].z) != EOF) k++;
	  fclose (fp1);
	  nfix = k;

	  /* take clicked points from control point data set */
	  for (j=0; j<4; j++)	for (k=0; k<nfix; k++)
	    {
	      if (fix[k].pnr == nr[i][j])	fix4[j] = fix[k];
	    }

	  /* get approx for orientation and ap */
	  read_ori (&Ex[i], &I[i], img_ori0[i]);
	  fp1 = fopen (img_addpar0[i], "r");
	  if (! fp1)  fp1 = fopen ("addpar.raw", "r");

	  if (fp1) {
	    fscanf (fp1, "%lf %lf %lf %lf %lf %lf %lf",
		    &ap[i].k1,&ap[i].k2,&ap[i].k3,
		    &ap[i].p1,&ap[i].p2,
		    &ap[i].scx,&ap[i].she);
	    fclose (fp1);} else {
	      printf("no addpar.raw\n");
	      ap[i].k1=ap[i].k2=ap[i].k3=ap[i].p1=ap[i].p2=ap[i].she=0.0;
	      ap[i].scx=1.0;
	    }


	  /* transform clicked points */
	  for (j=0; j<4; j++)
	    {
	      pixel_to_metric (pix0[i][j].x, pix0[i][j].y,
			       imx,imy, pix_x, pix_y,
			       &crd0[i][j].x, &crd0[i][j].y,
			       chfield);
	      correct_brown_affin (crd0[i][j].x, crd0[i][j].y, ap[i],
				   &crd0[i][j].x, &crd0[i][j].y);
	    }

	  /* raw orientation with 4 points */
	  raw_orient (Ex[i], I[i], ap[i], mmp, 4, fix4, crd0[i], &Ex[i]);
	  sprintf (filename, "raw%d.ori", i);
	  write_ori (Ex[i], I[i], filename);
	 
	  /* sorting of detected points by back-projection */
	  sortgrid_man (/*interp,*/ Ex[i], I[i], ap[i], mmp,
			imx,imy, pix_x,pix_y,
			nfix, fix, num[i], pix[i], chfield, i);

	  /* adapt # of detected points */
	  num[i] = nfix;

	  for (j=0; j<nfix; j++)
	    {
#if 0
	      if (pix[i][j].pnr < 0)	continue;
	      intx1 = (int) pix[i][j].x ;
	      inty1 = (int) pix[i][j].y ;

	      drawcross (interp, intx1, inty1, cr_sz, i, "white");
	      draw_pnr (interp, intx1, inty1, fix[j].pnr, i, "white");
#endif
	    }
	}

      /* dump dataset for rdb */
      if (examine == 4)
	{
	  /* create filename for dumped dataset */
	  sprintf (filename, "dump_for_rdb");
	  fp1 = fopen (filename, "w");

	  /* write # of points to file */
	  fprintf (fp1, "%d\n", nfix);

	  /* write point and image coord to file */
	  for (i=0; i<nfix; i++)
	    {
	      fprintf (fp1, "%4d %10.3f %10.3f %10.3f   %d    ",
		       fix[i].pnr, fix[i].x, fix[i].y, fix[i].z, 0);
	      for (i_img=0; i_img<n_img; i_img++)
		{
		  if (pix[i_img][i].pnr >= 0)
		    {
		      /* transform pixel coord to metric */
		      pixel_to_metric (pix[i_img][i].x,
				       pix[i_img][i].y, imx,imy, pix_x, pix_y,
				       &crd[i_img][i].x, &crd[i_img][i].y,
				       chfield);
		      fprintf (fp1, "%4d %8.5f %8.5f    ",
			       pix[i_img][i].pnr,
			       crd[i_img][i].x, crd[i_img][i].y);
		    }
		  else
		    {
		      fprintf (fp1, "%4d %8.5f %8.5f    ",
			       pix[i_img][i].pnr, 0.0, 0.0);
		    }
		}
	      fprintf (fp1, "\n");
	    }
	  fclose (fp1);
	  printf ("dataset dumped into %s\n", filename);
	}
      break;




    case 6: puts ("Orientation"); strcpy(buf, "");

      for (i_img=0; i_img<n_img; i_img++)
	{
	  for (i=0; i<nfix ; i++)
	    {
	      pixel_to_metric (pix[i_img][i].x, pix[i_img][i].y,
			       imx,imy, pix_x, pix_y,
			       &crd[i_img][i].x, &crd[i_img][i].y,
			       chfield);
	      crd[i_img][i].pnr = pix[i_img][i].pnr;
	    }

	  /* save data for special use of resection routine */
	  if (examine == 4)
	    {
	      printf ("try write resection data to disk\n");
	      /* point coordinates */
	      sprintf (filename, "resect_%s.fix", img_name[i_img]);
	      write_ori (Ex[i_img], I[i_img], img_ori[i_img]);
	      fp1 = fopen (filename, "w");
	      for (i=0; i<nfix; i++)
		fprintf (fp1, "%3d  %10.5f  %10.5f  %10.5f\n",
			 fix[i].pnr, fix[i].x, fix[i].y, fix[i].z);
	      fclose (fp1);

	      /* metric image coordinates */
	      sprintf (filename, "resect_%s.crd", img_name[i_img]);
	      fp1 = fopen (filename, "w");
	      for (i=0; i<nfix; i++)
		fprintf (fp1,
			 "%3d  %9.5f  %9.5f\n", crd[i_img][i].pnr,
			 crd[i_img][i].x, crd[i_img][i].y);
	      fclose (fp1);

	      /* orientation and calibration approx data */
	      write_ori (Ex[i_img], I[i_img], "resect.ori0");
	      fp1 = fopen ("resect.ap0", "w");
	      fprintf (fp1, "%f %f %f %f %f %f %f",
		       ap[i_img].k1, ap[i_img].k2, ap[i_img].k3,
		       ap[i_img].p1, ap[i_img].p2,
		       ap[i_img].scx, ap[i_img].she);
	      fclose (fp1);
	      printf ("resection data written to disk\n");
	    }


	  /* resection routine */
	  /* ================= */

	  if (examine != 4)
	    orient (/*interp,*/ Ex[i_img], I[i_img], ap[i_img], mmp,
		    nfix, fix, crd[i_img],
		    &Ex[i_img], &I[i_img], &ap[i_img], i_img);

	  /* ================= */


	  /* resection with dumped datasets */
	  if (examine == 4)
	    {

	      printf("Resection with dumped datasets? (y/n)");
	      scanf("%s",buf);
	      if (buf[0] != 'y')	continue;
	      strcpy (buf, "");

	      /* read calibration frame datasets */
	      for (n=0, nfix=0, dump_for_rdb=0; n<100; n++)
		{
		  sprintf (filename, "resect.fix%d", n);
		  fp1 = fopen (filename, "r");
		  if (! fp1)	continue;

		  printf("reading file: %s\n", filename);
		  printf ("reading dumped resect data #%d\n", n);
		  k = 0;
		  while ( fscanf (fp1, "%d %lf %lf %lf",
				  &fix[nfix+k].pnr, &fix[nfix+k].x,
				  &fix[nfix+k].y, &fix[nfix+k].z)
			  != EOF) k++;
		  fclose (fp1);
		  /* read metric image coordinates */
		  sprintf (filename, "resect_%d.crd%d", i_img, n);
		  printf("reading file: %s\n", filename);
		  fp1 = fopen (filename, "r");
		  for (i=nfix; i<nfix+k; i++)
		    fscanf (fp1, "%d %lf %lf",
			    &crd[i_img][i].pnr,
			    &crd[i_img][i].x, &crd[i_img][i].y);
		  nfix += k;
		}

	      /* resection */
	      orient (/*interp,*/ Ex[i_img], I[i_img], ap[i_img], mmp,
		      nfix, fix, crd[i_img],
		      &Ex[i_img], &I[i_img], &ap[i_img], i_img);
	    }


	  /* save orientation and additional parameters */
	  write_ori (Ex[i_img], I[i_img], img_ori[i_img]);
	  fp1 = fopen (img_addpar[i_img], "w");
	  fprintf (fp1, "%f %f %f %f %f %f %f",
		   ap[i_img].k1, ap[i_img].k2, ap[i_img].k3,
		   ap[i_img].p1, ap[i_img].p2,
		   ap[i_img].scx, ap[i_img].she);
	  fclose (fp1);
	}

      //Tcl_Eval(interp, ".text delete 3");
      //Tcl_Eval(interp, ".text delete 1");
      //Tcl_Eval(interp, ".text insert 1 \"Orientation and self calibration \"");
      //Tcl_Eval(interp, ".text delete 2");
      //Tcl_Eval(interp, ".text insert 2 \"...done, sigma0 for each image -> \"");
      //Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
      //Tcl_Eval(interp, ".text insert 3 $tbuf");

      break;

    case 7: checkpoint_proc (/*interp*/);
#if 0
      sprintf(val,"blue: planimetry,   yellow: height");
      Tcl_SetVar(interp, "tbuf", val, TCL_GLOBAL_ONLY);
      Tcl_Eval(interp, ".text delete 2");
      Tcl_Eval(interp, ".text insert 2 $tbuf");
      Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
      Tcl_Eval(interp, ".text delete 3");
      Tcl_Eval(interp, ".text insert 3 $tbuf");
#endif
      break;


    case 8: /* draw additional parameter figures */

      //Tcl_Eval(interp, "clearcam");

      /*  read orientation and additional parameters  */
      for (i=0; i<n_img; i++)	read_ori (&Ex[i], &I[i], img_ori[i]);
      for (i=0; i<n_img; i++)
	{
	  fp1 = fopen_r (img_addpar[i]);
	  fscanf (fp1,"%lf %lf %lf %lf %lf %lf %lf",
		  &ap[i].k1, &ap[i].k2, &ap[i].k3,
		  &ap[i].p1, &ap[i].p2, &ap[i].scx, &ap[i].she);
	  fclose (fp1);
	}
      for (i_img=0; i_img<n_img; i_img++)
	{
	  /* create undistorted grid */
	  for (i=0; i<11; i++)	for (j=0; j<11; j++)
	    {
	      apfig1[i][j].x = i * imx/10;
	      apfig1[i][j].y = j * imy/10;
	    }
	  /* draw undistorted grid */
	  for (i=0; i<10; i++)	for (j=0; j<10; j++)
	    {
	      intx1 = (int) apfig1[i][j].x;
	      inty1 = (int) apfig1[i][j].y;
	      intx2 = (int) apfig1[i+1][j].x;
	      inty2 = (int) apfig1[i][j+1].y;
	      //drawvector (interp, intx1, inty1, intx2, inty1, 1, i_img, "black");
	      //drawvector (interp, intx1, inty1, intx1, inty2, 1, i_img, "black");
	    }
	  for (j=0; j<10; j++)
	    {
	      intx1 = (int) apfig1[10][j].x;
	      inty1 = (int) apfig1[10][j].y;
	      inty2 = (int) apfig1[10][j+1].y;
	      //drawvector (interp, intx1, inty1, intx1, inty2, 1, i_img, "black");
	    }
	  for (i=0; i<10; i++)
	    {
	      intx1 = (int) apfig1[i][10].x;
	      inty1 = (int) apfig1[i][10].y;
	      intx2 = (int) apfig1[i+1][10].x;
	      //drawvector (interp, intx1, inty1, intx2, inty1, 1, i_img, "black");
	    }
	  /* distort grid */
	  for (i=0; i<11; i++)	for (j=0; j<11; j++)
	    {
	      /* transform to metric, distort and re-transform */
	      pixel_to_metric (apfig1[i][j].x, apfig1[i][j].y,
			       imx,imy, pix_x,pix_y,
			       &apfig2[i][j].x, &apfig2[i][j].y, chfield);
	      distort_brown_affin (apfig2[i][j].x, apfig2[i][j].y,
				   ap[i_img], &apfig2[i][j].x, &apfig2[i][j].y);
	      metric_to_pixel (apfig2[i][j].x, apfig2[i][j].y,
			       imx,imy, pix_x,pix_y,
			       &apfig2[i][j].x, &apfig2[i][j].y, chfield);
	      /* exaggerate distortion by factor 5 */
	      apfig2[i][j].x = 5*apfig2[i][j].x - 4*apfig1[i][j].x;
	      apfig2[i][j].y = 5*apfig2[i][j].y - 4*apfig1[i][j].y;

	    }
	  /* draw distorted grid */
	  for (i=0; i<10; i++)	for (j=0; j<10; j++)
	    {
	      intx1 = (int) apfig2[i][j].x;
	      inty1 = (int) apfig2[i][j].y;
	      intx2 = (int) apfig2[i+1][j].x;
	      inty2 = (int) apfig2[i+1][j].y;
	      //drawvector (interp, intx1, inty1, intx2, inty2, 3, i_img, "magenta");
	      intx2 = (int) apfig2[i][j+1].x ;
	      inty2 = (int) apfig2[i][j+1].y ;
	      //drawvector (interp, intx1, inty1, intx2, inty2, 3, i_img, "magenta");
	    }
	  for (j=0; j<10; j++)
	    {
	      intx1 = (int) apfig2[10][j].x;
	      inty1 = (int) apfig2[10][j].y;
	      intx2 = (int) apfig2[10][j+1].x;
	      inty2 = (int) apfig2[10][j+1].y;
	      //drawvector (interp, intx1, inty1, intx2, inty2, 3, i_img, "magenta");
	    }
	  for (i=0; i<10; i++)
	    {
	      intx1 = (int) apfig2[i][10].x;
	      inty1 = (int) apfig2[i][10].y;
	      intx2 = (int) apfig2[i+1][10].x;
	      inty2 = (int) apfig2[i+1][10].y ;
	      //drawvector (interp, intx1, inty1, intx2, inty2, 3, i_img, "magenta");
	    }
	}

      break;
    }
  return TCL_OK;
}
Exemplo n.º 11
0
void correspondences_4 (Tcl_Interp* interp, const char** argv)
{
  int 	i,j,k,l,m,n,o,  i1,i2,i3;
  int   count, match0=0, match4=0, match3=0, match2=0, match1=0;
  int 	p1,p2,p3,p4, p31, p41, p42;
  int  	pt1;
  int 	tim[4][nmax];
  int  	intx, inty;
  double       	xa12,ya12,xb12,yb12,X,Y,Z;
  double       	corr;
  candidate   	cand[maxcand];
  n_tupel     	*con0;
  correspond  	*list[4][4];
/* ----------------------------------------------------------------------- */


  /* allocate memory for lists of correspondences */
  for (i1=0; i1<n_img-1; i1++)	for (i2=i1+1; i2<n_img; i2++)
    list[i1][i2] = (correspond *) malloc (num[i1] * sizeof (correspond));


  con0 = (n_tupel *) malloc (4*nmax * sizeof (n_tupel));

  /* ----------------------------------------------------------------------- */


printf("in corres zmin0: %f, zmax0: %f\n", Zmin_lay[0],Zmax_lay[0] );

  /*  initialize ...  */
  sprintf (buf,"Establishing correspondences");
  Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 2");
  Tcl_Eval(interp, ".text insert 2 $tbuf");

  match=0; match0=0; match2=0;

  for (i1=0; i1<n_img-1; i1++)
    for (i2=i1+1; i2<n_img; i2++)
      for (i=0; i<num[i1]; i++)
	{
	  list[i1][i2][i].p1 = 0;
	  list[i1][i2][i].n = 0;
	}

  for (i=0; i<nmax; i++)
    {
      for (j=0; j<4; j++) tim[j][i] = 0;
      for (j=0; j<4; j++) con0[i].p[j] = -1; con0[i].corr = 0;
    }


  /* -------------if only one cam and 2D--------- */ //by Beat Lüthi June 2007
  if(n_img==1){
	  if(res_name[0]==0){
          sprintf (res_name, "rt_is");
	  }
	 fp1 = fopen (res_name, "w");
		fprintf (fp1, "%4d\n", num[0]);
	  for (i=0; i<num[0]; i++){
          o = epi_mm_2D (geo[0][i].x,geo[0][i].y,
		      Ex[0], I[0],  G[0], mmp,
		      &X,&Y,&Z);
          pix[0][geo[0][i].pnr].tnr=i;
		  fprintf (fp1, "%4d", i+1);
		  fprintf (fp1, " %9.3f %9.3f %9.3f", X, Y, Z);
          fprintf (fp1, " %4d", geo[0][i].pnr);
          fprintf (fp1, " %4d", -1);
          fprintf (fp1, " %4d", -1);
          fprintf (fp1, " %4d\n", -1);
	  }
	  fclose (fp1);
	  match1=num[0];
  }
  /* -------------end of only one cam and 2D ------------ */

  /* matching  1 -> 2,3,4  +  2 -> 3,4  +  3 -> 4 */

  for (i1=0; i1<n_img-1; i1++)	for (i2=i1+1; i2<n_img; i2++)
    {
      sprintf (buf, "Establishing correspondences  %d - %d", i1, i2);
      puts (buf);

      /* establish correspondences from num[i1] points of img[i1] to img[i2] */
      for (i=0; i<num[i1]; i++)	if (geo[i1][i].x != -999)
	{
	  /*o = epi_mm (geo[i1][i].x,geo[i1][i].y,
		      Ex[i1], I[i1], G[i1], Ex[i2], I[i2], G[i2], mmp,
		      &xa12, &ya12, &xb12, &yb12);

	  o = epi_mm (xa12, ya12,
		      Ex[i2], I[i2], G[i2], Ex[i1], I[i1], G[i1], mmp,
		      &xa12, &ya12, &xb12, &yb12);*/

      o = epi_mm (geo[i1][i].x,geo[i1][i].y,
		      Ex[i1], I[i1], G[i1], Ex[i2], I[i2], G[i2], mmp,
		      &xa12, &ya12, &xb12, &yb12);
	  
    /////ich glaube, da muss ich einsteigen, wenn alles erledigt ist.
	  ///////mit bild_1 x,y Epipole machen und dann selber was schreiben um die Distanz zu messen.
	  ///////zu Punkt in bild_2.


	  /* origin point in the list */
	  p1 = i;  list[i1][i2][p1].p1 = p1;	pt1 = geo[i1][p1].pnr;

	  /* search for a conjugate point in geo[i2] */
	  find_candidate_plus (geo[i2], pix[i2], num[i2],
			       xa12, ya12, xb12, yb12, eps0,
			       pix[i1][pt1].n,pix[i1][pt1].nx,pix[i1][pt1].ny,
			       pix[i1][pt1].sumg, cand, &count, i2,argv);


	  /* write all corresponding candidates to the preliminary list */
	  /* of correspondences */
	  if (count > maxcand)	{ count = maxcand; }
	  for (j=0; j<count; j++)
	    {
	      list[i1][i2][p1].p2[j] = cand[j].pnr;
	      list[i1][i2][p1].corr[j] = cand[j].corr;
	      list[i1][i2][p1].dist[j] = cand[j].tol;
	    }
	  list[i1][i2][p1].n = count;
	}
    }

  /* repair memory fault (!?) */
  for (j=0; j<4; j++) for (i=0; i<nmax; i++) tim[j][i] = 0;


  /* ------------------------------------------------------------------ */
  /* ------------------------------------------------------------------ */

  /* search consistent quadruplets in the list */
  if (n_img == 4)
    {
      puts ("Search consistent quadruplets");
      for (i=0, match0=0; i<num[0]; i++)
	{
	  p1 = list[0][1][i].p1;
	  for (j=0; j<list[0][1][i].n; j++)
	    for (k=0; k<list[0][2][i].n; k++)
	      for (l=0; l<list[0][3][i].n; l++)
		{
		  p2 = list[0][1][i].p2[j];
		  p3 = list[0][2][i].p2[k];
		  p4 = list[0][3][i].p2[l];
		  for (m=0; m<list[1][2][p2].n; m++)
		    for (n=0; n<list[1][3][p2].n; n++)
		      {
			p31 = list[1][2][p2].p2[m];
			p41 = list[1][3][p2].p2[n];
			if (p3 == p31  &&  p4 == p41)
			  for (o=0; o<list[2][3][p3].n; o++)
			    {
			      p42 = list[2][3][p3].p2[o];
			      if (p4 == p42)
				{
				  corr = (list[0][1][i].corr[j]
					  + list[0][2][i].corr[k]
					  + list[0][3][i].corr[l]
					  + list[1][2][p2].corr[m]
					  + list[1][3][p2].corr[n]
					  + list[2][3][p3].corr[o])
				    / (list[0][1][i].dist[j]
				       + list[0][2][i].dist[k]
				       + list[0][3][i].dist[l]
				       + list[1][2][p2].dist[m]
				       + list[1][3][p2].dist[n]
				       + list[2][3][p3].dist[o]);
				  if (corr > corrmin)
				    {
				      /* accept as preliminary match */
				      con0[match0].p[0] = p1;
				      con0[match0].p[1] = p2;
				      con0[match0].p[2] = p3;
				      con0[match0].p[3] = p4;
				      con0[match0++].corr = corr;
				      if (match0 == 4*nmax)	/* security */
					{
					  printf ("Overflow in correspondences:");
					  printf (" > %d matches\n", match0);
					  i = num[0];
					}
				    }
				}
			    }
		      }
		}
	}


      /* -------------------------------------------------------------------- */

      /* sort quadruplets for match quality (.corr) */
      quicksort_con (con0, match0);

      /* -------------------------------------------------------------------- */

      /* take quadruplets from the top to the bottom of the sorted list */
      /* only if none of the points has already been used */
      for (i=0, match=0; i<match0; i++)
	{
	  p1 = con0[i].p[0];	if (p1 > -1)	if (++tim[0][p1] > 1)	continue;
	  p2 = con0[i].p[1];	if (p2 > -1)	if (++tim[1][p2] > 1)	continue;
	  p3 = con0[i].p[2];	if (p3 > -1)	if (++tim[2][p3] > 1)	continue;
	  p4 = con0[i].p[3];	if (p4 > -1)	if (++tim[3][p4] > 1)	continue;
	  con[match++] = con0[i];
	}

      match4 = match;
      sprintf (buf, "%d consistent quadruplets, ", match4);	puts (buf);
    }

  /* ----------------------------------------------------------------------- */
  /* ----------------------------------------------------------------------- */

  /* search consistent triplets :  123, 124, 134, 234 */
  if ((n_img ==4 && allCam_flag==0) || n_img ==3)
    {
      puts ("Search consistent triplets");
      match0=0;
      for (i1=0; i1<n_img-2; i1++)
	for (i2=i1+1; i2<n_img-1; i2++)
	  for (i3=i2+1; i3<n_img; i3++)
	    for (i=0; i<num[i1]; i++)
	      {
		p1 = list[i1][i2][i].p1;
		if (p1 > nmax  ||  tim[i1][p1] > 0)	continue;

		for (j=0; j<list[i1][i2][i].n; j++)
		  for (k=0; k<list[i1][i3][i].n; k++)
		    {
		      p2 = list[i1][i2][i].p2[j];
		      if (p2 > nmax  ||  tim[i2][p2] > 0)	continue;
		      p3 = list[i1][i3][i].p2[k];
		      if (p3 > nmax  ||  tim[i3][p3] > 0)	continue;

		      for (m=0; m<list[i2][i3][p2].n; m++)
			{
			  p31 = list[i2][i3][p2].p2[m];
			  if (p3 == p31)
			    {
			      corr = (list[i1][i2][i].corr[j]
				      + list[i1][i3][i].corr[k]
				      + list[i2][i3][p2].corr[m])
				/ (list[i1][i2][i].dist[j]
				   + list[i1][i3][i].dist[k]
				   + list[i2][i3][p2].dist[m]);
 			      if (corr > corrmin)
				{ for (n=0; n<n_img; n++) con0[match0].p[n] = -2;
				  con0[match0].p[i1] = p1;
				  con0[match0].p[i2] = p2;
				  con0[match0].p[i3] = p3;
				  con0[match0++].corr = corr;
				}
			    }
			}
		    }
	      }

      /* ----------------------------------------------------------------------- */

      /* sort triplets for match quality (.corr) */
      quicksort_con (con0, match0);

      /* ----------------------------------------------------------------------- */

      /* pragmatic version: */
      /* take triplets from the top to the bottom of the sorted list */
      /* only if none of the points has already been used */
      for (i=0; i<match0; i++)
	{
	  p1 = con0[i].p[0];	if (p1 > -1)	if (++tim[0][p1] > 1)	continue;
	  p2 = con0[i].p[1];	if (p2 > -1)	if (++tim[1][p2] > 1)	continue;
	  p3 = con0[i].p[2];	if (p3 > -1)	if (++tim[2][p3] > 1)	continue;
	  p4 = con0[i].p[3];	if (p4 > -1  && n_img > 3) if (++tim[3][p4] > 1) continue;

	  con[match++] = con0[i];
	}

      match3 = match - match4;
      sprintf (buf, "%d consistent quadruplets, %d triplets ", match4, match3);
      puts (buf);

      /* repair artifact (?) */
      if (n_img == 3)	for (i=0; i<match; i++)	con[i].p[3] = -1;
    }

  /* ----------------------------------------------------------------------- */
  /* ----------------------------------------------------------------------- */

  /* search consistent pairs :  12, 13, 14, 23, 24, 34 */
  /* only if an object model is available or if only 2 images are used */
  if(1<2 && n_img>1 && allCam_flag==0){
	  puts ("Search pairs");


  match0 = 0;
  for (i1=0; i1<n_img-1; i1++)
    //if ( n_img == 2 || (num[0] < 64 && num[1] < 64 && num[2] < 64 && num[3] < 64))
	if ( n_img > 1)
      for (i2=i1+1; i2<n_img; i2++)
	for (i=0; i<num[i1]; i++)
	  {
	    p1 = list[i1][i2][i].p1;
	    if (p1 > nmax  ||  tim[i1][p1] > 0)	continue;

	    /* take only unambigous pairs */
	    if (list[i1][i2][i].n != 1)	continue;

	    p2 = list[i1][i2][i].p2[0];
	    if (p2 > nmax  ||  tim[i2][p2] > 0)	continue;

	    corr = list[i1][i2][i].corr[0] / list[i1][i2][i].dist[0];

	    if (corr > corrmin)
	      {
		con0[match0].p[i1] = p1;
		con0[match0].p[i2] = p2;
		con0[match0++].corr = corr;
	      }
	  }

  /* ----------------------------------------------------------------------- */


  /* sort pairs for match quality (.corr) */
  quicksort_con (con0, match0);

  /* ----------------------------------------------------------------------- */


  /* take pairs from the top to the bottom of the sorted list */
  /* only if none of the points has already been used */
  for (i=0; i<match0; i++)
    {
      p1 = con0[i].p[0];	if (p1 > -1)	if (++tim[0][p1] > 1)	continue;
      p2 = con0[i].p[1];	if (p2 > -1)	if (++tim[1][p2] > 1)	continue;
      p3 = con0[i].p[2];	if (p3 > -1  && n_img > 2)
	if (++tim[2][p3] > 1)	continue;
      p4 = con0[i].p[3];	if (p4 > -1  && n_img > 3)
	if (++tim[3][p4] > 1)	continue;

      con[match++] = con0[i];
    }
  } //end pairs?

  match2 = match-match4-match3;
  if(n_img==1){
     sprintf (buf, "determined %d points from 2D", match1);
     puts (buf);
  }
  else{
     sprintf (buf, "%d consistent quadruplets(red), %d triplets(green) and %d unambigous pairs",
	      match4, match3, match2);
     puts (buf);
  }
  Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 3");
  Tcl_Eval(interp, ".text insert 3 $tbuf");

  /* ----------------------------------------------------------------------- */

  /* give each used pix the correspondence number */
  for (i=0; i<match; i++){
      for (j=0; j<n_img; j++){
		  if (con[i].p[j] > -1){ //Bug, detected in Nov 2011 by Koni&Beat
	          p1 = geo[j][con[i].p[j]].pnr;
	          if (p1 > -1 && p1 < 1202590843){
	              pix[j][p1].tnr= i;
	          }
		  }
	  }
  }

  /* draw crosses on canvas */
  if (display) {
    for (i=0; i<match4; i++)	       	/* red crosses for quadruplets */
      {
	for (j=0; j<n_img; j++)
	  {
	    p1 = geo[j][con[i].p[j]].pnr;
	    if (p1 > -1)
	      {
		if (   (fabs(pix[j][p1].x-zoom_x[j]) < imx/(2*zoom_f[j]))
		       && (fabs(pix[j][p1].y-zoom_y[j]) < imy/(2*zoom_f[j])))
		  {
		    intx = (int) ( imx/2 + zoom_f[j] * (pix[j][p1].x-zoom_x[j]));
		    inty = (int) ( imy/2 + zoom_f[j] * (pix[j][p1].y-zoom_y[j]));
		    drawcross (interp, intx, inty, cr_sz, j, "red");
		    if (zoom_f[j]>=2) draw_pnr (interp, intx+5 , inty+0, i, j, "white");
		  }
	      }
	  }
      }

    for (i=match4; i<match4+match3; i++)	/* green crosses for triplets */
      {
	for (j=0; j<n_img; j++)
	  {
	    p1 = geo[j][con[i].p[j]].pnr;
	    if (p1 > -1 && con[i].p[j] > -1)
	      {
		if (   (fabs(pix[j][p1].x-zoom_x[j]) < imx/(2*zoom_f[j]))
		       && (fabs(pix[j][p1].y-zoom_y[j]) < imy/(2*zoom_f[j])))
		  {
		    intx = (int) ( imx/2 + zoom_f[j] * (pix[j][p1].x-zoom_x[j]));
		    inty = (int) ( imy/2 + zoom_f[j] * (pix[j][p1].y-zoom_y[j]));
		    drawcross ( interp, intx, inty, cr_sz, j, "green" );
		    if (zoom_f[j]>=2) draw_pnr (interp, intx+5 , inty+0, i, j, "white");/* number of triplet */
		  }
		
	      }
	  }
      }
    for (i=match4+match3; i<match4+match3+match2; i++)
      {			      	/* yellow crosses for pairs */
	for (j=0; j<n_img; j++)
	  {
	    p1 = geo[j][con[i].p[j]].pnr;
	    if (p1 > -1 && con[i].p[j] > -1)
	      {
		if (   (fabs(pix[j][p1].x-zoom_x[j]) < imx/(2*zoom_f[j]))
		       && (fabs(pix[j][p1].y-zoom_y[j]) < imy/(2*zoom_f[j])))
		  {
		    intx = (int) ( imx/2 + zoom_f[j] * (pix[j][p1].x-zoom_x[j]));
		    inty = (int) ( imy/2 + zoom_f[j] * (pix[j][p1].y-zoom_y[j]));
		    drawcross (interp, intx, inty, cr_sz, j, "yellow");
		    if (zoom_f[j]>=2) draw_pnr (interp, intx+5 , inty+0, i, j, "white"); /* number of triplet */
		  }
	      }
	  }
      }
    
    for (j=0; j<n_img; j++)
      {
	
	for (i=0; i<num[j]; i++)
	  {			      	/* blue crosses for unused detections */
	    p1 = pix[j][i].tnr;
	    if (p1 == -1 )
	      {
		if (   (fabs(pix[j][i].x-zoom_x[j]) < imx/(2*zoom_f[j]))
		       && (fabs(pix[j][i].y-zoom_y[j]) < imy/(2*zoom_f[j])))
		  {
		    intx = (int) ( imx/2 + zoom_f[j] * (pix[j][i].x-zoom_x[j]));
		    inty = (int) ( imy/2 + zoom_f[j] * (pix[j][i].y-zoom_y[j]));
		    drawcross (interp, intx, inty, cr_sz, j, "blue");
		    
		  }
	      }
	  }
      }
  }
  /* ----------------------------------------------------------------------- */
  /* free memory for lists of correspondences */
  for (i1=0; i1<n_img-1; i1++)
    {
      for (i2=i1+1; i2<n_img; i2++) free (list[i1][i2]);
    }

  free (con0);

  sprintf (buf,"Correspondences done");
  Tcl_SetVar(interp, "tbuf", buf, TCL_GLOBAL_ONLY);
  Tcl_Eval(interp, ".text delete 2");
  Tcl_Eval(interp, ".text insert 2 $tbuf");
}
Exemplo n.º 12
0
_Bool svg_draw(_Bool needmemory)
{
    int size, s;
    void *p;

    if(svg_data) {
        free(svg_data);
    }

    size = SCROLL_WIDTH * SCROLL_WIDTH + BM_STATUSAREA_WIDTH * BM_STATUSAREA_HEIGHT + BM_ADD_WIDTH * BM_ADD_WIDTH * 4 +
            BM_CONTACT_WIDTH * BM_CONTACT_WIDTH * 2 + BM_LBICON_WIDTH * BM_LBICON_HEIGHT * 3 + BM_STATUS_WIDTH * BM_STATUS_WIDTH * 4 +
            BM_STATUS_NOTIFY_WIDTH * BM_STATUS_NOTIFY_WIDTH +
            BM_LBUTTON_WIDTH * BM_LBUTTON_HEIGHT + BM_SBUTTON_WIDTH * BM_SBUTTON_HEIGHT + BM_FT_WIDTH * BM_FT_HEIGHT +
            BM_FTM_WIDTH * BM_FT_HEIGHT + (BM_FTB_WIDTH * (BM_FTB_HEIGHT + SCALE) + BM_FTB_WIDTH * BM_FTB_HEIGHT) +
            BM_FB_WIDTH * BM_FB_HEIGHT * 4;
    svg_data = calloc(1, size);

    if(!svg_data) {
        return 0;
    }

    p = svg_data;

    drawcircle(p, SCROLL_WIDTH);
    loadalpha(BM_SCROLLHALFTOP, p, SCROLL_WIDTH, SCROLL_WIDTH / 2);
    loadalpha(BM_SCROLLHALFBOT, p + SCROLL_WIDTH * SCROLL_WIDTH / 2, SCROLL_WIDTH, SCROLL_WIDTH / 2);
    p += SCROLL_WIDTH * SCROLL_WIDTH;

    drawrectrounded(p, BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT, SCALE * 2);
    loadalpha(BM_STATUSAREA, p, BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT);
    p += BM_STATUSAREA_WIDTH * BM_STATUSAREA_HEIGHT;

    s = BM_ADD_WIDTH * BM_ADD_WIDTH;

    drawcross(p, BM_ADD_WIDTH);
    loadalpha(BM_ADD, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += s;

    drawgroup(p, BM_ADD_WIDTH);
    loadalpha(BM_GROUPS, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += s;

    drawline(p, BM_ADD_WIDTH, BM_ADD_WIDTH, SCALE * 3, SCALE * 3, SCALE * 5, 0.75 * SCALE);
    drawline(p, BM_ADD_WIDTH, BM_ADD_WIDTH, SCALE * 6, SCALE * 6, SCALE * 5, 0.75 * SCALE);
    drawtri(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 6 * SCALE, 0, 4 * SCALE, 0);
    drawtri(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 3 * SCALE, 9 * SCALE, 4 * SCALE, 1);
    loadalpha(BM_TRANSFER, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += s;

    drawcross(p, BM_ADD_WIDTH);
    drawxcross(p, BM_ADD_WIDTH, BM_ADD_WIDTH, BM_ADD_WIDTH);
    drawnewcircle(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 7 * SCALE);
    drawsubcircle(p, BM_ADD_WIDTH, BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 0.5 * BM_ADD_WIDTH, 3 * SCALE);
    loadalpha(BM_SETTINGS, p, BM_ADD_WIDTH, BM_ADD_WIDTH);
    p += s;

    s = BM_CONTACT_WIDTH * BM_CONTACT_WIDTH;

    drawnewcircle(p, BM_CONTACT_WIDTH, 18 * SCALE, 10 * SCALE, 18 * SCALE, 14 * SCALE);
    drawsubcircle(p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, 10 * SCALE, 10 * SCALE, 6 * SCALE);
    drawhead(p, BM_CONTACT_WIDTH, 10 * SCALE, 6 * SCALE, 8 * SCALE);
    loadalpha(BM_CONTACT, p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH);
    p += s;

    drawgroup(p, BM_CONTACT_WIDTH);
    loadalpha(BM_GROUP, p, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH);
    p += s;

    s = BM_LBICON_WIDTH * BM_LBICON_HEIGHT;

    drawlineround(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 5.5 * SCALE, 5 * SCALE, 1 * SCALE, 3.85 * SCALE, 6.6 * SCALE, 0);
    drawlineroundempty(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 5.5 * SCALE, 5 * SCALE, 1 * SCALE, 2.4 * SCALE, 4.5 * SCALE);
    drawsubcircle(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 6.0 * SCALE, 8.1 * SCALE, 2.5 * SCALE);
    drawlineround(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 7.0 * SCALE, 5.40 * SCALE, 0.5 * SCALE, 2.2 * SCALE, 3.75 * SCALE, 1);
    drawlineroundempty(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 7.25 * SCALE, 5.15 * SCALE, 0.75 * SCALE, 0.75 * SCALE, 1.5 * SCALE);
    loadalpha(BM_FILE, p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT);
    p += s;

    drawnewcircle(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, SCALE, 0, 19 * SCALE);
    drawsubcircle(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, SCALE, 0, 15 * SCALE);
    drawnewcircle2(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 9 * SCALE, 2 * SCALE, 3 * SCALE, 0);
    drawnewcircle2(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 3 * SCALE, 8 * SCALE, 3 * SCALE, 1);
    loadalpha(BM_CALL, p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT);
    p += s;

    int x, y;
    uint8_t *data = p;
    for(y = 0; y != BM_LBICON_HEIGHT; y++) {
        for(x = 0; x != SCALE * 4; x++) {
            double d = fabs(y - 4.5 * SCALE) - 0.66 * (SCALE * 4 - x);
            *data++ = pixel(d);
        }
        data += BM_LBICON_WIDTH - SCALE * 4;
    }
    drawrectroundedsub(p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT, 4 * SCALE, SCALE, 7 * SCALE, 7 * SCALE, SCALE);
    loadalpha(BM_VIDEO, p, BM_LBICON_WIDTH, BM_LBICON_HEIGHT);
    p += s;

    s = BM_STATUS_WIDTH * BM_STATUS_WIDTH;

    drawcircle(p, BM_STATUS_WIDTH);
    loadalpha(BM_ONLINE, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH / 2, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 3 * SCALE);
    loadalpha(BM_AWAY, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH / 2, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 3 * SCALE);
    loadalpha(BM_BUSY, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_WIDTH);
    drawsubcircle(p, BM_STATUS_WIDTH, BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 0.5 * BM_STATUS_WIDTH, 3 * SCALE);
    loadalpha(BM_OFFLINE, p, BM_STATUS_WIDTH, BM_STATUS_WIDTH);
    p += s;

    drawcircle(p, BM_STATUS_NOTIFY_WIDTH);
    drawsubcircle(p, BM_STATUS_NOTIFY_WIDTH, BM_STATUS_NOTIFY_WIDTH, 0.5 * BM_STATUS_NOTIFY_WIDTH, 0.5 * BM_STATUS_NOTIFY_WIDTH, 5 * SCALE);
    loadalpha(BM_STATUS_NOTIFY, p, BM_STATUS_NOTIFY_WIDTH, BM_STATUS_NOTIFY_WIDTH);
    p += BM_STATUS_NOTIFY_WIDTH * BM_STATUS_NOTIFY_WIDTH;

    drawrectrounded(p, BM_LBUTTON_WIDTH, BM_LBUTTON_HEIGHT, SCALE * 2);
    loadalpha(BM_LBUTTON, p, BM_LBUTTON_WIDTH, BM_LBUTTON_HEIGHT);
    p += BM_LBUTTON_WIDTH * BM_LBUTTON_HEIGHT;

    drawrectrounded(p, BM_SBUTTON_WIDTH, BM_SBUTTON_HEIGHT, SCALE);
    loadalpha(BM_SBUTTON, p, BM_SBUTTON_WIDTH, BM_SBUTTON_HEIGHT);
    p += BM_SBUTTON_WIDTH * BM_SBUTTON_HEIGHT;

    drawrectrounded(p, BM_FT_WIDTH, BM_FT_HEIGHT, SCALE * 2);
    loadalpha(BM_FT, p, BM_FT_WIDTH, BM_FT_HEIGHT);
    p += BM_FT_WIDTH * BM_FT_HEIGHT;

    drawrectroundedex(p, BM_FTM_WIDTH, BM_FT_HEIGHT, SCALE * 2, 13);
    loadalpha(BM_FTM, p, BM_FTM_WIDTH, BM_FT_HEIGHT);
    p += BM_FTM_WIDTH * BM_FT_HEIGHT;

    drawrectroundedex(p, BM_FTB_WIDTH, BM_FTB_HEIGHT + SCALE, SCALE * 2, 6);
    loadalpha(BM_FTB1, p, BM_FTB_WIDTH, BM_FTB_HEIGHT + SCALE);
    p += BM_FTB_WIDTH * (BM_FTB_HEIGHT + SCALE);

    drawrectroundedex(p, BM_FTB_WIDTH, BM_FTB_HEIGHT, SCALE * 2, 10);
    loadalpha(BM_FTB2, p, BM_FTB_WIDTH, BM_FTB_HEIGHT);
    p += BM_FTB_WIDTH * BM_FTB_HEIGHT;

    s = BM_FB_WIDTH * BM_FB_HEIGHT;

    drawxcross(p, BM_FB_WIDTH, BM_FB_HEIGHT, BM_FB_HEIGHT);
    loadalpha(BM_NO, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawlinevert(p, BM_FB_WIDTH, BM_FB_HEIGHT, 0.75 * SCALE, 1.25 * SCALE);
    drawlinevert(p, BM_FB_WIDTH, BM_FB_HEIGHT, 4.25 * SCALE, 1.25 * SCALE);
    loadalpha(BM_PAUSE, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawline(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 1.75, SCALE * 3.5, SCALE * 2.5, 0.5 * SCALE);
    drawline(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 4, SCALE * 3.5, SCALE * 2.5, 0.5 * SCALE);
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 1.75, SCALE * 1.75, SCALE * 2.5, 0.5 * SCALE);
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 4, SCALE * 1.75, SCALE * 2.5, 0.5 * SCALE);
    loadalpha(BM_RESUME, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    drawline(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 3.75, SCALE * 2.75, SCALE * 4, 0.5 * SCALE);
    drawlinedown(p, BM_FB_WIDTH, BM_FB_HEIGHT, SCALE * 1.9, SCALE * 3.25, SCALE * 2.5, 0.5 * SCALE);
    loadalpha(BM_YES, p, BM_FB_WIDTH, BM_FB_HEIGHT);
    p += s;

    if(p - svg_data != size) {
        debug("something went wrong\n");
    }

    if(!needmemory) {
        free(svg_data);
        svg_data = NULL;
    }

    return 1;
}