コード例 #1
0
/*
 * Set the volume level for the left and right channels.  Their values
 * range from 0 to 100.
 */
int
gen_set_volume(struct wm_drive *d, int left, int right)
{
  struct ioc_vol vol;
  
  if (left < 0)	/* don't laugh, I saw this happen once! */
    left = 0;
  if (right < 0)
    right = 0;
  left = scale_volume(left, 100);
  right = scale_volume(right, 100);
  
  bzero((char *)&vol, sizeof(vol));
  
  vol.vol[LEFT_PORT] = left;
  vol.vol[RIGHT_PORT] = right;
  
  if (ioctl(d->fd, CDIOCSETVOL, &vol))
    return (-1);
  
  return (0);
} /* gen_set_volume() */
コード例 #2
0
/*
 * unscale_volume(cd_vol, max)
 *
 * Given a value between min_volume and max_volume, return the volume slider
 * value needed to achieve that value.
 *
 * Rather than perform floating-point calculations to reverse the above
 * formula, we simply do a binary search of scale_volume()'s return values.
 */
static int
unscale_volume(int cd_vol, int max)
{
	int	vol = 0, top = max, bot = 0, scaled;

	while (bot <= top)
	{
		vol = (top + bot) / 2;
		scaled = scale_volume(vol, max);
		if (cd_vol == scaled)
			break;
		if (cd_vol < scaled)
			top = vol - 1;
		else
			bot = vol + 1;
	}
	
	if (vol < 0)
		vol = 0;
	else if (vol > max)
		vol = max;

	return (vol);
} /* unscale_volume() */
コード例 #3
0
ファイル: volregrid.c プロジェクト: andrewjanke/volregrid
int main(int argc, char *argv[])
{
   char   **infiles;
   int      n_infiles;
   char    *out_fn;
   char    *history;
   VIO_progress_struct progress;
   VIO_Volume   totals, weights;
   int      i, j, k, v;
   double   min, max;
   double   w_min, w_max;
   long     num_missed;
   double   weight, value;
   double   initial_weight;

   VIO_Real     dummy[3];

   int      sizes[MAX_VAR_DIMS];
   double   starts[MAX_VAR_DIMS];
   double   steps[MAX_VAR_DIMS];
   
   long     t = 0;

   /* start the time counter */
   current_realtime_seconds();
   
   /* get the history string */
   history = time_stamp(argc, argv);

   /* get args */
   if(ParseArgv(&argc, argv, argTable, 0) || (argc < 3)){
      fprintf(stderr,
              "\nUsage: %s [options] <in1.mnc> [<in2.mnc> [...]] <out.mnc>\n", argv[0]);
      fprintf(stderr,
              "       %s [options] -arb_path pth.conf <infile.raw> <out.mnc>\n", argv[0]);
      fprintf(stderr, "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
      }

   /* get file names */
   n_infiles = argc - 2;
   infiles = (char **)malloc(sizeof(char *) * n_infiles);
   for(i = 0; i < n_infiles; i++){
      infiles[i] = argv[i + 1];
      }
   out_fn = argv[argc - 1];

   /* check for infiles and outfile */
   for(i = 0; i < n_infiles; i++){
      if(!file_exists(infiles[i])){
         fprintf(stderr, "%s: Couldn't find input file %s.\n\n", argv[0], infiles[i]);
         exit(EXIT_FAILURE);
         }
      }
   if(!clobber && file_exists(out_fn)){
      fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0], out_fn);
      exit(EXIT_FAILURE);
      }

   /* check for weights_fn if required */
   if(weights_fn != NULL){
      if(!clobber && file_exists(weights_fn)){
         fprintf(stderr, "%s: %s exists, -clobber to overwrite.\n\n", argv[0],
                 weights_fn);
         exit(EXIT_FAILURE);
         }
      }

   /* set up parameters for reconstruction */
   if(out_dtype == NC_UNSPECIFIED){
      out_dtype = in_dtype;
      }
   if(out_is_signed == DEF_BOOL){
      out_is_signed = in_is_signed;
      }

   /* check vector dimension size */
   if(vect_size < 1){
      fprintf(stderr, "%s: -vector (%d) must be 1 or greater.\n\n", argv[0], vect_size);
      exit(EXIT_FAILURE);
      }

   /* check sigma */
   if(regrid_sigma[0] <= 0 || regrid_sigma[1] <= 0 || regrid_sigma[2] <= 0 ){
      fprintf(stderr, "%s: -sigma must be greater than 0\n\n", argv[0]);
      exit(EXIT_FAILURE);
      }

   /* read in the output file config from a file is specified */
   if(out_config_fn != NULL){
      int      ext_args_c;
      char    *ext_args[32];           /* max possible is 32 arguments */

      ext_args_c = read_config_file(out_config_fn, ext_args);
      if(ParseArgv(&ext_args_c, ext_args, argTable,
                   ARGV_DONT_SKIP_FIRST_ARG | ARGV_NO_LEFTOVERS | ARGV_NO_DEFAULTS)){
         fprintf(stderr, "\nError in parameters in %s\n", out_config_fn);
         exit(EXIT_FAILURE);
         }
      }

   if(verbose){
      fprintf_vol_def(stdout, &out_inf);
      }

   /* transpose the geometry arrays */
   /* out_inf.*[] are in world xyz order, perm[] is the permutation
      array to map world xyz to the right voxel order in the volume */
   for(i = 0; i < WORLD_NDIMS; i++){
      sizes[i] = out_inf.nelem[perm[i]];  /* sizes, starts, steps are in voxel volume order. */
      starts[i] = out_inf.start[perm[i]];
      steps[i] = out_inf.step[perm[i]];
      }
   sizes[WORLD_NDIMS] = vect_size;

   /* create the totals volume */
   totals = create_volume((vect_size > 1) ? 4 : 3,
                          (vect_size > 1) ? std_dimorder_v : std_dimorder,
                          out_dtype, out_is_signed, 0.0, 0.0);
   set_volume_sizes(totals, sizes);
   set_volume_starts(totals, starts);
   set_volume_separations(totals, steps);
   for(i = 0; i < WORLD_NDIMS; i++){
      /* out_inf.dircos is in world x,y,z order, we have to use the perm array to 
         map each direction to the right voxel axis. */
      set_volume_direction_cosine(totals, i, out_inf.dircos[perm[i]]);
      }
   alloc_volume_data(totals);

   /* create the "weights" volume */
   weights = create_volume(3, std_dimorder, out_dtype, out_is_signed, 0.0, 0.0);
   set_volume_sizes(weights, sizes);
   set_volume_starts(weights, starts);
   set_volume_separations(weights, steps);
   for(i = 0; i < WORLD_NDIMS; i++){
      set_volume_direction_cosine(weights, i, out_inf.dircos[perm[i]]);
      }
   alloc_volume_data(weights);

   /* down below in regrid_loop, Andrew makes a nasty direct reference to the
      voxel_to_world transformation in the volume.  This
      transformation is not necessarily up to date, particularly when
      non-default direction cosines are used.  In volume_io, the
      direction cosines are set and a FLAG is also set to indicate
      that the voxel-to-world xform is not up to date.  If the stanrd
      volume_io general transform code is used, it checks internally
      to see if the matrix is up to date, and if not it is recomputed.

      So here, we'll (LC + MK) force an update by calling a general
      transform.  */

