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 */
14 unsigned short int classes[32];
20 unsigned short int* table;
21 typedef struct record *rec;
23 EPP *files[32]; /* array of pointers to files
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
33 /* comparation function. Sorts two records according to classes
35 returns -1 if *r1 <*r2 ,0 if *r1=*r2 1 if *r1>*r2
37 int compare(struct record *r1, struct record *r2)
39 for (i=0;i<files_count;i++)
40 { if (r1->classes[i]>r2->classes[i]) return 1;
42 if (r1->classes[i]<r2->classes[i]) return -1;
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
52 int search(struct record *key,int *index)
53 {int l=0,h=count-1,i,c;
56 c=compare((struct record *)(table+(tuple_size)*i),key);
60 if (!c) { *index=i;return 1;}
66 /* Inserts given record into table at position index.
67 Fills count field of inserted record by 1
69 void insert(struct record *key,int index)
73 table=realloc(table,(limit+=delta)*(tuple_size)*sizeof(short int));
75 { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
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));
85 memcpy(table+index*tuple_size+2,key->classes,files_count*sizeof(short int));
89 adds pixel into table, i.e. if record with such combination of classes
90 already exists, increments its count. Otherwise inserts new record.
92 void add_pixel(struct record *key)
93 {int index;long int *l;
94 if (search(key,&index))
96 l=((long int *)(table+index*(tuple_size)));
99 else insert(key,index);
103 { printf("Usage: outtab [-%%] files\n");
108 Processes cell - forms record and adds it to table
110 void do_cell(int x,int y)
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;
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);
131 /******************** main ***********************************/
132 int main(int argc,char **argv)
135 if (!strcmp(argv[1],"-%")) {verbose=1;i++;}
136 for(j=0;i<argc;i++,j++)
138 { fprintf(stderr,"To many files in command line, 32 max\n");
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]);
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]);
155 tuple_size=(3+files_count);
157 tuple_size=(2+files_count);
159 table=malloc(65536*tuple_size*sizeof(short int));
160 if (!table) { fprintf(stderr,"Not enough memory to allocate %d records\n",65536);
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++)
171 if (EndLineProc) if ((*EndLineProc)(j,k,rows)) break;
174 if (verbose) {fprintf(stderr,"\r \rdone\n");}
178 for(i=0;i<files_count;close_epp(files[i++]));