[GRASS-SVN] r57251 - sandbox/turek/scatter_plot/lib/imagery
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Jul 22 14:15:47 PDT 2013
Author: turek
Date: 2013-07-22 14:15:47 -0700 (Mon, 22 Jul 2013)
New Revision: 57251
Added:
sandbox/turek/scatter_plot/lib/imagery/scatt.c
sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c
Removed:
sandbox/turek/scatter_plot/lib/imagery/scatt_plot.c
Log:
backend support for mapwindow
Copied: sandbox/turek/scatter_plot/lib/imagery/scatt.c (from rev 57180, sandbox/turek/scatter_plot/lib/imagery/scatt_plot.c)
===================================================================
--- sandbox/turek/scatter_plot/lib/imagery/scatt.c (rev 0)
+++ sandbox/turek/scatter_plot/lib/imagery/scatt.c 2013-07-22 21:15:47 UTC (rev 57251)
@@ -0,0 +1,588 @@
+/*!
+ \file lib/imagery/scatt.c
+
+ \brief Imagery library - functions for wx Scatter Plot Tool.
+
+ Low level functions used by wx Scatter Plot Tool.
+
+ Copyright (C) 2013 by the GRASS Development Team
+
+ This program is free software under the GNU General Public License
+ (>=v2). Read the file COPYING that comes with GRASS for details.
+
+ \author Stepan Turek <stepan.turek at seznam.cz> (Mentor: Martin Landa)
+ */
+
+#include <grass/raster.h>
+#include <grass/imagery.h>
+#include <grass/gis.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+
+static const int CAT_RAST_SCATT_SEL = 2;
+static const int CAT_RAST_RAST_SEL = 1;
+static const int CAT_RAST_NULL = 0;
+
+static int get_cat_rast_header(struct Cell_head * region, char * header){
+ return sprintf(header, "P5\n%d\n%d\n1\n", region->cols, region->rows);
+}
+
+int I_create_cat_rast(struct Cell_head * cat_rast_region, const char * cat_rast)
+{
+ FILE * f_cat_rast;
+ char cat_rast_header[1024];//TODO magic number
+ int i_row, i_col;
+ int head_nchars;
+
+ unsigned char * row_data;
+
+ f_cat_rast = fopen(cat_rast, "wb");
+ if(!f_cat_rast)
+ return -1;
+
+ head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
+
+ fwrite(cat_rast_header, sizeof(char), head_nchars/sizeof(char), f_cat_rast);
+ if (ferror(f_cat_rast)){
+ fclose(f_cat_rast);
+ return -1;
+ }
+
+ row_data = (unsigned char *) G_malloc(cat_rast_region->cols * sizeof(unsigned char));
+ for(i_col = 0; i_col < cat_rast_region->cols; i_col++)
+ row_data[i_col] = 0 & 255;
+
+ for(i_row = 0; i_row < cat_rast_region->rows; i_row++) {
+ fwrite(row_data, sizeof(unsigned char), (cat_rast_region->cols)/sizeof(unsigned char), f_cat_rast);
+ // TODO when code will be paralelized put it out of the loop
+ if (ferror(f_cat_rast))
+ {
+ fclose(f_cat_rast);
+ G_debug(3, "Unable to write into file.");
+ return -1;
+ }
+ }
+
+ fclose(f_cat_rast);
+ return 0;
+}
+
+static int print_reg(struct Cell_head * intersec, const char * pref)
+{
+ G_message("%s:\n n:%f\ns:%f\ne:%f\nw:%f\nns_res:%f\new_res:%f", pref, intersec->north, intersec->south,
+ intersec->east, intersec->west, intersec->ns_res, intersec->ew_res);
+}
+
+static int regions_intersecion(struct Cell_head * A, struct Cell_head * B, struct Cell_head * intersec)
+{
+
+ if(B->north < A->south) return -1;
+ else if(B->north > A->north) intersec->north = A->north;
+ else intersec->north = B->north;
+
+ if(B->south > A->north) return -1;
+ else if(B->south < A->south) intersec->south = A->south;
+ else intersec->south = B->south;
+
+ if(B->east < A->west) return -1;
+ else if(B->east > A->east) intersec->east = A->east;
+ else intersec->east = B->east;
+
+ if(B->west > A->east) return -1;
+ else if(B->west < A->west) intersec->west = A->west;
+ else intersec->west = B->west;
+
+ if(intersec->north == intersec->south) return -1;
+
+ if(intersec->east == intersec->west) return -1;
+
+ return 0;
+
+}
+
+static int get_rows_and_cols_bounds(struct Cell_head * A, struct Cell_head * B, struct Cell_head * A_bounds, struct Cell_head * B_bounds)
+{
+ float ns_res, ew_res;
+
+ struct Cell_head intersec;
+
+ if(A->ns_res != B->ns_res)
+ return -1;
+
+ if(A->ew_res != B->ew_res)
+ return -1;
+
+ ns_res = A->ns_res;
+ ew_res = A->ew_res;
+
+ if(regions_intersecion(A, B, &intersec) == -1)
+ return -1;
+
+ A_bounds->north = ceil((A->north - intersec.north - ns_res * 0.5) / ns_res);
+ A_bounds->south = ceil((A->north - intersec.south - ns_res * 0.5) / ns_res);
+
+ A_bounds->east = ceil((intersec.east - A->west - ew_res * 0.5) / ew_res);
+ A_bounds->west = ceil((intersec.west - A->west - ew_res * 0.5) / ew_res);
+
+ B_bounds->north = ceil((B->north - intersec.north - ns_res * 0.5) / ns_res);
+ B_bounds->south = ceil((B->north - intersec.south - ns_res * 0.5) / ns_res);
+
+ B_bounds->east = ceil((intersec.east - B->west - ew_res * 0.5) / ew_res);
+ B_bounds->west = ceil((intersec.west - B->west - ew_res * 0.5) / ew_res);
+
+ print_reg(A, "A");
+ print_reg(B, "B");
+
+ print_reg(&intersec, "intersec");
+
+ print_reg(A_bounds, "A_bounds");
+
+ print_reg(B_bounds, "B_bounds");
+
+ return 0;
+}
+
+
+int I_insert_patch_to_cat_rast(const char * patch_rast, struct Cell_head * cat_rast_region, const char * cat_rast)
+{
+
+ FILE * f_cat_rast;
+ struct Cell_head patch_region, patch_bounds, cat_rast_bounds;
+ char cat_rast_header[1024];//TODO magic number
+ int i_row, i_col, ncols, nrows, cat_rast_col, patch_col, val;
+ int head_nchars;
+ int fd_patch_rast, init_shift, step_shift;
+ unsigned char * patch_data;
+
+ char * null_chunk;
+
+ //TODO free mapset (aslo in compute scatts)
+ const char *mapset;
+
+ struct Cell_head patch_lines, cat_rast_lines;
+
+ unsigned char * row_data;
+
+ f_cat_rast = fopen(cat_rast, "rb+");
+ if(!f_cat_rast)
+ return -10;
+
+
+ /* TODO */
+ head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
+
+ if ((mapset = G_find_raster2(patch_rast,"")) == NULL) {
+ fclose(f_cat_rast);
+ return -2;
+ }
+
+ Rast_get_cellhd(patch_rast, mapset, &patch_region);
+ Rast_set_window(&patch_region);
+
+ if ((fd_patch_rast = Rast_open_old(patch_rast, mapset)) < 0) {
+ fclose(f_cat_rast);
+ return -3;
+ }
+
+ null_chunk = Rast_allocate_null_buf();
+
+ print_reg(&cat_rast_bounds, "cat_rast_bounds");
+ print_reg(&patch_bounds, "patch_bounds");
+
+ if(get_rows_and_cols_bounds(cat_rast_region, &patch_region, &cat_rast_bounds, &patch_bounds) == -1) return -1;
+
+ ncols = cat_rast_bounds.east - cat_rast_bounds.west;
+ nrows = cat_rast_bounds.south - cat_rast_bounds.north;
+
+ patch_data = (unsigned char *) malloc(ncols * sizeof(unsigned char));
+
+ init_shift = head_nchars + cat_rast_region->cols * cat_rast_bounds.north + cat_rast_bounds.west;
+
+ if(fseek(f_cat_rast, init_shift, SEEK_SET) != 0) {
+ G_message("seek failed");
+ return -4;
+ }
+
+ step_shift = cat_rast_region->cols - ncols;
+
+
+ G_message("init_shift %d", init_shift);
+ G_message("step_shift %d", step_shift);
+ G_message("ncols %d", ncols);
+ G_message("nrows %d", nrows);
+
+ for(i_row = 0; i_row < nrows; i_row++) {
+ Rast_get_null_value_row (fd_patch_rast, null_chunk, i_row + patch_bounds.north);
+
+ for(i_col = 0; i_col < ncols; i_col++) {
+ patch_col = patch_bounds.west + i_col;
+
+ if(null_chunk[patch_col] != 1)
+ patch_data[i_col] = 1 & 255;
+ else {
+ patch_data[i_col] = 0 & 255;
+ }
+ }
+
+ fwrite(patch_data, sizeof(unsigned char), (ncols)/sizeof(unsigned char), f_cat_rast);
+ if (ferror(f_cat_rast))
+ {
+ G_free(null_chunk);
+ fclose(f_cat_rast);
+ return -5;
+ }
+ if(fseek(f_cat_rast, step_shift, SEEK_CUR) != 0) {
+ G_message("seek failed");
+ return -6;
+ }
+ }
+
+ Rast_close(fd_patch_rast);
+ G_free(null_chunk);
+ fclose(f_cat_rast);
+ return 0;
+}
+
+
+static inline void update_cat_scatt_plt(CELL ** chunks, int chunk_size, unsigned short * belongs_pix, struct scScatts * scatts)
+{
+ int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix;
+ int r_bits = 256;
+
+ CELL * band_1_chunks;
+ CELL * band_2_chunks;
+
+ int * scatts_bands = scatts->scatts_bands;
+
+ for(i_scatt = 0; i_scatt < scatts->n_a_scatts; i_scatt++)
+ {
+ band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
+ band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
+ {
+ if(!belongs_pix[i_chunks_pix])
+ continue;
+
+ array_idx = band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits;
+ ++scatts->scatts_arr[i_scatt]->scatt_vals_arr[array_idx];
+ }
+ }
+}
+
+static inline int compute_scatts_from_chunk(struct scCats * scatt_plts, struct scCats * scatt_conds,
+ CELL ** chunks, char ** null_chunks, int chunk_size, FILE ** f_cats_rasts_in,
+ FILE ** f_cats_rasts_out, struct Cell_head *region, int i_chunk)
+{
+
+ int i_chunks_pix, i_cat, i_scatt, n_a_scatts, i_cond;
+ int cat_id, scatt_plts_cat_idx, array_idx;
+ char * band_1_null_chunks,* band_2_null_chunks;
+
+ int r_bits = 256;
+
+ struct scScatts * scatts_conds;
+ struct scScatts * scatt_plts_scatts;
+ struct scdScattData * conds;
+
+ int * scatts_bands;
+ struct scdScattData ** scatts_arr;
+
+ CELL * band_1_chunks;
+ CELL * band_2_chunks;
+ unsigned int * i_scatt_conds;
+
+ unsigned short * belongs_pix = (unsigned short *) malloc(chunk_size * sizeof(unsigned short));
+ unsigned char * rast_pixs = (unsigned char *) malloc(chunk_size * sizeof(unsigned char));
+
+ for(i_cat = 0; i_cat < scatt_conds->n_a_cats; i_cat++)
+ {
+ scatts_conds = scatt_conds->cats_arr[i_cat];
+
+ cat_id = scatt_conds->cats_ids[i_cat];
+
+ scatt_plts_cat_idx = scatt_plts->cats_idxs[cat_id];
+ if(scatt_plts_cat_idx < 0)
+ continue;
+
+ scatts_bands = scatts_conds->scatts_bands;
+
+ scatt_plts_scatts = scatt_plts->cats_arr[scatt_plts_cat_idx];
+
+ // if no condition for cats_arr is defined, all pixels are taken
+ memset(belongs_pix, 0, chunk_size * sizeof(unsigned short));
+ if(!scatts_conds->n_a_scatts) {
+
+ for(i_scatt = 0; i_scatt < scatt_plts_scatts->n_a_scatts; i_scatt++)
+ {
+ band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
+ band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++){
+ if(band_1_null_chunks[i_chunks_pix] != 1 &&
+ band_2_null_chunks[i_chunks_pix] != 1)
+ belongs_pix[i_chunks_pix] = 1;
+ }
+ }
+ }
+ else
+ {
+ fread(rast_pixs, sizeof(unsigned char), (chunk_size)/sizeof(unsigned char), f_cats_rasts_in[i_cat]);
+ if (ferror(f_cats_rasts_in[i_cat]))
+ {
+ free(rast_pixs);
+ free(belongs_pix);
+ G_message("Unable to read from file.");
+ return -1;
+ }
+
+ // test every defined conditions in scatter plots
+ for(i_scatt = 0; i_scatt < scatts_conds->n_a_scatts; i_scatt++)
+ {
+ band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
+ band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
+ band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
+
+ i_scatt_conds = scatts_conds->scatts_arr[i_scatt]->b_conds_arr;
+
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
+ {
+ if(belongs_pix[i_chunks_pix] ||
+ band_1_null_chunks[i_chunks_pix] == 1 ||
+ band_2_null_chunks[i_chunks_pix] == 1)
+ continue;
+ if(rast_pixs[i_chunks_pix] != 0 & 255) {
+ belongs_pix[i_chunks_pix] = 1;
+ continue;
+ }
+
+ if(i_scatt_conds[band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits])
+ belongs_pix[i_chunks_pix] = 1;
+ }
+ }
+ }
+
+ for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
+ rast_pixs[i_chunks_pix] = belongs_pix[i_chunks_pix] & 255;
+
+ fwrite(rast_pixs, sizeof(unsigned char), (chunk_size)/sizeof(unsigned char), f_cats_rasts_out[i_cat]);
+ // TODO when code will be paralelized put it out of the loop
+ if (ferror(f_cats_rasts_out[i_cat]))
+ {
+ free(rast_pixs);
+ free(belongs_pix);
+ G_debug(3, "Unable to write into file.");
+ return -1;
+ }
+ update_cat_scatt_plt(chunks, chunk_size, belongs_pix, scatt_plts_scatts);
+ }
+
+ free(rast_pixs);
+ free(belongs_pix);
+
+ return 0;
+}
+
+static void get_needed_bands(struct scCats * cats, int * b_needed_bands)
+{
+ // results in b_needed_bands - array of bools - if item has value 1, band (defined by item index) is needed to be opened
+ int i_cat, i_scatt, cat_id;
+
+ for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
+ {
+ for(i_scatt = 0; i_scatt < cats->cats_arr[i_cat]->n_a_scatts; i_scatt++)
+ {
+ G_debug(3, "Active scatt %d in catt %d", i_scatt, i_cat);
+
+ b_needed_bands[cats->cats_arr[i_cat]->scatts_bands[i_scatt * 2]] = 1;
+ b_needed_bands[cats->cats_arr[i_cat]->scatts_bands[i_scatt * 2 + 1]] = 1;
+ }
+ }
+ return;
+}
+
+static void free_compute_scatts_data(int * fd_bands, CELL ** chunks, char ** null_chunks, int * n_a_bands, int * bands_ids,
+ FILE ** f_cats_rasts_in, FILE ** f_cats_rasts_out, int n_a_cats)
+{
+ int i, band_id;
+
+ for(i = 0; i < (* n_a_bands); i++)
+ {
+ band_id = bands_ids[i];
+ if(band_id >= 0) {
+ Rast_close(fd_bands[i]);
+ G_free(chunks[band_id]);
+ G_free(null_chunks[band_id]);
+ }
+ }
+
+ if(f_cats_rasts_in)
+ for(i = 0; i < n_a_cats; i++)
+ fclose(f_cats_rasts_in[i]);
+
+ if(f_cats_rasts_out)
+ for(i = 0; i < n_a_cats; i++)
+ fclose(f_cats_rasts_out[i]);
+
+}
+
+
+static int open_cats_rasts_files(const char ** cats_rasts, int n_a_cats, int * cats_ids, const char * mode, FILE ** f_cats_rasts)
+{
+ int i_cat, id_cat;
+
+ for(i_cat = 0; i_cat < n_a_cats; i_cat++)
+ {
+ id_cat = cats_ids[i_cat];
+ f_cats_rasts[i_cat] = fopen(cats_rasts[id_cat], mode);
+ if(!f_cats_rasts[i_cat]) return -1;
+ }
+
+ return 0;
+}
+
+static int cats_rasts_write_header(int n_a_cats, struct Cell_head * region, FILE ** f_cats_rasts)
+{
+ int i_cat, id_cat, head_nchars;
+ char cat_rast_header[1024];//TODO magic number
+
+ head_nchars = get_cat_rast_header(region, cat_rast_header);
+
+ for(i_cat = 0; i_cat < n_a_cats; i_cat++)
+ {
+ fwrite(cat_rast_header, sizeof(char), head_nchars/sizeof(char), f_cats_rasts[i_cat]);
+ if (ferror(f_cats_rasts[i_cat])) return -1;
+ }
+
+ return head_nchars;
+
+}
+
+
+
+//TODO change name: I_UpdateScattData???
+int I_compute_scatts(struct Cell_head *region, struct scCats * scatt_conds, const char ** bands,
+ int n_bands, struct scCats * scatt_plts, const char ** cats_rasts_in, const char ** cats_rasts_out)
+{/*scatt_plts must be zeros! */
+ if (n_bands != scatt_plts->n_bands ||
+ n_bands != scatt_conds->n_bands)
+ return -1;
+
+ const char *mapset;
+
+ FILE * f_cats_rasts_out[scatt_conds->n_a_cats];
+ FILE * f_cats_rasts_in[scatt_conds->n_a_cats];
+
+ CELL * chunks[n_bands];
+ char * null_chunks[n_bands];
+
+ RASTER_MAP_TYPE data_type;
+
+ int max_chunk_size = 11234;
+ int nrows, i_band, id_band, n_a_bands, band_id,
+ chunk_size, i, i_chunk, i_row, head_nchars, i_cat;
+ int fd_bands[n_bands];
+ for(i_band = 0; i_band < n_bands; i_band++)
+ fd_bands[i_band] = -1;
+
+ int bands_ids[n_bands];
+ for(i_band = 0; i_band < n_bands; i_band++)
+ bands_ids[i_band] = -1;
+
+ int b_needed_bands[n_bands];
+ memset(b_needed_bands, 0, (size_t)n_bands * sizeof(int));
+
+ get_needed_bands(scatt_conds, &b_needed_bands[0]);
+ get_needed_bands(scatt_plts, &b_needed_bands[0]);
+
+ Rast_set_window(region);
+
+ n_a_bands = 0;/*TODO realy needed?*/
+ for(id_band = 0; id_band < n_bands; id_band++)
+ {
+ if(b_needed_bands[id_band])
+ {
+ G_debug(3, "Opening raster no. %d with name: %s", id_band, bands[id_band]);
+
+ /* TODO solve returns*/
+ if ((mapset = G_find_raster2(bands[id_band],"")) == NULL) {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], NULL, NULL, scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ if ((fd_bands[n_a_bands] = Rast_open_old(bands[id_band], mapset)) < 0) {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], NULL, NULL, scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ //TODO check data type, minimum and maximum value
+ data_type = Rast_get_map_type(fd_bands[n_a_bands]);
+ //if(data_type != CELL)
+ // return -1;
+
+ //What happens if it is not CELL tyoe
+ chunks[id_band] = Rast_allocate_c_buf();
+ null_chunks[id_band] = Rast_allocate_null_buf();
+
+ bands_ids[n_a_bands] = id_band;
+
+ ++n_a_bands;
+ }
+ }
+
+ if (open_cats_rasts_files(cats_rasts_out, scatt_conds->n_a_cats, scatt_conds->cats_ids, "wb", f_cats_rasts_out) != 0) {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], &f_cats_rasts_out[0], NULL, scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ head_nchars = cats_rasts_write_header(scatt_conds->n_a_cats, region, f_cats_rasts_out);
+ if (head_nchars < 0) {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], &f_cats_rasts_out[0], NULL, scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ if (open_cats_rasts_files(cats_rasts_in, scatt_conds->n_a_cats, scatt_conds->cats_ids, "rb", f_cats_rasts_in) != 0) {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], &f_cats_rasts_out[0], &f_cats_rasts_in[0], scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ for(i_cat = 0; i_cat < scatt_conds->n_a_cats; i_cat++)
+ fseek(f_cats_rasts_in[i_cat] , head_nchars, SEEK_SET);
+
+ i_chunk = 0;
+
+ nrows = Rast_window_rows();
+ chunk_size = Rast_window_cols();
+
+ for (i_row = 0; i_row < nrows; i_row++)
+ {
+ for(i_band = 0; i_band < n_a_bands; i_band++)
+ {
+ band_id = bands_ids[i_band];
+ G_debug(3, "Reading data for band %d", band_id);
+ Rast_get_c_row(fd_bands[i_band], chunks[band_id], i_row);
+ Rast_get_null_value_row (fd_bands[i_band], null_chunks[band_id], i_row);
+ }
+ if(compute_scatts_from_chunk(scatt_plts, scatt_conds, chunks, null_chunks, chunk_size, &f_cats_rasts_in[0], &f_cats_rasts_out[0], region, i_chunk) == -1)
+ {
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], &f_cats_rasts_out[0], &f_cats_rasts_in[0], scatt_conds->n_a_cats);
+ return -1;
+ }
+
+ }
+ free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
+ &bands_ids[0], &f_cats_rasts_out[0], &f_cats_rasts_in[0], scatt_conds->n_a_cats);
+ return 0;
+}
\ No newline at end of file
Deleted: sandbox/turek/scatter_plot/lib/imagery/scatt_plot.c
===================================================================
--- sandbox/turek/scatter_plot/lib/imagery/scatt_plot.c 2013-07-22 20:20:48 UTC (rev 57250)
+++ sandbox/turek/scatter_plot/lib/imagery/scatt_plot.c 2013-07-22 21:15:47 UTC (rev 57251)
@@ -1,616 +0,0 @@
-/*!
- \file lib/imagery/scatt_plot.c
-
- \brief Imagery library - functions for wx Scatter Plot Tool.
-
- Low level functions used by wx Scatter Plot Tool.
-
- Copyright (C) 2013 by the GRASS Development Team
-
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
-
- \author Stepan Turek <stepan.turek at seznam.cz> (Mentor: Martin Landa)
- */
-
-#include <grass/raster.h>
-#include <grass/imagery.h>
-#include <grass/gis.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <time.h>
-
-
-//TODO split formulas to be more understandable
-static void id_scatt_to_bands(const int scatt_id, const int n_bands, int * band_1, int * band_2)
-{
- int n_b1 = n_bands - 1;
-
- * band_1 = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
-
- * band_2 = scatt_id - ((* band_1) * (2 * n_b1 + 1) - (* band_1) * (* band_1)) / 2 + (* band_1) + 1;
-
- return;
-}
-
-static void bands_to_id_scatt(const int band_1, const int band_2, const int n_bands, int * scatt_id)
-{
- int n_b1 = n_bands - 1;
-
- * scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1;
-
- return;
-}
-
-void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
-{
- int i_cat;
-
- cats->type = type;
-
- cats->n_cats = 10;
- cats->n_a_cats = 0;
-
- cats->n_bands = n_bands;
- cats->n_scatts = (n_bands - 1) * n_bands / 2;
-
- cats->cats_arr = (struct scScatts **) malloc(cats->n_cats * sizeof(struct scScatts *));
- memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
-
- cats->cats_ids = (int *) malloc(cats->n_cats * sizeof(int));
- cats->cats_idxs =(int *) malloc(cats->n_cats * sizeof(int));
-
- for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
- cats->cats_idxs[i_cat] = -1;
-
- return;
-}
-
-void I_sc_free_cats(struct scCats * cats)
-{
- int i_cat;
-
- for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
- {
- if(cats->cats_arr[i_cat])
- {
- free(cats->cats_arr[i_cat]->scatt_idxs);
- free(cats->cats_arr[i_cat]->scatts_bands);
- free(cats->cats_arr[i_cat]->scatts_arr);
- free(cats->cats_arr[i_cat]);
- }
- }
-
- free(cats->cats_ids);
- free(cats->cats_idxs);
- free(cats->cats_arr);
-
- cats->n_cats = 0;
- cats->n_a_cats = 0;
- cats->n_bands = 0;
- cats->n_scatts = 0;
- cats->type = -1;
-
- return;
-}
-
-void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
-{
- a_cats_ids = cats->cats_ids;
- * n_a_cats = cats->n_a_cats;
-}
-
-int I_sc_add_cat(struct scCats * cats, int cat_id)
-{
- int i_scatt;
- int n_a_cats = cats->n_a_cats;
-
- if(cat_id < 0 || cat_id >= cats->n_cats)
- return -1;
-
- if(cats->cats_idxs[cat_id] >= 0)
- return -1;
- G_message("Adding category %d", cat_id);
-
- cats->cats_ids[n_a_cats] = cat_id;
- cats->cats_idxs[cat_id] = n_a_cats;
-
- cats->cats_arr[n_a_cats] = (struct scScatts *) malloc(sizeof(struct scScatts));
-
- cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) malloc(cats->n_scatts * sizeof(struct scdScattData *));
- memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, cats->n_scatts * sizeof(struct scdScattData *));
-
- cats->cats_arr[n_a_cats]->n_a_scatts = 0;
-
- cats->cats_arr[n_a_cats]->scatts_bands = (int *) malloc(cats->n_scatts * 2 * sizeof(int));
-
- cats->cats_arr[n_a_cats]->scatt_idxs = (int *) malloc(cats->n_scatts * sizeof(int));
- for(i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
- cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
-
- ++cats->n_a_cats;
- G_message("nacats %d ", cats->n_a_cats);
-
- return 0;
-}
-
-int I_sc_delete_cat(struct scCats * cats, int cat_id)
-{
- int cat_idx, i_cat;
-
- if(cat_id < 0 || cat_id >= cats->n_cats)
- return -1;
-
- cat_idx = cats->cats_idxs[cat_id];
- if(cat_idx < 0)
- return -1;
-
- free(cats->cats_arr[cat_idx]->scatt_idxs);
- free(cats->cats_arr[cat_idx]->scatts_bands);
- free(cats->cats_arr[cat_idx]->scatts_arr);
- free(cats->cats_arr[cat_idx]);
-
- for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
- {
- cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
- cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
- }
- cats->cats_idxs[cat_id] = -1;
-
- --cats->n_a_cats;
-
- return 0;
-}
-
-
-int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
-{
- int band_1, band_2, cat_idx, n_a_scatts;
- struct scScatts * scatts;
-
- if(cat_id < 0 || cat_id >= cats->n_cats)
- return -1;
-
- cat_idx = cats->cats_idxs[cat_id];
- if(cat_idx < 0)
- return -1;
-
- if(scatt_id < 0 && scatt_id >= cats->n_scatts)
- return -1;
-
- scatts = cats->cats_arr[cat_idx];
- if(scatts->scatt_idxs[scatt_id] >= 0)
- return -1;
-
- if(!scatt_vals->b_conds_arr && cats->type == 1)
- return -1;
-
- if(!scatt_vals->scatt_vals_arr && cats->type == 0)
- return -1;
-
- n_a_scatts = scatts->n_a_scatts;
-
- scatts->scatt_idxs[scatt_id] = n_a_scatts;
-
- id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
-
- scatts->scatts_bands[n_a_scatts * 2] = band_1;
- scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
-
- scatts->scatts_arr[n_a_scatts] = scatt_vals;
- ++scatts->n_a_scatts;
-
- G_message("I_sc_insert_scatt_data cat_id %d, scatt_id %d, scatt_idx", cat_id, scatt_id, n_a_scatts);
-
- return 0;
-}
-
-int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
-{
- int cat_idx, scatt_idx, n_init_scatts, i_scatt;
- struct scScatts * scatts;
-
- if(cat_id < 0 && cat_id >= cats->n_cats)
- return -1;
-
- cat_idx = cats->cats_idxs[cat_id];
- if(cat_idx < 0)
- return -1;
-
- if(scatt_id < 0 || scatt_id >= cats->n_scatts)
- return -1;
-
- scatts = cats->cats_arr[cat_idx];
- if(scatts->scatt_idxs[scatt_id] < 0)
- return -1;
-
- scatt_vals = scatts->scatts_arr[scatt_idx];
-
- for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
- {
- scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
- scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
- scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
- }
- scatts->scatts_arr[scatts->n_a_scatts] = NULL;
-
- scatts->scatt_idxs[scatt_id] = -1;
-
- scatt_vals = scatts->scatts_arr[scatt_id];
- scatts->n_a_scatts--;
-
- G_message("I_sc_remove_scatt_data %d, %d", cat_id, scatt_id);
-
- return 0;
-}
-
-int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
-{
- int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
- int cat_idx, scatt_idx, ret;
-
- cat_idx = cats->cats_idxs[cat_id];
- if(cat_idx < 0)
- return -1;
-
- if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
- return -1;
-
- cat_idx = cats->cats_idxs[cat_id];
- scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
-
- I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
-
- return 0;
-}
-
-void I_scd_init_scatt_data(struct scdScattData * scatt_vals, int n_vals, int type)
-{
- scatt_vals->n_vals = n_vals;
-
- if(type == 0)
- {
- scatt_vals->scatt_vals_arr = (unsigned int *) malloc(n_vals * sizeof(unsigned int));
- memset(scatt_vals->scatt_vals_arr, 0, n_vals * sizeof(unsigned int));
- scatt_vals->b_conds_arr = NULL;
- }
- else if(type == 1)
- {
- scatt_vals->b_conds_arr = (unsigned short *) malloc(n_vals * sizeof(unsigned short));
- memset(scatt_vals->b_conds_arr, 0, n_vals * sizeof(unsigned short));
- scatt_vals->scatt_vals_arr = NULL;
- }
-
- return;
-}
-
-void I_scd_free_scatt_data(struct scdScattData * scatt_vals)
-{
-
- free(scatt_vals->b_conds_arr);
- free(scatt_vals->scatt_vals_arr);
-
- scatt_vals = NULL;
-
- return;
-}
-
-int I_scd_get_data_size(struct scdScattData * scatt_vals)
-{
-
- return scatt_vals->n_vals;
-}
-
-void * I_scd_get_data_ptr(struct scdScattData * scatt_vals)
-{
- if(!scatt_vals->b_conds_arr)
- return scatt_vals->b_conds_arr;
- else if(!scatt_vals->scatt_vals_arr)
- return scatt_vals->scatt_vals_arr;
-
- return NULL;
-}
-
-int I_scd_set_value(struct scdScattData * scatt_vals, unsigned int val_idx, unsigned int val)
-{
- if(val_idx < 0 && val_idx > scatt_vals->n_vals)
- return -1;
-
- if(scatt_vals->b_conds_arr)
- scatt_vals->b_conds_arr[val_idx] = val;
- else if(scatt_vals->scatt_vals_arr)
- scatt_vals->scatt_vals_arr[val_idx] = val;
- else
- return -1;
-
- return 0;
-}
-
-static inline void update_cat_scatt_plt(CELL ** chunks, int chunk_size, unsigned short * belongs_pix, struct scScatts * scatts)
-{
- int band_axis_1, band_axis_2, i_scatt, array_idx, cat_idx, i_chunks_pix;
- int r_bits = 256;
-
- CELL * band_1_chunks;
- CELL * band_2_chunks;
-
- int * scatts_bands = scatts->scatts_bands;
-
- for(i_scatt = 0; i_scatt < scatts->n_a_scatts; i_scatt++)
- {
- band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
- band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
-
- for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
- {
- if(!belongs_pix[i_chunks_pix])
- continue;
-
- array_idx = band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits;
- ++scatts->scatts_arr[i_scatt]->scatt_vals_arr[array_idx];
- }
- }
-}
-
-static inline int compute_scatts_from_chunk(struct scCats * scatt_plts, struct scCats * scatt_conds,
- CELL ** chunks, char ** null_chunks, int chunk_size, FILE ** f_cats_rasts, struct Cell_head *region, int i_chunk)
-{
-
- int i_chunks_pix, i_cat, i_scatt, n_a_scatts, i_cond;
- int cat_id, scatt_plts_cat_idx, array_idx;
- char * band_1_null_chunks,* band_2_null_chunks;
-
- int r_bits = 256;
-
- struct scScatts * scatts_conds;
- struct scScatts * scatt_plts_scatts;
- struct scdScattData * conds;
-
- int * scatts_bands;
- struct scdScattData ** scatts_arr;
-
- CELL * band_1_chunks;
- CELL * band_2_chunks;
- unsigned int * i_scatt_conds;
-
- unsigned short * belongs_pix = (unsigned short *) malloc(chunk_size * sizeof(unsigned short));
- unsigned char * rast_pixs = (unsigned char *) malloc(chunk_size * sizeof(unsigned char));
-
- for(i_cat = 0; i_cat < scatt_conds->n_a_cats; i_cat++)
- {
- scatts_conds = scatt_conds->cats_arr[i_cat];
-
- cat_id = scatt_conds->cats_ids[i_cat];
-
- scatt_plts_cat_idx = scatt_plts->cats_idxs[cat_id];
- if(scatt_plts_cat_idx < 0)
- continue;
-
- scatts_bands = scatts_conds->scatts_bands;
-
- scatt_plts_scatts = scatt_plts->cats_arr[scatt_plts_cat_idx];
-
- // if no condition for cats_arr is defined, all pixels are taken
- memset(belongs_pix, 0, chunk_size * sizeof(unsigned short));
- if(!scatts_conds->n_a_scatts) {
-
- for(i_scatt = 0; i_scatt < scatt_plts_scatts->n_a_scatts; i_scatt++)
- {
- band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
- band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
-
- for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++){
- if(band_1_null_chunks[i_chunks_pix] != 1 &&
- band_2_null_chunks[i_chunks_pix] != 1)
- belongs_pix[i_chunks_pix] = 1;
- }
- }
- }
- else
- {
- // test every defined conditions in scatter plots
- for(i_scatt = 0; i_scatt < scatts_conds->n_a_scatts; i_scatt++)
- {
- band_1_chunks = chunks[scatts_bands[i_scatt * 2]];
- band_2_chunks = chunks[scatts_bands[i_scatt * 2 + 1]];
-
- band_1_null_chunks = null_chunks[scatts_bands[i_scatt * 2]];
- band_2_null_chunks = null_chunks[scatts_bands[i_scatt * 2 + 1]];
-
- i_scatt_conds = scatts_conds->scatts_arr[i_scatt]->b_conds_arr;
-
- for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
- {
- if(belongs_pix[i_chunks_pix] ||
- band_1_null_chunks[i_chunks_pix] == 1 ||
- band_2_null_chunks[i_chunks_pix] == 1)
- continue;
- if(i_scatt_conds[band_1_chunks[i_chunks_pix] + band_2_chunks[i_chunks_pix] * r_bits])
- belongs_pix[i_chunks_pix] = 1;
- }
- }
- }
-
- for(i_chunks_pix = 0; i_chunks_pix < chunk_size; i_chunks_pix++)
- rast_pixs[i_chunks_pix] = belongs_pix[i_chunks_pix] & 255;
-
- fwrite(rast_pixs, sizeof(unsigned char), (chunk_size)/sizeof(unsigned char), f_cats_rasts[i_cat]);
- // TODO when code will be paralelized put it out of the loop
- if (ferror(f_cats_rasts[i_cat]))
- {
- free(rast_pixs);
- free(belongs_pix);
- G_debug(3, "Unable to write into file.");
- return -1;
- }
- update_cat_scatt_plt(chunks, chunk_size, belongs_pix, scatt_plts_scatts);
- }
-
- free(rast_pixs);
- free(belongs_pix);
-
- return 0;
-}
-
-static void get_needed_bands(struct scCats * cats, int * b_needed_bands)
-{
- // results in b_needed_bands - array of bools - if item has value 1, band (defined by item index) is needed to be opened
- int i_cat, i_scatt, cat_id;
-
- for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
- {
- for(i_scatt = 0; i_scatt < cats->cats_arr[i_cat]->n_a_scatts; i_scatt++)
- {
- G_debug(3, "Active scatt %d in catt %d", i_scatt, i_cat);
-
- b_needed_bands[cats->cats_arr[i_cat]->scatts_bands[i_scatt * 2]] = 1;
- b_needed_bands[cats->cats_arr[i_cat]->scatts_bands[i_scatt * 2 + 1]] = 1;
- }
- }
- return;
-}
-
-static void free_compute_scatts_data(int * fd_bands, CELL ** chunks, char ** null_chunks, int * n_a_bands, int * bands_ids,
- FILE ** f_cats_rasts, int n_a_cats)
-{
- int i, band_id;
-
- for(i = 0; i < (* n_a_bands); i++)
- {
- band_id = bands_ids[i];
- if(band_id >= 0) {
- Rast_close(fd_bands[i]);
- G_free(chunks[band_id]);
- G_free(null_chunks[band_id]);
- }
- }
-
- if(f_cats_rasts)
- for(i = 0; i < n_a_cats; i++)
- fclose(f_cats_rasts[i]);
-}
-
-
-//TODO change name: I_UpdateScattData???
-int I_compute_scatts(struct Cell_head *region, struct scCats * scatt_conds, const char ** bands,
- int n_bands, struct scCats * scatt_plts, const char ** cats_rasts)
-{/*scatt_plts must be zeros! */
- if (n_bands != scatt_plts->n_bands ||
- n_bands != scatt_conds->n_bands)
- return -1;
-
- const char *mapset;
-
- FILE * f_cats_rasts[scatt_conds->n_a_cats];
-
- char rast_cats_header[1024];//TODO magic number
-
- CELL * chunks[n_bands];
- char * null_chunks[n_bands];
-
- RASTER_MAP_TYPE data_type;
-
- int max_chunk_size = 11234;
- int nrows, i_band, id_band, n_a_bands, band_id,
- chunk_size, i_cat, id_cat, i, i_chunk, i_chars, i_row;
- int fd_bands[n_bands];
- for(i_band = 0; i_band < n_bands; i_band++)
- fd_bands[i_band] = -1;
-
- int bands_ids[n_bands];
- for(i_band = 0; i_band < n_bands; i_band++)
- bands_ids[i_band] = -1;
-
- int b_needed_bands[n_bands];
- memset(b_needed_bands, 0, (size_t)n_bands * sizeof(int));
-
- get_needed_bands(scatt_conds, &b_needed_bands[0]);
- get_needed_bands(scatt_plts, &b_needed_bands[0]);
-
- Rast_set_window(region);
-
- n_a_bands = 0;/*TODO realy needed?*/
- for(id_band = 0; id_band < n_bands; id_band++)
- {
- if(b_needed_bands[id_band])
- {
- G_debug(3, "Opening raster no. %d with name: %s", id_band, bands[id_band]);
-
- /* TODO solve returns*/
- if ((mapset = G_find_raster2(bands[id_band],"")) == NULL) {
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], NULL, scatt_conds->n_a_cats);
- return -1;
- }
-
- if ((fd_bands[n_a_bands] = Rast_open_old(bands[id_band], mapset)) < 0) {
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], NULL, scatt_conds->n_a_cats);
- return -1;
- }
-
- //TODO check data type, minimum and maximum value
- data_type = Rast_get_map_type(fd_bands[n_a_bands]);
- //if(data_type != CELL)
- // return -1;
-
- //What happens if it is not CELL tyoe
- chunks[id_band] = Rast_allocate_c_buf();
- null_chunks[id_band] = Rast_allocate_null_buf();
-
- bands_ids[n_a_bands] = id_band;
-
- ++n_a_bands;
- }
- }
-
- i_chars = sprintf(rast_cats_header, "P5\n%d\n%d\n1\n", region->cols, region->rows);
- for(i_cat = 0; i_cat < scatt_conds->n_a_cats; i_cat++)
- {
-
- id_cat = scatt_conds->cats_ids[i_cat];
- f_cats_rasts[i_cat] = fopen(cats_rasts[id_cat], "wb");
- if(!f_cats_rasts[i_cat])
- {
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], &f_cats_rasts[0], scatt_conds->n_a_cats);
- return -1;
- }
-
- fwrite(rast_cats_header, sizeof(char), i_chars/sizeof(char), f_cats_rasts[i_cat]);
- if (ferror(f_cats_rasts[i_cat])){
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], &f_cats_rasts[0], scatt_conds->n_a_cats);
- return -1;
- }
- }
-
- i_chunk = 0;
-
- nrows = Rast_window_rows();
- chunk_size = Rast_window_cols();
-
- for (i_row = 0; i_row < nrows; i_row++)
- {
- for(i_band = 0; i_band < n_a_bands; i_band++)
- {
- band_id = bands_ids[i_band];
- G_debug(3, "Reading data for band %d", band_id);
- Rast_get_c_row(fd_bands[i_band], chunks[band_id], i_row);
- Rast_get_null_value_row (fd_bands[i_band], null_chunks[band_id], i_row);
- }
- if(compute_scatts_from_chunk(scatt_plts, scatt_conds, chunks, null_chunks, chunk_size, &f_cats_rasts[0], region, i_chunk) == -1)
- {
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], &f_cats_rasts[0], scatt_conds->n_a_cats);
- return -1;
- }
-
- }
- free_compute_scatts_data(&fd_bands[0], &chunks[0], &null_chunks[0], &n_a_bands,
- &bands_ids[0], &f_cats_rasts[0], scatt_conds->n_a_cats);
- return 0;
-}
\ No newline at end of file
Added: sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c
===================================================================
--- sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c (rev 0)
+++ sandbox/turek/scatter_plot/lib/imagery/scatt_sccats.c 2013-07-22 21:15:47 UTC (rev 57251)
@@ -0,0 +1,327 @@
+/*!
+ \file lib/imagery/scatt_cat_rast.c
+
+ \brief Imagery library - functions for wx Scatter Plot Tool.
+
+ Low level functions used by wx Scatter Plot Tool.
+
+ Copyright (C) 2013 by the GRASS Development Team
+
+ This program is free software under the GNU General Public License
+ (>=v2). Read the file COPYING that comes with GRASS for details.
+
+ \author Stepan Turek <stepan.turek at seznam.cz> (Mentor: Martin Landa)
+ */
+
+#include <grass/raster.h>
+#include <grass/imagery.h>
+#include <grass/gis.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+//TODO split formulas to be more understandable
+static void id_scatt_to_bands(const int scatt_id, const int n_bands, int * band_1, int * band_2)
+{
+ int n_b1 = n_bands - 1;
+
+ * band_1 = (int) ((2 * n_b1 + 1 - sqrt((double)((2 * n_b1 + 1) * (2 * n_b1 + 1) - 8 * scatt_id))) / 2);
+
+ * band_2 = scatt_id - ((* band_1) * (2 * n_b1 + 1) - (* band_1) * (* band_1)) / 2 + (* band_1) + 1;
+
+ return;
+}
+
+static void bands_to_id_scatt(const int band_1, const int band_2, const int n_bands, int * scatt_id)
+{
+ int n_b1 = n_bands - 1;
+
+ * scatt_id = (band_1 * (2 * n_b1 + 1) - band_1 * band_1) / 2 + band_2 - band_1 - 1;
+
+ return;
+}
+
+void I_sc_init_cats(struct scCats * cats, int n_bands, int type)
+{
+ int i_cat;
+
+ cats->type = type;
+
+ cats->n_cats = 10;
+ cats->n_a_cats = 0;
+
+ cats->n_bands = n_bands;
+ cats->n_scatts = (n_bands - 1) * n_bands / 2;
+
+ cats->cats_arr = (struct scScatts **) malloc(cats->n_cats * sizeof(struct scScatts *));
+ memset(cats->cats_arr, 0, cats-> n_cats * sizeof(struct scScatts *));
+
+ cats->cats_ids = (int *) malloc(cats->n_cats * sizeof(int));
+ cats->cats_idxs =(int *) malloc(cats->n_cats * sizeof(int));
+
+ for(i_cat = 0; i_cat < cats->n_cats; i_cat++)
+ cats->cats_idxs[i_cat] = -1;
+
+ return;
+}
+
+void I_sc_free_cats(struct scCats * cats)
+{
+ int i_cat;
+
+ for(i_cat = 0; i_cat < cats->n_a_cats; i_cat++)
+ {
+ if(cats->cats_arr[i_cat])
+ {
+ free(cats->cats_arr[i_cat]->scatt_idxs);
+ free(cats->cats_arr[i_cat]->scatts_bands);
+ free(cats->cats_arr[i_cat]->scatts_arr);
+ free(cats->cats_arr[i_cat]);
+ }
+ }
+
+ free(cats->cats_ids);
+ free(cats->cats_idxs);
+ free(cats->cats_arr);
+
+ cats->n_cats = 0;
+ cats->n_a_cats = 0;
+ cats->n_bands = 0;
+ cats->n_scatts = 0;
+ cats->type = -1;
+
+ return;
+}
+
+void I_sc_get_active_categories(int * a_cats_ids, int * n_a_cats, struct scCats * cats)
+{
+ a_cats_ids = cats->cats_ids;
+ * n_a_cats = cats->n_a_cats;
+}
+
+int I_sc_add_cat(struct scCats * cats, int cat_id)
+{
+ int i_scatt;
+ int n_a_cats = cats->n_a_cats;
+
+ if(cat_id < 0 || cat_id >= cats->n_cats)
+ return -1;
+
+ if(cats->cats_idxs[cat_id] >= 0)
+ return -1;
+ G_message("Adding category %d", cat_id);
+
+ cats->cats_ids[n_a_cats] = cat_id;
+ cats->cats_idxs[cat_id] = n_a_cats;
+
+ cats->cats_arr[n_a_cats] = (struct scScatts *) malloc(sizeof(struct scScatts));
+
+ cats->cats_arr[n_a_cats]->scatts_arr = (struct scdScattData **) malloc(cats->n_scatts * sizeof(struct scdScattData *));
+ memset((cats->cats_arr[n_a_cats]->scatts_arr), 0, cats->n_scatts * sizeof(struct scdScattData *));
+
+ cats->cats_arr[n_a_cats]->n_a_scatts = 0;
+
+ cats->cats_arr[n_a_cats]->scatts_bands = (int *) malloc(cats->n_scatts * 2 * sizeof(int));
+
+ cats->cats_arr[n_a_cats]->scatt_idxs = (int *) malloc(cats->n_scatts * sizeof(int));
+ for(i_scatt = 0; i_scatt < cats->n_scatts; i_scatt++)
+ cats->cats_arr[n_a_cats]->scatt_idxs[i_scatt] = -1;
+
+ ++cats->n_a_cats;
+ G_message("nacats %d ", cats->n_a_cats);
+
+ return 0;
+}
+
+int I_sc_delete_cat(struct scCats * cats, int cat_id)
+{
+ int cat_idx, i_cat;
+
+ if(cat_id < 0 || cat_id >= cats->n_cats)
+ return -1;
+
+ cat_idx = cats->cats_idxs[cat_id];
+ if(cat_idx < 0)
+ return -1;
+
+ free(cats->cats_arr[cat_idx]->scatt_idxs);
+ free(cats->cats_arr[cat_idx]->scatts_bands);
+ free(cats->cats_arr[cat_idx]->scatts_arr);
+ free(cats->cats_arr[cat_idx]);
+
+ for(i_cat = cat_idx; i_cat < cats->n_a_cats - 1; i_cat++)
+ {
+ cats->cats_arr[i_cat] = cats->cats_arr[i_cat + 1];
+ cats->cats_ids[i_cat] = cats->cats_ids[i_cat + 1];
+ }
+ cats->cats_idxs[cat_id] = -1;
+
+ --cats->n_a_cats;
+
+ return 0;
+}
+
+
+int I_sc_insert_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
+{
+ int band_1, band_2, cat_idx, n_a_scatts;
+ struct scScatts * scatts;
+
+ if(cat_id < 0 || cat_id >= cats->n_cats)
+ return -1;
+
+ cat_idx = cats->cats_idxs[cat_id];
+ if(cat_idx < 0)
+ return -1;
+
+ if(scatt_id < 0 && scatt_id >= cats->n_scatts)
+ return -1;
+
+ scatts = cats->cats_arr[cat_idx];
+ if(scatts->scatt_idxs[scatt_id] >= 0)
+ return -1;
+
+ if(!scatt_vals->b_conds_arr && cats->type == 1)
+ return -1;
+
+ if(!scatt_vals->scatt_vals_arr && cats->type == 0)
+ return -1;
+
+ n_a_scatts = scatts->n_a_scatts;
+
+ scatts->scatt_idxs[scatt_id] = n_a_scatts;
+
+ id_scatt_to_bands(scatt_id, cats->n_bands, &band_1, &band_2);
+
+ scatts->scatts_bands[n_a_scatts * 2] = band_1;
+ scatts->scatts_bands[n_a_scatts * 2 + 1] = band_2;
+
+ scatts->scatts_arr[n_a_scatts] = scatt_vals;
+ ++scatts->n_a_scatts;
+
+ G_message("I_sc_insert_scatt_data cat_id %d, scatt_id %d, scatt_idx", cat_id, scatt_id, n_a_scatts);
+
+ return 0;
+}
+
+int I_sc_remove_scatt_data(struct scCats * cats, struct scdScattData * scatt_vals, int cat_id, int scatt_id)
+{
+ int cat_idx, scatt_idx, n_init_scatts, i_scatt;
+ struct scScatts * scatts;
+
+ if(cat_id < 0 && cat_id >= cats->n_cats)
+ return -1;
+
+ cat_idx = cats->cats_idxs[cat_id];
+ if(cat_idx < 0)
+ return -1;
+
+ if(scatt_id < 0 || scatt_id >= cats->n_scatts)
+ return -1;
+
+ scatts = cats->cats_arr[cat_idx];
+ if(scatts->scatt_idxs[scatt_id] < 0)
+ return -1;
+
+ scatt_vals = scatts->scatts_arr[scatt_idx];
+
+ for(i_scatt = scatt_idx; i_scatt < scatts->n_a_scatts - 1; i_scatt++)
+ {
+ scatts->scatts_arr[i_scatt] = scatts->scatts_arr[i_scatt + 1];
+ scatts->scatts_bands[i_scatt * 2] = scatts->scatts_bands[(i_scatt + 1)* 2];
+ scatts->scatts_bands[i_scatt * 2 + 1] = scatts->scatts_bands[(i_scatt + 1) * 2 + 1];
+ }
+ scatts->scatts_arr[scatts->n_a_scatts] = NULL;
+
+ scatts->scatt_idxs[scatt_id] = -1;
+
+ scatt_vals = scatts->scatts_arr[scatt_id];
+ scatts->n_a_scatts--;
+
+ G_message("I_sc_remove_scatt_data %d, %d", cat_id, scatt_id);
+
+ return 0;
+}
+
+int I_sc_set_value(struct scCats * cats, int cat_id, int scatt_id, int value_idx, int value)
+{
+ int n_a_scatts = cats->cats_arr[cat_id]->n_a_scatts;
+ int cat_idx, scatt_idx, ret;
+
+ cat_idx = cats->cats_idxs[cat_id];
+ if(cat_idx < 0)
+ return -1;
+
+ if(cats->cats_arr[cat_idx]->scatt_idxs[scatt_id] < 0)
+ return -1;
+
+ cat_idx = cats->cats_idxs[cat_id];
+ scatt_idx = cats->cats_arr[cat_idx]->scatt_idxs[scatt_id];
+
+ I_scd_set_value(cats->cats_arr[cat_idx]->scatts_arr[scatt_idx], value_idx, value);
+
+ return 0;
+}
+
+void I_scd_init_scatt_data(struct scdScattData * scatt_vals, int n_vals, int type)
+{
+ scatt_vals->n_vals = n_vals;
+
+ if(type == 0)
+ {
+ scatt_vals->scatt_vals_arr = (unsigned int *) malloc(n_vals * sizeof(unsigned int));
+ memset(scatt_vals->scatt_vals_arr, 0, n_vals * sizeof(unsigned int));
+ scatt_vals->b_conds_arr = NULL;
+ }
+ else if(type == 1)
+ {
+ scatt_vals->b_conds_arr = (unsigned short *) malloc(n_vals * sizeof(unsigned short));
+ memset(scatt_vals->b_conds_arr, 0, n_vals * sizeof(unsigned short));
+ scatt_vals->scatt_vals_arr = NULL;
+ }
+
+ return;
+}
+
+void I_scd_free_scatt_data(struct scdScattData * scatt_vals)
+{
+
+ free(scatt_vals->b_conds_arr);
+ free(scatt_vals->scatt_vals_arr);
+
+ scatt_vals = NULL;
+
+ return;
+}
+
+int I_scd_get_data_size(struct scdScattData * scatt_vals)
+{
+ return scatt_vals->n_vals;
+}
+
+void * I_scd_get_data_ptr(struct scdScattData * scatt_vals)
+{
+ if(!scatt_vals->b_conds_arr)
+ return scatt_vals->b_conds_arr;
+ else if(!scatt_vals->scatt_vals_arr)
+ return scatt_vals->scatt_vals_arr;
+
+ return NULL;
+}
+
+int I_scd_set_value(struct scdScattData * scatt_vals, unsigned int val_idx, unsigned int val)
+{
+ if(val_idx < 0 && val_idx > scatt_vals->n_vals)
+ return -1;
+
+ if(scatt_vals->b_conds_arr)
+ scatt_vals->b_conds_arr[val_idx] = val;
+ else if(scatt_vals->scatt_vals_arr)
+ scatt_vals->scatt_vals_arr[val_idx] = val;
+ else
+ return -1;
+
+ return 0;
+}
More information about the grass-commit
mailing list