|
A Portable Floating-Point-Based Image Format
1.0
|
00001 /* 00002 * Implementation of the PFI library, a portable format to store 00003 * images with a double representation for every pixel of the same 00004 * color... 00005 * 00006 * $Date$ 00007 * $Revision$ 00008 * 00009 */ 00010 00011 #include "pfi.h" 00012 #include <stdio.h> 00013 #include <math.h> 00014 #include <float.h> 00015 #include <assert.h> 00016 #include <string.h> 00017 #include <ctype.h> 00018 #include <stdlib.h> 00019 #include <stdarg.h> 00020 #include <errno.h> 00021 00022 #define SIZE_CHECK(type,size,name) \ 00023 typedef type name[(sizeof (type) == size)*2-1] 00024 00025 SIZE_CHECK (pfiu32, 4, bar); 00026 SIZE_CHECK (pfiu16, 2, foobar); 00027 00056 /* Example: 00057 * +------------------------------------------------------------- 00058 * | PFI 00059 * | # file123.pfi 00060 * | # number of rows: 00061 * | 512 00062 * | # number of columns: 00063 * | 512 00064 * | # number of colors and colormodel: 00065 * | 3 1 00066 * | # binary data starts... 00067 * | ... 00068 * +------------------------------------------------------------- 00069 */ 00070 #ifdef TEST 00071 int main (void); 00072 #endif 00073 00074 static void double2pfi (double val, /*@exposed@*//*@out@*/pfiu32 *results); 00075 static int pfi2double (pfiu32 *coded, /*@exposed@*//*@out@*/double *res); 00076 static int numexpect (char *bufp, int expect); 00077 static void skipwhite (/*@exposed@*/char **pos); 00078 00079 #define PIXEL_PFIS 7 00080 00081 #define DPRINTF(x) 00082 #if !defined (NDEBUG) && !defined (DPRINTF) 00083 static int 00084 debug_printf (const char *tmpl, ...) 00085 { 00086 va_list ap; 00087 int result; 00088 00089 va_start (ap, tmpl); 00090 result = vfprintf (stderr, tmpl, ap); 00091 va_end (ap); 00092 return result; 00093 } 00094 00095 #define STRR(X) #X 00096 #define STR(X) STRR(X) 00097 #define DPRINTF(X) \ 00098 (debug_printf("DEBUG %s [%s]: ", __FILE__, STR(__LINE__)), debug_printf X) 00099 00100 #else /* NDEBUG */ 00101 00102 #ifndef DPRINTF 00103 #define DPRINTF(x) 00104 #endif 00105 00106 #endif /* NDEBUG */ 00107 00108 #ifdef TEST 00109 int 00110 main (void) 00111 { 00112 double d1 = sqrt (2), d2; 00113 pfiu32 results[PIXEL_PFIS]; 00114 double ar[9]; 00115 FILE *stream = NULL; 00116 double *res; 00117 int rows, cols, colors, colormodel, i, size; 00118 00119 ar[0] = sqrt (2); 00120 ar[1] = sqrt (3); 00121 ar[2] = sqrt (5); 00122 ar[3] = sqrt (6); 00123 ar[4] = sqrt (7); 00124 ar[5] = sqrt (8); 00125 ar[6] = sqrt (10); 00126 ar[7] = sqrt (11); 00127 ar[8] = sqrt (12); 00128 00129 printf ("From ze test its beginnink...\n"); 00130 00131 /* 00132 * Testing the internal functions... 00133 */ 00134 assert (numexpect (" 12 12 ", 2) == 2); 00135 assert (numexpect ("12", 2) == -1); 00136 assert (numexpect (" 12 12 12", 2) == -1); 00137 assert (numexpect (" 1a2 12 ", 2) == -1); 00138 assert (numexpect ("12 a12 ", 1) == -1); 00139 00140 DPRINTF (("main: d1: %1.52f\n", d1)); 00141 double2pfi (d1, results); 00142 (void)pfi2double (results, &d2); 00143 DPRINTF (("main: d1: %1.60f\n", d1)); 00144 DPRINTF (("main: d2: %1.60f\n", d2)); 00145 assert (fabs (d2 - d1) < 2*PFI_EPSILON); 00146 d1 *= -1.0; 00147 double2pfi (d1, results); 00148 (void)pfi2double (results, &d2); 00149 DPRINTF (("main: d1: %1.60f\n", d1)); 00150 DPRINTF (("main: d2: %1.60f\n", d2)); 00151 assert (fabs (d2 - d1) < PFI_EPSILON); 00152 d1 = 0.1230; 00153 double2pfi (d1, results); 00154 (void)pfi2double (results, &d2); 00155 assert (fabs (d2 - d1) < PFI_EPSILON); 00156 d1 = 10.1230; 00157 double2pfi (d1, results); 00158 (void)pfi2double (results, &d2); 00159 DPRINTF (("main: d1: %1.60f\n", d1)); 00160 DPRINTF (("main: d2: %1.60f\n", d2)); 00161 assert (fabs (d2 - d1) < PFI_EPSILON); 00162 00163 /* 00164 * Testing the file functions... 00165 */ 00166 if (pfi_write_name ("test.pfi", ar, 3, 3, 1, 0) < 0) 00167 { 00168 perror ("writing data to file"); 00169 return 1; 00170 } 00171 00172 printf ("File just created...\n"); 00173 if (pfi_properties_name ("test.pfi", &rows, &cols, 00174 &colors, &colormodel) < 0) 00175 { 00176 perror ("rading image properties"); 00177 return 1; 00178 } 00179 res = malloc (rows * cols * colors * sizeof (*res)); 00180 if (pfi_read_name ("test.pfi", rows, cols, colors, res) < 0) 00181 { 00182 perror ("reading data from file"); 00183 return 1; 00184 } 00185 00186 assert (rows == 3); 00187 assert (cols == 3); 00188 assert (colors == 1); 00189 assert (colormodel == 0); 00190 00191 size = rows*cols*colors; 00192 for (i = 0; i < size; i++) 00193 { 00194 DPRINTF (("res[%d]: %f == ar[%d]: %f?\n", i, res[i], i, ar[i])); 00195 assert (fabs (res[i] - ar[i]) < PFI_EPSILON); 00196 } 00197 free (res); 00198 printf ("...kewl\n"); 00199 00200 printf ("File with DOS-style line ends...\n"); 00201 if (pfi_properties_name ("crlf.pfi", &rows, &cols, 00202 &colors, &colormodel) < 0) 00203 { 00204 perror ("rading image properties"); 00205 return 1; 00206 } 00207 res = malloc (rows * cols * colors * sizeof (*res)); 00208 if (pfi_read_name ("crlf.pfi", rows, cols, colors, res) < 0) 00209 { 00210 perror ("reading data from file"); 00211 return 1; 00212 } 00213 assert (rows == 3); 00214 assert (cols == 3); 00215 assert (colors == 1); 00216 assert (colormodel == 0); 00217 00218 size = rows*cols*colors; 00219 for (i = 0; i < size; i++) 00220 { 00221 DPRINTF (("res[%d]: %f == ar[%d]: %f?\n", i, res[i], i, ar[i])); 00222 assert (fabs (res[i] - ar[i]) < PFI_EPSILON); 00223 } 00224 free (res); 00225 printf ("...kewl\n"); 00226 00227 printf ("File with rgb colors...\n"); 00228 if (pfi_properties_name ("colors.pfi", &rows, &cols, 00229 &colors, &colormodel) < 0) 00230 { 00231 perror ("rading image properties"); 00232 return 1; 00233 } 00234 res = malloc (rows * cols * colors * sizeof (*res)); 00235 if (pfi_read_name ("colors.pfi", rows, cols, colors, res) < 0) 00236 { 00237 perror ("reading data from file"); 00238 return 1; 00239 } 00240 assert (rows == 2); 00241 assert (cols == 2); 00242 assert (colors == 3); 00243 assert (colormodel == 1); 00244 free (res); 00245 printf ("...kewl\n"); 00246 00247 printf ("File with excessive comments...\n"); 00248 if (pfi_properties_name ("comments.pfi", &rows, &cols, 00249 &colors, &colormodel) < 0) 00250 { 00251 perror ("rading image properties"); 00252 return 1; 00253 } 00254 res = malloc (rows * cols * colors * sizeof (*res)); 00255 if (pfi_read_name ("comments.pfi", rows, cols, colors, res) < 0) 00256 { 00257 perror ("reading data from file"); 00258 return 1; 00259 } 00260 assert (rows == 3); 00261 assert (cols == 3); 00262 assert (colors == 1); 00263 assert (colormodel == 0); 00264 00265 size = rows*cols*colors; 00266 for (i = 0; i < size; i++) 00267 { 00268 printf ("res[%d]: %f == ar[%d]: %f?\n", i, res[i], i, ar[i]); 00269 assert (fabs (res[i] - ar[i]) < PFI_EPSILON); 00270 } 00271 free (res); 00272 printf ("...kewl\n"); 00273 00274 #if !defined _MSC_VER && !defined __WATCOMC__ 00275 /* test of error checking disabled since pfi_read is not in the 00276 * DLL exports */ 00277 /* 00278 * Error checking for the input file... 00279 */ 00280 printf ("Error checking...\n"); 00281 if ((stream = fopen ("invalid1.pfi", "rb")) == NULL) 00282 { 00283 perror ("opening file"); 00284 return 1; 00285 } 00286 00287 if ((res = pfi_read (stream, &rows, &cols, &colors, &colormodel)) == NULL) 00288 { 00289 perror ("Expected error found"); 00290 } 00291 else 00292 { 00293 assert (0); 00294 } 00295 00296 fclose (stream); 00297 if ((stream = fopen ("invalid2.pfi", "rb")) == NULL) 00298 { 00299 perror ("opening file"); 00300 return 1; 00301 } 00302 if ((res = pfi_read (stream, &rows, &cols, &colors, &colormodel)) == NULL) 00303 { 00304 perror ("Expected error found"); 00305 } 00306 else 00307 { 00308 assert (0); 00309 } 00310 00311 fclose (stream); 00312 if ((stream = fopen ("invalid3.pfi", "rb")) == NULL) 00313 { 00314 perror ("opening file"); 00315 return 1; 00316 } 00317 if ((res = pfi_read (stream, &rows, &cols, &colors, &colormodel)) == NULL) 00318 { 00319 perror ("Expected error found"); 00320 } 00321 else 00322 { 00323 assert (0); 00324 } 00325 00326 fclose (stream); 00327 if ((stream = fopen ("invalid4.pfi", "rb")) == NULL) 00328 { 00329 perror ("opening file"); 00330 return 1; 00331 } 00332 if ((res = pfi_read (stream, &rows, &cols, &colors, &colormodel)) == NULL) 00333 { 00334 perror ("Expected error found"); 00335 } 00336 else 00337 { 00338 assert (0); 00339 } 00340 00341 fclose (stream); 00342 if ((stream = fopen ("invalid5.pfi", "rb")) == NULL) 00343 { 00344 perror ("opening file"); 00345 return 1; 00346 } 00347 if ((res = pfi_read (stream, &rows, &cols, &colors, &colormodel)) == NULL) 00348 { 00349 perror ("Expected error found"); 00350 } 00351 else 00352 { 00353 assert (0); 00354 } 00355 fclose (stream); 00356 #endif 00357 printf ("...kewl\n"); 00358 printf ("From ze test its end...\n"); 00359 return 0; 00360 } 00361 00362 #else /* TEST */ 00363 00364 static int skipcomments (FILE *stream); 00365 static int pfi_read_internal (FILE *, int, int, int, /*@out@*/double *); 00366 00379 int 00380 pfi_getv (FILE *stream, /*@exposed@*//*@out@*/double *valp) 00381 { 00382 pfiu32 results[PIXEL_PFIS]; 00383 pfiu16 *tmp; 00384 00385 int i; 00386 00387 if (fread (results, sizeof (*results), PIXEL_PFIS, stream) != PIXEL_PFIS) 00388 { 00389 DPRINTF (("pfi_getv: fread failed.")); 00390 /*@-mustdefine@*/ 00391 return -1; 00392 /*@=mustdefine@*/ 00393 } 00394 DPRINTF (("pfi_getv: 1st original byte is: 0x%02x\n", ((char*)results)[0])); 00395 DPRINTF (("pfi_getv: 2nd original byte is: 0x%02x\n", ((char*)results)[1])); 00396 DPRINTF (("pfi_getv: 3st original byte is: 0x%02x\n", ((char*)results)[2])); 00397 DPRINTF (("pfi_getv: 4nd original byte is: 0x%02x\n", ((char*)results)[3])); 00398 for (i = 0; i < 2; i++) 00399 { 00400 tmp = &((pfiu16*)results)[i]; 00401 *tmp = pfi_ftoh16 (*tmp); 00402 } 00403 for (i = 1; i < PIXEL_PFIS; i++) 00404 { 00405 results[i] = pfi_ftoh32 (results[i]); 00406 } 00407 DPRINTF (("pfi_getv: 1st swapped byte is: 0x%02x\n", ((char*)results)[0])); 00408 DPRINTF (("pfi_getv: 2nd swapped byte is: 0x%02x\n", ((char*)results)[1])); 00409 DPRINTF (("pfi_getv: 3st swapped byte is: 0x%02x\n", ((char*)results)[2])); 00410 DPRINTF (("pfi_getv: 4nd swapped byte is: 0x%02x\n", ((char*)results)[3])); 00411 00412 return pfi2double (results, valp); 00413 } 00414 00427 int 00428 pfi_putv (FILE *stream, double val) 00429 { 00430 pfiu32 values[PIXEL_PFIS]; 00431 pfiu16 *tmp; 00432 int i; 00433 00434 double2pfi (val, values); 00435 00436 DPRINTF (("pfi_putv: 1st original byte is: 0x%02x\n", ((char*)values)[0])); 00437 DPRINTF (("pfi_putv: 2nd original byte is: 0x%02x\n", ((char*)values)[1])); 00438 DPRINTF (("pfi_putv: 3st original byte is: 0x%02x\n", ((char*)values)[2])); 00439 DPRINTF (("pfi_putv: 4nd original byte is: 0x%02x\n", ((char*)values)[3])); 00440 for (i = 0; i < 2; i++) 00441 { 00442 tmp = &((pfiu16*)values)[i]; 00443 *tmp = pfi_htof16 (*tmp); 00444 } 00445 for (i = 1; i < PIXEL_PFIS; i++) 00446 { 00447 values[i] = pfi_htof32 (values[i]); 00448 } 00449 DPRINTF (("pfi_putv: 1st swapped byte is: 0x%02x\n", ((char*)values)[0])); 00450 DPRINTF (("pfi_putv: 2nd swapped byte is: 0x%02x\n", ((char*)values)[1])); 00451 DPRINTF (("pfi_putv: 3st swapped byte is: 0x%02x\n", ((char*)values)[2])); 00452 DPRINTF (("pfi_putv: 4nd swapped byte is: 0x%02x\n", ((char*)values)[3])); 00453 00454 if (fwrite (values, sizeof (*values), PIXEL_PFIS, stream) != PIXEL_PFIS) 00455 { 00456 return -1; 00457 } 00458 00459 return 0; 00460 } 00461 00488 int 00489 pfi_properties (FILE *stream, int *rows, int *cols, 00490 int *colors, int *colormodel) 00491 { 00492 enum { s_pfi, s_rows, s_cols, s_colors, s_done, s_error }; 00493 int state = s_pfi; 00494 int ch; 00495 char buf[256]; 00496 char *crlf; 00497 00498 /*@-infloops@*/ 00499 while (state < s_done) 00500 /*@=infloops@*/ 00501 { 00502 switch (state) 00503 { 00504 case s_pfi: 00505 DPRINTF (("pfi_properties: s_pfi\n")); 00506 if (fgets (buf, (int) sizeof buf, stream) == NULL) 00507 { 00508 DPRINTF (("OOPS\n")); 00509 state = s_error; 00510 break; 00511 } 00512 while ((crlf = strchr (buf, '\n')) != NULL) 00513 { 00514 *crlf = '\0'; 00515 } 00516 while ((crlf = strchr (buf, '\r')) != NULL) 00517 { 00518 *crlf = '\0'; 00519 } 00520 00521 if (strcmp (buf, "PFI") != 0) 00522 { 00523 state = s_error; 00524 break; 00525 } 00526 state = s_rows; 00527 break; 00528 00529 case s_rows: 00530 DPRINTF (("pfi_properties: s_rows\n")); 00531 ch = skipcomments (stream); 00532 (void)ungetc (ch, stream); 00533 if (fgets (buf, (int) sizeof buf, stream) == NULL) 00534 { 00535 state = s_error; 00536 break; 00537 } 00538 if (numexpect (buf, 1) != 1) 00539 { 00540 state = s_error; 00541 break; 00542 } 00543 (void)sscanf (buf, "%d", rows); 00544 if (*rows < 1) 00545 { 00546 state = s_error; 00547 break; 00548 } 00549 00550 state = s_cols; 00551 break; 00552 00553 case s_cols: 00554 DPRINTF (("pfi_properties: s_cols\n")); 00555 ch = skipcomments (stream); 00556 (void)ungetc (ch, stream); 00557 if (fgets (buf, (int) sizeof buf, stream) == NULL) 00558 { 00559 state = s_error; 00560 break; 00561 } 00562 if (numexpect (buf, 1) != 1) 00563 { 00564 state = s_error; 00565 break; 00566 } 00567 (void)sscanf (buf, "%d", cols); 00568 if (*cols < 1) 00569 { 00570 state = s_error; 00571 break; 00572 } 00573 state = s_colors; 00574 break; 00575 00576 case s_colors: 00577 DPRINTF (("pfi_properties: s_colors\n")); 00578 ch = skipcomments (stream); 00579 (void)ungetc ((char)ch, stream); 00580 if (fgets (buf, (int) sizeof buf, stream) == NULL) 00581 { 00582 state = s_error; 00583 break; 00584 } 00585 if (numexpect (buf, 2) == 2) 00586 { 00587 (void)sscanf (buf, "%d%d", colors, colormodel); 00588 } 00589 else if (numexpect (buf, 1) == 1) 00590 { 00591 (void)sscanf (buf, "%d", colors); 00592 *colormodel = 0; 00593 } 00594 else 00595 { 00596 state = s_error; 00597 break; 00598 } 00599 if (*colors < 1 || (*colors < 3 && *colormodel > 0)) 00600 { 00601 state = s_error; 00602 break; 00603 } 00604 00605 state = s_done; 00606 break; 00607 00608 default: 00609 state = s_error; 00610 break; 00611 } 00612 } 00613 00614 if (state == s_error) 00615 { 00616 #ifdef EINVAL 00617 errno = EINVAL; 00618 #endif 00619 return -1; 00620 } 00621 00622 return state == s_done? 0: -1; 00623 } 00624 00653 double * 00654 pfi_read (FILE *stream, int *rows, int *cols, int *colors, int *colormodel) 00655 { 00656 double *res = NULL; 00657 00658 DPRINTF (("pfi_read: s_properties\n")); 00659 if (pfi_properties (stream, rows, cols, colors, colormodel) < 0) 00660 { 00661 return NULL; 00662 } 00663 00664 if ((res = malloc ((*rows)*(*cols)*(*colors)*sizeof (*res))) == NULL) 00665 { 00666 return NULL; 00667 } 00668 if (pfi_read_internal (stream, *rows, *cols, *colors, res) < 0) 00669 { 00670 free (res); 00671 return NULL; 00672 } 00673 return res; 00674 } 00675 00676 00714 int 00715 pfi_write (FILE *stream, double *buf, int rows, 00716 int cols, int colors, int colormodel, char *fname) 00717 { 00718 int pixel, color, size; 00719 00720 /* 00721 * Write the header... 00722 */ 00723 if (fprintf (stream, "PFI\n#%s\n%d\n%d\n%d %d\n", 00724 fname, rows, cols, colors, colormodel) < 0) 00725 { 00726 return -1; 00727 } 00728 00729 /* 00730 * And the rest... 00731 */ 00732 size = rows * cols; 00733 for (pixel = 0; pixel < size; pixel++) 00734 { 00735 for (color = 0; color < colors; color++) 00736 { 00737 if (pfi_putv (stream, buf[colors*pixel+color]) < 0) 00738 { 00739 return -1; 00740 } 00741 } 00742 } 00743 00744 return 0; 00745 } 00746 00769 DLL_EXPORT int 00770 pfi_read_name (char *name, int rows, int cols, int colors, double *result) 00771 { 00772 FILE *handle = NULL; 00773 int rc = 0; 00774 00775 if (name == NULL) 00776 { 00777 handle = stdin; 00778 } 00779 else 00780 { 00781 if ((handle = fopen (name, "rb")) == NULL) 00782 { 00783 return -1; 00784 } 00785 } 00786 00787 rc = pfi_read_internal (handle, rows, cols, colors, result); 00788 00789 if (handle != stdin) 00790 { 00791 (void)fclose (handle); 00792 } 00793 00794 return rc; 00795 } 00796 00797 00832 DLL_EXPORT int 00833 pfi_write_name (char *name, double *buf, int rows, int cols, 00834 int colors, int colormodel) 00835 { 00836 FILE *handle = NULL; 00837 int rc = 0; 00838 00839 if (name == NULL) 00840 { 00841 handle = stdin; 00842 rc = pfi_write (handle, buf, rows, cols, colors, colormodel, "stdin"); 00843 } 00844 else 00845 { 00846 if ((handle = fopen (name, "wb")) == NULL) 00847 { 00848 return -1; 00849 } 00850 rc = pfi_write (handle, buf, rows, cols, colors, colormodel, name); 00851 } 00852 00853 if (handle != stdin) 00854 { 00855 (void)fclose (handle); 00856 } 00857 00858 return rc; 00859 } 00860 00887 DLL_EXPORT int 00888 pfi_properties_name (char *name, int *rows, int *cols, 00889 int *colors, int *colormodel) 00890 { 00891 int rc = 0; 00892 FILE *handle = NULL; 00893 00894 if (name == NULL) 00895 { 00896 handle = stdin; 00897 } 00898 else 00899 { 00900 if ((handle = fopen (name, "rb")) == NULL) 00901 { 00902 return -1; 00903 } 00904 } 00905 00906 rc = pfi_properties (handle, rows, cols, colors, colormodel); 00907 00908 if (handle != stdin) 00909 { 00910 (void)fclose (handle); 00911 } 00912 00913 return rc; 00914 } 00915 00926 static int 00927 skipcomments (FILE *stream) 00928 { 00929 int ch; 00930 /* 00931 * Skip comments... 00932 */ 00933 do 00934 { 00935 ch = fgetc (stream); 00936 } 00937 while (isspace (ch)); 00938 00939 while ((ch == (int)'#')) 00940 { 00941 while (ch != (int)'\n') 00942 { 00943 if ((ch = fgetc (stream)) == EOF) 00944 { 00945 return ch; 00946 } 00947 } 00948 while (ch < (int)' ' ) 00949 { 00950 if ((ch = fgetc (stream)) == EOF) 00951 { 00952 return ch; 00953 } 00954 } 00955 } 00956 return ch; 00957 } 00958 00981 static int 00982 pfi_read_internal (FILE *stream, int rows, int cols, int colors, 00983 /*@out@*/double *res) 00984 { 00985 enum { s_read, s_done, s_error }; 00986 int state = s_read; 00987 int pixel, color, size; 00988 long fpos; 00989 00990 /*@-infloops@*/ 00991 while (state < s_done) 00992 /*@=infloops@*/ 00993 { 00994 switch (state) 00995 { 00996 case s_read: 00997 DPRINTF (("pfi_read: s_read\n")); 00998 00999 size = rows * cols; 01000 state = s_done; 01001 fpos = -1l * (long)size * (long)colors 01002 * (long)PIXEL_PFIS * (long) sizeof (pfiu32); 01003 DPRINTF (("fpos: %ld\n", fpos)); 01004 (void)fseek(stream, fpos, SEEK_END); 01005 01006 for (pixel = 0; pixel < size && state != s_error; pixel++) 01007 { 01008 for (color = 0; color < colors; color++) 01009 { 01010 if (pfi_getv (stream, &res[colors*pixel+color]) < 0) 01011 { 01012 state = s_error; 01013 DPRINTF (("pfi_read: s_read: upsa!\n")); 01014 break; 01015 } 01016 } 01017 } 01018 break; 01019 01020 default: 01021 state = s_error; 01022 break; 01023 } 01024 } 01025 01026 /*@-mustdefine@*/ 01027 if (state == s_error) 01028 { 01029 #ifdef EINVAL 01030 errno = EINVAL; 01031 #endif 01032 return -1; 01033 } 01034 01035 return state == s_done? 0: -1; 01036 /*@=mustdefine@*/ 01037 } 01038 01039 #endif /* TEST */ 01040 01050 static void 01051 double2pfi (double val, /*@exposed@*//*@out@*/pfiu32 *results) 01052 { 01053 char buf[64]; 01054 char *start; 01055 int i; 01056 pfiu16 *highp = (pfiu16*)results; 01057 pfiu16 *expnp = (pfiu16*)results + 1; 01058 01059 DPRINTF (("double2pfi ()\n")); 01060 DPRINTF (("double2pfi: %+.54e\n", val)); 01061 (void)snprintf (buf, sizeof buf, "%+.54e", val); 01062 /*DPRINTF (("double2pfi: %s\n", buf));*/ 01063 01064 start = strchr (buf, 'e'); 01065 /*@-nullderef@*/ 01066 assert (start[0] != '\0'); 01067 start[0] = '\0'; 01068 /*@=nullderef@*/ 01069 01070 assert (start != NULL); 01071 assert (start [1] == '+' || start[1] == '-'); 01072 start++; 01073 (void)sscanf (start+1, "%hu", expnp); 01074 if (*start == '-') 01075 { 01076 *expnp = ~(*expnp) + (pfiu16)1; 01077 } 01078 01079 /*DPRINTF (("double2pfi: %d\n", (short)*expnp));*/ 01080 01081 start = strchr (buf, '.') + 1; 01082 /*DPRINTF (("double2pfi: %s\n", start));*/ 01083 assert (start != NULL); 01084 assert (start[0] != '\0'); 01085 start += 45; 01086 01087 for (i = 6; i > 0; i--) 01088 { 01089 (void)sscanf (start, "%lu", &results[i]); 01090 *start = '\0'; 01091 start -= 9; 01092 } 01093 01094 DPRINTF (("double2pfi: %09lu%09lu%09lu%09lu%09lu%09lu\n", 01095 results[1], results[2], results[3], 01096 results[4], results[5], results[6])); 01097 start = strchr (buf, '.'); 01098 assert (start != NULL); 01099 assert (*start != '\0'); 01100 *start = '\0'; 01101 01102 (void)sscanf (buf+1, "%hu", highp); 01103 if (*buf == '-') 01104 { 01105 *highp = ~(*highp) + (pfiu16)1; 01106 } 01107 DPRINTF (("double2pfi: %+d.%09lu%09lu%09lu%09lu%09lu%09lue%+d\n", 01108 *highp, results[1], results[2], results[3], results[4], 01109 results[5], results[6], *expnp)); 01110 } 01111 01124 static int 01125 pfi2double (pfiu32 *coded, /*@exposed@*//*@out@*/double *res) 01126 { 01127 pfiu16 *highp = (pfiu16*)coded; 01128 pfiu16 *expnp = (pfiu16*)coded + 1; 01129 int high = 1, expn = 1; 01130 char buf[64]; 01131 DPRINTF (("pfi2double ()\n")); 01132 if ((*highp & 0x8000) != 0) 01133 { 01134 *highp = ~(*highp) + (pfiu16)1; 01135 high *= -1; 01136 } 01137 01138 high *= *highp; 01139 01140 if ((*expnp & 0x8000) != 0) 01141 { 01142 *expnp = ~(*expnp) + (pfiu16)1; 01143 expn *= -1; 01144 } 01145 expn *= *expnp; 01146 01147 /* 01148 * Data source corrupted? 01149 */ 01150 if (*highp > 9 || expn > DBL_MAX_EXP || expn < DBL_MIN_EXP) 01151 { 01152 DPRINTF (("pfi2double: data source corrupted: %d %d %d\n", 01153 *highp > 9, expn > DBL_MAX_EXP, expn < DBL_MIN_EXP)); 01154 /*@-mustdefine@*/ 01155 return -1; 01156 /*@=mustdefine@*/ 01157 } 01158 01159 01160 (void)snprintf (buf, sizeof buf, "%+d.%09lu%09lu%09lu%09lu%09lu%09lue%+d", 01161 high, coded[1], coded[2], coded[3], 01162 coded[4], coded[5], coded[6], expn); 01163 DPRINTF (("pfi2double: %+d.%09lu%09lu%09lu%09lu%09lu%09lue%+d\n", high, 01164 coded[1], coded[2], coded[3], coded[4], coded[5], coded[6], expn)); 01165 DPRINTF (("pfi2double: %s\n", buf)); 01166 (void)sscanf (buf, "%le", res); 01167 DPRINTF (("pfi2double: %+.54e\n", *res)); 01168 return 0; 01169 } 01170 01171 01183 static int 01184 numexpect (char *bufp, int expect) 01185 { 01186 int i; 01187 char *pos; 01188 01189 for (pos = bufp, i = 0; i < expect; i++) 01190 { 01191 skipwhite (&pos); 01192 if (!isdigit ((unsigned char)*pos)) 01193 { 01194 return -1; 01195 } 01196 for (; *pos != '\0' && isdigit ((unsigned char)*pos); pos++) 01197 { 01198 } 01199 } 01200 skipwhite (&pos); 01201 return (*pos == '\0')? expect: -1; 01202 } 01203 01213 static void 01214 skipwhite (/*@exposed@*/char **pos) 01215 { 01216 for (; **pos != '\0' && isspace ((unsigned char)**pos); (*pos)++) 01217 { 01218 } 01219 } 01220 01221
1.7.6.1