//   convert_world_to_voxel(weights, (Real) 0, (Real) 0, (Real) 0, dummy);
//   convert_world_to_voxel(totals, (Real) 0, (Real) 0, (Real) 0, dummy);

   fprintf(stderr, "2Sizes: [%d:%d:%d] \n", sizes[perm[0]], sizes[perm[1]], sizes[perm[2]]);
   
   /* initialize weights to be arbitray large value if using NEAREST */
   /* volume interpolation else initialize all to zero */
   if(regrid_type == NEAREST_FUNC && ap_coord_fn == NULL){
      initial_weight = LARGE_INITIAL_WEIGHT;
      }
   else{
      initial_weight = 0.0;
      }
   
   /* initialize weights and totals */   
   for(k = sizes[Z_IDX]; k--;){
      for(j = sizes[Y_IDX]; j--;){
         for(i = sizes[X_IDX]; i--;){
            set_volume_real_value(weights, k, j, i, 0, 0, initial_weight);
            for(v = vect_size; v--;){
               set_volume_real_value(totals, k, j, i, v, 0, 0.0);
               }
            }
         }
      }

   /* if regridding via an arbitrary path */
   if(ap_coord_fn != NULL){

      if(n_infiles > 1){
         fprintf(stderr, "%s: arb_path only works for one input file (so far).\n\n",
                 argv[0]);
         exit(EXIT_FAILURE);
         }

      /* print some pretty output */
      if(verbose){
         fprintf(stdout, " | Input data:      %s\n", infiles[0]);
         fprintf(stdout, " | Arb path:        %s\n", ap_coord_fn);
         fprintf(stdout, " | Output range:    [%g:%g]\n", out_range[0], out_range[1]);
         fprintf(stdout, " | Output file:     %s\n", out_fn);
         }

      regrid_arb_path(ap_coord_fn, infiles[0], max_buffer_size_in_kb,
                      &totals, &weights, vect_size, regrid_range[0], regrid_range[1]);
      }

   /* else if regridding via a series of input minc file(s) */
   else {
      for(i = 0; i < n_infiles; i++){
         if(verbose){
            fprintf(stdout, " | Input file:      %s\n", infiles[i]);
            }
         regrid_minc(infiles[i], max_buffer_size_in_kb,
                     &totals, &weights, vect_size, regrid_range[0], regrid_range[1]);
         }
      }

   /* initialise min and max counters and divide totals/weights */
   num_missed = 0;
   min = get_volume_real_value(totals, 0, 0, 0, 0, 0);
   max = get_volume_real_value(totals, 0, 0, 0, 0, 0);
   w_min = get_volume_real_value(weights, 0, 0, 0, 0, 0);
   w_max = get_volume_real_value(weights, 0, 0, 0, 0, 0);
   initialize_progress_report(&progress, FALSE, out_inf.nelem[Z_IDX], "Dividing through");
   
   for(i = sizes[perm[0]]; i--;){
      for(j = sizes[perm[1]]; j--;){
         for(k = sizes[perm[2]]; k--;){
            weight = get_volume_real_value(weights, k, j, i, 0, 0);
            if(weight < w_min){
               w_min = weight;
               }
            else if(weight > w_max){
               w_max = weight;
               }
            
            if(weight != 0){
               for(v = vect_size; v--;){
                  value = get_volume_real_value(totals, k, j, i, v, 0) / weight;
                  if(value < min){
                     min = value;
                     }
                  else if(value > max){
                     max = value;
                     }
                  
                  set_volume_real_value(totals, k, j, i, v, 0, value);
                  }
               }
            else {
               num_missed++;
               }
            }
         }
      update_progress_report(&progress, k + 1);
      }
   terminate_progress_report(&progress);

   /* set the volumes range */
   if(verbose){
      fprintf(stdout, " + data range:   [%g:%g]\n", min, max);
      fprintf(stdout, " + weight range: [%g:%g]\n", w_min, w_max);
      }
   set_volume_real_range(totals, min, max);
   set_volume_real_range(weights, w_min, w_max);

   if(num_missed > 0 && verbose){
      int      nvox;

      nvox = out_inf.nelem[X_IDX] * out_inf.nelem[Y_IDX] * out_inf.nelem[Z_IDX];
      fprintf(stdout,
              "\n-regrid_radius possibly too small, no data in %ld/%d[%2.2f%%] voxels\n\n",
              num_missed, nvox, ((float)num_missed / nvox * 100));
      }

   /* rescale data if required */
   if(out_range[0] != -DBL_MAX && out_range[1] != DBL_MAX){
      double   o_min, o_max;

      /* get the existing range */
      get_volume_real_range(totals, &o_min, &o_max);

      /* rescale it */
      scale_volume(&totals, o_min, o_max, out_range[0], out_range[1]);
      }

   /* output the result */
   if(verbose){
      fprintf(stdout, " | Outputting %s...\n", out_fn);
      }
   if(output_volume(out_fn, out_dtype, out_is_signed,
                    0.0, 0.0, totals, history, NULL) != VIO_OK){
      fprintf(stderr, "Problems outputing: %s\n\n", out_fn);
      }

   /* output weights volume if required */
   if(weights_fn != NULL){
      if(verbose){
         fprintf(stdout, " | Outputting %s...\n", weights_fn);
         }
      if(output_volume(weights_fn, out_dtype, out_is_signed,
                       0.0, 0.0, weights, history, NULL) != VIO_OK){
         fprintf(stderr, "Problems outputting: %s\n\n", weights_fn);
         }
      }

   delete_volume(totals);
   delete_volume(weights);
   
   t = current_realtime_seconds();
   printf("Total reconstruction time: %ld hours %ld minutes %ld seconds\n", t/3600, (t/60)%60, t%60);
   
   return (EXIT_SUCCESS);
   }