]> www.wagner.pp.ru Git - oss/fgis.git/blob - epu/outtab.c
First checked in version
[oss/fgis.git] / epu / outtab.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "eppl_ut.h"
5 #include "epp.h"
6
7 /* This structure is used to keep information about 
8    combination of classes. count is count of cells already found,
9    classes are classes. Really each of these structures occupies
10    less then sizeof(struct record) bytes, becouse count of files is
11    usially less than 32 */ 
12 struct record {
13                long int count;
14                unsigned short int classes[32];
15               };
16
17   
18
19
20 unsigned short int* table;
21 typedef struct record *rec;
22
23 EPP *files[32]; /* array of pointers to files
24
25 int tuple_size, /* bytes in tuple != files_count*sizeof(short)+sizeof(int)
26                    due to 4-byte alignment of
27     files_count, /* Count of files */
28     count,       /* current size of table */
29     limit,       /* number of records, currently allocated */
30     delta;       /* Increment of record number to reallocate when reserves
31                     exhausted */
32    
33 /* comparation function. Sorts two records according to classes
34    of files in order 
35    returns -1 if *r1 <*r2 ,0 if *r1=*r2 1 if *r1>*r2
36 */
37 int compare(struct record *r1, struct record *r2)
38 {int i; 
39  for (i=0;i<files_count;i++)
40  { if (r1->classes[i]>r2->classes[i]) return 1;
41    else
42    if (r1->classes[i]<r2->classes[i]) return -1;
43  }
44  return 0;
45
46 }
47
48 /* Searches table for record which contains classes, specified
49    in record key. if found, returns non-zero and places index of it
50    into index. If not, returns zero and places index, where to insert
51    record into index */ 
52 int search(struct record *key,int *index)
53 {int l=0,h=count-1,i,c;
54  while(l<=h)
55  { i=(l+h)>>1;
56    c=compare((struct record *)(table+(tuple_size)*i),key);
57    if (c<0) l=i+1;
58    else
59    { h=i-1;
60      if (!c) { *index=i;return 1;}
61    }
62   } 
63  *index=l;
64  return 0;
65 }
66 /* Inserts given record into table at position index.
67    Fills count field of inserted record by 1
68  */
69 void insert(struct record *key,int index)
70 { int i;long int *l;
71   if (count==limit)
72   {  
73      table=realloc(table,(limit+=delta)*(tuple_size)*sizeof(short int));
74      if (!table)
75      { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
76        exit(1);
77      }
78    }
79
80  for(i=count;i>index;i--)
81   memcpy(table+(i)*(tuple_size),table+(i-1)*(tuple_size),
82   (tuple_size)*sizeof(short int)); 
83  l=(long int *)(table+index*(tuple_size));
84  *l=1L;
85  memcpy(table+index*tuple_size+2,key->classes,files_count*sizeof(short int));
86  count++;
87
88 /*
89    adds pixel into table, i.e. if record with such combination of classes
90    already exists, increments its count. Otherwise inserts new record.
91  */
92 void add_pixel(struct record *key)
93 {int index;long int *l; 
94  if (search(key,&index))
95   {
96    l=((long int *)(table+index*(tuple_size)));
97    (*l)++;
98   }
99  else insert(key,index);
100 }
101
102 void help()
103 { printf("Usage: outtab [-%%] files\n");
104   exit(0);
105 }
106
107 /*
108    Processes cell - forms record and adds it to table
109  */
110 void do_cell(int x,int y)
111    { int k;
112      struct record r;
113      unsigned short int *c=r.classes;  
114      for(k=0;k<files_count;k++,c++)
115        if((*c=epp_get(files[k],x,y))==files[k]->offsite) return;
116      add_pixel(&r);
117    } 
118
119 /*
120    Prints table.
121  */
122 void print_table()
123 {int i,j;
124  unsigned short *t;
125 for(i=0,t=table;i<count;i++,t+=tuple_size)
126 { for(j=0;j<files_count;j++)
127    printf("%d,",((struct record *)t)->classes[j]);
128   printf("%ld\n",((struct record *)t)->count);
129 }
130 }
131 /******************** main ***********************************/
132 int main(int argc,char **argv)
133 {int i=1,j,k,rows;
134  int verbose=0;
135  if (!strcmp(argv[1],"-%")) {verbose=1;i++;}
136  for(j=0;i<argc;i++,j++)
137  { if (j>=32) 
138    { fprintf(stderr,"To many files in command line, 32 max\n");
139      exit(1);
140    }
141    files[j]=open_epp(argv[i]);
142    if (!files[j]) files[j]=open_epp(default_ext(argv[i],".epp"));
143    if (!files[j]) { fprintf(stderr,"Cannot open file %s\n",argv[i]);
144                     exit(1);
145                   }
146    if(j){ if(files[j]->fr!=files[0]->fr||files[j]->fc!=files[0]->fc||
147              files[j]->lr!=files[0]->lr||files[j]->lc!=files[0]->lc)
148            {fprintf(stderr,"Size of file %s doesn't match.\n",argv[i]);
149             exit(1);
150            }
151          }  
152  }
153  files_count=j;
154  if (files_count%2) {
155     tuple_size=(3+files_count);
156  } else {
157     tuple_size=(2+files_count);
158  }
159  table=malloc(65536*tuple_size*sizeof(short int));
160  if (!table) { fprintf(stderr,"Not enough memory to allocate %d records\n",65536);
161  exit(1);
162  }
163  limit=65536;
164  delta=1024;
165  count=0;
166  rows=files[0]->lr-files[0]->fr;
167  install_progress_indicator(verbose?show_percent:check_int);
168  for(i=files[0]->fr,k=1;i<files[0]->lr;i++,k++)
169  { for(j=files[0]->fc;j<files[0]->lc;j++)
170     do_cell(j,i);
171     if (EndLineProc) if ((*EndLineProc)(j,k,rows)) break;
172  
173  }
174  if (verbose) {fprintf(stderr,"\r                                        \rdone\n");}
175   print_table();
176  free(table);
177
178  for(i=0;i<files_count;close_epp(files[i++]));
179  return 0;
180