]> www.wagner.pp.ru Git - oss/fgis.git/blob - lib/epp_input.c
First checked in version
[oss/fgis.git] / lib / epp_input.c
1 # include "epp.h"
2 # include <string.h>
3 # include <stdlib.h>
4 # include <math.h>
5 # include <time.h>
6 # include "epp_private.h"
7 int map_error=0; /* after each operation contains error code */
8 EPP *open_epp(char *pathname)
9 /* opens existing EPP file */
10 {
11   FILE *f;
12   f=fopen(pathname,"rb");
13   if (f==NULL) {map_error=ME_NO_FILE;return NULL;}
14   return fopen_epp(f);
15 }  
16
17
18
19 EPP *fopen_epp(FILE* f)
20 {
21   EPPHEADER h;
22   EPP *epp;
23 #ifndef LSB_FIRST 
24   short *file_width_table;
25 #endif
26   fseek(f,0,SEEK_SET);
27   if (fread(&h,1,128,f)<128) {fclose(f);map_error=ME_INVALID_FILE;return NULL;};
28   
29   if ((swapshort(h.kind)!=8)&&(swapshort(h.kind)!=16)) {fclose(f);map_error=ME_INVALID_FILE;return NULL;}
30   epp=malloc(sizeof(EPP));
31   if (NULL==epp) { fclose(f);map_error=ME_OUT_OF_MEMORY;return NULL;}
32   epp->XLeft=swapdouble(h.fcx);
33   epp->XRight=swapdouble(h.lcx);
34   epp->YTop=swapdouble(h.fry);
35   epp->YBottom=swapdouble(h.lry);
36   epp->fr=swapshort(h.fr);
37   epp->fc=swapshort(h.fc);
38   epp->lc=swapshort(h.lc)+1;
39   epp->lr=swapshort(h.lr)+1;
40   epp->min=swapshort(h.minclass);
41   epp->max=swapshort(h.maxclass);
42   epp->offsite=swapshort(h.offsite);
43   epp->kind=swapshort(h.kind);
44   if (epp->kind==8&&(epp->min>255||epp->max>255||epp->min>epp->max))
45    {epp->min=0;epp->max=255;}
46   epp->mode=MAP_INPUT;
47   epp->position=position_input;
48   epp->cell_area=swapdouble(h.sfact);
49   epp->width=(epp->lc-epp->fc+1);
50   if ((epp->row=calloc(epp->width+1,sizeof(short)))==NULL)
51     {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
52   if(( h.access_ptr!=0)&&(h.access_ptr!=0x20202020))
53 #ifdef LSB_FIRST
54   { if((epp->widthtable = calloc(epp->lr-epp->fr,sizeof(short)))==NULL)
55      {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
56      fseek(f,128*h.access_ptr,SEEK_SET);
57      fread(epp->widthtable,epp->lr-epp->fr,sizeof(short),f);
58   } 
59 #else  
60   { if((epp->widthtable = calloc(epp->lr-epp->fr,sizeof(short)))==NULL ||
61     ( file_width_table = calloc(epp->lr-epp->fr,sizeof(short)))==NULL )
62      {fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
63      fseek(f,128*swaplong(h.access_ptr),SEEK_SET);
64      fread(file_width_table,epp->lr-epp->fr,sizeof(short),f);
65      swab(file_width_table,epp->widthtable,(epp->lr-epp->fr)*sizeof(short));
66      free(file_width_table);
67   } 
68 #endif  
69   else epp->widthtable=NULL; 
70   if ((epp->packed_buffer=malloc(epp->width*4/3))==NULL)
71   { free(epp->row);if (epp->widthtable!=NULL) free(epp->widthtable);
72     fclose(f);free(epp);map_error=ME_OUT_OF_MEMORY;return NULL;}
73  epp->F=f;
74  epp->filepos=128;
75  fseek(f,128,SEEK_SET);
76  epp->currentline=epp->fr-1; 
77  epp->cache_size=0;
78  epp->cache=NULL;
79  return epp;
80 }
81 void get_epp_header(EPP* epp, EPPHEADER *h)
82 /* reads header of EPP file */
83 {
84 #ifndef LSB_FIRST
85  EPPHEADER file_header;
86 #endif 
87  fseek(epp->F,0L,SEEK_SET);
88 #ifdef LSB_FIRST
89  fread(h,1,128,epp->F);
90 #else
91  fread(&file_header,1,128,epp->F);
92  swab(&file_header,h,64);
93  memcpy(&(h->area_unit),&(file_header.area_unit),64);
94  h->fry=swapdouble(file_header.fry); 
95  h->lry=swapdouble(file_header.lry); 
96  h->fcx=swapdouble(file_header.fcx); 
97  h->lcx=swapdouble(file_header.lcx); 
98  h->sfact=swapdouble(file_header.sfact);
99  h->access_ptr=swaplong(file_header.access_ptr);  
100 #endif  
101  fseek(epp->F,epp->filepos,SEEK_SET);
102 }
103
104 char *getcomment(EPP *epp)
105 /* returns comment of EPP file (address of static buffer,which would be
106    overriden by next call */
107 {static char cmt[33];
108  char *endptr;
109  EPPHEADER h;
110  get_epp_header(epp,&h);
111  strncpy(cmt,h.comment,32);
112  cmt[32]='\0';
113  for(endptr=cmt+31;endptr>=cmt&&*endptr==' ';endptr--);
114  *(++endptr)='\0';
115  return cmt;
116 }
117
118 unsigned short int *epp_getline(EPP *epp,int x,int y)
119 /* returns pointer to array of integer, which represents line y of raster,
120    starting from col x. NULL if x<fr */
121
122   map_error=0;
123   if (!epp_contains(epp,x,y)) {map_error=ME_POINT_OUTSIDE; return NULL;}
124   if (!(epp->mode&MAP_INPUT)){map_error=ME_INVALID_MODE; return NULL;}
125   if (epp->currentline!=y)
126    { epp->position(epp,y);
127      if (map_error) return NULL;
128    }
129   return epp->row+(x-epp->fc);
130 }
131
132 int  epp_get(EPP *epp,int x,int y)
133 /* returns value of given cell, offsite if cell is outside file boundaries */
134 { map_error=0;
135   if (!(epp->mode&MAP_INPUT)){map_error=ME_INVALID_MODE; return epp->offsite;}
136   if (!epp_contains(epp,x,y)) {map_error=ME_POINT_OUTSIDE; return epp->offsite;}
137   if (epp->currentline!=y) 
138     { 
139       epp->position(epp,y);
140       if (map_error) return epp->offsite;
141     }
142   return epp->row[x-epp->fc];
143 }
144 int epp_contains(EPP *epp,int x,int y)
145 /* returns non-zero if <x,y> is within boundares of epp */
146 {
147  return (x<epp->lc)&&(x>=epp->fc)&&(y<epp->lr)&&(y>=epp->fr);
148 }
149 void close_epp(EPP *epp)
150
151   if (epp->mode==MAP_OUTPUT) update_header(epp);
152   if (epp->mode&MAP_CACHED)  free_cache(epp);
153   if (epp->mode&MAP_LOADED)
154   { char **row=epp->cache;
155     int i;
156     for(i=epp->fr;i<epp->lr;i++,row++) free(*row);
157     free(epp->cache); 
158   }
159   free(epp->packed_buffer);
160   fclose(epp->F);
161   free(epp->row);
162   if (epp->widthtable!=NULL) free (epp->widthtable);
163   free(epp);
164 }
165 /*********** coordinate recalculation **********/
166 int epp_row(EPP *epp,double y)/* returns row by given alternate y */
167 {
168  return floor((y-epp->YTop)/(epp->YBottom-epp->YTop)*(epp->lr-epp->fr))+epp->fr;
169
170 }
171 int epp_col(EPP *epp,double x)/* returns col for given alternate x */
172 {
173 return floor((x-epp->XLeft)/(epp->XRight-epp->XLeft)*(epp->lc-epp->fc))+epp->fc;
174 }
175 double alt_x(EPP *epp,int col)/* returns alternate x for given col */
176 {
177 return (epp->XRight-epp->XLeft)*(col-epp->fc)/(epp->lc-epp->fc)+epp->XLeft;
178 }
179 double alt_y(EPP *epp,int row)/* returns alternate y for given row */
180 {
181 return (epp->YBottom-epp->YTop)*(row-epp->fr)/(epp->lr-epp->fr)+epp->YTop;
182 }
183 double alt_xc(EPP *epp,int col)/* returns alternate x for given col */
184 {
185 return (epp->XRight-epp->XLeft)*(col-epp->fc+0.5)/(epp->lc-epp->fc)+epp->XLeft;
186 }
187 double alt_yc(EPP *epp,int row)/* returns alternate y for given row */
188 {
189 return (epp->YBottom-epp->YTop)*(row-epp->fr+0.5)/(epp->lr-epp->fr)+epp->YTop;
190 }
191 /**** this was private in pascal version ********/
192 void position_input(EPP *epp,int row)
193 {  int i,offset;
194    if (epp->currentline==row) return;
195    if (epp->currentline+1!=row)
196    {
197       if (epp->widthtable==NULL)
198       {
199          if (row>epp->currentline)
200             for(i=epp->currentline+1;i<=row;i++) get_row(epp);
201          else
202          {  fseek(epp->F,128L,SEEK_SET);
203             epp->filepos=128;
204             epp->currentline=epp->fr-1;
205             for(i=epp->fr;i<row;i++) get_row(epp);
206          }
207       }
208       else
209       {  offset=128L;
210          for (i=0;i<row-epp->fr;offset+=epp->widthtable[i++]);
211          fseek(epp->F,offset,SEEK_SET);
212          epp->filepos=offset;
213          epp->currentline=--row;
214       }
215    }
216    get_row(epp);
217
218    }
219                
220 void unpack_row(unsigned char *row,int *bufpos,EPP *epp)
221 {register unsigned char a,c,*r,*src;
222  int i,k;  
223  i=0;
224  r=row;
225  src=epp->packed_buffer+(*bufpos);
226  do {
227       c=*(src++);
228  if (c)
229   {
230     a=*(src++);
231     if (c+i>epp->width) c=epp->width-i+1;
232     for(k=0;k<c;k++,r+=2,i++)
233      *r=a;
234   }
235  else
236   {
237     c=*(src++);
238     if (c+i>epp->width) c=epp->width-i+1;
239     for(k=0;k<c;k++,r+=2,i++)
240       { *r=*(src++); }
241   }
242  } while (i<(epp->width-1));
243  *bufpos=src-(epp->packed_buffer);
244 }
245 int unpack_buffer(EPP *epp)
246 { unsigned short *r;
247   int i;
248   int bufpos=0;
249   if (epp->kind==8)
250         for(i=0,r=epp->row;i<epp->width;*(r++)=0,i++);
251 #ifdef LSB_FIRST
252  unpack_row((unsigned char *)epp->row,&bufpos,epp);
253  if (epp->kind==16)
254     unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
255 #else
256  unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
257  if (epp->kind==16)
258    unpack_row((unsigned char *)epp->row,&bufpos,epp);
259 #endif
260   return bufpos; 
261 }  
262 void get_row(EPP *epp)/* reads and unpacks row of epp file */
263 {
264  
265  if  (!(epp->mode & MAP_INPUT)) {map_error=ME_INVALID_MODE;return; }
266  epp->currentline++;
267  fread(epp->packed_buffer,epp->widthtable?
268          epp->widthtable[epp->currentline-epp->fr]:epp->width*4/3,1,epp->F);
269  epp->filepos+=unpack_buffer(epp);        
270  if (!epp->widthtable)
271  { 
272    fseek(epp->F,epp->filepos,SEEK_SET);
273  }
274 }