root/tags/rel-5-0-2/mapserver/epplib.c

Revision 6428, 10.1 kB (checked in by dmorissette, 1 year ago)

Added missing line at end of license text

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /******************************************************************************
2  *
3  * Project:  MapServer
4  * Purpose:  Low level EPP file access, supports drawEPP() in mapraster.c.
5  * Author:   Steve Lime and the MapServer team.
6  *
7  ******************************************************************************
8  * Copyright (c) 1996-2005 Regents of the University of Minnesota.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies of this Software or works derived from this Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "epplib.h"
34 #include "mapserver.h"
35
36 MS_CVSID("$Id$")
37
38 static int REVERSE; /* set to 1 on bigendian machines */
39
40 void swap2(short *x, int count)
41 {
42   int n;
43   char tmp;
44   for (n=0; n<count; n++) {
45     tmp=*(char *)x;
46     *(char *)x=*(((char *)x)+1);
47     *(((char *)x)+1)=tmp;
48     x++;
49   }
50 }
51
52 void swap4(long *x, int count)
53 {
54   int n;
55   char tmp;
56   for (n=0; n<count; n++) {
57     tmp=*(char *)x;
58     *(char *)x=*(((char *)x)+3);
59     *(((char *)x)+3)=tmp;
60     tmp=*(((char *)x)+1);
61     *(((char *)x)+1)=*(((char *)x)+2);
62     *(((char *)x)+2)=tmp;
63     x++;
64   }
65 }
66
67 void swap8(double *x, int count)
68 {
69   int n;
70   char tmp;
71   for (n=0; n<count; n++) {
72     tmp=*(char *)x;
73     *(char *)x=*(((char *)x)+7);
74     *(((char *)x)+7)=tmp;
75     tmp=*(((char *)x)+1);
76     *(((char *)x)+1)=*(((char *)x)+6);
77     *(((char *)x)+6)=tmp;
78     tmp=*(((char *)x)+2);
79     *(((char *)x)+2)=*(((char *)x)+5);
80     *(((char *)x)+5)=tmp;
81     tmp=*(((char *)x)+3);
82     *(((char *)x)+3)=*(((char *)x)+4);
83     *(((char *)x)+4)=tmp;
84     x++;
85   }
86 }
87
88 static char getrow(eppfile *epp,rowptr buff)
89 {
90   rowptr rp;
91   char *cp;
92   int col,ncol,nc,n,v;
93   ncol=epp->lc-epp->fc+1;
94   rp=buff+1;
95   for (col=0; col<ncol; col+=nc) {
96     if (epp->fp-epp->fptr>4095) {
97       memcpy(epp->fptr,epp->fptr+4096,256);
98       epp->fp-=4096;
99       nc=fread(epp->fptr+256,1,4096,epp->fil);
100       /* eof check ?? */
101       }
102     nc=*epp->fp++;
103     if (nc!=0) {
104       v=*epp->fp++;
105       for (n=0; n<nc; n++) *rp++=v;
106     } else {
107       nc=*epp->fp++;
108       for (n=0; n<nc; n++) *rp++=*epp->fp++;
109     }
110   }
111   if (epp->kind==16 && col==ncol) {
112     if (REVERSE) cp=((char *)(epp->rptr+1))+2;  /* pick up high half */
113     else cp=((char *)(epp->rptr+1))+3;
114     for (col=0; col<ncol; col+=nc) {
115       if (epp->fp-epp->fptr>4095) {
116         memcpy(epp->fptr,epp->fptr+4096,256);
117         epp->fp-=4096;
118         nc=fread(epp->fptr+256,1,4096,epp->fil);
119         /* eof check ?? */
120         }
121       nc=*epp->fp++;
122       if (nc!=0) {
123         v=*epp->fp++;
124         for (n=0; n<nc; n++) {
125           *cp=v;
126           cp+=4;
127         }
128       } else {
129         nc=*epp->fp++;
130         for (n=0; n<nc; n++) {
131           *cp=*epp->fp++;
132           cp+=4;
133         }
134       }
135     }
136   }
137   return (ncol==col);
138 }
139
140 char get_row(eppfile *EPP)
141 {
142 char STR1[80];
143   if (!getrow(EPP,EPP->rptr)) {
144     sprintf(STR1,"Error in reading file %s",EPP->filname);
145     msSetError(MS_IMGERR,STR1,"drawEPP()");
146     eppclose(EPP);
147     return 0;
148   }
149   EPP->row_cnt++;
150   return 1;
151 }
152
153 char eppreset(eppfile *EPP)
154 /*Open_file*/
155   int nrd;
156   char STR1[102];
157
158   { union { long i; char c[4]; } u; u.i=1; REVERSE=(u.c[0]==0); }
159   EPP->fil=fopen(EPP->filname,"rb");
160   if (EPP->fil==NULL) {
161     sprintf(STR1,"Can't open %s",EPP->filname);
162     msSetError(MS_IMGERR,STR1,"drawEPP()");
163     return 0;
164   }
165   nrd=fread(&EPP->fr,1,128,EPP->fil);
166       /*fr is start of data*/
167   if (REVERSE) {        /* fix up header on big-endian machines */
168     swap2(&EPP->fr,4);
169     swap8(&EPP->fry,4);
170     swap2((short *)&EPP->kind,4);
171     swap8(&EPP->sfactor,1);
172     swap4(&EPP->access_ptr,1);
173     swap2((short *)&EPP->minval,2);
174   }
175   if (EPP->kind!=8 && (EPP->kind!=16 || nrd!=128)) {
176     sprintf(STR1,"%s is not an EPPL file.",EPP->filname);
177     msSetError(MS_IMGERR,STR1,"drawEPP()");
178     fclose(EPP->fil);
179     return 0;
180   }
181   EPP->row_cnt=0;
182   if (EPP->kind==8 && (EPP->minval > 256 || EPP->maxval > 256)) {
183     /*old EPPL file; try to fix up*/
184     EPP->minval=0;
185     EPP->maxval=255;
186   }
187   EPP->fptr =(unsigned char *)malloc(sizeof(file_buffer));
188   nrd=fread(&EPP->fptr[384],1,3968,EPP->fil);
189       /*so we read even 4096 byte chunks*/
190   EPP->fp=EPP->fptr+384;
191   if (nrd==3968)
192     EPP->lastbyte=4096;
193   else
194     EPP->lastbyte=nrd + 384;
195   EPP->rptr =(rowptr)malloc((EPP->lc-EPP->fc+3) * sizeof(*EPP->rptr));
196   EPP->access_table=NULL;
197   return 1;
198 }
199
200 static char epprewind(eppfile *EPP)
201 {
202   if (!eppclose(EPP))
203     return 0;
204   return eppreset(EPP);
205 }
206
207 char position(eppfile *EPP,int row)
208 {
209   int r,nread;
210   long z,now;
211
212   if (EPP->access_table==NULL) {  /*first time through*/
213     EPP->access_table=(unsigned short *)malloc((EPP->lr-EPP->fr+2)*2+2);
214         /*2 bytes of extra space*/
215     EPP->saved=EPP->access_table;
216     now=ftell(EPP->fil);
217     fseek(EPP->fil,EPP->access_ptr*128,0);
218     nread=fread(EPP->access_table,1,(EPP->lr-EPP->fr+1)*2,EPP->fil);
219     if (nread!=(EPP->lr-EPP->fr+1)*2)
220           /*if not right amount,assume bad*/
221             EPP->access_ptr=0;
222     if (REVERSE) swap2((short*)EPP->access_table,EPP->lr-EPP->fr+1);
223     fseek(EPP->fil,now,0);
224   }
225   if (EPP->access_ptr==0) {  /*some kind of bad table,just count*/
226     if (row<EPP->row_cnt+EPP->fr) {
227       if (!epprewind(EPP)) return 0;
228     }
229     for (r=EPP->fr+EPP->row_cnt; r<row; r++) {
230       if (!get_row(EPP)) return 0;
231     }
232     return 1;
233   }
234   z=128;   /*header*/
235   for (r=0; r<row-EPP->fr; r++)
236     z+=EPP->access_table[r];
237   if (feof(EPP->fil) && EPP->lastbyte!=4096)
238     now=ftell(EPP->fil)-EPP->lastbyte+256;
239   else
240     now=ftell(EPP->fil)-4096;
241   if ((unsigned long)(z-now)<3840) {
242     EPP->fp=EPP->fptr+z-now+256;
243     return 1;
244   }
245   EPP->fp=EPP->fptr+(z & 127)+256;
246   fseek(EPP->fil,z & 0xffffff80,0);
247   nread=fread(&EPP->fptr[256],1,4096,EPP->fil);
248   if (nread==4096)
249     EPP->lastbyte=4096;
250   else
251     EPP->lastbyte=nread+256;
252   return 1;
253 }
254
255
256 char eppclose(eppfile *EPP)
257 {
258   char badfile,eightbit;
259
260   badfile=0;
261   eightbit=0;
262   if (EPP->access_table!=NULL) free(EPP->saved);
263   if (EPP->rptr!=NULL) free(EPP->rptr);
264   free(EPP->fptr);
265   fclose(EPP->fil);
266   return 1;
267 }
268
269 #ifdef LEGENDS
270 char legfile::reset(void)
271 {
272   char j,k;
273   long v;
274   char s[100],*s2;
275   legend *p,*p1,*p2;
276
277   root=NULL;
278   defaultleg.level=1;
279   defaultleg.npass=1;
280   memcpy(defaultleg.printchar,"    ",4);
281   defaultleg.next=NULL;
282   if (*filname=='\0') return 0;
283 #ifdef __BORLANDC__
284   _fullpath(s,filname,80);
285   strcpy(filname,s);
286 #else
287   if (*filname!='/') {
288     getcwd(s,80);
289     strcat(s,"/");
290     strcat(s,filname);
291     strcpy(filname,s);
292   }
293 #endif
294   addExt(filname,".leg",0);
295   tfil=fopen(filname,"r");
296   if (tfil==NULL) return 0;
297   while (!feof(tfil)) {
298     fgets(s,100,tfil);
299     if (strchr(s,'\n')!=NULL) *strchr(s,'\n')=0;
300     j=sscanf(s,"%ld",&v);
301     if (v<0 || j==0) continue;
302     s2=s;
303     while (*s2==' ') s2++;
304     while (*s2 && *s2!=' ') s2++;
305     while (*s2==' ') s2++;
306     p=(legend *)malloc(sizeof(legend)-255+strlen(s2));
307     strcpy(p->legtext,s2);
308     p->level=v;
309     p->npass=0;
310     memcpy(p->printchar,"    ",4);
311     if (root==NULL) {
312       root=p;
313       root->next=NULL;
314       continue;
315     }
316     p1=root;
317     while (p1!=NULL && p1->level<v) {
318       p2=p1;
319       p1=p1->next;
320     }
321     if (p1==NULL) {   /*already there,keep first line*/
322       p2->next=p;
323       p->next=NULL;
324       continue;
325     }
326     if (p1->level==v) {
327       free(p);
328       continue;
329     }
330     if (p1==root) {
331       p->next=root;
332       root=p;
333     } else {
334       p->next=p2->next;
335       p2->next=p;
336     }
337   }
338   fclose(tfil);
339   return (root!=NULL);
340
341 }
342
343
344 legend *legfile::getptr(epplev v)
345 {
346   legend *p;
347
348   p=root;
349   while (p!=NULL && p->level<v)
350     p=p->next;
351   if (p==NULL || p->level!=v) {
352     defaultleg.printchar[0]=v % 78+'0';
353     *defaultleg.legtext='\0';
354     return (&defaultleg);
355   } else
356     return p;
357 }
358
359
360 char legfile::close(void)
361 {
362   char n;
363   legend *p1,*p2;
364
365   for (n=0; n<=14; n++) if (this==open_fibs[n]) open_fibs[n]=NULL;
366   p1=root;
367   while (p1!=NULL) {
368     p2=p1->next;
369     free(p1);
370     p1=p2;
371   }
372   return 1;
373 }
374 #endif
375
376 char clrreset(clrfile *CLR)
377 {
378   int valu;
379   int n,r,g,b,sz;
380   clrTag tmp[300];
381   char STR1[80];
382
383   CLR->lastColor=0;
384   strcpy(strrchr(CLR->filname,'.'),".clr");
385   CLR->fil=fopen(CLR->filname,"r");
386   if (CLR->fil==NULL) return 0;
387   memset(tmp,0,sizeof(tmp));
388   sz=sizeof(tmp)/300;
389
390   while (!feof(CLR->fil)) {
391     fgets(STR1,80,CLR->fil);
392     sscanf(STR1,"%d%d%d%d",&valu,&r,&g,&b);
393     n=CLR->lastColor-1;
394     while (n>=0 && tmp[n].eppval>valu) {
395       tmp[n+1]=tmp[n];
396       n--;
397     }
398     if (r>=1000) r=999;
399     if (g>=1000) g=999;
400     if (b>=1000) b=999;
401     tmp[n+1].color.red=r*32/125;
402     tmp[n+1].color.green=g*32/125;
403     tmp[n+1].color.blue=b*32/125;
404     tmp[n+1].eppval=valu;
405     CLR->lastColor++;   /*?? check overflow*/
406   }
407   fclose(CLR->fil);
408   CLR->clrTbl=(clrTag *)malloc(CLR->lastColor*sz);
409   memmove(CLR->clrTbl,tmp,CLR->lastColor*sz);
410   return (CLR->lastColor!=0);
411 }
412
413
414 void clrget(clrfile *CLR,epplev n,TRGB *color)
415 {
416   int ndx;
417
418   ndx=0;   /**** use binary search for efficiency,later*/
419   while (ndx<CLR->lastColor && CLR->clrTbl[ndx].eppval<n)
420     ndx++;
421   if (ndx!=CLR->lastColor && CLR->clrTbl[ndx].eppval==n)
422   {   /*lousy choice of names*/
423     *color=CLR->clrTbl[ndx].color;
424     return;
425   }
426   color->red=0;   /*paint it black...*/
427   color->green=0;
428   color->blue=0;
429 }
430
431 char clrclose(clrfile *CLR)
432 {
433   free(CLR->clrTbl);
434   return 1;
435 }
436
Note: See TracBrowser for help on using the browser.