src/io.c

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   I/O functions for the libit library
00022   Copyright (C) 2005 Herve Jegou
00023 */
00024 
00025 #include <stdio.h>
00026 #include <assert.h>
00027 #include <string.h>
00028 #include <math.h>
00029 #include <it/vec.h>
00030 #include <it/mat.h>
00031 #include <it/io.h>
00032 #include <it/types.h>
00033 #include <it/cplx.h>
00034 #include <it/poly.h>
00035 
00036 
00037 /* Default format for vector (called by format $v)  */
00038 #define it_fmt_max_length (20)
00039 static char it_printf_vec_default_fmt[it_fmt_max_length + 1] = "%.3lf";
00040 static char it_printf_mat_default_fmt[it_fmt_max_length + 1] = "$9.3lf";
00041 
00042 
00043 /*------------------------------------------------------------------------------*/
00044 void it_set_vec_default_fmt (char *fmt)
00045 {
00046   assert (strlen (fmt) < it_fmt_max_length);
00047   strcpy (it_printf_vec_default_fmt, fmt);
00048 }
00049 
00050 
00051 /*------------------------------------------------------------------------------*/
00052 void it_set_mat_default_fmt (char *fmt)
00053 {
00054   assert (strlen (fmt) < it_fmt_max_length);
00055   strcpy (it_printf_vec_default_fmt, fmt);
00056 }
00057 
00058 
00059 /*------------------------------------------------------------------------------*/
00060 void it_printf (char *fmt, ...)
00061 {
00062   va_list ap;
00063   va_start (ap, fmt);
00064   it_vfprintf (stdout, fmt, ap);
00065   va_end (ap);
00066 }
00067 
00068 /*------------------------------------------------------------------------------*/
00069 void it_vprintf (char *fmt, va_list args)
00070 {
00071   it_vfprintf (stdout, fmt, args);
00072 }
00073 
00074 /*------------------------------------------------------------------------------*/
00075 void it_warning (char *fmt, ...)
00076 {
00077   va_list ap;
00078   va_start (ap, fmt);
00079 #if defined(__GNUC__)
00080   fprintf (stderr, "## IT Warning : %s:%d ##  ", __FILE__, __LINE__);
00081 #else
00082   fprintf (stderr, "## IT Warning ##  ");
00083 #endif
00084   it_vfprintf (stderr, fmt, ap);
00085   fprintf (stderr, "\n");
00086   va_end (ap);
00087 }
00088 
00089 
00090 /*------------------------------------------------------------------------------*/
00091 void it_error (char *fmt, ...)
00092 {
00093   va_list ap;
00094   va_start (ap, fmt);
00095 #if defined(__GNUC__)
00096   fprintf (stderr, "## IT Error : %s:%d ##  ", __FILE__, __LINE__);
00097 #else
00098   fprintf (stderr, "## IT Error ##  ");
00099 #endif
00100   it_vfprintf (stderr, fmt, ap);
00101   fprintf (stderr, "\n");
00102   va_end (ap);
00103   exit (1);
00104 }
00105 
00106 
00107 /*---------------------------------------------------------------------------*/
00108 void __it_assert (int a, const char *filename, int line, char *message)
00109 {
00110   if (!a) {
00111 
00112 #if defined(__GNUC__)
00113     fprintf (stderr, "## IT Assert : %s:%d ##  %s\n", filename, line,
00114        message);
00115 #else
00116     fprintf (stderr, "## IT Assert  ##  %s\n", message);
00117 #endif
00118     abort ();
00119   }
00120 }
00121 
00122 
00123 /*------------------------------------------------------------------------------*/
00124 void it_fprintf (FILE * output, char *fmt, ...)
00125 {
00126   va_list ap;
00127   va_start (ap, fmt);
00128   it_vfprintf (output, fmt, ap);
00129   va_end (ap);
00130 }
00131 
00132 
00133 /*------------------------------------------------------------------------------*/
00134 void it_vfprintf (FILE * output, char *fmt, va_list ap)
00135 {
00136   char fmt_opt[100];    /* A string for the format and one for the options */
00137   int  fmt_opt_len;
00138 
00139   /* Declare a variable for each kind of type that may be displayed */
00140   char c, *s;
00141   int  d;
00142   idx_t i;
00143   double f;
00144   cplx z;
00145   void *p;
00146   vec  P;
00147 
00148   vec  v;
00149   ivec iv;
00150   bvec bv;
00151   cvec cv;
00152   pvec Pv;
00153 
00154   mat  m;
00155   imat im;
00156   bmat bm;
00157   cmat cm;
00158   pmat Pm;
00159 
00160 
00161   for (; *fmt; fmt++) {
00162 
00163     /*--------------------         common display       ----------------------*/
00164     switch (*fmt) {
00165     case '%':
00166       assert (*(fmt + 1));  /* Unfinished sequence. Format string must continue. */
00167 
00168       if (*(fmt + 1) == '%') {
00169   fprintf (output, "%%");
00170   fmt++;
00171   continue;
00172       }
00173 
00174       /* Find the length of the segment consisting to the format option */
00175       fmt_opt_len = strcspn (fmt, "sdxcfgpzP");
00176 
00177 
00178       memcpy (fmt_opt, fmt, fmt_opt_len + 1);
00179       fmt_opt[fmt_opt_len + 1] = '\0';
00180       fmt = fmt + fmt_opt_len;
00181 
00182       switch (*fmt) {
00183       case 's':   /* string */
00184   s = va_arg (ap, char *);
00185   fprintf (output, fmt_opt, s);
00186   break;
00187 
00188       case 'd':   /* int */
00189   d = va_arg (ap, int);
00190   fprintf (output, fmt_opt, d);
00191   break;
00192 
00193       case 'x':   /* hexadecimal int */
00194   d = va_arg (ap, int);
00195   fprintf (output, "0x");
00196   fprintf (output, fmt_opt, d);
00197   break;
00198 
00199       case 'c':   /* char */
00200   /* need a cast here since va_arg only
00201      takes fully promoted types */
00202   c = (char) va_arg (ap, int);
00203   fprintf (output, fmt_opt, c);
00204   break;
00205 
00206       case 'f':
00207   f = va_arg (ap, double);
00208   fprintf (output, fmt_opt, f);
00209   break;
00210 
00211       case 'g':
00212   f = va_arg (ap, double);
00213   fprintf (output, fmt_opt, f);
00214   break;
00215 
00216       case 'z':   /* complex */
00217   /* This one is a particular case: there are two values to display */
00218   z = va_arg (ap, cplx);
00219   fmt_opt[strlen (fmt_opt) - 1] = 'f';
00220 
00221   if (creal (z) == 0 && cimag (z) == 0) {
00222     fprintf (output, "0");
00223     break;
00224   }
00225 
00226   if (creal (z) != 0)
00227     fprintf (output, fmt_opt, creal (z));
00228 
00229   if (cimag (z) > 0) {
00230     fprintf (output, "+");
00231     fprintf (output, fmt_opt, cimag (z));
00232     fprintf (output, "i");
00233   }
00234   else if (cimag (z) < 0) {
00235     fprintf (output, fmt_opt, cimag (z));
00236     fprintf (output, "i");
00237   }
00238   break;
00239 
00240       case 'p':
00241   p = va_arg (ap, void *);
00242   fprintf (output, fmt_opt, p);
00243   break;
00244 
00245       case 'P':   /* polynomial */
00246   P = va_arg (ap, vec);
00247 
00248   if (vec_length (P) == 0) {
00249     fprintf (output, "(0)");
00250     break;
00251   }
00252 
00253   fmt_opt[fmt_opt_len] = 'f';
00254 
00255   fprintf (output, "(");
00256   for (i = 0; i < vec_length (P) - 1; i++) {
00257     fprintf (output, fmt_opt, P[i]);
00258     if (i)
00259       fprintf (output, "*X^%d", i);
00260     fprintf (output, " + ");
00261   }
00262   fprintf (output, fmt_opt, P[i]);
00263   if (i)
00264     fprintf (output, "*X^%d", i);
00265   fprintf (output, ")");
00266   break;
00267 
00268       default:
00269   fprintf (stderr, "## it_vfprintf : unrecognized type ## ");
00270   exit (1);
00271       }
00272       break;
00273 
00274       /*--------------------         Vector display       ----------------------*/
00275     case '$':
00276       if (*(fmt + 1) == '$') {
00277   fprintf (output, "$");
00278   fmt++;
00279   continue;
00280       }
00281 
00282       /* Find the length of the segment consisting to the format option */
00283       fmt_opt_len = strcspn (fmt, "idxbfgvzP");
00284 
00285       memcpy (fmt_opt, fmt, fmt_opt_len + 1);
00286       fmt_opt[0] = '%';
00287       fmt_opt[fmt_opt_len + 1] = '\0';
00288       fmt = fmt + fmt_opt_len;
00289 
00290       switch (*fmt) {
00291       case 'v':   /* Default representation of the vector. Other format are ignored */
00292   strcpy (fmt_opt, it_printf_vec_default_fmt);
00293       case 'f':
00294       case 'g':
00295   v = va_arg (ap, vec);
00296   if (Vec_header (v).element_size != sizeof (double)) {
00297     it_warning
00298       ("Incompatible formatting type in it_fprintf. Double base type was expected\n");
00299     return;
00300   }
00301   fprintf (output, "[");
00302   for (i = 0; i < vec_length (v); i++) {
00303     it_fprintf (output, fmt_opt, v[i]);
00304     if (i < vec_length (v) - 1)
00305       fprintf (output, " ");
00306   }
00307   fprintf (output, "]");
00308   break;
00309 
00310       case 'i':
00311   fmt_opt[strlen (fmt_opt) - 1] = 'd';
00312       case 'x':
00313       case 'd':
00314   iv = va_arg (ap, ivec);
00315   if (Vec_header (iv).element_size != sizeof (int)) {
00316     it_warning
00317       ("Incompatible formatting type in it_fprintf. Integer base type was expected\n");
00318     return;
00319   }
00320   fprintf (output, "[");
00321   for (i = 0; i < ivec_length (iv); i++) {
00322     it_fprintf (output, fmt_opt, iv[i]);
00323     if (i < ivec_length (iv) - 1)
00324       fprintf (output, " ");
00325   }
00326   fprintf (output, "]");
00327   break;
00328 
00329       case 'b':
00330   fmt_opt[strlen (fmt_opt) - 1] = 'd';  /* Displayed as an integer */
00331       case 'c':
00332   bv = va_arg (ap, bvec);
00333   if (Vec_header (bv).element_size != sizeof (byte)) {
00334     it_warning
00335       ("Incompatible formatting type in it_fprintf. Byte base type was expected\n");
00336     return;
00337   }
00338   fprintf (output, "[");
00339   for (i = 0; i < bvec_length (bv); i++) {
00340     it_fprintf (output, fmt_opt, bv[i]);
00341     if (i < bvec_length (bv) - 1)
00342       fprintf (output, " ");
00343   }
00344   fprintf (output, "]");
00345   break;
00346 
00347       case 'z':
00348   cv = va_arg (ap, cvec);
00349   if (Vec_header (cv).element_size != sizeof (cplx)) {
00350     it_warning
00351       ("Incompatible formatting type in it_fprintf. Complex base type was expected\n");
00352     return;
00353   }
00354   fmt_opt[strlen (fmt_opt) - 1] = 'f';
00355   fprintf (output, "[");
00356   for (i = 0; i < cvec_length (cv); i++) {
00357     z = cv[i];
00358 
00359     if (creal (z) == 0 && cimag (z) == 0) {
00360       fprintf (output, "0");
00361     }
00362     else {
00363 
00364       if (creal (z) != 0)
00365         fprintf (output, fmt_opt, creal (z));
00366 
00367       if (cimag (z) > 0) {
00368         fprintf (output, "+");
00369         fprintf (output, fmt_opt, cimag (z));
00370         fprintf (output, "i");
00371       }
00372       else if (cimag (z) < 0) {
00373         fprintf (output, fmt_opt, cimag (z));
00374         fprintf (output, "i");
00375       }
00376     }
00377     if (i < cvec_length (cv) - 1)
00378       fprintf (output, " ");
00379   }
00380   fprintf (output, "]");
00381   break;
00382 
00383       case 'P':
00384   Pv = va_arg (ap, pvec);
00385 
00386   if (Vec_header (Pv).element_size != sizeof (vec)) {
00387     it_warning
00388       ("Incompatible formatting type in it_fprintf. Polynomial base type was expected\n");
00389     return;
00390   }
00391 
00392   fprintf (output, "[");
00393   for (i = 0; i < Vec_length (Pv); i++) {
00394     P = Pv[i];
00395 
00396     it_fprintf (output, fmt_opt, Pv[i]);
00397     if (i < Vec_length (Pv) - 1)
00398       fprintf (output, " ");
00399   }
00400   fprintf (output, "]");
00401   break;
00402 
00403       default:
00404   fprintf (stderr, "## it_vfprintf : unrecognized type ## ");
00405   exit (1);
00406       }
00407       break;
00408 
00409       /*--------------------         Matrix display       ----------------------*/
00410     case '#':
00411       if (*(fmt + 1) == '#') {
00412   fprintf (output, "#");
00413   fmt++;
00414   continue;
00415       }
00416 
00417       /* Find the length of the segment consisting to the format option */
00418       fmt_opt_len = strcspn (fmt, "idxbfgmzP");
00419 
00420       memcpy (fmt_opt, fmt, fmt_opt_len + 1);
00421       fmt_opt[0] = '$';
00422       fmt_opt[fmt_opt_len + 1] = '\0';
00423       fmt = fmt + fmt_opt_len;
00424 
00425       switch (*fmt) {
00426       case 'm':   /* Default representation of the matrix. Other format are ignored */
00427   strcpy (fmt_opt, it_printf_mat_default_fmt);
00428       case 'f':
00429       case 'g':
00430   m = va_arg (ap, mat);
00431   fprintf (output, "[");
00432   for (i = 0; i < mat_height (m); i++) {
00433     it_fprintf (output, fmt_opt, m[i]);
00434     if (i < mat_height (m) - 1)
00435       fprintf (output, "\n ");
00436   }
00437   fprintf (output, "]");
00438   break;
00439 
00440       case 'i':
00441   fmt_opt[strlen (fmt_opt) - 1] = 'd';
00442       case 'x':
00443       case 'd':
00444   im = va_arg (ap, imat);
00445   fprintf (output, "[");
00446   for (i = 0; i < imat_height (im); i++) {
00447     it_fprintf (output, fmt_opt, im[i]);
00448     if (i < imat_height (im) - 1)
00449       fprintf (output, "\n ");
00450   }
00451   fprintf (output, "]");
00452   break;
00453 
00454       case 'b':
00455   fmt_opt[strlen (fmt_opt) - 1] = 'b';  /* Displayed as integer */
00456       case 'c':
00457   bm = va_arg (ap, bmat);
00458   fprintf (output, "[");
00459   for (i = 0; i < bmat_height (bm); i++) {
00460     it_fprintf (output, fmt_opt, bm[i]);
00461     if (i < bmat_height (bm) - 1)
00462       fprintf (output, "\n ");
00463   }
00464   fprintf (output, "]");
00465   break;
00466 
00467 
00468       case 'z':
00469   cm = va_arg (ap, cmat);
00470   fprintf (output, "[");
00471   for (i = 0; i < cmat_height (cm); i++) {
00472     it_fprintf (output, fmt_opt, cm[i]);
00473     if (i < cmat_height (cm) - 1)
00474       fprintf (output, "\n ");
00475   }
00476   fprintf (output, "]");
00477   break;
00478 
00479       case 'P':
00480   Pm = va_arg (ap, pmat);
00481   fprintf (output, "[");
00482   for (i = 0; i < Mat_height (Pm); i++) {
00483     it_fprintf (output, fmt_opt, Pm[i]);
00484     if (i < Mat_height (Pm) - 1)
00485       fprintf (output, "\n ");
00486   }
00487   fprintf (output, "]");
00488   break;
00489 
00490       default:
00491   fprintf (stderr, "## it_vfprintf : unrecognized type ## ");
00492   exit (1);
00493       }
00494       break;
00495 
00496       /*---------------         Direct display       ------------------*/
00497     default:
00498       fprintf (output, "%c", *fmt);
00499     }
00500   }
00501 }
00502 
00503 
00504 /*---------------------------------------------------------------------*/
00505 char *it_read_double (char *s, double *p_val)
00506 {
00507   int  nb_char_number = strspn (s, "0123456789.e+-");
00508   int  nb_char_not_delim = strcspn (s, " ,\t\n];");
00509   char *buf;
00510 
00511   if (nb_char_number != nb_char_not_delim)
00512     it_error ("Unable to read a double in string %s\n", s);
00513 
00514   buf = (char *) malloc (nb_char_number + 1);
00515   buf[nb_char_number] = '\0';
00516   strncpy (buf, s, nb_char_number);
00517 
00518   sscanf (buf, "%lf", p_val);
00519   free (buf);
00520   return s + nb_char_not_delim;
00521 }
00522 
00523 
00524 /*---------------------------------------------------------------------*/
00525 char *it_read_float (char *s, float *p_val)
00526 {
00527   int  nb_char_number = strspn (s, "0123456789.e+-");
00528   int  nb_char_not_delim = strcspn (s, " ,\t\n];");
00529   char *buf;
00530 
00531   if (nb_char_number != nb_char_not_delim)
00532     it_error ("Unable to read a float in string %s\n", s);
00533 
00534   buf = (char *) malloc (nb_char_number + 1);
00535   buf[nb_char_number] = '\0';
00536   strncpy (buf, s, nb_char_number);
00537 
00538   sscanf (buf, "%f", p_val);
00539   free (buf);
00540   return s + nb_char_not_delim;
00541 }
00542 
00543 
00544 /*---------------------------------------------------------------------*/
00545 char *it_read_cplx (char *s, cplx * p_val)
00546 {
00547   int  nb_char_number;
00548   int  nb_char_not_delim;
00549   int  read_something = 0, r;
00550   char *buf;
00551   creal (*p_val) = 0;
00552   cimag (*p_val) = 0;
00553 
00554   while (*s == ' ' || *s == '\t')
00555     s++;
00556 
00557   if (*s == '+' || *s == '-') {
00558     nb_char_number = strspn (s + 1, "0123456789.e") + 1;
00559     nb_char_not_delim = strcspn (s + 1, " ,\t\n];i+-") + 1;
00560   }
00561   else {
00562     nb_char_number = strspn (s, "0123456789.e");
00563     nb_char_not_delim = strcspn (s, " ,\t\n];i+-");
00564   }
00565 
00566   if (nb_char_number != nb_char_not_delim)
00567     it_error ("Unable to read a complex number in string %s\n", s);
00568 
00569   if (*s == 'i') {    /* Special case */
00570     nb_char_not_delim = strcspn (s + 1, " ,\t\n];");
00571     if (nb_char_not_delim)
00572       it_warning ("Something nasty occured while reading the complex %s\n",
00573       s);
00574 
00575     cimag (*p_val) = 1;
00576     return s + 1;
00577   }
00578 
00579   if (s[nb_char_not_delim] != 'i') {  /* It is the real part */
00580     buf = (char *) malloc (nb_char_number + 1);
00581     buf[nb_char_number] = '\0';
00582     strncpy (buf, s, nb_char_number);
00583     sscanf (buf, "%lf", &(creal (*p_val)));
00584     free (buf);
00585     s += nb_char_not_delim;
00586     read_something = 1;
00587 
00588     /* Ready to read the (optional) imaginary part */
00589     nb_char_number = strspn (s, "0123456789.e+-");
00590     nb_char_not_delim = strcspn (s, " ,\t\n];i");
00591   }
00592 
00593   if (s[nb_char_not_delim] == 'i') {  /* It is the complex part */
00594     buf = (char *) malloc (nb_char_number + 1);
00595     buf[nb_char_number] = '\0';
00596     strncpy (buf, s, nb_char_number);
00597     r = sscanf (buf, "%lf", &(cimag (*p_val)));
00598     if (r == 0) {   /* Bad return value for sscanf */
00599       if (*s == 'i' || (*s == '+' && s[1] == 'i'))
00600   cimag (*p_val) = 1;
00601       else if (*s == '-' && s[1] == 'i')
00602   cimag (*p_val) = -1;
00603       else
00604   it_warning
00605     ("Something wrong happened while reading the complex. Unsafe result.\n");
00606     }
00607     free (buf);
00608     s += nb_char_not_delim + 1;
00609     read_something = 1;
00610   }
00611 
00612   it_assert (read_something, "Invalid complex");
00613   return s;
00614 }
00615 
00616 
00617 /*---------------------------------------------------------------------*/
00618 char *it_read_int (char *s, int *p_val)
00619 {
00620   int  nb_char_number = strspn (s, "0123456789+-");
00621   int  nb_char_not_delim = strcspn (s, " ,\t\n];");
00622   char *buf;
00623 
00624   if (nb_char_number != nb_char_not_delim)
00625     it_error ("Bad integer numbers in string %s\n", s);
00626 
00627   buf = (char *) malloc (nb_char_number + 1);
00628   buf[nb_char_number] = '\0';
00629   strncpy (buf, s, nb_char_number);
00630 
00631   sscanf (buf, "%d", p_val);
00632   free (buf);
00633   return s + nb_char_not_delim;
00634 }
00635 
00636 
00637 /*---------------------------------------------------------------------*/
00638 char *it_read_vec (char *s, vec * v)
00639 {
00640   char *s_start, *s_end;
00641   char *s_first_b = strpbrk (s, "[");
00642   char *s_last_b = strpbrk (s, "]");
00643   char *s_first_number = strpbrk (s, "0123456789.e+-");
00644   char *s_last_semicol = strpbrk (s, "\n];");
00645   double d;
00646 
00647   if (s_first_b < s_last_semicol && s_last_b > s_last_semicol && s_first_b)
00648     return (NULL);
00649 
00650   if (s_first_b == NULL) {
00651     if (s_last_semicol == NULL)
00652       s_last_semicol = s + strlen (s);
00653 
00654     s_start = s_first_number;
00655     s_end = s_last_semicol;
00656   }
00657   else {
00658     s_start = strpbrk (s_first_b, "0123456789.e+-");
00659     s_end = s_last_b;
00660   }
00661 
00662   if (s_first_number == NULL)
00663     s_start = s_end;
00664 
00665   vec_set_length (*v, 0);
00666 
00667   for (s = s_start; s && s < s_end;) {
00668     s = it_read_double (s, &d);
00669     vec_push (*v, d);
00670     s = strpbrk (s, "0123456789.e+-");
00671   }
00672   return s_end + 1;
00673 }
00674 
00675 
00676 /*---------------------------------------------------------------------*/
00677 char *it_read_fvec (char *s, vec * v)
00678 {
00679   char *s_start, *s_end;
00680   char *s_first_b = strpbrk (s, "[");
00681   char *s_last_b = strpbrk (s, "]");
00682   char *s_first_number = strpbrk (s, "0123456789.e+-");
00683   char *s_last_semicol = strpbrk (s, "\n];");
00684   float d;
00685 
00686   if (s_first_b < s_last_semicol && s_last_b > s_last_semicol && s_first_b)
00687     return (NULL);
00688 
00689   if (s_first_b == NULL) {
00690     if (s_last_semicol == NULL)
00691       s_last_semicol = s + strlen (s);
00692 
00693     s_start = s_first_number;
00694     s_end = s_last_semicol;
00695   }
00696   else {
00697     s_start = strpbrk (s_first_b, "0123456789.e+-");
00698     s_end = s_last_b;
00699   }
00700 
00701   if (s_first_number == NULL)
00702     s_start = s_end;
00703 
00704   vec_set_length (*v, 0);
00705 
00706   for (s = s_start; s && s < s_end;) {
00707     s = it_read_float (s, &d);
00708     vec_push (*v, d);
00709     s = strpbrk (s, "0123456789.e+-");
00710   }
00711   return s_end + 1;
00712 }
00713 
00714 
00715 /*---------------------------------------------------------------------*/
00716 char *it_read_cvec (char *s, cvec * v)
00717 {
00718   char *s_start, *s_end;
00719   char *s_first_b = strpbrk (s, "[");
00720   char *s_last_b = strpbrk (s, "]");
00721   char *s_first_number = strpbrk (s, "0123456789.e+-i");
00722   char *s_last_semicol = strpbrk (s, "\n];");
00723   cplx c;
00724 
00725   if (s_first_b < s_last_semicol && s_last_b > s_last_semicol && s_first_b)
00726     return (NULL);
00727 
00728   if (s_first_b == NULL) {
00729     if (s_last_semicol == NULL)
00730       s_last_semicol = s + strlen (s);
00731 
00732     s_start = s_first_number;
00733     s_end = s_last_semicol;
00734   }
00735   else {
00736     s_start = strpbrk (s_first_b, "0123456789.e+-i");
00737     s_end = s_last_b;
00738   }
00739 
00740   if (s_first_number == NULL)
00741     s_start = s_end;
00742 
00743   cvec_set_length (*v, 0);
00744 
00745   for (s = s_start; s && s < s_end;) {
00746     s = it_read_cplx (s, &c);
00747     cvec_push (*v, c);
00748     s = strpbrk (s, "0123456789.e+-i");
00749   }
00750   return s_end + 1;
00751 }
00752 
00753 
00754 /*---------------------------------------------------------------------*/
00755 char *it_read_ivec (char *s, ivec * v)
00756 {
00757   char *s_start, *s_end;
00758   char *s_first_b = strpbrk (s, "[");
00759   char *s_last_b = strpbrk (s, "]");
00760   char *s_first_number = strpbrk (s, "0123456789+-");
00761   char *s_last_semicol = strpbrk (s, "\n];");
00762   int  d;
00763 
00764   if (s_first_b < s_last_semicol && s_last_b > s_last_semicol && s_first_b)
00765     return (NULL);
00766 
00767   if (s_first_b == NULL) {
00768     if (s_last_semicol == NULL)
00769       s_last_semicol = s + strlen (s);
00770 
00771     s_start = s_first_number;
00772     s_end = s_last_semicol;
00773   }
00774   else {
00775     s_start = strpbrk (s_first_b, "0123456789+-");
00776     s_end = s_last_b;
00777   }
00778 
00779   if (s_first_number == NULL)
00780     s_start = s_end;
00781 
00782   ivec_set_length (*v, 0);
00783 
00784   for (s = s_start; s && s < s_end;) {
00785     s = it_read_int (s, &d);
00786     ivec_push (*v, d);
00787     s = strpbrk (s, "0123456789+-");
00788   }
00789   return s_end + 1;
00790 }
00791 
00792 
00793 /*---------------------------------------------------------------------*/
00794 char *it_read_bvec (char *s, bvec * v)
00795 {
00796   char *s_start, *s_end;
00797   char *s_first_b = strpbrk (s, "[");
00798   char *s_last_b = strpbrk (s, "]");
00799   char *s_first_number = strpbrk (s, "+-0123456789");
00800   char *s_last_semicol = strpbrk (s, "\n];");
00801   int  d;
00802 
00803   if (s_first_b < s_last_semicol && s_last_b > s_last_semicol && s_first_b)
00804     return (NULL);
00805 
00806   if (s_first_b == NULL) {
00807     if (s_last_semicol == NULL)
00808       s_last_semicol = s + strlen (s);
00809 
00810     s_start = s_first_number;
00811     s_end = s_last_semicol;
00812   }
00813   else {
00814     s_start = strpbrk (s_first_b, "+-0123456789");
00815     s_end = s_last_b;
00816   }
00817 
00818   if (s_first_number == NULL)
00819     s_start = s_end;
00820 
00821   bvec_set_length (*v, 0);
00822 
00823   for (s = s_start; s && s < s_end;) {
00824 
00825     s = it_read_int (s, &d);
00826     if (d < 0 || d >= (1 << (8 * sizeof (byte))))
00827       it_warning ("Invalid byte value : %d. Casting to %d...\n", d, (byte) d);
00828 
00829     bvec_push (*v, (byte) d);
00830     s = strpbrk (s, "+-0123456789");
00831   }
00832   return s_end + 1;
00833 }
00834 
00835 
00836 /*---------------------------------------------------------------------*/
00837 char *it_read_mat (char *s, mat * m)
00838 {
00839   char *s_start, *s_end;
00840   vec  v;
00841   int  c, l;
00842 
00843   /* find the opening bracket */
00844   s_start = strchr (s, '[');
00845   /* find the closing bracket */
00846   s_end = NULL;
00847   if (s_start) {
00848     l = strlen (s);
00849     c = 0;
00850     for (s_end = s_start; s_end < s + l; s_end++) {
00851       if (*s_end == '[')
00852   c++;
00853       if (*s_end == ']')
00854   c--;
00855       if (c == 0)
00856   break;
00857     }
00858     if (s_end >= s + l || *s_end != ']')
00859       s_end = NULL;
00860   }
00861 
00862   if (!s_start || !s_end)
00863     it_error ("Unable to read a matrix of double in string %s\n", s);
00864 
00865   mat_set_height (*m, 0);
00866 
00867   /* read the vectors */
00868   s = s_start + 1;
00869   while (s && s < s_end) {
00870     v = vec_new (10);
00871     s = it_read_vec (s, &v);
00872     if (s)
00873       mat_push_row (*m, v);
00874     else
00875       vec_delete (v);
00876   }
00877 
00878   return s_end + 1;
00879 }
00880 
00881 
00882 /*---------------------------------------------------------------------*/
00883 char *it_read_fmat (char *s, mat * m)
00884 {
00885   char *s_start, *s_end;
00886   vec  v;
00887   int  c, l;
00888 
00889   /* find the opening bracket */
00890   s_start = strchr (s, '[');
00891   /* find the closing bracket */
00892   s_end = NULL;
00893   if (s_start) {
00894     l = strlen (s);
00895     c = 0;
00896     for (s_end = s_start; s_end < s + l; s_end++) {
00897       if (*s_end == '[')
00898   c++;
00899       if (*s_end == ']')
00900   c--;
00901       if (c == 0)
00902   break;
00903     }
00904     if (s_end >= s + l || *s_end != ']')
00905       s_end = NULL;
00906   }
00907 
00908   if (!s_start || !s_end)
00909     it_error ("Unable to read a matrix of float in string %s\n", s);
00910 
00911   mat_set_height (*m, 0);
00912 
00913   /* read the vectors */
00914   s = s_start + 1;
00915   while (s && s < s_end) {
00916     v = vec_new (10);
00917     s = it_read_vec (s, &v);
00918     if (s)
00919       mat_push_row (*m, v);
00920     else
00921       vec_delete (v);
00922   }
00923 
00924   return s_end + 1;
00925 }
00926 
00927 
00928 /*---------------------------------------------------------------------*/
00929 char *it_read_cmat (char *s, cmat * m)
00930 {
00931   char *s_start, *s_end;
00932   cvec v;
00933   int  c, l;
00934 
00935   /* find the opening bracket */
00936   s_start = strchr (s, '[');
00937   /* find the closing bracket */
00938   s_end = NULL;
00939   if (s_start) {
00940     l = strlen (s);
00941     c = 0;
00942     for (s_end = s_start; s_end < s + l; s_end++) {
00943       if (*s_end == '[')
00944   c++;
00945       if (*s_end == ']')
00946   c--;
00947       if (c == 0)
00948   break;
00949     }
00950     if (s_end >= s + l || *s_end != ']')
00951       s_end = NULL;
00952   }
00953 
00954   if (!s_start || !s_end)
00955     it_error ("Unable to read a matrix of double in string %s\n", s);
00956 
00957   cmat_set_height (*m, 0);
00958 
00959   /* read the vectors */
00960   s = s_start + 1;
00961   while (s && s < s_end) {
00962     v = cvec_new (10);
00963     s = it_read_cvec (s, &v);
00964     if (s)
00965       cmat_push_row (*m, v);
00966     else
00967       cvec_delete (v);
00968   }
00969 
00970   return s_end + 1;
00971 }
00972 
00973 /*---------------------------------------------------------------------*/
00974 char *it_read_imat (char *s, imat * m)
00975 {
00976   char *s_start, *s_end;
00977   ivec v;
00978   int  c, l;
00979 
00980   /* find the opening bracket */
00981   s_start = strchr (s, '[');
00982   /* find the closing bracket */
00983   s_end = NULL;
00984   if (s_start) {
00985     l = strlen (s);
00986     c = 0;
00987     for (s_end = s_start; s_end < s + l; s_end++) {
00988       if (*s_end == '[')
00989   c++;
00990       if (*s_end == ']')
00991   c--;
00992       if (c == 0)
00993   break;
00994     }
00995     if (s_end >= s + l || *s_end != ']')
00996       s_end = NULL;
00997   }
00998 
00999   if (!s_start || !s_end)
01000     it_error ("Unable to read a matrix of double in string %s\n", s);
01001 
01002   imat_set_height (*m, 0);
01003 
01004   /* read the vectors */
01005   s = s_start + 1;
01006   while (s && s < s_end) {
01007     v = ivec_new (10);
01008     s = it_read_ivec (s, &v);
01009     if (s)
01010       imat_push_row (*m, v);
01011     else
01012       ivec_delete (v);
01013   }
01014 
01015   return s_end + 1;
01016 }
01017 
01018 /*---------------------------------------------------------------------*/
01019 char *it_read_bmat (char *s, bmat * m)
01020 {
01021   char *s_start, *s_end;
01022   bvec v;
01023   int  c, l;
01024 
01025   /* find the opening bracket */
01026   s_start = strchr (s, '[');
01027   /* find the closing bracket */
01028   s_end = NULL;
01029   if (s_start) {
01030     l = strlen (s);
01031     c = 0;
01032     for (s_end = s_start; s_end < s + l; s_end++) {
01033       if (*s_end == '[')
01034   c++;
01035       if (*s_end == ']')
01036   c--;
01037       if (c == 0)
01038   break;
01039     }
01040     if (s_end >= s + l || *s_end != ']')
01041       s_end = NULL;
01042   }
01043 
01044   if (!s_start || !s_end)
01045     it_error ("Unable to read a matrix of double in string %s\n", s);
01046 
01047   bmat_set_height (*m, 0);
01048 
01049   /* read the vectors */
01050   s = s_start + 1;
01051   while (s && s < s_end) {
01052     v = bvec_new (10);
01053     s = it_read_bvec (s, &v);
01054     if (s)
01055       bmat_push_row (*m, v);
01056     else
01057       bvec_delete (v);
01058   }
01059 
01060   return s_end + 1;
01061 }
01062 
01063 /*---------------------------------------------------------------------*/
01064 vec vec_new_string (char *s)
01065 {
01066   vec  v = vec_new_alloc (0, 10);
01067   if (!it_read_vec (s, &v))
01068     it_error ("Unable to read a vector of double in string %s\n", s);
01069 
01070   return v;
01071 }
01072 
01073 
01074 /*---------------------------------------------------------------------*/
01075 vec fvec_new_string (char *s)
01076 {
01077   vec  v = vec_new_alloc (0, 10);
01078   if (!it_read_fvec (s, &v))
01079     it_error ("Unable to read a vector of float in string %s\n", s);
01080 
01081   return v;
01082 }
01083 
01084 
01085 /*---------------------------------------------------------------------*/
01086 ivec ivec_new_string (char *s)
01087 {
01088   ivec v = ivec_new_alloc (0, 10);
01089   if (!it_read_ivec (s, &v))
01090     it_error ("Unable to read a vector of integers in string %s\n", s);
01091 
01092   return v;
01093 }
01094 
01095 
01096 /*---------------------------------------------------------------------*/
01097 bvec bvec_new_string (char *s)
01098 {
01099   bvec v = bvec_new_alloc (0, 10);
01100   if (!it_read_bvec (s, &v))
01101     it_error ("Unable to read a vector of bytes in string %s\n", s);
01102 
01103   return v;
01104 }
01105 
01106 
01107 /*---------------------------------------------------------------------*/
01108 cvec cvec_new_string (char *s)
01109 {
01110   cvec v = cvec_new_alloc (0, 10);
01111   if (!it_read_cvec (s, &v))
01112     it_error ("Unable to read a vector of complexes in string %s\n", s);
01113 
01114   return v;
01115 }
01116 
01117 
01118 /*---------------------------------------------------------------------*/
01119 mat mat_new_string (char *s)
01120 {
01121   mat  m = mat_new_alloc (0, 0, 10, 10);
01122   if (!it_read_mat (s, &m))
01123     it_error ("Unable to read a matrix of double in string %s\n", s);
01124 
01125   return m;
01126 }
01127 
01128 
01129 /*---------------------------------------------------------------------*/
01130 mat fmat_new_string (char *s)
01131 {
01132   mat  m = mat_new_alloc (0, 0, 10, 10);
01133   if (!it_read_fmat (s, &m))
01134     it_error ("Unable to read a matrix of double in string %s\n", s);
01135 
01136   return m;
01137 }
01138 
01139 
01140 /*---------------------------------------------------------------------*/
01141 cmat cmat_new_string (char *s)
01142 {
01143   cmat m = cmat_new_alloc (0, 0, 10, 10);
01144   if (!it_read_cmat (s, &m))
01145     it_error ("Unable to read a matrix of double in string %s\n", s);
01146 
01147   return m;
01148 }
01149 
01150 /*---------------------------------------------------------------------*/
01151 imat imat_new_string (char *s)
01152 {
01153   imat m = imat_new_alloc (0, 0, 10, 10);
01154   if (!it_read_imat (s, &m))
01155     it_error ("Unable to read a matrix of double in string %s\n", s);
01156 
01157   return m;
01158 }
01159 
01160 /*---------------------------------------------------------------------*/
01161 bmat bmat_new_string (char *s)
01162 {
01163   bmat m = bmat_new_alloc (0, 0, 10, 10);
01164   if (!it_read_bmat (s, &m))
01165     it_error ("Unable to read a matrix of double in string %s\n", s);
01166 
01167   return m;
01168 }
01169 
01170 
01171 /*---------------------------------------------------------------------*/
01172 /*   PNM related functions                                             */
01173 /*---------------------------------------------------------------------*/
01174 
01175 /* Suppress the additional white characters and concatenate the comments 
01176  to the string comments                                                */
01177 static void pnm_read_comments (FILE * F, char *comments, int length)
01178 {
01179   int  r;
01180   int  comment_pos = 0;
01181 
01182   do
01183     r = fgetc (F);
01184   while (r == (int) '\n' || r == (int) ' ' || r == (int) '\t');
01185 
01186   while (r == (int) '#')
01187     /* Comments, read characters until the end of line                 */
01188     do {
01189       r = fgetc (F);
01190       if (comment_pos < length - 1)
01191   comments[comment_pos++] = (char) r;
01192     }
01193     while (r != (int) '\n' && !feof (F));
01194 
01195   if (r >= '0' && r <= '9')
01196     ungetc (r, F);
01197 
01198   if (length)
01199     comments[comment_pos] = '\0';
01200 }
01201 
01202 
01203 /* Read/Write the header for the pnm file format */
01204 static int pnm_read_header (FILE * file, char *p_pnm_type, int *p_width,
01205           int *p_height, int *p_max_val, char *comments,
01206           int length)
01207 {
01208 
01209   int  r;
01210 
01211   /* Set default values if the parsing would fails before the end */
01212   *p_pnm_type = 0;
01213   *p_width = 0;
01214   *p_height = 0;
01215   *p_max_val = 0;
01216 
01217   /* Read the 'P' identifier required for a pnm file */
01218   r = fgetc (file);
01219   if (r != (int) 'P') {
01220     it_warning ("Invalid format file: not a pnm file\n");
01221     return 0;
01222   }
01223 
01224   *p_pnm_type = fgetc (file);
01225   if (*p_pnm_type < '1' || *p_pnm_type > '6') {
01226     it_warning ("Unknown pnm type");
01227     return 0;
01228   }
01229 
01230   /* Read the comments */
01231   pnm_read_comments (file, comments, length);
01232 
01233   fscanf (file, "%d", p_width);
01234   fscanf (file, "%d", p_height);
01235 
01236 
01237   /* Maximal value does not exist in PBM files */
01238   if (*p_pnm_type == '2' || *p_pnm_type == '3' ||
01239       *p_pnm_type == '5' || *p_pnm_type == '6')
01240     fscanf (file, "%d", p_max_val);
01241   else
01242     *p_max_val = 1;
01243 
01244   /* According to the pnm specification, the maximal value should not
01245      be greater than 65536 and lower than 0                             */
01246   if (*p_max_val >= 65536 || *p_max_val <= 0) {
01247     it_warning ("Invalid maximum number in pnm header\n");
01248     return 0;
01249   }
01250 
01251   /* Eat the last whitespace */
01252   r = fgetc (file);
01253 
01254   /* For type P5 and P6, the value have to be lower than 255            */
01255   if ((*p_pnm_type == '5' || *p_pnm_type == '6') && *p_max_val > 255) {
01256     it_warning ("Invalid maximum number in pnm header\n");
01257     return 0;
01258   }
01259   return 1;
01260 }
01261 
01262 
01263 static int pnm_write_header (FILE * file, char type, int width, int height,
01264            int max_val, const char *comments)
01265 {
01266   fprintf (file, "P%c\n#%s\n%d %d\n", type, comments, width, height);
01267   if (type == '2' || type == '3' || type == '5' || type == '6')
01268     fprintf (file, "%d\n", max_val);
01269   return 1;
01270 }
01271 
01272 
01273 /*----------------------------------------------------------------------*/
01274 char pnm_type (const char *filename)
01275 {
01276   FILE *F = fopen (filename, "r+b");
01277   char pnm_type;
01278   int  width, height, max_val;
01279 
01280   if (!F) {
01281     it_printf ("Unable to open file %s\n", filename);
01282     return 0;
01283   }
01284 
01285   pnm_read_header (F, &pnm_type, &width, &height, &max_val, NULL, 0);
01286   fclose (F);
01287   return pnm_type;
01288 }
01289 
01290 
01291 /*----------------------------------------------------------------------*/
01292 int pnm_info (const char *filename, char *p_pnm_type, int *p_width,
01293         int *p_height, int *p_max_val, char *comments, int length)
01294 {
01295   FILE *F = fopen (filename, "r+b");
01296   if (!F) {
01297     it_printf ("Unable to open file %s\n", filename);
01298     return 0;
01299   }
01300 
01301   pnm_read_header (F, p_pnm_type, p_width, p_height, p_max_val, comments,
01302        length);
01303   fclose (F);
01304   return 1;
01305 }
01306 
01307 
01308 /*----------------------------------------------------------------------*/
01309 mat mat_pgm_read (const char *filename)
01310 {
01311   FILE *F = fopen (filename, "r+b");
01312   char type;
01313   int  width, height, max_val, i, j;
01314   mat  m;
01315 
01316   if (!F) {
01317     it_printf ("Unable to open file %s\n", filename);
01318     return 0;
01319   }
01320 
01321   /* Return a void matrix */
01322   if (!pnm_read_header (F, &type, &width, &height, &max_val, NULL, 0))
01323     return mat_new (0, 0);
01324 
01325   m = mat_new (height, width);
01326   for (i = 0; i < height; i++)
01327     for (j = 0; j < width; j++)
01328       m[i][j] = (double) fgetc (F);
01329 
01330   fclose (F);
01331   return m;
01332 }
01333 
01334 
01335 /*----------------------------------------------------------------------*/
01336 imat imat_pgm_read (const char *filename)
01337 {
01338   FILE *F = fopen (filename, "r+b");
01339   char type;
01340   int  width, height, max_val, i, j;
01341   imat m;
01342 
01343   if (!F) {
01344     it_printf ("Unable to open file %s\n", filename);
01345     return 0;
01346   }
01347 
01348   /* Return a void matrix */
01349   if (!pnm_read_header (F, &type, &width, &height, &max_val, NULL, 0))
01350     return imat_new (0, 0);
01351 
01352   m = imat_new (height, width);
01353   for (i = 0; i < height; i++)
01354     for (j = 0; j < width; j++)
01355       m[i][j] = (int) fgetc (F);
01356 
01357   fclose (F);
01358   return m;
01359 }
01360 
01361 
01362 /*----------------------------------------------------------------------*/
01363 /* Write a matrix of double as a pgm image file                         */
01364 int mat_pgm_write (const char *filename, mat m)
01365 {
01366   idx_t i, j;
01367   double v;
01368   FILE *F = fopen (filename, "w+b");
01369   pnm_write_header (F, '5', mat_width (m), mat_height (m), 255,
01370         "Generated by libit");
01371 
01372   for (i = 0; i < mat_height (m); i++)
01373     for (j = 0; j < mat_width (m); j++) {
01374       v = m[i][j] + 0.5;
01375       if (v < 0)
01376   v = 0;
01377       if (v > 255)
01378   v = 255;
01379       fputc ((int) v, F);
01380     }
01381 
01382   fclose (F);
01383   return 1;
01384 }
01385 
01386 
01387 /*----------------------------------------------------------------------*/
01388 /* Write a matrix of integers as a pgm file                             */
01389 int imat_pgm_write (const char *filename, imat m)
01390 {
01391   idx_t i, j;
01392   FILE *F = fopen (filename, "w+b");
01393   pnm_write_header (F, '5', imat_width (m), imat_height (m), 255,
01394         "Generated by libit");
01395 
01396   for (i = 0; i < imat_height (m); i++)
01397     for (j = 0; j < imat_width (m); j++)
01398       fputc (m[i][j], F);
01399 
01400   fclose (F);
01401   return 1;
01402 }
01403 
01404 
01405 /*---------------------------------------------------------------------*/
01406 /*   WAV related functions                                             */
01407 /*---------------------------------------------------------------------*/
01408 
01409 static byte wav_read8 (FILE * file)
01410 {
01411   int  c;
01412   if ((c = fgetc (file)) == EOF) {
01413     it_warning ("unexpected end of file\n");
01414     return (0);
01415   }
01416   return ((byte) c);
01417 }
01418 
01419 
01420 static unsigned short wav_read16 (FILE * file)
01421 {
01422   unsigned short v = 0;
01423 
01424   v |= wav_read8 (file);
01425   v |= wav_read8 (file) << 8;
01426 
01427   return (v);
01428 }
01429 
01430 
01431 static unsigned long wav_read32 (FILE * file)
01432 {
01433   unsigned long v = 0;
01434 
01435   v |= wav_read8 (file);
01436   v |= wav_read8 (file) << 8;
01437   v |= wav_read8 (file) << 16;
01438   v |= wav_read8 (file) << 24;
01439 
01440   return (v);
01441 }
01442 
01443 
01444 static int wav_read_sample (FILE * file, int depth)
01445 {
01446   int  v = 0;
01447 
01448   v |= wav_read8 (file);
01449   if (depth == 8)
01450     return (v - 128);   /* what a stupid file format */
01451 
01452   if (depth > 8)
01453     v |= wav_read8 (file) << 8;
01454   if (depth > 16)
01455     v |= wav_read8 (file) << 8;
01456   if (depth > 24)
01457     v |= wav_read8 (file) << 8;
01458 
01459   /* sign extend */
01460   v <<= 32 - (((depth + 7) >> 3) << 3);
01461   v >>= 32 - depth;
01462 
01463   return (v);
01464 }
01465 
01466 
01467 static void wav_write8 (FILE * file, byte c)
01468 {
01469   fputc (c, file);
01470 }
01471 
01472 static void wav_write16 (FILE * file, unsigned short c)
01473 {
01474   wav_write8 (file, (byte) c);
01475   wav_write8 (file, (byte) (c >> 8));
01476 }
01477 
01478 
01479 static void wav_write32 (FILE * file, unsigned long c)
01480 {
01481   wav_write8 (file, (byte) c);
01482   wav_write8 (file, (byte) (c >> 8));
01483   wav_write8 (file, (byte) (c >> 16));
01484   wav_write8 (file, (byte) (c >> 24));
01485 }
01486 
01487 
01488 static void wav_write_sample (FILE * file, int depth, int v)
01489 {
01490   if (depth == 8)
01491     v += 128;     /* what a stupid file format */
01492 
01493   /* align to the next byte msb */
01494   v <<= (((depth + 7) >> 3) << 3) - depth;
01495 
01496   wav_write8 (file, (byte) v);
01497   if (depth > 8)
01498     wav_write8 (file, (byte) (v >> 8));
01499   if (depth > 16)
01500     wav_write8 (file, (byte) (v >> 16));
01501   if (depth > 24)
01502     wav_write8 (file, (byte) (v >> 24));
01503 }
01504 
01505 
01506 #define FOURCC(a,b,c,d) ((int)(a) | ((int)(b) << 8) | ((int)(c) << 16) | ((int)(d) << 24) )
01507 
01508 /* Read/Write the header for the wav file format */
01509 static int wav_read_header (FILE * file, int *p_channels, int *p_srate,
01510           int *p_depth, int *p_length)
01511 {
01512   int  r;
01513 
01514   /* Set default values if the parsing would fails before the end */
01515   *p_channels = 0;
01516   *p_srate = 0;
01517   *p_depth = 0;
01518   *p_length = 0;
01519 
01520   /* Read the 'RIFF' identifier required for a wave file */
01521   r = wav_read32 (file);
01522   if (r != FOURCC ('R', 'I', 'F', 'F')) {
01523     it_warning ("Invalid format file: not a wav file\n");
01524     return 0;
01525   }
01526 
01527   /* Read the size of the following data */
01528   r = wav_read32 (file);
01529 
01530   /* Read the 'WAVE' identifier required for a wave file */
01531   r = wav_read32 (file);
01532   if (r != FOURCC ('W', 'A', 'V', 'E')) {
01533     it_warning ("Invalid format file: not a wav file\n");
01534     return 0;
01535   }
01536 
01537   /* Read the 'fmt ' identifier */
01538   r = wav_read32 (file);
01539   if (r != FOURCC ('f', 'm', 't', ' ')) {
01540     it_warning ("Invalid format file: not a wav file\n");
01541     return 0;
01542   }
01543 
01544   /* Read the size of the following data */
01545   r = wav_read32 (file);
01546 
01547   /* Read the format */
01548   r = wav_read16 (file);
01549   if (r != 1) {
01550     it_warning ("WAV: unsupported compressed file\n");
01551     return 0;
01552   }
01553 
01554   /* Read the number of channels */
01555   r = wav_read16 (file);
01556   if (r <= 0) {
01557     it_warning ("Invalid format file: invalid number of channels\n");
01558     return 0;
01559   }
01560   *p_channels = r;
01561 
01562   /* Read the sampling rate */
01563   r = wav_read32 (file);
01564   if (r <= 0) {
01565     it_warning ("Invalid format file: invalid sampling rate\n");
01566     return 0;
01567   }
01568   *p_srate = r;
01569 
01570   /* Read the average number of bytes per second (ignore) */
01571   r = wav_read32 (file);
01572 
01573   /* Read the block alignment (ignore) */
01574   r = wav_read16 (file);
01575 
01576   /* Read the number of bits per sample */
01577   r = wav_read16 (file);
01578   if (r <= 0) {
01579     it_warning ("Invalid format file: invalid number of bits per sample\n");
01580     return 0;
01581   }
01582   *p_depth = r;
01583 
01584   /* Read the 'data' identifier */
01585   r = wav_read32 (file);
01586   if (r != FOURCC ('d', 'a', 't', 'a')) {
01587     it_warning ("Invalid format file: not a wav file\n");
01588     return 0;
01589   }
01590 
01591   /* Read the size of the data chunk */
01592   r = wav_read32 (file);
01593   *p_length = r / ((*p_depth / 8) * *p_channels);
01594 
01595   return 1;
01596 }
01597 
01598 
01599 static void wav_write_header (FILE * file, int channels, int srate,
01600             int depth, int length)
01601 {
01602   int  data_size = length * ((depth + 7) / 8) * channels;
01603 
01604   /* Write the 'RIFF' identifier required for a wave file */
01605   wav_write32 (file, FOURCC ('R', 'I', 'F', 'F'));
01606 
01607   /* Read the size of the following data */
01608   wav_write32 (file, data_size + 36);
01609 
01610   /* Write the 'WAVE' identifier */
01611   wav_write32 (file, FOURCC ('W', 'A', 'V', 'E'));
01612 
01613   /* Write the 'fmt ' identifier */
01614   wav_write32 (file, FOURCC ('f', 'm', 't', ' '));
01615 
01616   /* Write the size of the following data */
01617   wav_write32 (file, 16);
01618 
01619   /* Write the format (uncompressed = 1) */
01620   wav_write16 (file, 1);
01621 
01622   /* Write the number of channels */
01623   wav_write16 (file, (unsigned short) channels);
01624 
01625   /* Write the sampling rate */
01626   wav_write32 (file, srate);
01627 
01628   /* Write the average number of bytes per second */
01629   wav_write32 (file, srate * channels * ((depth + 7) / 8));
01630 
01631   /* Write the block alignment */
01632   wav_write16 (file, (unsigned short) (channels * ((depth + 7) / 8)));
01633 
01634   /* Write the number of bits per sample */
01635   wav_write16 (file, (unsigned short) depth);
01636 
01637   /* Read the 'data' identifier */
01638   wav_write32 (file, FOURCC ('d', 'a', 't', 'a'));
01639 
01640   /* Write the size of the data chunk */
01641   wav_write32 (file, data_size);
01642 }
01643 
01644 
01645 /*----------------------------------------------------------------------*/
01646 int wav_info (const char *filename, int *p_channels, int *p_srate,
01647         int *p_depth, int *p_length)
01648 {
01649   FILE *F = fopen (filename, "r+b");
01650   if (!F) {
01651     it_printf ("Unable to open file %s\n", filename);
01652     return 0;
01653   }
01654 
01655   wav_read_header (F, p_channels, p_srate, p_depth, p_length);
01656   fclose (F);
01657   return 1;
01658 }
01659 
01660 
01661 /*----------------------------------------------------------------------*/
01662 mat mat_wav_read (const char *filename)
01663 {
01664   FILE *F = fopen (filename, "r+b");
01665   int  channels, srate, depth, length;
01666   int  i, j;
01667   mat  m;
01668 
01669   if (!F) {
01670     it_printf ("Unable to open file %s\n", filename);
01671     return 0;
01672   }
01673 
01674   /* Return a void matrix */
01675   if (!wav_read_header (F, &channels, &srate, &depth, &length))
01676     return mat_new (0, 0);
01677 
01678   m = mat_new (channels, length);
01679   for (j = 0; j < length; j++)
01680     for (i = 0; i < channels; i++)
01681       m[i][j] = (double) wav_read_sample (F, depth);
01682 
01683   fclose (F);
01684   return m;
01685 }
01686 
01687 
01688 /*----------------------------------------------------------------------*/
01689 imat imat_wav_read (const char *filename)
01690 {
01691   FILE *F = fopen (filename, "r+b");
01692   int  channels, srate, depth, length;
01693   int  i, j;
01694   imat m;
01695 
01696   if (!F) {
01697     it_printf ("Unable to open file %s\n", filename);
01698     return 0;
01699   }
01700 
01701   /* Return a void matrix */
01702   if (!wav_read_header (F, &channels, &srate, &depth, &length))
01703     return imat_new (0, 0);
01704 
01705   m = imat_new (channels, length);
01706   for (j = 0; j < length; j++)
01707     for (i = 0; i < channels; i++)
01708       m[i][j] = wav_read_sample (F, depth);
01709 
01710   fclose (F);
01711   return m;
01712 }
01713 
01714 
01715 /*----------------------------------------------------------------------*/
01716 void mat_wav_write (const char *filename, mat m, int srate, int depth)
01717 {
01718   FILE *F = fopen (filename, "w+b");
01719   int  channels, length;
01720   int  i, j;
01721   double s;
01722   double min, max;
01723 
01724   channels = mat_height (m);
01725   length = mat_width (m);
01726 
01727   if (!F) {
01728     it_printf ("Unable to open file %s\n", filename);
01729     return;
01730   }
01731 
01732   wav_write_header (F, channels, srate, depth, length);
01733 
01734   max = (1 << (depth - 1)) - 1;
01735   min = -max - 1;
01736 
01737   for (j = 0; j < length; j++)
01738     for (i = 0; i < channels; i++) {
01739       s = m[i][j];
01740       if (s > 0)
01741   s += 0.5;
01742       if (s < 0)
01743   s -= 0.5;
01744       if (s < min)
01745   s = min;
01746       if (s > max)
01747   s = max;
01748       wav_write_sample (F, depth, (int) s);
01749     }
01750 
01751   fclose (F);
01752 }
01753 
01754 /*----------------------------------------------------------------------*/
01755 void imat_wav_write (const char *filename, imat m, int srate, int depth)
01756 {
01757   FILE *F = fopen (filename, "w+b");
01758   int  channels, length;
01759   int  i, j;
01760 
01761   channels = imat_height (m);
01762   length = imat_width (m);
01763 
01764   if (!F) {
01765     it_printf ("Unable to open file %s\n", filename);
01766     return;
01767   }
01768 
01769   wav_write_header (F, channels, srate, depth, length);
01770 
01771   for (j = 0; j < length; j++)
01772     for (i = 0; i < channels; i++)
01773       wav_write_sample (F, depth, m[i][j]);
01774 
01775   fclose (F);
01776 }
01777 
01778 
01779 /*----------------------------------------------------------------------*/
01780 /* Write and read matrix in a packed format                             */
01781 
01782 void vec_fwrite (FILE * stream, vec v)
01783 {
01784   int  n = vec_length (v), ret;
01785   ret = fwrite (&n, sizeof (n), 1, stream);
01786   assert (ret == 1);
01787 
01788   if (n) {
01789     ret = fwrite (v, sizeof (*v), n, stream);
01790     assert (ret == n);
01791   }
01792 }
01793 
01794 
01795 void fvec_fwrite (FILE * stream, vec v)
01796 {
01797   int  n = vec_length (v), ret;
01798   float ftmp;
01799   ret = fwrite (&n, sizeof (n), 1, stream);
01800   assert (ret == 1);
01801 
01802   if (n) {
01803     int i;
01804     for (i = 0 ; i < n ; i++) {
01805       ftmp = (float) v[i];
01806       ret = fwrite (&ftmp, sizeof (ftmp), 1, stream);
01807       assert (ret == 1);
01808     }
01809   }
01810 }
01811 
01812 
01813 /*----------------------------------------------------------------------*/
01814 void bvec_fwrite (FILE * stream, bvec v)
01815 {
01816   int  n = bvec_length (v), ret;
01817   ret = fwrite (&n, sizeof (n), 1, stream);
01818   assert (ret == 1);
01819 
01820   if (n) {
01821     ret = fwrite (v, sizeof (*v), n, stream);
01822     assert (ret == n);
01823   }
01824 }
01825 
01826 
01827 /*----------------------------------------------------------------------*/
01828 void ivec_fwrite (FILE * stream, ivec v)
01829 {
01830   int  n = ivec_length (v), ret;
01831   ret = fwrite (&n, sizeof (n), 1, stream);
01832   assert (ret == 1);
01833 
01834   if (n) {
01835     ret = fwrite (v, sizeof (*v), n, stream);
01836     assert (ret == n);
01837   }
01838 }
01839 
01840 
01841 /*----------------------------------------------------------------------*/
01842 void cvec_fwrite (FILE * stream, cvec v)
01843 {
01844   int  n = cvec_length (v), ret;
01845   ret = fwrite (&n, sizeof (n), 1, stream);
01846   assert (ret == 1);
01847 
01848   if (n) {
01849     ret = fwrite (v, sizeof (*v), n, stream);
01850     assert (ret == n);
01851   }
01852 }
01853 
01854 
01855 
01856 /*----------------------------------------------------------------------*/
01857 int vec_fread (FILE * stream, vec v)
01858 {
01859   int  n, ret;
01860   ret = fread (&n, sizeof (n), 1, stream);
01861   if (ret != 1)
01862     return 0;
01863 
01864   if (n != vec_length (v))
01865     return 0;
01866 
01867   if (n) {
01868     ret = fread (v, sizeof (*v), n, stream);
01869     if (ret != n)
01870       return 0;
01871   }
01872 
01873   return 1;
01874 }
01875 
01876 
01877 /*----------------------------------------------------------------------*/
01878 int fvec_fread (FILE * stream, vec v)
01879 {
01880   int  n, ret;
01881   ret = fread (&n, sizeof (n), 1, stream);
01882   if (ret != 1)
01883     return 0;
01884 
01885   if (n != vec_length (v))
01886     return 0;
01887 
01888   if (n) {
01889     int i;
01890     float ftmp;
01891     for (i = 0 ; i < n ; i++) {
01892       ret = fread (&ftmp, sizeof (ftmp), 1, stream);
01893       if (ret != 1)
01894   return 0;
01895       v[i] = ftmp;
01896     }
01897   }
01898 
01899   return 1;
01900 }
01901 
01902 
01903 
01904 /*----------------------------------------------------------------------*/
01905 int ivec_fread (FILE * stream, ivec v)
01906 {
01907   int  n, ret;
01908   ret = fread (&n, sizeof (n), 1, stream);
01909   if (ret != 1)
01910     return 0;
01911 
01912   if (n != ivec_length (v))
01913     return 0;
01914 
01915   if (n) {
01916     ret = fread (v, sizeof (*v), n, stream);
01917   }
01918 
01919   return 1;
01920 }
01921 
01922 
01923 /*----------------------------------------------------------------------*/
01924 int bvec_fread (FILE * stream, bvec v)
01925 {
01926   int  n, ret;
01927   ret = fread (&n, sizeof (n), 1, stream);
01928   if (ret != 1)
01929     return 0;
01930 
01931   if (n != bvec_length (v))
01932     return 0;
01933 
01934   if (n) {
01935     ret = fread (v, sizeof (*v), n, stream);
01936     if (ret != n)
01937       return 0;
01938   }
01939 
01940   return 1;
01941 }
01942 
01943 
01944 /*----------------------------------------------------------------------*/
01945 int cvec_fread (FILE * stream, cvec v)
01946 {
01947   int  n, ret;
01948   ret = fread (&n, sizeof (n), 1, stream);
01949   if (ret != 1)
01950     return 0;
01951 
01952   if (n != cvec_length (v))
01953     return 0;
01954 
01955   if (n) {
01956     ret = fread (v, sizeof (*v), n, stream);
01957     if (ret != n)
01958       return 0;
01959   }
01960 
01961   return 1;
01962 }
01963 
01964 
01965 
01966 /*----------------------------------------------------------------------*/
01967 vec vec_new_fread (FILE * stream)
01968 {
01969   int  n, ret;
01970   vec  v;
01971   ret = fread (&n, sizeof (n), 1, stream);
01972   if (ret != 1)
01973     return NULL;
01974 
01975   v = vec_new (n);
01976   if (n) {
01977     ret = fread (v, sizeof (*v), n, stream);
01978     if (ret != n)
01979       return NULL;
01980   }
01981   return v;
01982 }
01983 
01984 
01985 /*----------------------------------------------------------------------*/
01986 vec fvec_new_fread (FILE * stream)
01987 {
01988   int  n, ret;
01989   vec  v;
01990   ret = fread (&n, sizeof (n), 1, stream);
01991   if (ret != 1)
01992     return NULL;
01993 
01994   v = vec_new (n);
01995   if (n) {
01996     int i;
01997     float ftmp;
01998     for (i = 0 ; i < n ; i++) {
01999       ret = fread (&ftmp, sizeof (ftmp), 1, stream);
02000       if (ret != 1)
02001   return NULL;
02002       v[i] = ftmp;
02003     }
02004   }
02005   return v;
02006 }
02007 
02008 
02009 /*----------------------------------------------------------------------*/
02010 bvec bvec_new_fread (FILE * stream)
02011 {
02012   int  n, ret;
02013   bvec v;
02014   ret = fread (&n, sizeof (n), 1, stream);
02015   if (ret != 1)
02016     return NULL;
02017 
02018   v = bvec_new (n);
02019   if (n) {
02020     ret = fread (v, sizeof (*v), n, stream);
02021     if (ret != n)
02022       return NULL;
02023   }
02024   return v;
02025 
02026 }
02027 
02028 
02029 /*----------------------------------------------------------------------*/
02030 ivec ivec_new_fread (FILE * stream)
02031 {
02032   int  n, ret;
02033   ivec v;
02034   ret = fread (&n, sizeof (n), 1, stream);
02035   if (ret != 1)
02036     return NULL;
02037 
02038   v = ivec_new (n);
02039 
02040   if (n) {
02041     ret = fread (v, sizeof (*v), n, stream);
02042 
02043     if (ret != n)
02044       return NULL;
02045   }
02046   return v;
02047 }
02048 
02049 
02050 /*----------------------------------------------------------------------*/
02051 cvec cvec_new_fread (FILE * stream)
02052 {
02053   int  n, ret;
02054   cvec v;
02055   ret = fread (&n, sizeof (n), 1, stream);
02056   if (ret != 1)
02057     return NULL;
02058 
02059   v = cvec_new (n);
02060   ret = fread (v, sizeof (*v), n, stream);
02061   if (ret != n)
02062     return NULL;
02063   return v;
02064 }
02065 
02066 
02067 /*----------------------------------------------------------------------*/
02068 void mat_fwrite (FILE * stream, mat m)
02069 {
02070   int  w = mat_width (m);
02071   int  h = mat_height (m), i, ret;
02072 
02073   /* Write the dimension of the matrix (first the height) */
02074   ret = fwrite (&h, sizeof (h), 1, stream);
02075   assert (ret == 1);
02076 
02077   fwrite (&w, sizeof (w), 1, stream);
02078   assert (ret == 1);
02079 
02080   if (w && h)
02081     for (i = 0; i < h;  i++) {
02082       ret = fwrite (m[i], sizeof (**m), w, stream);
02083       assert (ret == w);
02084     }
02085 }
02086 
02087 
02088 /*----------------------------------------------------------------------*/
02089 void fmat_fwrite (FILE * stream, mat m)
02090 {
02091   int  w = mat_width (m);
02092   int  h = mat_height (m), j, i, ret;
02093 
02094   /* Write the dimension of the matrix (first the height) */
02095   ret = fwrite (&h, sizeof (h), 1, stream);
02096   assert (ret == 1);
02097 
02098   fwrite (&w, sizeof (w), 1, stream);
02099   assert (ret == 1);
02100 
02101   if (w && h)
02102     for (i = 0; i < h; i++) {
02103       ret = 0;
02104       for (j = 0 ; j < w ; j++) {
02105   float tmp = (float) m[i][j];
02106   ret += fwrite (&tmp, sizeof (tmp), 1, stream);
02107       }
02108       assert (ret == w);
02109     }
02110 }
02111 
02112 
02113 /*----------------------------------------------------------------------*/
02114 void bmat_fwrite (FILE * stream, bmat m)
02115 {
02116   int  w = bmat_width (m);
02117   int  h = bmat_height (m), i, ret;
02118 
02119   /* Write the dimension of the matrix (first the height) */
02120   ret = fwrite (&h, sizeof (h), 1, stream);
02121   assert (ret == 1);
02122   ret = fwrite (&w, sizeof (w), 1, stream);
02123   assert (ret == 1);
02124 
02125   if (w && h)
02126     for (i = 0; i < h; i++) {
02127       ret = fwrite (m[i], sizeof (**m), w, stream);
02128       assert (ret == w);
02129     }
02130 }
02131 
02132 
02133 /*----------------------------------------------------------------------*/
02134 void imat_fwrite (FILE * stream, imat m)
02135 {
02136   int  w = imat_width (m);
02137   int  h = imat_height (m), i, ret;
02138 
02139   /* Write the dimension of the matrix (first the height) */
02140   ret = fwrite (&h, sizeof (h), 1, stream);
02141   assert (ret == 1);
02142   ret = fwrite (&w, sizeof (w), 1, stream);
02143   assert (ret == 1);
02144 
02145   if (w && h)
02146     for (i = 0; i < h; i++) {
02147       ret = fwrite (m[i], sizeof (**m), w, stream);
02148       assert (ret == w);
02149     }
02150 }
02151 
02152 
02153 /*----------------------------------------------------------------------*/
02154 void cmat_fwrite (FILE * stream, cmat m)
02155 {
02156   int  w = cmat_width (m);
02157   int  h = cmat_height (m), i, ret;
02158 
02159   /* Write the dimension of the matrix (first the height) */
02160   ret = fwrite (&h, sizeof (h), 1, stream);
02161   assert (ret == 1);
02162 
02163   ret = fwrite (&w, sizeof (w), 1, stream);
02164   assert (ret == 1);
02165 
02166   if (w && h)
02167     for (i = 0; i < h; i++) {
02168       ret = fwrite (m[i], sizeof (**m), w, stream);
02169       assert (ret == w);
02170     }
02171 }
02172 
02173 
02174 
02175 /*----------------------------------------------------------------------*/
02176 int vec_sread (void * buffer, vec v)
02177 {
02178   int n;
02179 
02180   n = * ((int *) buffer);
02181   buffer += sizeof (int);  /* Position the buffer at the beginning of the date */
02182   
02183   vec_init (v, (double *) buffer, n);
02184 
02185   return sizeof (int) + n * sizeof (double);
02186 }
02187 
02188 
02189 /*----------------------------------------------------------------------*/
02190 int ivec_sread (void * buffer, ivec v)
02191 {
02192   int n;
02193 
02194   n = * ((int *) buffer);
02195   buffer += sizeof (int);  /* Position the buffer at the beginning of the date */
02196   
02197   ivec_init (v, (int *) buffer, n);
02198 
02199   return sizeof (int) + n * sizeof (int);
02200 }
02201 
02202 
02203 /*----------------------------------------------------------------------*/
02204 mat mat_new_fread (FILE * stream)
02205 {
02206   int  w, h, i, ret;
02207   mat  m;
02208   ret = fread (&h, sizeof (h), 1, stream);
02209   assert (ret == 1);
02210   ret = fread (&w, sizeof (w), 1, stream);
02211   assert (ret == 1);
02212 
02213   m = mat_new (h, w);
02214 
02215   if (w && h)
02216     for (i = 0; i < h; i++) {
02217       ret = fread (m[i], sizeof (**m), w, stream);
02218       assert (ret == w);
02219     }
02220   return m;
02221 }
02222 
02223 
02224 /*----------------------------------------------------------------------*/
02225 bmat bmat_new_fread (FILE * stream)
02226 {
02227   int  w, h, i, ret;
02228   bmat m;
02229   ret = fread (&h, sizeof (h), 1, stream);
02230   assert (ret == 1);
02231   ret = fread (&w, sizeof (w), 1, stream);
02232   assert (ret == 1);
02233 
02234   m = bmat_new (h, w);
02235 
02236   if (w && h)
02237     for (i = 0; i < h; i++) {
02238       ret = fread (m[i], sizeof (**m), w, stream);
02239       assert (ret == w);
02240     }
02241   return m;
02242 }
02243 
02244 
02245 /*----------------------------------------------------------------------*/
02246 imat imat_new_fread (FILE * stream)
02247 {
02248   int  w, h, i, ret;
02249   imat m;
02250   ret = fread (&h, sizeof (h), 1, stream);
02251   assert (ret == 1);
02252   ret = fread (&w, sizeof (w), 1, stream);
02253   assert (ret == 1);
02254 
02255   m = imat_new (h, w);
02256 
02257   if (w && h)
02258     for (i = 0; i < h; i++) {
02259       ret = fread (m[i], sizeof (**m), w, stream);
02260       assert (ret == w);
02261     }
02262   return m;
02263 }
02264 
02265 
02266 /*----------------------------------------------------------------------*/
02267 cmat cmat_new_fread (FILE * stream)
02268 {
02269   int  w, h, i, ret;
02270   cmat m;
02271   ret = fread (&h, sizeof (h), 1, stream);
02272   assert (ret == 1);
02273   ret = fread (&w, sizeof (w), 1, stream);
02274   assert (ret == 1);
02275 
02276   m = cmat_new (h, w);
02277 
02278   if (w && h)
02279     for (i = 0; i < h; i++) {
02280       ret = fread (m[i], sizeof (**m), w, stream);
02281       assert (ret == w);
02282     }
02283   return m;
02284 }
02285 
02286 
02287 /*----------------------------------------------------------------------*/
02288 bvec bvec_file_read_bits (const char *filename, int nb_max)
02289 {
02290   FILE *F = fopen (filename, "r+b");
02291   byte b = 0;
02292   bvec v, buf;
02293   int  i, return_code;
02294 
02295   if (F == NULL)
02296     it_error ("Unable to open file %s\n", filename);
02297 
02298   /* The whole file has to be read. We have to find the length of this file */
02299   if (nb_max <= 0) {
02300     fseek (F, 0, SEEK_END); /* Reach the end of the file */
02301     nb_max = ftell (F) * 8; /* vector length = Length of the file * 8 */
02302     rewind (F);     /* Come back to the start of the file */
02303   }
02304 
02305   /* Read a vector of characters from the file */
02306   buf = bvec_new ((nb_max + 7) / 8);
02307   return_code = fread (buf, 1, bvec_length (buf), F);
02308   fclose (F);
02309 
02310   /* Verify that we have read the correct number of bits, otherwise quit */
02311   if (return_code != (nb_max + 7) / 8)
02312     it_error ("Incorrect number of bits read from file %s\n", filename);
02313 
02314   v = bvec_new (nb_max);
02315 
02316   for (i = 0; i < nb_max; i++) {
02317     if (i % 8 == 0)
02318       b = buf[i / 8];
02319 
02320     v[i] = (b >> (7 - (i % 8))) & 1;
02321   }
02322 
02323   bvec_delete (buf);
02324   return v;
02325 }
02326 
02327 
02328 /*----------------------------------------------------------------------*/
02329 void bvec_file_write_bits (const char *filename, bvec v)
02330 {
02331   FILE *F = fopen (filename, "w+b");
02332   bvec buf = bvec_new_zeros ((bvec_length (v) + 7) / 8);
02333   int  i, return_code;
02334 
02335   if (F == NULL)
02336     it_error ("Unable to create the file %s\n", filename);
02337 
02338   for (i = 0; i < bvec_length (v); i++) {
02339 
02340     /* Note that v must be a vector of bits */
02341     buf[i / 8] ^= (v[i] & 1) << (7 - i % 8);
02342   }
02343 
02344   return_code = fwrite (buf, bvec_length (buf), 1, F);
02345 
02346   printf ("bvec_length(v)   = %d\n", bvec_length (v));
02347   printf ("bvec_length(buf) = %d\n", bvec_length (buf));
02348   printf ("return_code      = %d\n", return_code);
02349 
02350   if (!return_code)
02351     it_error ("Could not write a bit vector in file %d\n", filename);
02352   fclose (F);
02353   bvec_delete (buf);
02354 }
02355 
02356 

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau