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 */
12 f=fopen(pathname,"rb");
13 if (f==NULL) {map_error=ME_NO_FILE;return NULL;}
19 EPP *fopen_epp(FILE* f)
24 short *file_width_table;
27 if (fread(&h,1,128,f)<128) {fclose(f);map_error=ME_INVALID_FILE;return NULL;};
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;}
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))
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);
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);
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;}
75 fseek(f,128,SEEK_SET);
76 epp->currentline=epp->fr-1;
81 void get_epp_header(EPP* epp, EPPHEADER *h)
82 /* reads header of EPP file */
85 EPPHEADER file_header;
87 fseek(epp->F,0L,SEEK_SET);
89 fread(h,1,128,epp->F);
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);
101 fseek(epp->F,epp->filepos,SEEK_SET);
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];
110 get_epp_header(epp,&h);
111 strncpy(cmt,h.comment,32);
113 for(endptr=cmt+31;endptr>=cmt&&*endptr==' ';endptr--);
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 */
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;
129 return epp->row+(x-epp->fc);
132 int epp_get(EPP *epp,int x,int y)
133 /* returns value of given cell, offsite if cell is outside file boundaries */
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)
139 epp->position(epp,y);
140 if (map_error) return epp->offsite;
142 return epp->row[x-epp->fc];
144 int epp_contains(EPP *epp,int x,int y)
145 /* returns non-zero if <x,y> is within boundares of epp */
147 return (x<epp->lc)&&(x>=epp->fc)&&(y<epp->lr)&&(y>=epp->fr);
149 void close_epp(EPP *epp)
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;
156 for(i=epp->fr;i<epp->lr;i++,row++) free(*row);
159 free(epp->packed_buffer);
162 if (epp->widthtable!=NULL) free (epp->widthtable);
165 /*********** coordinate recalculation **********/
166 int epp_row(EPP *epp,double y)/* returns row by given alternate y */
168 return floor((y-epp->YTop)/(epp->YBottom-epp->YTop)*(epp->lr-epp->fr))+epp->fr;
171 int epp_col(EPP *epp,double x)/* returns col for given alternate x */
173 return floor((x-epp->XLeft)/(epp->XRight-epp->XLeft)*(epp->lc-epp->fc))+epp->fc;
175 double alt_x(EPP *epp,int col)/* returns alternate x for given col */
177 return (epp->XRight-epp->XLeft)*(col-epp->fc)/(epp->lc-epp->fc)+epp->XLeft;
179 double alt_y(EPP *epp,int row)/* returns alternate y for given row */
181 return (epp->YBottom-epp->YTop)*(row-epp->fr)/(epp->lr-epp->fr)+epp->YTop;
183 double alt_xc(EPP *epp,int col)/* returns alternate x for given col */
185 return (epp->XRight-epp->XLeft)*(col-epp->fc+0.5)/(epp->lc-epp->fc)+epp->XLeft;
187 double alt_yc(EPP *epp,int row)/* returns alternate y for given row */
189 return (epp->YBottom-epp->YTop)*(row-epp->fr+0.5)/(epp->lr-epp->fr)+epp->YTop;
191 /**** this was private in pascal version ********/
192 void position_input(EPP *epp,int row)
194 if (epp->currentline==row) return;
195 if (epp->currentline+1!=row)
197 if (epp->widthtable==NULL)
199 if (row>epp->currentline)
200 for(i=epp->currentline+1;i<=row;i++) get_row(epp);
202 { fseek(epp->F,128L,SEEK_SET);
204 epp->currentline=epp->fr-1;
205 for(i=epp->fr;i<row;i++) get_row(epp);
210 for (i=0;i<row-epp->fr;offset+=epp->widthtable[i++]);
211 fseek(epp->F,offset,SEEK_SET);
213 epp->currentline=--row;
220 void unpack_row(unsigned char *row,int *bufpos,EPP *epp)
221 {register unsigned char a,c,*r,*src;
225 src=epp->packed_buffer+(*bufpos);
231 if (c+i>epp->width) c=epp->width-i+1;
232 for(k=0;k<c;k++,r+=2,i++)
238 if (c+i>epp->width) c=epp->width-i+1;
239 for(k=0;k<c;k++,r+=2,i++)
242 } while (i<(epp->width-1));
243 *bufpos=src-(epp->packed_buffer);
245 int unpack_buffer(EPP *epp)
250 for(i=0,r=epp->row;i<epp->width;*(r++)=0,i++);
252 unpack_row((unsigned char *)epp->row,&bufpos,epp);
254 unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
256 unpack_row(((unsigned char *)epp->row)+1,&bufpos,epp);
258 unpack_row((unsigned char *)epp->row,&bufpos,epp);
262 void get_row(EPP *epp)/* reads and unpacks row of epp file */
265 if (!(epp->mode & MAP_INPUT)) {map_error=ME_INVALID_MODE;return; }
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)
272 fseek(epp->F,epp->filepos,SEEK_SET);