int G_read_colors(const char *name, const char *mapset, struct Colors *colors) { int fp; char buf[GNAME_MAX]; char *err; char xname[GNAME_MAX]; struct Range range; struct FPRange drange; CELL min, max; DCELL dmin, dmax; fp = G_raster_map_is_fp(name, mapset); G_init_colors(colors); strcpy(xname, name); mapset = G_find_cell(xname, mapset); name = xname; if (fp) G_mark_colors_as_fp(colors); /* first look for secondary color table in current mapset */ sprintf(buf, "colr2/%s", mapset); if (read_colors(buf, name, G_mapset(), colors) >= 0) return 1; /* now look for the regular color table */ switch (read_colors("colr", name, mapset, colors)) { case -2: if (!fp) { if (G_read_range(name, mapset, &range) >= 0) { G_get_range_min_max(&range, &min, &max); if (!G_is_c_null_value(&min) && !G_is_c_null_value(&max)) G_make_rainbow_colors(colors, min, max); return 0; } } else { if (G_read_fp_range(name, mapset, &drange) >= 0) { G_get_fp_range_min_max(&drange, &dmin, &dmax); if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax)) G_make_rainbow_fp_colors(colors, dmin, dmax); return 0; } } err = "missing"; break; case -1: err = "invalid"; break; default: return 1; } G_warning(_("color support for [%s] in mapset [%s] %s"), name, mapset, err); return -1; }
/*! \brief Get map data type \param filename raster map name \param negflag \return -1 if map is integer and G_read_range() fails \return data type (ARRY_*) */ int Gs_numtype(const char *filename, int *negflag) { CELL max = 0, min = 0; struct Range range; const char *mapset; int shortbits, charbits, bitplace; static int max_short, max_char; static int first = 1; if (first) { max_short = max_char = 1; shortbits = 8 * sizeof(short); for (bitplace = 1; bitplace < shortbits; ++bitplace) { /*1 bit for sign */ max_short *= 2; } max_short -= 1; /* NO bits for sign, using unsigned char */ charbits = 8 * sizeof(unsigned char); for (bitplace = 0; bitplace < charbits; ++bitplace) { max_char *= 2; } max_char -= 1; first = 0; } mapset = G_find_cell2(filename, ""); if (!mapset) { G_warning(_("Raster map <%s> not found"), filename); return -1; } if (G_raster_map_is_fp(filename, mapset)) { G_debug(3, "Gs_numtype(): fp map detected"); return (ATTY_FLOAT); } if (-1 == G_read_range(filename, mapset, &range)) { return (-1); } G_get_range_min_max(&range, &min, &max); *negflag = (min < 0); if (max < max_char && min > 0) { return (ATTY_CHAR); } if (max < max_short && min > -max_short) { return (ATTY_SHORT); } return (ATTY_INT); }
int main(int argc, char *argv[]) { /* Global variable & function declarations */ char Cellmap_orig[50]; FILE *realfp, *imagfp; /* the input and output file descriptors */ int outputfd, maskfd; /* the input and output file descriptors */ char *realmapset, *imagmapset; /* the input mapset names */ struct Cell_head orig_wind, realhead; CELL *cell_row, *maskbuf = NULL; int i, j; /* Loop control variables */ int or, oc; /* Original dimensions of image */ int rows, cols; /* Smallest powers of 2 >= number of rows & columns */ long totsize; /* Total number of data points */ int halfrows, halfcols; double *data[2]; /* Data structure containing real & complex values of FFT */ struct Option *op1, *op2, *op3; struct GModule *module; G_gisinit(argv[0]); /* Set description */ module = G_define_module(); module->keywords = _("imagery, FFT"); module->description = _("Inverse Fast Fourier Transform (IFFT) for image processing."); /* define options */ op1 = G_define_standard_option(G_OPT_R_INPUT); op1->key = "real_image"; op1->description = _("Name of input raster map (image fft, real part)"); op2 = G_define_standard_option(G_OPT_R_INPUT); op2->key = "imaginary_image"; op2->description = _("Name of input raster map (image fft, imaginary part"); op3 = G_define_standard_option(G_OPT_R_OUTPUT); op3->key = "output_image"; op3->description = _("Name for output raster map"); /*call parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); strcpy(Cellmap_real, op1->answer); strcpy(Cellmap_imag, op2->answer); strcpy(Cellmap_orig, op3->answer); /* open input raster map */ if ((realmapset = G_find_cell(Cellmap_real, "")) == NULL) G_fatal_error(_("Raster map <%s> not found"), Cellmap_real); if ((realfp = G_fopen_old_misc("cell_misc", "fftreal", Cellmap_real, realmapset)) == NULL) G_fatal_error(_("Unable to open real-image in the 'cell_misc' directory. " "Raster map probably wasn't created by i.fft")); if ((imagmapset = G_find_cell(Cellmap_imag, "")) == NULL) G_fatal_error(_("Raster map <%s> not found"), Cellmap_imag); if ((imagfp = G_fopen_old_misc("cell_misc", "fftimag", Cellmap_imag, imagmapset)) == NULL) G_fatal_error(_("Unable to open imaginary-image in the 'cell_misc' directory. " "Raster map probably wasn't created by i.fft")); /* check command line args for validity */ if (G_legal_filename(Cellmap_orig) < 0) G_fatal_error(_("<%s> is an illegal file name"), Cellmap_orig); /* get and compare the original window data */ get_orig_window(&orig_wind, realmapset, imagmapset); or = orig_wind.rows; oc = orig_wind.cols; G_get_cellhd(Cellmap_real, realmapset, &realhead); G_set_window(&realhead); /* set the window to the whole cell map */ /* get the rows and columns in the current window */ rows = G_window_rows(); cols = G_window_cols(); totsize = rows * cols; halfrows = rows / 2; halfcols = cols / 2; G_verbose_message(_("Power 2 values: %d rows %d columns"), rows, cols); /* Allocate appropriate memory for the structure containing the real and complex components of the FFT. DATA[0] will contain the real, and DATA[1] the complex component. */ data[0] = (double *)G_malloc((rows * cols) * sizeof(double)); data[1] = (double *)G_malloc((rows * cols) * sizeof(double)); /* Initialize real & complex components to zero */ G_message(_("Reading raster maps...")); { fread((char *)data[0], sizeof(double), totsize, realfp); fread((char *)data[1], sizeof(double), totsize, imagfp); } /* Read in cell map values */ G_message(_("Masking raster maps...")); maskfd = G_maskfd(); if (maskfd >= 0) maskbuf = G_allocate_cell_buf(); if (maskfd >= 0) { for (i = 0; i < rows; i++) { double *data0, *data1; data0 = data[0] + i * cols; data1 = data[1] + i * cols; G_get_map_row(maskfd, maskbuf, i); for (j = 0; j < cols; j++, data0++, data1++) { if (maskbuf[j] == (CELL) 0) { *(data0) = 0.0; *(data1) = 0.0; } } } } G_message(_("Rotating data...")); /* rotate the data array for standard display */ for (i = 0; i < rows; i++) { double temp; for (j = 0; j < halfcols; j++) { temp = *(data[0] + i * cols + j); *(data[0] + i * cols + j) = *(data[0] + i * cols + j + halfcols); *(data[0] + i * cols + j + halfcols) = temp; temp = *(data[1] + i * cols + j); *(data[1] + i * cols + j) = *(data[1] + i * cols + j + halfcols); *(data[1] + i * cols + j + halfcols) = temp; } } for (i = 0; i < halfrows; i++) { double temp; for (j = 0; j < cols; j++) { temp = *(data[0] + i * cols + j); *(data[0] + i * cols + j) = *(data[0] + (i + halfrows) * cols + j); *(data[0] + (i + halfrows) * cols + j) = temp; temp = *(data[1] + i * cols + j); *(data[1] + i * cols + j) = *(data[1] + (i + halfrows) * cols + j); *(data[1] + (i + halfrows) * cols + j) = temp; } } /* close input cell maps and release the row buffers */ fclose(realfp); fclose(imagfp); if (maskfd >= 0) { G_close_cell(maskfd); G_free(maskbuf); } /* perform inverse FFT */ G_message(_("Starting Inverse FFT...")); fft(1, data, totsize, cols, rows); /* set up a window for the transform cell map */ G_set_window(&orig_wind); /* open the output cell map and allocate a cell row buffer */ if ((outputfd = G_open_cell_new(Cellmap_orig)) < 0) G_fatal_error(_("Unable to create raster map <%s>"), Cellmap_orig); cell_row = G_allocate_cell_buf(); /* Write out result to a new cell map */ G_message(_("Writing data...")); for (i = 0; i < or; i++) { for (j = 0; j < oc; j++) { *(cell_row + j) = (CELL) (*(data[0] + i * cols + j) + 0.5); } G_put_raster_row(outputfd, cell_row, CELL_TYPE); G_percent(i+1, or, 2); } G_close_cell(outputfd); G_free(cell_row); { struct Colors colors; struct Range range; CELL min, max; /* make a real component color table */ G_read_range(Cellmap_orig, G_mapset(), &range); G_get_range_min_max(&range, &min, &max); G_make_grey_scale_colors(&colors, min, max); G_write_colors(Cellmap_orig, G_mapset(), &colors); } /* Release memory resources */ G_free(data[0]); G_free(data[1]); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Cell_head cellhd; struct Range range; char *name; /* input raster name */ char *result; /* output raster name */ char *mapset; /* mapset name */ DCELL *inrast; /* input buffer */ DCELL *outrast; /* output buffer */ int row,col; int infd, outfd; /* file descriptor */ int verbose; double *weights; /* array of weights */ DCELL **D_rows; DCELL *tmp; int nrows; int ncols; double min, max; /* raster map range */ RASTER_MAP_TYPE data_type; /* type of the map */ void *values; /* neighborhood values */ int n,i; /* number of neighborhood cells */ int size; /* matrix size */ double ssigma; /* sigma of the spatial part */ double csigma; /* sigma of the color part */ char title[1024]; /* map title */ struct GModule *module; /* GRASS module for parsing arguments */ struct { struct Option *input, *output; struct Option *sigma_s, *sigma_c, *size; struct Option *title; } parm; struct { struct Flag *quiet; struct Flag *print_sigmas; } flag; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name */ /* initialize module */ module = G_define_module(); module->description = ("Gaussian filter for raster maps."); /* Define the different options */ parm.input = G_define_option() ; parm.input->key = "input"; parm.input->type = TYPE_STRING; parm.input->required = YES; parm.input->description= ("Name of an input layer" ); parm.output = G_define_option() ; parm.output->key = "output"; parm.output->type = TYPE_STRING; parm.output->required = YES; parm.output->description= ("Name of an output layer"); parm.sigma_s = G_define_option() ; parm.sigma_s->key = "ssigma"; parm.sigma_s->type = TYPE_DOUBLE; parm.sigma_s->required = NO; parm.sigma_s->description= ("Sigma for space part of the filter\n\t(default: 0.465*((size-1)/2)"); parm.sigma_c = G_define_option() ; parm.sigma_c->key = "csigma"; parm.sigma_c->type = TYPE_DOUBLE; parm.sigma_c->required = NO; parm.sigma_c->description= ("Sigma for color part of the filter\n(default: 0.465*((color_range)/2)"); parm.size = G_define_option() ; parm.size->key = "size"; parm.size->type = TYPE_INTEGER; parm.size->required = YES; parm.size->description= ("Size of the matrix (odd number)"); flag.print_sigmas = G_define_flag() ; flag.print_sigmas->key = 's' ; flag.print_sigmas->description = "Print calculated values for sigmas" ; flag.quiet = G_define_flag() ; flag.quiet->key = 'q' ; flag.quiet->description = "Quiet" ; /* options and flags pareser */ if (G_parser(argc, argv)) exit (-1); /* stores options and flags to variables */ name = parm.input->answer; result = parm.output->answer; verbose = (! flag.quiet->answer); sscanf(parm.size->answer, "%d", &size); if (!parm.sigma_s->answer) ssigma = 0.465*((size-1)/2); else sscanf(parm.sigma_s->answer, "%lf", &ssigma); /* controlling the input values */ if (size%2 == 0) G_fatal_error("Size <%d> is not odd number", size); /* returs NULL if the map was not found in any mapset, * mapset name otherwise*/ mapset = G_find_cell2 (name, ""); if (mapset == NULL) G_fatal_error ("cell file [%s] not found", name); /* color sigma next */ if (!parm.sigma_c->answer) { if (G_read_range(name, mapset, &range) < 0) G_fatal_error("Could not read the raster map range"); /* for raster maps with range from 0-255 the result * should be around 60 */ min = (double)range.min; max = (double)range.max; csigma = 0.456*(max - min)/2; } else sscanf(parm.sigma_c->answer, "%lf", &csigma); /* print if appropriate */ if (flag.print_sigmas->answer) printf("Space sigma: %f\nColor sigma: %f\n", ssigma, csigma); if (G_legal_filename (result) < 0) G_fatal_error ("[%s] is an illegal name", result); /* count weights */ weights = (double *)malloc(size * size * sizeof(double)); /* stores values of gauss. bell into 'weigts'*/ count_weights(weights, size, ssigma); /* determine the inputmap type (CELL/FCELL/DCELL) */ data_type = G_raster_map_type(name, mapset); /* G_open_cell_old - returns file destriptor (>0) */ if ( (infd = G_open_cell_old (name, mapset)) < 0) G_fatal_error ("Cannot open cell file [%s]", name); /* controlling, if we can open input raster */ if (G_get_cellhd (name, mapset, &cellhd) < 0) G_fatal_error ("Cannot read file header of [%s]", name); /* Allocate input buffer */ inrast = G_allocate_raster_buf(data_type); /* Allocate output buffer, use input map data_type */ nrows = G_window_rows(); ncols = G_window_cols(); outrast = G_allocate_d_raster_buf(); /* Allocate values buffers */ values = (DCELL *) malloc(size * size * sizeof(DCELL)); /* allocating memory for rows */ D_rows = (DCELL **)malloc(size * sizeof(DCELL)); for (i = 0; i < size; i++) { D_rows[i] = G_allocate_raster_buf(DCELL_TYPE); } if (values == NULL) G_fatal_error("Cannot allocate memory"); /* controlling, if we can write the raster */ if ( (outfd = G_open_raster_new (result, data_type)) < 0) G_fatal_error ("Could not open <%s>",result); /* write first rows as NULL values */ for (row = 0; row < size/2; row++) { G_set_d_null_value(outrast, ncols); if (G_put_d_raster_row (outfd, outrast) < 0) G_fatal_error ("Cannot write to <%s>",result); } /* allocate first size/2 rows */ for (row = 0; row < size; row++) if (G_get_d_raster_row(infd, D_rows[row], row) < 0) G_fatal_error ("Could not open <%s>",result); /****************************************************************/ /* for each row inside the region */ for ( row = size/2; row < nrows - size/2; row++) { if (verbose) G_percent (row, nrows, 2); /* allocate new last row */ G_get_d_raster_row(infd, D_rows[size-1], row+(size/2)); /*process the data */ for (col=0; col < ncols; col++){ /* skip the outside columns */ if ( (col - size/2) < 0 || ncols <= (col + size/2)) { G_set_d_null_value(outrast, 1); } /* work only with columns, which are inside */ else { /* store values of the matrix into arry 'values', 'n' is * number of elements of the matrix */ n = D_gather(infd, values, D_rows, col, row,size); ((DCELL *)outrast)[col] = D_bilateral(values, ssigma, csigma, size, weights); } } /* for each column */ /* write raster row to output raster file */ G_put_d_raster_row (outfd, outrast); /* switch rows */ tmp = D_rows[0]; for (i = 0; i < size; i++){ D_rows[i] = D_rows[i + 1]; } D_rows[size-1] = tmp; } /* for each row */ /* write last rows as NULL values */ for (i = 0; i < size/2; i++) { G_set_d_null_value(outrast, ncols); G_put_d_raster_row (outfd, outrast); } /* memory cleaning */ G_free(outrast); G_free(inrast); G_free(values); for (i = 0; i < size; i++) { G_free(D_rows[i]); } free((void *) D_rows); /* closing rastr files */ G_close_cell (infd); G_close_cell (outfd); /* set the map title */ sprintf(title, "Bilateral filter of %s with %dx%d matrix: ssigma %.3f, csigma %.3f", name, size, size, ssigma, csigma ); G_put_cell_title (result, title ); return 0; }