/** * Execute redraw request queue * * \param avail_time time available for executing redraw requests */ static s32 exec_redraw(s32 avail_time) { static float pix_per_usec = 8.0; /* average number of pixels per usec */ int used_time = 0; /* time used for the iteration */ int pix_cnt = 0; /* number of overall processed pixels */ int min_pix = 1000; /* minimal number of pixels to process */ int num_pix = 0; /* number of currently processed pixels */ u32 start_time; /* start time of drawing */ start_time = timer->get_time(); /* process pixels as int as there are due redraw requests and there is time left */ while (last != first && used_time < avail_time) { /* determine number of pixels that can be processed in the available time */ num_pix = (avail_time - used_time) * pix_per_usec; /* sanity check */ if (num_pix < 0) break; /* process num_pix pixels */ pix_cnt += process_pixels(num_pix); used_time = timer->get_diff(start_time, timer->get_time()); } /* adapt the pix_per_usec ratio */ if (config_adapt_redraw && num_pix > 10000) pix_per_usec = adapt_pix_per_usec(pix_per_usec, pix_cnt, used_time); /* * Clamp the pix/usec ratio to a lower border. In some situation * (for example if someone switches off interrupts for some time), * the measurement of drawing duration times may be messed up. * This could cause MTK to adapt to these timing constrains in a * way that only a few pixels are drawn for each period, which * raises the overhead of traversing widget structures and clipping * an never allows MTK to recover from that situation. Thus, * limiting the adaption to a lower border is needed to preserve * robustness even in such bad situations. */ if (pix_per_usec < 8.0) pix_per_usec = 8.0; /* * If there was not enough time to process min_pix pixels * draw min_pix pixels to keep the user interface alive. */ if (pix_cnt < min_pix) process_pixels(min_pix); return 1; }
bool bitmap_from_file(bitmap *bmp, const char *filepath) { if (!bmp || bmp->pixels) return false; bmp->width = 0; bmp->height = 0; bmp->pixels = NULL; #if defined _WIN32 || defined _WIN64 FILE *file = fopen(filepath, "rb"); #else int file = fopen(filepath, "rb"); #endif if (file) { uint8_t header[54]; if (fread(header, 1, sizeof(header), file) != sizeof(header)) { perror("Cannot read bitmap header."); goto error; } if (header[0] != 'B' && header[1] != 'M') { perror("Invalid bitmap. Only 24bit and 32bit bitmaps supported."); goto error; } uint16_t bpp = header[28]; bmp->width = header[18] + (header[19] << 8); bmp->height = header[22] + (header[23] << 8); uint32_t pxoffset = header[10] + (header[11] << 8); uint32_t size = ((bmp->width * bpp + 31) / 32) * 4 * bmp->height; fseek(file, pxoffset, SEEK_SET); if (!(bmp->pixels = malloc(size))) { perror("Cannot allocate pixel memory."); goto error; } if (fread(bmp->pixels, 1, size, file) != size) { perror("Cannot read all pixels."); goto error; } fclose(file); return process_pixels(bmp, size, bpp); } perror("Cannot open file."); error: fclose(file); return false; }
/*** EXECUTE ALL PENDING REDRAW REQUESTS ***/ static void exec_redraw_all(void) { verify(); process_pixels(0x7fffffff); }
int main(int argc, char **argv) { GHashTable *pixtable; int c; char *ffile,*mfile,*ignfile,*unistr; GList *ignlist=NULL; /* list of islands to ignore */ GList *ignli; FILE *cfp; int ignc, *ignp; double threshold=0.0; int use_em=1; int donegative=0; int maxiter=1000; int maxemiter=4; int outformat=0; /* 0: BBS, 1: LSM */ /* for parsing integers */ int base=10; char *endptr; int beam_given=0; double bmaj=0.001; double bmin=0.001; double bpa=0.0; double minpix; double clusterratio=1.0; int maxfits=10; int multifits=0; int nclusters=0; double wcutoff=0.0; int scaleflux=0; /* if 1, scale flux to match the total flux of island */ /* for multiple FITS files */ int Nf=0; double *freqs,*bmajs,*bmins,*bpas; double ref_freq; print_copyright(); ffile=mfile=ignfile=unistr=0; if (argc<2) { print_help(); return 1; } while ((c=getopt(argc,argv,"a:b:c:d:e:f:g:i:k:l:m:o:p:q:s:t:w:Nnh"))!=-1) { switch(c) { case 'f': if (optarg) { ffile=(char*)calloc((size_t)strlen((char*)optarg)+1,sizeof(char)); if ( ffile== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } strcpy(ffile,(char*)optarg); } break; case 'd': if (optarg) { ffile=(char*)calloc((size_t)strlen((char*)optarg)+1,sizeof(char)); if ( ffile== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } strcpy(ffile,(char*)optarg); multifits=1; } break; case 'm': if (optarg) { mfile=(char*)calloc((size_t)strlen((char*)optarg)+1,sizeof(char)); if ( mfile== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } strcpy(mfile,(char*)optarg); } break; case 'g': if (optarg) { ignfile=(char*)calloc((size_t)strlen((char*)optarg)+1,sizeof(char)); if ( ignfile== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } strcpy(ignfile,(char*)optarg); } break; case 's': if (optarg) { unistr=(char*)calloc((size_t)strlen((char*)optarg)+1,sizeof(char)); if ( unistr== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } strcpy(unistr,(char*)optarg); } break; case 't': if (optarg) { threshold=strtod(optarg,0); } break; case 'c': if (optarg) { clusterratio=strtod(optarg,0); } break; case 'i': if (optarg) { maxiter=(int)strtol(optarg,&endptr,base); if (endptr==optarg) maxiter=1000; } break; case 'k': if (optarg) { nclusters=(int)strtol(optarg,&endptr,base); if (endptr==optarg) nclusters=0; } break; case 'l': if (optarg) { maxfits=(int)strtol(optarg,&endptr,base); if (endptr==optarg) maxfits=10; } break; case 'o': if (optarg) { outformat=(int)strtol(optarg,&endptr,base); if (endptr==optarg) outformat=0; } break; case 'e': if (optarg) { maxemiter=(int)strtol(optarg,&endptr,base); if (endptr==optarg) maxemiter=1000; } break; case 'q': if (optarg) { scaleflux=(int)strtol(optarg,&endptr,base); if (endptr==optarg) scaleflux=0; } break; case 'a': if (optarg) { bmaj=strtod(optarg,0); /* convert arcsec to radians , divide by 2 to get radius*/ if(!bmaj) { bmaj=0.001; } else { bmaj=(bmaj/3600.0)/360.0*M_PI; } beam_given=1; } break; case 'b': if (optarg) { bmin=strtod(optarg,0); /* convert arcsec to radians , divide by 2 to get radius*/ if(!bmin) { bmin=0.001; } else { bmin=(bmin/3600.0)/360.0*M_PI; } beam_given=1; } break; case 'p': if (optarg) { bpa=strtod(optarg,0); if(!bpa) { bpa=0.01; } else { /* convert deg to rad */ bpa=(bpa)/180.0*M_PI; } beam_given=1; } break; case 'n': use_em=0; break; case 'N': donegative=1; break; case 'w': if (optarg) { wcutoff=strtod(optarg,0); } if (wcutoff<0.0) { wcutoff=0.0; } break; case 'h': print_help(); return 1; default: print_help(); break; } } if (ffile && mfile) { if (!unistr) { unistr=(char*)calloc((size_t)1,sizeof(char)); if ( unistr== 0 ) { fprintf(stderr,"%s: %d: no free memory",__FILE__,__LINE__); exit(1); } unistr[0]='\0'; } /* use a new random seed */ srand(time(0)); /* build ignore list, if given */ if (ignfile) { if ((cfp=fopen(ignfile,"r"))==0) { fprintf(stderr,"%s: %d: no file %s\n",__FILE__,__LINE__,ignfile); exit(1); } do { c=fscanf(cfp,"%d",&ignc); if (c>0) { if ((ignp= (int*)malloc(sizeof(int)))==0) { fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__); exit(1); } *ignp=ignc; ignlist=g_list_prepend(ignlist,ignp); } } while (c>= 0); printf("Ignore %d islands\n",g_list_length(ignlist)); fclose(cfp); } if (!multifits) { read_fits_file(ffile,mfile, &pixtable,&bmaj,&bmin,&bpa, beam_given, &minpix, ignlist); } else { freqs=bmajs=bmins=bpas=0; read_fits_file_f(ffile,mfile, &pixtable,&Nf,&freqs,&bmajs,&bmins,&bpas, beam_given, &minpix, ignlist,donegative); } /* dont need ignore list anymore */ for(ignli=ignlist; ignli!=NULL; ignli=g_list_next(ignli)) { ignp=ignli->data; g_free(ignp); } g_list_free(ignlist); /* filter pixel blobs, remove dodgy ones */ if (wcutoff>0.0) { if (!multifits ) { filter_pixels(pixtable,wcutoff); } else { filter_pixels_f(pixtable,wcutoff); } /* if filter is on, quit now */ printf("quitting. re-run without filter\n"); free(unistr); return 0; } if (!multifits) { process_pixels(pixtable,bmaj,bmin,bpa,minpix,threshold,maxiter,maxemiter,use_em,maxfits); write_world_coords(ffile,pixtable,minpix,bmaj,bmin,bpa,outformat,clusterratio,nclusters,unistr,scaleflux); } else { process_pixels_f(pixtable,Nf,freqs,bmajs,bmins,bpas,&ref_freq,minpix,threshold,maxiter,maxemiter,use_em,maxfits); write_world_coords_f(mfile,pixtable,minpix,Nf,freqs,bmajs,bmins,bpas,ref_freq,outformat,clusterratio,nclusters,unistr,donegative, scaleflux); free(freqs); free(bmajs); free(bmins); free(bpas); } g_hash_table_destroy(pixtable); free(ffile); free(mfile); free(ignfile); free(unistr); } else { print_help(); } return 0; }