Example #1
0
void go_plot_contours(
    char *device, char *title, char *xvar, char *yvar, char *topline,
    double **data, double xmin, double xmax, double ymin, double ymax,
    double dx, double dy, long nx, long ny,
    double *contour_level, long n_contours, long contour_label_interval,
    long contour_label_offset, long layout[2], long ix, long iy,
    char *shapes, int *pen, long flags, long pause_interval,
    SHAPE_DATA *shape, long nshapes, unsigned long long tsetFlags, double xlableScale, double ylabelScale)
{
    double map[4], average, spread;
    double pmin, pmax, qmin, qmax;
    double wpmin, wpmax=0, wqmin, wqmax=0;
    long title_at_top=0;
    char newLabel[50];
    time_t timeValue;

    if (!(flags&DEVICE_DEFINED)) 
      change_term(device, strlen(device));
    if ((ix == 0) && (iy == 0))
      graphics_on();
    if (layout[0] && layout[1]) {
      wpmin = (1.0*ix+0)/layout[0];
      wpmax = (1.0*ix+1)/layout[0];
      wqmin = (layout[1]*1.0 - 1 - iy)/layout[1];
      wqmax = (layout[1]*1.0 - 0 - iy)/layout[1];
      set_wspace(wpmin, wpmax, wqmin, wqmax);
      pmin = (wpmax - wpmin) * .15 + wpmin;
      pmax = wpmax - (wpmax - wpmin) * .1;
      qmin = (wqmax - wqmin) * .17 + wqmin;
      qmax = wqmax - (wqmax - wqmin) * .08;
      set_pspace(pmin, pmax, qmin, qmax);
    }

    if (contour_label_interval<0) {
      get_pspace(&pmin, &pmax, &qmin, &qmax);
      set_pspace(pmin, 0.9 * wpmax, qmin, 0.85 * wqmax);
    }
    if (flags&TITLE_AT_TOP) {
      /* adjust pspace to make room at top for the title */
      get_pspace(&pmin, &pmax, &qmin, &qmax);
      spread = qmax-qmin;
      qmax -= 0.04*spread;
      qmin -= 0.04*spread;
      /*    qmax -= 0.04;
            qmin -= 0.04;*/
      set_pspace(pmin, pmax, qmin, qmax);
      title_at_top = 1;
    }
    set_clipping(1, 1, 1);


    if (flags&EQUAL_ASPECT1) 
        set_aspect(1.0L);
    else if (flags&EQUAL_ASPECT_1)
        set_aspect(-1.0L);

    set_linetype(pen[0]);
    get_mapping(map, map+1, map+2, map+3);
    if (map[0]==map[1]) {
        average  = (xmax+xmin)/2;
        spread   = (xmax-xmin)/2;
        map[0]   = average - spread*1.05;
        map[1]   = average + spread*1.05;
        }
    if (map[2]==map[3]) {
        average  = (ymax+ymin)/2;
        spread   = (ymax-ymin)/2;
        map[2]   = average - spread*1.05;
        map[3]   = average + spread*1.05;
        }
    set_mapping(map[0], map[1], map[2], map[3]);
    get_pspace(&pmin, &pmax, &qmin, &qmax);
    get_wspace(&wpmin, &wpmax, &wqmin, &wqmax);

    if (!(flags&NO_BORDER)) {
      border();
      if (!(flags&NO_SCALES)) {
        if (tsetFlags&TICKSET_XTIME) {
          timeValue = map[0];
          if (timeValue!=DBL_MAX)
            sprintf(newLabel, "Time starting %s", ctime(&timeValue));
          else
            sprintf(newLabel, "Undefined time values!");
          delete_chars(newLabel, "\n");
          makeTimeScales(0, 0.02, 0, map[2], map[2], newLabel, 
                         0, 0.67*(qmin-wqmin)*(map[3]-map[2])/(qmax-qmin), 
                         0, 1, 1);
        } else {
          make_scales_with_label(0, 0, 1, 0.0, 0.02, 0.0, 
                                 0.0, 1.0, 0, 0, 
                                 0, 0, 0, 0, xvar, 0, 0, xlableScale);
        }
	if (!(flags&NO_YSCALES)) {
          if (tsetFlags&TICKSET_YTIME) {
            timeValue = map[2];
            if (timeValue!=DBL_MAX)
              sprintf(newLabel, "Time starting %s", ctime(&timeValue));
            else
              sprintf(newLabel, "Undefined time values!");
            delete_chars(newLabel, "\n");
            makeTimeScales(1, 0.0125, 0, map[0], map[0], newLabel, 
                           0, (pmin-wpmin)*(map[1]-map[0])/(pmax-pmin), 
                           0, 1, 1);
          } else {
            make_scales_with_label(1, 0, 1, 0.0, 0.0125, 0.0, 
                                   0.0, 1.0, 0, 0, 
                                   0, 0, 0, 0, yvar, 0, 0, ylabelScale);
          }
	}
      }
    }
    if (!(flags&NO_LABELS)) {
      plotTitle(title, 1, title_at_top, 1.0, 0.0, 0, 0);
      if (contour_label_interval>=0)
	plotTitle(topline, 0, 0, 1.0, 0.0, 0, 0);
    }
    set_linetype(pen[1]);
    draw_contours(data, xmin, xmax, ymin, ymax, nx, ny, contour_level, n_contours);
    if (contour_label_interval!=0) {
        set_linetype(pen[2]);
        label_contours(data, nx, ny, contour_level, n_contours,
            contour_label_interval, contour_label_offset,
            xmin, (double)dx, ymin, (double)dy);
        }
    set_linetype(pen[0]);

    if (nshapes)
      PlotShapesData(shape, nshapes, xmin, xmax, ymin, ymax);

    if (flags&DATE_STAMP)
        time_date_stamp();

    }
