~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina4/src/file/avs/avs_io.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* avs_io.c */
  2 /* James S Perrin Time-stamp: <Tuesday 25/07/00 11:06:00 zzcgujp> */
  3 /* read/write avs uniform field binary files */
  4 /* the header and data are written to separate files xxxx.fld and xxx.dat */
  5 /* for sequences write 3D field (2D if only one image) */
  6 /* for images write 2D field though AVS does have a v.simple image format it is not suitable */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <string.h>
 10 
 11 #include "avs.h"
 12 #include "tina/sys.h"
 13 #include "tina/sysfuncs.h"
 14 #include "tina/image.h"
 15 #include "tina/seqoral.h"
 16 
 17 #define DEBUG
 18 
 19 /* header files in tina are crap so do decl myself */
 20 extern Bool fread_imrect_data(const Imrect * imrect, FILE * stream, const char *pathname);
 21 extern Bool fwrite_imrect_data(const Imrect * imrect, FILE * stream, const char *pathname);
 22 
 23 static char *avs_data_out[] = { "byte", "byte", "short", "short",  "integer", "integer",  "float", "double" };
 24 /* AVS doesn't defined signedness of types */
 25 static char *avs_data_in[] = { "", "byte", "", "short",  "integer", "",  "float", "double" };
 26 static char avs_ndata = 8;
 27  char avs_end_head[3] = "\f\f";
 28 
 29 typedef struct _avs_header {
 30   int ndim;
 31   int dim1, dim2, dim3; /* assume we'll only deal with <= 3D data in Tina */
 32   int datatype; /* im.vtype */
 33   int filetype; /* 0 bin, 1 ascii */
 34   int skip;
 35   char dataname[512]; /* name of the file containg the data, NULL otherwise */
 36 } avs_header;
 37 
 38 /* internal functions */
 39 int avs_read_header(FILE *fp, avs_header *header)
 40 {
 41   int i,j;
 42   char buffer[256], *tok, *tmp;
 43   int buffer_size = 255;
 44   
 45   char *avs_keys[] = { "ndim", "dim1", "dim2", "dim3", "nspace",
 46                       "veclen", "data", "field", "variable", "#", "label", "unit" };
 47   const int avs_nkeys = 10;
 48   char *avs_format_keys[] = { "file", "filetype", "skip", "offset", "stride" };
 49   char avs_format_nkeys = 5;
 50   
 51   char filename_data[512], dirname_tmp[512], *filetype_str="rb";
 52   int nspace, veclen=1, offset=0, stride=1, data=4;
 53 
 54   /* is this an AVS field file? */
 55   tmp = fgets(buffer, buffer_size, fp);
 56   
 57   if(!tmp || strncmp(buffer, "# AVS field file", 16))
 58   {
 59     errorf(non_fatal, "File is not an AVS file\n");
 60     fclose(fp);
 61     return 0;
 62   }
 63 
 64   /* set defaults */
 65   header->dataname[0]='\0';
 66   header->skip=0;
 67   header->filetype=0;
 68   header->datatype=4;
 69   
 70   /* parse rest of header */
 71   tmp = fgets(buffer, buffer_size, fp);
 72 
 73   while(tmp && strncmp(tmp, avs_end_head, 2))
 74   {
 75     /* find avs keyword */
 76     tok = strtok(buffer, " =\n\t");
 77 
 78     if(tok) /* not a blank line */
 79     {
 80       for(i=0; i<avs_nkeys; i++)
 81       {
 82         if(!strcmp(avs_keys[i], tok))
 83           break;
 84       }
 85 
 86       switch(i)
 87       {
 88       case 0: /* ndim */
 89         header->ndim = atoi(strtok(NULL, " =\n\t"));
 90       
 91         if(header->ndim<2)
 92         {
 93           errorf(non_fatal, "AVS file must have 2D or 3D data\n");
 94           fclose(fp);
 95           return 0;
 96         }
 97         break;
 98       case 1: /* dim1 */
 99         header->dim1 = atoi(strtok(NULL, " =\n\t"));
100         break;
101       case 2: /* dim2 */
102         header->dim2 = atoi(strtok(NULL, " =\n\t"));
103         break;
104       case 3: /* dim3 */
105         header->dim3 = atoi(strtok(NULL, " =\n\t"));
106         break;
107       case 4: /* nspace */
108         nspace = atoi(strtok(NULL, " =\n\t"));
109         break;
110       case 5: /* veclen */
111         /* if not scalar only first value will be read */
112         veclen = atoi(strtok(NULL, " =\n\t"));
113         if(veclen!=1)
114           errorf(non_fatal, "AVS file must should scalar data\n");
115       
116         break;
117       case 6: /* data */
118         tok = strtok(NULL, " =\n\t");
119         
120         for(data=0; data<avs_ndata; data++)
121         {
122           if(!strcmp(avs_data_in[data], tok))
123             break;
124         }
125 
126         if(data==avs_ndata)
127         {
128           errorf(non_fatal, "AVS file data type not recognised\n");
129           fclose(fp);
130           return 0;
131         }
132         
133         header->datatype = data;
134         break;
135       case 7: /* field */
136         if(strcmp("uniform", strtok(NULL, " =\n\t")) )
137         {
138           errorf(non_fatal, "AVS file must have uniform data\n");
139           fclose(fp);
140           return 0;
141         }
142       
143         break;
144       case 8: /* variable */
145         if(atoi(strtok(NULL, " ="))!=1)
146           errorf(non_fatal, "AVS file should contain scalar data\nignoring other values\n");
147         else {
148           while(tok = strtok(NULL, " =\n\t"))
149           {
150             for(j=0; j<avs_format_nkeys; j++)
151             {
152               if(!strcmp(avs_format_keys[j], tok))
153                 break;
154             }
155         
156             switch(j)
157             {
158             case 0: /* file */
159               strcpy(header->dataname, strtok(NULL, " =\n\t"));
160               break;
161             case 1: /* filetype */
162               if(!strcmp("binary",strtok(NULL, " =\n\t")) )
163               {
164                 header->filetype = 0;
165                 filetype_str="rb";
166               } else {
167                 header->filetype = 1;
168                 filetype_str="r";
169                 errorf(non_fatal, "AVS reader can only handle binary data at the moment\n");
170                 fclose(fp);
171                 return 0;
172               }
173               break;
174             case 2: /* skip */
175               header->skip = atoi(strtok(NULL, " =\n\t"));
176               break;
177             case 3: /* offset */
178               offset = atoi(strtok(NULL, " =\n\t"));
179               break;
180             case 4: /* stride */
181               stride = atoi(strtok(NULL, " =\n\t"));
182               if(stride!=1)
183               {
184                 errorf(non_fatal, "AVS reader can only handle stride=1 at the moment\n");
185                 fclose(fp);
186                 return 0;
187               }
188               break;
189             }   
190           } /* while */
191         
192         }
193         break;
194       
195       case 9: /* # */
196       case 10: /* label */
197       case 11: /* unit */
198         /* do nothing */
199         break;
200       default:
201         errorf(non_fatal, "Invalid keyword in AVS file: %s\n", tok);
202       }
203       
204     } /* not a blank line */
205     
206     /* next line */
207     tmp = fgets(buffer, buffer_size, fp);
208   } /* while */
209   
210 #ifdef DEBUG
211   /* print header */
212   printf("ndim %d dim1 %d dim2 %d dim3 %d\n", header->ndim, header->dim1, header->dim2, header->dim3);
213   printf("nspace %d veclen %d data %s\n", nspace, veclen, avs_data_in[header->datatype]);
214   printf("filetype %d skip %d offset %d stride %d\n", header->filetype, header->skip, offset, stride);
215 #endif
216 
217   return 1;
218 }
219 
220 int avs_write_header(FILE *fp, avs_header *header)
221 {
222   fprintf(fp, "# AVS field file\n");
223   fprintf(fp, "# Output generated by Tina\n");
224   fprintf(fp, "ndim = %d\n", header->ndim);
225   fprintf(fp, "dim1 = %d\n", header->dim1);
226   fprintf(fp, "dim2 = %d\n",  header->dim2);
227   if(header->ndim==3) fprintf(fp, "dim3 = %d\n", header->dim3);
228   fprintf(fp, "nspace = %d\n", header->ndim);
229   fprintf(fp, "veclen = 1\n");
230 
231   if(header->datatype>= avs_ndata || *avs_data_out[header->datatype] == '\0')
232   {
233     errorf(non_fatal, "AVS files don't support current datatype %d\n", header->datatype);
234     return 0;
235   }
236   
237   fprintf(fp, "data = %s\n", avs_data_out[header->datatype]);
238   fprintf(fp, "field = uniform\n\n");
239   fprintf(fp, "variable 1 file = %s filetype = binary\n", header->dataname);
240   fprintf(fp, "\f\f");
241 
242   return 1;
243 }
244 
245 
246 Imrect *avs_read_volume(Sequence *seq)
247 {
248   FILE *fp;
249   int i, j;
250   char buffer[256], *tok, *tmp;
251   int buffer_size = 255;
252   
253   char filename_data[512], dirname_tmp[512], *filetype_str[]={"rb","r"};
254   avs_header header;
255 
256   Imrect *im = NULL;
257   Imregion *roi = NULL;
258   
259   filename_data[0]='\0';
260 
261   fp = fopen(seq->filename, "rb");
262 
263   if(!fp)
264   {
265     /* seq->filename is [512] */
266     strcat(seq->filename, ".fld");
267     fp = fopen(seq->filename, "rb");
268     
269     if(!fp)
270     {
271       errorf(non_fatal, "Couldn't open AVS file: %s\n", seq->filename);
272       return NULL;
273     }
274   }
275 
276   /* parse header */
277   avs_read_header(fp, &header);
278   if(header.ndim == 2) header.dim3 = 1;
279 
280   /* fill in seq */
281   seq->seq_start = 0;
282   seq->seq_end = header.dim3 - 1;
283   
284   /* redirect input from new file if necessary */
285   if(header.dataname != NULL)
286   {
287     fclose(fp);
288 
289     if(header.dataname[0]!='/')
290     {
291       char *slash;
292       strcpy(dirname_tmp, seq->filename);
293       
294       if ((slash = strrchr(dirname_tmp, '/')))
295         *(++slash) = '\0';
296       else
297         (void) strcpy(dirname_tmp, "./");
298 
299       strcat(dirname_tmp, header.dataname);
300       strcpy(filename_data, dirname_tmp);
301     }
302     
303     fp = fopen(filename_data, filetype_str[header.filetype]);
304     
305     if(!fp)
306     {
307       errorf(non_fatal, "Can't open AVS data file: %s\n", filename_data);
308       im_free(im);
309       fclose(fp);
310       return NULL;
311     }
312   } else { /* repostion file ptr due to over reading of \f\f */
313     if(strncmp(tmp, avs_end_head, 2)==0)
314     {
315       int len;
316 
317       len = strlen(tmp);
318       fseek(fp, 2 - len, SEEK_CUR);
319     }
320   }
321   
322   /* skip lines/bytes */
323   if(header.skip)
324   {
325     if(header.filetype==0)
326       for(j=0; j<header.skip; j++)
327         getc(fp);
328     else
329       for(j=0; j<header.skip; j++)
330         fgets(buffer, buffer_size, fp);
331   }
332     
333   /* read in data as a series of images */
334   for(i=0; i<header.dim3; i++)
335   {
336     roi = roi_alloc(0, 0, header.dim1, header.dim2);
337     im = im_alloc(header.dim2, header.dim1, roi, (Vartype)header.datatype);
338     rfree((void *) roi);
339 
340 
341     if (!fread_imrect_data(im, fp, filename_data))
342     {
343       im_free(im);
344       im = NULL;
345     }
346    
347     set_frame_no(im, i);
348     frame_insert(im, seq);
349     /*    if (prop_get(im->props,VOXELS)!=NULL)
350           iscale = (Vec3 *)prop_get(im->props,VOXELS);*/
351   }
352   
353   fclose(fp);
354   
355   return im;
356 }
357 
358 
359 Bool avs_write_volume(Sequence *seq, List *store)
360 {
361   FILE *fp;
362   int i;
363   char headname[512], dataname[512], *slash;
364   avs_header header;
365 
366   Imrect *im;
367   Imregion *roi;
368 
369   sprintf(headname, "%s.fld", seq->filename);
370   sprintf(dataname, "%s.dat", seq->filename);
371   
372   fp = fopen(headname, "w");
373 
374   if(!fp)
375   {
376     errorf(non_fatal, "Can't open AVS header file: %s\n", headname);
377     return 0;
378   }
379   
380   /* write header */
381   im = store->to;
382   roi = im->region;
383   header.dim1 = roi->ux - roi->lx;
384   header.dim2 = roi->uy - roi->ly;
385   header.dim3 = seq->seq_end - seq->seq_start +1;
386 
387   if(header.dim3>1)
388     header.ndim = 3;
389   else
390     header.ndim = 2;
391   
392   header.datatype = im->vtype;
393   
394   /* we want to write the .dat file relative to the .fld */
395   if ((slash = strrchr(dataname, '/')))
396      strcpy(header.dataname, ++slash);
397   else
398     strcpy(header.dataname, dataname);
399   
400   avs_write_header(fp, &header);
401   fclose(fp);
402 
403   /* store holds the images in reverse order Grrr! */
404   /* find end of lis and go through it backwards */
405   while(store->next!=NULL)
406     store = store->next;
407   
408   /* write data */
409   fp = fopen(dataname, "wb");
410 
411   if(!fp)
412   {
413     errorf(non_fatal, "Can't open AVS data file: %s\n", dataname);
414     return 0;
415   }
416   
417   for(i=0; i<header.dim3; i++)
418   {    
419     im = store->to;
420 
421     if ((store != NULL) && (store->to != NULL))
422     {
423       if(!fwrite_imrect_data(im, fp, dataname))
424       {
425         errorf(non_fatal, "Can't write data to AVS file: %s\n", dataname);
426         fclose(fp);
427         return 0;
428       }
429     } else {
430       errorf(non_fatal, "Can't write image %d to AVS file: %s\n", i, dataname);
431       fclose(fp);
432       return 0;
433     }
434 
435     store = store->last; /* backwards ! */
436   }
437 
438   fclose(fp);
439 
440   return 1;
441 }
442 
443 
444 Imrect *avs_read_image(char *filename)
445 {
446   FILE *fp;
447   int i, j;
448   char buffer[256], *tok, *tmp;
449   int buffer_size = 255;
450   
451   char filename_head[512], filename_data[512], dirname_tmp[512], *filetype_str[]={"rb", "r"};
452   avs_header header;
453 
454   Imrect *im = NULL;
455   Imregion *roi = NULL;
456 
457   strcpy(filename_head, filename);
458   filename_data[0]='\0';
459 
460   fp = fopen(filename, "rb");
461 
462   if(!fp)
463   {
464     /* !!! */
465     strcat(filename_head, ".fld");
466     fp = fopen(filename_head, "rb");
467     
468     if(!fp)
469     {
470       errorf(non_fatal, "Couldn't open AVS file: %s\n", filename);
471       return NULL;
472     }
473   }
474 
475   /* parse header */
476   avs_read_header(fp, &header);
477   
478   if(header.ndim == 3)
479       errorf(non_fatal, "Warning AVS file contains 3D data\nonly first slice will be read\n");
480 
481   /* redirect input from new file if necessary */
482   if(header.dataname != NULL)
483   {
484     fclose(fp);
485 
486     if(header.dataname[0]!='/')
487     {
488       char *slash;
489       strcpy(dirname_tmp, filename_head);
490       
491       if ((slash = strrchr(dirname_tmp, '/')))
492         *(++slash) = '\0';
493       else
494         (void) strcpy(dirname_tmp, "./");
495 
496       strcat(dirname_tmp, header.dataname);
497       strcpy(filename_data, dirname_tmp);
498     }
499     
500     fp = fopen(filename_data, filetype_str[header.filetype]);
501     
502     if(!fp)
503     {
504       errorf(non_fatal, "Can't open AVS data file: %s\n", filename_data);
505       im_free(im);
506       fclose(fp);
507       return NULL;
508     }
509   } else { /* repostion file ptr due to over reading of \f\f */
510     if(strncmp(tmp, avs_end_head, 2)==0)
511     {
512       int len;
513 
514       len = strlen(tmp);
515       fseek(fp, 2 - len, SEEK_CUR);
516     }
517   }
518   
519   /* skip lines/bytes */
520   if(header.skip)
521   {
522     if(header.filetype==0)
523       for(j=0; j<header.skip; j++)
524         getc(fp);
525     else
526       for(j=0; j<header.skip; j++)
527         fgets(buffer, buffer_size, fp);
528   }
529     
530   /* read in data */
531   roi = roi_alloc(0, 0, header.dim1, header.dim2);
532   im = im_alloc(header.dim2, header.dim1, roi, (Vartype)header.datatype);
533   rfree((void *) roi);
534   
535   if (!fread_imrect_data(im, fp, filename_data))
536   {
537     im_free(im);
538     im = NULL;
539   }
540   
541   fclose(fp);
542   
543   return im;
544 }
545 
546 
547 Bool avs_write_image(char *filename, Imrect *im)
548 {
549   FILE *fp;
550   int i;
551   char headname[512], dataname[512], *slash;
552   avs_header header;
553 
554   Imregion *roi;
555 
556   sprintf(headname, "%s.fld", filename);
557   sprintf(dataname, "%s.dat", filename);
558   
559   fp = fopen(headname, "w");
560 
561   if(!fp)
562   {
563     errorf(non_fatal, "Can't open AVS file: %s\n", filename);
564     return 0;
565   }
566 
567   /* write header */
568   roi = im->region;
569   header.ndim = 2;
570   header.dim1 = roi->ux - roi->lx;
571   header.dim2 = roi->uy - roi->ly;
572   header.datatype = im->vtype;
573   
574   /* we want to write the .dat file relative to the .fld */
575   if ((slash = strrchr(dataname, '/')))
576      strcpy(header.dataname, ++slash);
577   else
578     strcpy(header.dataname, dataname);
579       
580   avs_write_header(fp, &header);
581   fclose(fp);
582   
583   /* write data */
584   fp = fopen(dataname, "wb");
585   if(!fp)
586   {
587     errorf(non_fatal, "Can't open AVS data file: %s\n", dataname);
588     return 0;
589   }
590   
591   if(!fwrite_imrect_data(im, fp, dataname))
592   {
593     errorf(non_fatal, "Can't write data to AVS file: %s\n", dataname);
594     fclose(fp);
595     return 0;
596   }
597   
598   fclose(fp);
599 
600   return 1;
601 }
602 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.