Example #2
0
int cvsrename(int argc, char **argv)
{
    int c;
    int err = 0;
	char *repos_file1, *repos_file2;
	char *root1, *root2;
	const char *filename1, *filename2, *dir1, *dir2;
	int rootlen;
	List *ent,*ent2;
	Node *node;
	Entnode *entnode;
	const char *cwd;

	if (argc == -1)
		usage (rename_usage);

	quiet = 0;

    optind = 0;
    while ((c = getopt (argc, argv, "+q")) != -1)
    {
	switch (c)
	{
	case 'q':
		quiet = 1;
		break;
    case '?':
    default:
		usage (rename_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

	if(argc!=2)
	{
		usage(rename_usage);
	};

	error(0,0,"Warning: rename is still experimental and may not behave as you would expect");

	if(current_parsed_root->isremote)
	{
		if(!supported_request("Rename"))
			error(1,0,"Remote server does not support rename");
		if(!supported_request("Can-Rename"))
			error(1,0,"Renames are currently disabled");
	}

	if(!strcmp(argv[0],argv[1]))
		return 0;

	rootlen = strlen(current_parsed_root->directory);

	if(!isfile(argv[0]))
		error(1,0,"%s does not exist",argv[0]);

	if(isfile(argv[1]) && fncmp(argv[0],argv[1])) /* We allow case renames (on Unix this is redundant) */
		error(1,0,"%s already exists",argv[1]);

	if(isdir(argv[0]))
		error(1,0,"Directory renames are not currently supported");

	validate_file(argv[0],&root1, &repos_file1, &filename1, &dir1, 1);
	validate_file(argv[1],&root2, &repos_file2, &filename2, &dir2, 0);

	if(strcmp(root1,root2) || strcmp(root1,current_parsed_root->original))
		error(1,0,"%s and %s are in different repositories",argv[0],argv[1]);

	xfree(root1);
	xfree(root2);

	repos_file1 = (char*)xrealloc(repos_file1, strlen(filename1)+strlen(repos_file1)+rootlen+10);
	repos_file2 = (char*)xrealloc(repos_file2, strlen(filename2)+strlen(repos_file2)+rootlen+10);
	memmove(repos_file1+rootlen+1,repos_file1,strlen(repos_file1)+1);
	memmove(repos_file2+rootlen+1,repos_file2,strlen(repos_file2)+1);
	strcpy(repos_file1,current_parsed_root->directory);
	strcpy(repos_file2,current_parsed_root->directory);
	repos_file1[rootlen]='/';
	repos_file2[rootlen]='/';
	strcat(repos_file1,"/");
	strcat(repos_file2,"/");
	strcat(repos_file1,filename1);
	strcat(repos_file2,filename2);

	if(fncmp(argv[0],argv[1]))
		set_mapping(dir2,repos_file2+rootlen+1,""); /* Delete old file */
	if(fncmp(dir1,dir2))
		set_mapping(dir1,repos_file1+rootlen+1,""); 
	set_mapping(dir2,repos_file1+rootlen+1,repos_file2+rootlen+1); /* Rename to new file */

	cwd = xgetwd();
	if(CVS_CHDIR(dir1))
		error(1,errno,"Couldn't chdir to %s",dir1);
	ent = Entries_Open(0, NULL);
	node = findnode_fn(ent, filename1);
	entnode=(Entnode*)node->data;

	if(!node)
	{
		error(1,0,"%s is not listed in CVS/Entries",filename1);
		CVS_CHDIR(cwd);
		xfree(cwd);
		return 1;
	}

	if(!fncmp(dir1,dir2))
		Rename_Entry(ent,filename1,filename2);
	else
	{
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir2))
			error(1,errno,"Couldn't chdir to %s",dir2);
		ent2 = Entries_Open(0, NULL);
		if(entnode->type==ENT_FILE)
			Register(ent2,(char*)filename2,entnode->version,entnode->timestamp,entnode->options,entnode->tag,entnode->date,entnode->conflict,entnode->merge_from_tag_1,entnode->merge_from_tag_2,entnode->rcs_timestamp,entnode->edit_revision,entnode->edit_tag,entnode->edit_bugid,entnode->md5);
		else if(entnode->type==ENT_SUBDIR)
			Subdir_Register(ent2,NULL,filename2);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);

		Entries_Close(ent2);
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir1))
			error(1,errno,"Couldn't chdir to %s",dir1);

		if(entnode->type==ENT_SUBDIR)
			Subdir_Deregister(ent,NULL,filename1);
		else if(entnode->type==ENT_FILE)
			Scratch_Entry(ent,filename1);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);
	}
	Entries_Close(ent);

	CVS_RENAME(argv[0],argv[1]);

	if(isdir(argv[1]))
	{
		char *tmp=(char*)xmalloc(strlen(argv[1])+strlen(CVSADM_VIRTREPOS)+10);
		FILE *fp;
		sprintf(tmp,"%s/%s",argv[1],CVSADM_VIRTREPOS);
		fp = fopen(tmp,"w");
		if(!fp)
			error(0,errno,"Couldn't write %s",tmp);
		fprintf(fp,"%s\n",repos_file2+rootlen+1);
		fclose(fp);
	}

	xfree(repos_file1);
	xfree(repos_file2);
	xfree(dir1);
	xfree(dir2);
	CVS_CHDIR(cwd);
	xfree(cwd);

    return (err);
}
Example #3
0
//Main function.
int main(int argc,char *argv[])
{
    struct in_addr saddr;
    struct in6_addr saddr6;
    int index=2,seconds;
    unsigned short pset_index, pset_mask;
    
	if(argc==1)
        use_info();
    while(index<=argc)
    {
      if(strncmp(argv[index-1],"-help",5)==0 || strncmp(argv[index-1],"-h",2)==0)//help info
      {
          use_info();//display info for use interface
          break;
      }
      else if(strncmp(argv[index-1],"-a",2)==0)//set mapping of source4 source6
      /* [pset] set mapping of source6 source4 mask index time*/
      {
         if(index-1+4>=argc) //pset
         {
            printf("sorry,argument is wrong!\n");
            break;
         }
         seconds=atoi(argv[index+4]);//pset
	// pset_index = atoi(argv[index+2]);//pset_index
	// pset_mask = atoi(argv[index+3]);//pset_mask
		pset_index = (unsigned short)strtoul(argv[index + 2], 0, 0);
		pset_mask = (unsigned short)strtoul(argv[index + 3], 0, 0);
//		printf("0x%04x,0x%04x\n",pset_index,pset_mask);
		inet_pton(AF_INET,argv[index+1],&saddr);//source ipv4 address
		inet_pton(AF_INET6,argv[index],&saddr6);//source ipv6 address
		set_mapping(saddr,saddr6,pset_index,pset_mask,seconds);
         break;
      }
      else if(strncmp(argv[index-1],"-b",2)==0)
      {//pset: need modification
  	 printf("argc = %d\n",argc);
         if(index-1+3>=argc)
         {
            printf("sorry,argument is wrong!\n");
            break;
         }
         inet_pton(AF_INET,argv[index],&saddr);
	 pset_index = (unsigned short)strtoul(argv[index+1], 0, 0);
	 pset_mask = (unsigned short)strtoul(argv[index+2], 0, 0);
         del_mapping(saddr, pset_index, pset_mask);
         break;
      }
      else if(strncmp(argv[index-1],"-c",2)==0)
      {
         if(strncmp(argv[index],"eth0",4)==0 || strncmp(argv[index],"eth1",4)==0
            || strncmp(argv[index],"eth2",4)==0)
             set_tunnel_bind_iface(argv[index]);
         break;
      }
      else if(strncmp(argv[index-1],"-s",2)==0)
      {
         get_tunnel_ipv6();
         break;
      }
      else if(strncmp(argv[index-1],"-m",2)==0)//display tc_mapping_table
      {
         display_tc_mapping_table();
         break;
      }
      else if(strncmp(argv[index-1],"-d",2)==0)//del all mapping
      {
          del_all_mapping();
          break;
      }
      else
         break;
   }
   return 0;		
}
Example #4
0
static int
wiggler_connect (urj_cable_t *cable, urj_cable_parport_devtype_t devtype,
                 const char *devname, const urj_param_t *params[])
{
    const urj_param_t *param_bitmap = NULL;
    const char *bitmap = NULL;
    wiggler_params_t *wiggler_params;

    if (urj_param_num (params) > 0)
    {
        /* acquire optional parameter for bit<->pin mapping */
        param_bitmap = params[0];
        if (params[0]->type != URJ_PARAM_TYPE_STRING)
        {
            urj_error_set (URJ_ERROR_SYNTAX, "mapping name should be a string");
            return URJ_STATUS_FAIL;
        }
        /* urj_tap_cable_generic_parport_connect() shouldn't see this parameter */
        params[0] = NULL;
    }

    if (urj_tap_cable_generic_parport_connect (cable, devtype, devname,
                                               params) != URJ_STATUS_OK)
        return URJ_STATUS_FAIL;

    if (param_bitmap)
        params[0] = param_bitmap;

    wiggler_params = malloc (sizeof *wiggler_params);
    if (!wiggler_params)
    {
        urj_error_set (URJ_ERROR_OUT_OF_MEMORY, _("malloc(%zd) fails"),
                       sizeof *wiggler_params);
        /* NOTE:
         * Call the underlying parport driver (*free) routine directly
         * not generic_parconn_free() since it also free's cable->params
         * (which is not established) and cable (which the caller will do)
         */
        cable->link.port->driver->parport_free (cable->link.port);
        return 4;
    }

    /* set new wiggler-specific params */
    free (cable->params);
    cable->params = wiggler_params;

    if (!param_bitmap)
        bitmap = (char *) std_wgl_map;
    else
        bitmap = param_bitmap->value.string;

    if (set_mapping (bitmap, cable) != 0)
    {
        urj_log (URJ_LOG_LEVEL_ERROR, _("Pin mapping failed\n"));
        /* NOTE:
         * Call the underlying parport driver (*free) routine directly
         * not generic_parconn_free() since it also free's cable (which
         * the caller will do)
         */
        cable->link.port->driver->parport_free (cable->link.port);
        free (cable->params);
        return URJ_STATUS_FAIL;
    }

    /* Certain Macraigor Wigglers appear to use one of the unused data lines as a
       power line so set all unused bits high. */
    PRM_UNUSED_BITS (cable) =
        ~(PRM_SRST_ACT (cable) | PRM_SRST_INACT (cable) | PRM_TMS_ACT (cable)
          | PRM_TMS_INACT (cable) | PRM_TCK_ACT (cable) | PRM_TCK_INACT (cable)
          | PRM_TDI_ACT (cable) | PRM_TDI_INACT (cable) | PRM_TRST_ACT (cable)
          | PRM_TRST_INACT (cable)) & 0xff;

    return 0;
}
Example #5
0
// Now the thumbnail generation is combined with the stats calculations,
// to speed things up a little.  Both require a pass through the entire
// image, so it seems natural, and the stats calculation doesn't add much
// overhead.  (The user is waiting while the thumbnail is being generated,
// so we do want this to be as quick as possible.)
unsigned char *generate_thumbnail_data(ImageInfo *ii, int tsx, int tsy)
{
    int i,j;
    unsigned char *bdata = MALLOC(sizeof(unsigned char)*tsx*tsy*3);
    ImageStats *stats = &(ii->stats);

    // we will estimate the stats from the thumbnail data
    clear_stats(ii);

    // Here we do the rather ugly thing of making the thumbnail
    // loading code specific to each supported data type.  This is
    // because we've combined the stats calculation into this...
    if (ii->data_ci->data_type == GREYSCALE_FLOAT) {
        // store data used to build the small image pixmap
        // we will calculate the stats on this subset
        float *fdata = CALLOC(sizeof(float), tsx*tsy);

        load_thumbnail_data(ii->data_ci, tsx, tsy, fdata);
        set_ignores(ii, !g_startup);

        // split out the case where we have no ignore value --
        // should be quite a bit faster...
        if (have_ignore(stats)) {
            // Compute stats -- ignore "no data" value
            int n=0;
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    float v = fdata[j+i*tsx];
                    if (!is_ignored(stats, v) && fabs(v)<999999999)
                    {
                        stats->avg += v;

                        // first valid pixel --> initialize max/min
                        // subsequent pixels --> update max/min if needed
                        if (n==0) {
                            stats->act_max = stats->act_min = v;
                        } else {
                            if (v > stats->act_max)
                              stats->act_max = v;
                            if (v < stats->act_min)
                              stats->act_min = v;
                        }
                        ++n;
                    }
                }
            }
            stats->avg /= (double)n;
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    float v = fdata[j+i*tsx];
                    if (!is_ignored(stats, v) && fabs(v)<999999999)
                    {
                        stats->stddev +=
                          (v - stats->avg)*(v - stats->avg);
                    }
                }
            }
            stats->stddev = sqrt(stats->stddev / (double)n);
        } else {
            // Compute stats, no ignore (actually, do ignore data that is NaN)
            stats->act_max = stats->act_min = fdata[0];
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    float v = fdata[j+i*tsx];
                    // added in the fabs<999... thing... sometimes values
                    // are just ridiculous and we must ignore them
                    if (meta_is_valid_double(v) && fabs(v)<999999999) {
                        stats->avg += v;
                        if (v > stats->act_max) stats->act_max = v;
                        if (v < stats->act_min) stats->act_min = v;
                    }
                }
            }
            stats->avg /= (double)(tsx*tsy);
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    float v = fdata[j+i*tsx];
                    if (meta_is_valid_double(v) && fabs(v)<999999999)
                        stats->stddev +=
                          (v - stats->avg) * (v - stats->avg);
                }
            }
            stats->stddev = sqrt(stats->stddev / (double)(tsx*tsy));
        }

        //printf("Avg, StdDev: %f, %f\n", stats->avg, stats->stddev);

        set_mapping(ii, !g_startup);

        // Now actually scale the data, and convert to bytes.
        // Note that we need 3 values, one for each of the RGB channels.
        if (have_lut()) {
            // look up table case -- no scaling, just use the lut
            // to convert from float to rgb byte
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    int index = j+i*tsx;
                    int n = 3*index;
                    float val = fdata[index];

                    int ival;
                    if (is_ignored(stats, val) || val<0)
                        ival = ignore_grey_value;
                    else
                        ival = (int)val;

                    apply_lut(ival, &bdata[n], &bdata[n+1], &bdata[n+2]);

                    // histogram will appear as if we were scaling
                    // to greyscale byte
                    unsigned char uval = (unsigned char)
                      calc_scaled_pixel_value(stats, val);
                    stats->hist[uval] += 1;
                }
            }

        } else {
            // normal case -- no lut, apply selected scaling to convert from
            // floating point to byte for display
            for (i=0; i<tsy; ++i) {
                for (j=0; j<tsx; ++j) {
                    int index = j+i*tsx;
                    float val = fdata[index];
                    int n = 3*index;

                    unsigned char uval = (unsigned char)
                      calc_scaled_pixel_value(stats, val);

                    if (is_ignored(stats, val)) {
                      bdata[n] = bdata[n+1] = bdata[n+2] = ignore_grey_value;
                    }
                    else {
                      bdata[n] = uval;
                      bdata[n+1] = uval;
                      bdata[n+2] = uval;

                      stats->hist[uval] += 1;
                    }
                }
            }
        }

        // done with our subset
        free(fdata);
    }
    else if (ii->data_ci->data_type == RGB_BYTE) {

        // store data used to build the small image pixmap
        // we will calculate the stats on this subset
        unsigned char *rgbdata = CALLOC(sizeof(unsigned char), tsx*tsy*3);
        load_thumbnail_data(ii->data_ci, tsx, tsy, (void*)rgbdata);
        set_ignores(ii, !g_startup);

        ImageStatsRGB *stats_r = &ii->stats_r;
        ImageStatsRGB *stats_g = &ii->stats_g;
        ImageStatsRGB *stats_b = &ii->stats_b;

        stats_r->act_min = rgbdata[0];
        stats_r->act_max = rgbdata[0];

        stats_g->act_min = rgbdata[1];
        stats_g->act_max = rgbdata[1];

        stats_b->act_min = rgbdata[2];
        stats_b->act_max = rgbdata[2];

        int nr=0, ng=0, nb=0;
        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, rgbdata[kk])) {
                    stats_r->avg += rgbdata[kk];
                    ++nr;

                    if (rgbdata[kk] < stats_r->act_min)
                      stats_r->act_min = rgbdata[kk];
                    if (rgbdata[kk] > stats_r->act_max)
                      stats_r->act_max = rgbdata[kk];
                }

                if (!is_ignored_rgb(stats_g, rgbdata[kk+1])) {
                    stats_g->avg += rgbdata[kk+1];
                    ++ng;

                    if (rgbdata[kk+1] < stats_g->act_min)
                      stats_g->act_min = rgbdata[kk+1];
                    if (rgbdata[kk+1] > stats_g->act_max)
                      stats_g->act_max = rgbdata[kk+1];
                }

                if (!is_ignored_rgb(stats_b, rgbdata[kk+2])) {
                    stats_b->avg += rgbdata[kk+2];
                    ++nb;

                    if (rgbdata[kk+2] < stats_b->act_min)
                      stats_b->act_min = rgbdata[kk+2];
                    if (rgbdata[kk+2] > stats_b->act_max)
                      stats_b->act_max = rgbdata[kk+2];
                }
            }
        }
        
        if (nr>1) stats_r->avg /= (double)nr;
        if (ng>1) stats_g->avg /= (double)ng;
        if (nb>1) stats_b->avg /= (double)nb;

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, rgbdata[kk])) {
                    float d = rgbdata[kk] - stats_r->avg;
                    stats_r->stddev += d*d;
                }

                if (!is_ignored_rgb(stats_g, rgbdata[kk+1])) {
                    float d = rgbdata[kk+1] - stats_g->avg;
                    stats_g->stddev += d*d;
                }

                if (!is_ignored_rgb(stats_b, rgbdata[kk+2])) {
                    float d = rgbdata[kk+2] - stats_b->avg;
                    stats_b->stddev += d*d;
                }
            }
        }

        stats_r->stddev = sqrt(stats_r->stddev / (double)nr);
        stats_g->stddev = sqrt(stats_g->stddev / (double)ng);
        stats_b->stddev = sqrt(stats_b->stddev / (double)nb);

        set_mapping(ii, !g_startup);

        // clear out the stats for the greyscale image - we'll just use
        // the histogram
        stats->avg = 0;
        stats->stddev = 0;

	// these are used for the axis labels on the histogram, so we put
	// in the averages of the mins... these are sort of bogus anyway, we
	// really should have 3 histograms
        stats->map_min = calc_fake_min(ii);
	stats->map_max = calc_fake_max(ii);

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, rgbdata[kk]) &&
                    !is_ignored_rgb(stats_g, rgbdata[kk+1]) &&
                    !is_ignored_rgb(stats_b, rgbdata[kk+2]))
                {
                  bdata[kk] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_r, rgbdata[kk]);
                  bdata[kk+1] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_g, rgbdata[kk+1]);
                  bdata[kk+2] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_b, rgbdata[kk+2]);
                }
                else {
                  bdata[kk] = ignore_red_value;
                  bdata[kk+1] = ignore_green_value;
                  bdata[kk+2] = ignore_blue_value;
                }
            }
        }

        // Update the histogram -- use greyscale average
        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);
                if (!is_ignored_rgb(stats_r, rgbdata[kk]) &&
                    !is_ignored_rgb(stats_g, rgbdata[kk+1]) &&
                    !is_ignored_rgb(stats_b, rgbdata[kk+2]))
                {   
                  unsigned char uval = (bdata[kk]+bdata[kk+1]+bdata[kk+2])/3;
                  stats->hist[uval] += 1;
                }
            }
        }

        free(rgbdata);
    }
    else if (ii->data_ci->data_type == GREYSCALE_BYTE) {

        // this case is very similar to the RGB case, above, except we
        // have to first grab the data into a greyscale buffer, and
        // then copy it over to the 3-band buffer we're supposed to return
        unsigned char *gsdata = MALLOC(sizeof(unsigned char)*tsx*tsy);
        load_thumbnail_data(ii->data_ci, tsx, tsy, (void*)gsdata);
        set_ignores(ii, !g_startup);

        stats->act_max = 0;
        stats->act_min = 255;
        stats->map_min = 0;
        stats->map_max = 255;

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                unsigned char uval = gsdata[j+i*tsx];

                stats->avg += uval;
                if (uval > stats->act_max) stats->act_max = uval;
                if (uval < stats->act_min) stats->act_min = uval;
            }
        }

        stats->avg /= (double)(tsx*tsy);

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                unsigned char uval = gsdata[j+i*tsx];
                stats->stddev += (uval - stats->avg) * (uval - stats->avg);
            }
        }
        stats->stddev = sqrt(stats->stddev / (double)(tsx*tsy));

        set_mapping(ii, !g_startup);

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                unsigned char uval = gsdata[j+i*tsx];
                int kk = 3*(j+i*tsx);

                if (have_lut()) {
                    apply_lut(uval, &bdata[kk], &bdata[kk+1], &bdata[kk+2]);
                    stats->hist[uval] += 1;
                }
                else if (!is_ignored(stats, uval)) {
                    // apply selected scaling to display values
                    unsigned char display_value = (unsigned char)
                        calc_scaled_pixel_value(stats, uval);
                    bdata[kk] = bdata[kk+1] = bdata[kk+2] = display_value;
                    stats->hist[display_value] += 1;
                }
                else {
                    bdata[kk] = bdata[kk+1] = bdata[kk+2] = ignore_grey_value;
                }
            }
        }

        free(gsdata);
    }
    else if (ii->data_ci->data_type == RGB_FLOAT) {
        // store data used to build the small image pixmap
        // we will calculate the stats on this subset
        float *fdata = MALLOC(sizeof(float)*tsx*tsy*3);
        load_thumbnail_data(ii->data_ci, tsx, tsy, fdata);
        set_ignores(ii, !g_startup);

        ImageStatsRGB *stats_r = &ii->stats_r;
        ImageStatsRGB *stats_g = &ii->stats_g;
        ImageStatsRGB *stats_b = &ii->stats_b;

        stats_r->act_min = fdata[0];
        stats_r->act_max = fdata[0];

        stats_g->act_min = fdata[1];
        stats_g->act_max = fdata[1];

        stats_b->act_min = fdata[2];
        stats_b->act_max = fdata[2];

        int nr=0, ng=0, nb=0;
        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, fdata[kk])) {
                    stats_r->avg += fdata[kk];
                    ++nr;

                    if (fdata[kk] < stats_r->act_min)
                      stats_r->act_min = fdata[kk];
                    if (fdata[kk] > stats_r->act_max)
                      stats_r->act_max = fdata[kk];
                }

                if (!is_ignored_rgb(stats_g, fdata[kk+1])) {
                    stats_g->avg += fdata[kk+1];
                    ++ng;

                    if (fdata[kk+1] < stats_g->act_min)
                      stats_g->act_min = fdata[kk+1];
                    if (fdata[kk+1] > stats_g->act_max)
                      stats_g->act_max = fdata[kk+1];
                }

                if (!is_ignored_rgb(stats_b, fdata[kk+2])) {
                    stats_b->avg += fdata[kk+2];
                    ++nb;

                    if (fdata[kk+2] < stats_b->act_min)
                      stats_b->act_min = fdata[kk+2];
                    if (fdata[kk+2] > stats_b->act_max)
                      stats_b->act_max = fdata[kk+2];
                }
            }
        }
        
        if (nr>1) stats_r->avg /= (double)nr;
        if (ng>1) stats_g->avg /= (double)ng;
        if (nb>1) stats_b->avg /= (double)nb;

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, fdata[kk])) {
                    float d = fdata[kk] - stats_r->avg;
                    stats_r->stddev += d*d;
                }

                if (!is_ignored_rgb(stats_g, fdata[kk+1])) {
                    float d = fdata[kk+1] - stats_g->avg;
                    stats_g->stddev += d*d;
                }

                if (!is_ignored_rgb(stats_b, fdata[kk+2])) {
                    float d = fdata[kk+2] - stats_b->avg;
                    stats_b->stddev += d*d;
                }
            }
        }

        stats_r->stddev = sqrt(stats_r->stddev / (double)nr);
        stats_g->stddev = sqrt(stats_g->stddev / (double)ng);
        stats_b->stddev = sqrt(stats_b->stddev / (double)nb);

        set_mapping(ii, !g_startup);

        // clear out the stats for the greyscale image - we'll just use
        // the histogram
        stats->avg = 0;
        stats->stddev = 0;

	// these are used for the axis labels on the histogram, so we put
	// in the averages of the mins... these are sort of bogus anyway, we
	// really should have 3 histograms
        stats->map_min = calc_fake_min(ii);
	stats->map_max = calc_fake_max(ii);

        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);

                if (!is_ignored_rgb(stats_r, fdata[kk]) &&
                    !is_ignored_rgb(stats_g, fdata[kk+1]) &&
                    !is_ignored_rgb(stats_b, fdata[kk+2]))
                {
                  bdata[kk] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_r, fdata[kk]);
                  bdata[kk+1] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_g, fdata[kk+1]);
                  bdata[kk+2] = (unsigned char)calc_rgb_scaled_pixel_value(
                    stats_b, fdata[kk+2]);
                }
                else {
                  bdata[kk] = ignore_red_value;
                  bdata[kk+1] = ignore_green_value;
                  bdata[kk+2] = ignore_blue_value;
                }
            }
        }

        // Update the histogram -- use greyscale average
        for (i=0; i<tsy; ++i) {
            for (j=0; j<tsx; ++j) {
                int kk = 3*(j+i*tsx);
                if (!is_ignored_rgb(stats_r, fdata[kk]) &&
                    !is_ignored_rgb(stats_g, fdata[kk+1]) &&
                    !is_ignored_rgb(stats_b, fdata[kk+2]))
                {   
                  unsigned char uval = (bdata[kk]+bdata[kk+1]+bdata[kk+2])/3;
                  stats->hist[uval] += 1;
                }
            }
        }

        // done with our subset
        free(fdata);
    }
    else {
	    asfPrintError("Unexpected data type: %d!\n",
                          ii->data_ci->data_type);
    }

    return bdata;
}