PLplot
5.10.0
|
00001 // xId: pdfutils.c 11966 2011-10-14 07:10:05Z andrewross $ 00002 // 00003 // pdf_utils.c 00004 // 00005 // Copyright (C) 1992, 1993, 1994, 1995 00006 // Maurice LeBrun mjl@dino.ph.utexas.edu 00007 // Institute for Fusion Studies University of Texas at Austin 00008 // 00009 // Copyright (C) 2004 Joao Cardoso 00010 // Copyright (C) 2004 Alan W. Irwin 00011 // Copyright (C) 2004 Andrew Ross 00012 // 00013 // This file is part of PLplot. 00014 // 00015 // PLplot is free software; you can redistribute it and/or modify 00016 // it under the terms of the GNU Library General Public License as published 00017 // by the Free Software Foundation; either version 2 of the License, or 00018 // (at your option) any later version. 00019 // 00020 // PLplot is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 // GNU Library General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU Library General Public License 00026 // along with PLplot; if not, write to the Free Software 00027 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00028 // 00029 //-------------------------------------------------------------------------- 00030 // 00031 00036 00037 #define NEED_PLDEBUG 00038 #include "plplotP.h" 00039 00040 static void print_ieeef( float *, U_LONG * ); 00041 static int pdf_wrx( const U_CHAR *x, long nitems, PDFstrm *pdfs ); 00042 00043 static int debug = 0; 00044 00045 //-------------------------------------------------------------------------- 00046 // void pdf_set (string, value) 00047 // 00053 //-------------------------------------------------------------------------- 00054 00055 void 00056 pdf_set( char *option, int value ) 00057 { 00058 if ( !strcmp( option, "debug" ) ) 00059 debug = value; 00060 } 00061 00062 //-------------------------------------------------------------------------- 00063 // pdf_fopen() 00064 // 00071 //-------------------------------------------------------------------------- 00072 00073 PDFstrm * 00074 pdf_fopen( const char *filename, const char *mode ) 00075 { 00076 PDFstrm *pdfs; 00077 00078 dbug_enter( "pdf_fopen" ); 00079 00080 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) ); 00081 00082 if ( pdfs != NULL ) 00083 { 00084 pdfs->buffer = NULL; 00085 pdfs->file = NULL; 00086 pdfs->bp = 0; 00087 #ifdef PLPLOT_USE_TCL_CHANNELS 00088 pdfs->tclChan = NULL; 00089 if ( 1 ) 00090 { 00091 char new_mode[3]; 00092 int binary = 0; 00093 char *m, *p; 00094 00095 // Copy over the mode, removing 'b' if needed 00096 for ( m = mode, p = new_mode; *m != 0; m++ ) 00097 { 00098 if ( *m == 'b' ) 00099 { 00100 binary = 1; 00101 } 00102 else 00103 { 00104 *p = *m; 00105 p++; 00106 } 00107 } 00108 *p = 0; 00109 00110 pdfs->tclChan = Tcl_OpenFileChannel( NULL, filename, new_mode, 0 ); 00111 if ( pdfs->tclChan == NULL ) 00112 { 00113 pdf_close( pdfs ); 00114 pdfs = NULL; 00115 } 00116 else 00117 { 00118 if ( binary ) 00119 { 00120 Tcl_SetChannelOption( NULL, pdfs->tclChan, "-translation", 00121 "binary" ); 00122 } 00123 } 00124 } 00125 #else 00126 pdfs->file = fopen( filename, mode ); 00127 if ( pdfs->file == NULL ) 00128 { 00129 pdf_close( pdfs ); 00130 pdfs = NULL; 00131 } 00132 #endif 00133 } 00134 00135 return pdfs; 00136 } 00137 00138 //-------------------------------------------------------------------------- 00139 // pdf_bopen() 00140 // 00149 //-------------------------------------------------------------------------- 00150 00151 PDFstrm * 00152 pdf_bopen( U_CHAR *buffer, size_t bufmax ) 00153 { 00154 PDFstrm *pdfs; 00155 00156 dbug_enter( "pdf_bopen" ); 00157 00158 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) ); 00159 00160 if ( pdfs != NULL ) 00161 { 00162 pdfs->file = NULL; 00163 #ifdef PLPLOT_USE_TCL_CHANNELS 00164 pdfs->tclChan = NULL; 00165 #endif 00166 pdfs->bp = 0; 00167 00168 if ( buffer == NULL ) 00169 { 00170 if ( bufmax > 0 ) 00171 pdfs->bufmax = bufmax; 00172 else 00173 pdfs->bufmax = 2048; 00174 00175 pdfs->buffer = (U_CHAR *) malloc( pdfs->bufmax ); 00176 if ( pdfs->buffer == NULL ) 00177 { 00178 pdf_close( pdfs ); 00179 pdfs = NULL; 00180 } 00181 } 00182 else 00183 { 00184 pdfs->bufmax = bufmax; 00185 pdfs->buffer = buffer; 00186 } 00187 } 00188 00189 return pdfs; 00190 } 00191 00192 //-------------------------------------------------------------------------- 00193 // pdf_finit() 00194 // 00201 //-------------------------------------------------------------------------- 00202 00203 PDFstrm * 00204 pdf_finit( FILE *file ) 00205 { 00206 PDFstrm *pdfs; 00207 00208 dbug_enter( "pdf_finit" ); 00209 00210 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) ); 00211 00212 if ( pdfs != NULL ) 00213 { 00214 pdfs->buffer = NULL; 00215 pdfs->file = file; 00216 #ifdef PLPLOT_USE_TCL_CHANNELS 00217 pdfs->tclChan = NULL; 00218 #endif 00219 pdfs->bp = 0; 00220 } 00221 00222 return pdfs; 00223 } 00224 00225 //-------------------------------------------------------------------------- 00226 // pdf_close() 00227 // 00235 //-------------------------------------------------------------------------- 00236 00237 int 00238 pdf_close( PDFstrm *pdfs ) 00239 { 00240 dbug_enter( "pdf_close" ); 00241 00242 if ( pdfs != NULL ) 00243 { 00244 if ( pdfs->file != NULL ) 00245 { 00246 fclose( pdfs->file ); 00247 #ifdef PLPLOT_USE_TCL_CHANNELS 00248 } 00249 else if ( pdfs->tclChan != NULL ) 00250 { 00251 Tcl_Close( NULL, pdfs->tclChan ); 00252 #endif 00253 } 00254 else if ( pdfs->buffer != NULL ) 00255 { 00256 free( (void *) pdfs->buffer ); 00257 } 00258 free( (void *) pdfs ); 00259 } 00260 return 0; 00261 } 00262 00263 //-------------------------------------------------------------------------- 00264 // int pdf_putc() 00265 // 00273 //-------------------------------------------------------------------------- 00274 00275 int 00276 pdf_putc( int c, PDFstrm *pdfs ) 00277 { 00278 int result = EOF; 00279 00280 if ( pdfs->file != NULL ) 00281 { 00282 result = putc( c, pdfs->file ); 00283 pdfs->bp++; 00284 #ifdef PLPLOT_USE_TCL_CHANNELS 00285 } 00286 else if ( pdfs->tclChan != NULL ) 00287 { 00288 result = Tcl_WriteChars( pdfs->tclChan, &c, 1 ); 00289 pdfs->bp++; 00290 #endif 00291 } 00292 else if ( pdfs->buffer != NULL ) 00293 { 00294 if ( pdfs->bp >= pdfs->bufmax ) 00295 { 00296 pldebug( "pdf_putc", 00297 "Increasing buffer to %d bytes\n", pdfs->bufmax ); 00298 pdfs->bufmax += 512; 00299 if ( ( pdfs->buffer = (U_CHAR *) realloc( (void *) pdfs->buffer, pdfs->bufmax ) ) == NULL ) 00300 { 00301 plexit( "pdf_putc: Insufficient memory" ); 00302 } 00303 } 00304 pdfs->buffer[pdfs->bp++] = (unsigned char) c; 00305 result = c; 00306 } 00307 else 00308 plexit( "pdf_putc: Illegal operation" ); 00309 00310 return result; 00311 } 00312 00313 //-------------------------------------------------------------------------- 00314 // int pdf_getc() 00315 // 00322 //-------------------------------------------------------------------------- 00323 00324 int 00325 pdf_getc( PDFstrm *pdfs ) 00326 { 00327 int result = EOF; 00328 00329 if ( pdfs->file != NULL ) 00330 { 00331 result = getc( pdfs->file ); 00332 pdfs->bp++; 00333 #ifdef PLPLOT_USE_TCL_CHANNELS 00334 } 00335 else if ( pdfs->tclChan != NULL ) 00336 { 00337 result = Tcl_Read( pdfs->tclChan, &result, 1 ); 00338 pdfs->bp++; 00339 #endif 00340 } 00341 else if ( pdfs->buffer != NULL ) 00342 { 00343 if ( pdfs->bp < pdfs->bufmax ) 00344 result = pdfs->buffer[pdfs->bp++]; 00345 } 00346 else 00347 plexit( "pdf_getc: Illegal operation" ); 00348 00349 return result; 00350 } 00351 00352 //-------------------------------------------------------------------------- 00353 // int pdf_ungetc() 00354 // 00362 //-------------------------------------------------------------------------- 00363 00364 int 00365 pdf_ungetc( int c, PDFstrm *pdfs ) 00366 { 00367 int result = EOF; 00368 00369 if ( pdfs->file != NULL ) 00370 { 00371 result = ungetc( c, pdfs->file ); 00372 if ( pdfs->bp > 0 ) 00373 pdfs->bp--; 00374 #ifdef PLPLOT_USE_TCL_CHANNELS 00375 } 00376 else if ( pdfs->tclChan != NULL ) 00377 { 00378 result = Tcl_Ungets( pdfs->tclChan, &c, 1, 0 ); 00379 if ( pdfs->bp > 0 ) 00380 pdfs->bp--; 00381 #endif 00382 } 00383 else if ( pdfs->buffer != NULL ) 00384 { 00385 if ( pdfs->bp > 0 ) 00386 { 00387 pdfs->buffer[--pdfs->bp] = (unsigned char) c; 00388 result = c; 00389 } 00390 } 00391 else 00392 plexit( "pdf_ungetc: Illegal operation" ); 00393 00394 return result; 00395 } 00396 00397 //-------------------------------------------------------------------------- 00398 // int pdf_wrx() 00399 // 00408 //-------------------------------------------------------------------------- 00409 00410 static int 00411 pdf_wrx( const U_CHAR *x, long nitems, PDFstrm *pdfs ) 00412 { 00413 int i, result = 0; 00414 00415 if ( pdfs->file != NULL ) 00416 { 00417 result = (int) fwrite( x, 1, (size_t) nitems, pdfs->file ); 00418 pdfs->bp += (size_t) nitems; 00419 #ifdef PLPLOT_USE_TCL_CHANNELS 00420 } 00421 else if ( pdfs->tclChan != NULL ) 00422 { 00423 result = Tcl_Write( pdfs->tclChan, x, nitems ); 00424 pdfs->bp += nitems; 00425 #endif 00426 } 00427 else if ( pdfs->buffer != NULL ) 00428 { 00429 for ( i = 0; i < nitems; i++ ) 00430 { 00431 if ( pdfs->bp >= pdfs->bufmax ) 00432 { 00433 pldebug( "pdf_wrx", 00434 "Increasing buffer to %d bytes\n", pdfs->bufmax ); 00435 pdfs->bufmax += 512; 00436 if ( ( pdfs->buffer = (U_CHAR *) 00437 realloc( (void *) ( pdfs->buffer ), pdfs->bufmax ) ) == NULL ) 00438 { 00439 plexit( "pdf_wrx: Insufficient memory" ); 00440 } 00441 } 00442 pdfs->buffer[pdfs->bp++] = x[i]; 00443 } 00444 result = i; 00445 } 00446 00447 return result; 00448 } 00449 00450 //-------------------------------------------------------------------------- 00451 // int pdf_rdx() 00452 // 00461 //-------------------------------------------------------------------------- 00462 00463 int 00464 pdf_rdx( U_CHAR *x, long nitems, PDFstrm *pdfs ) 00465 { 00466 int i, result = 0; 00467 00468 if ( pdfs->file != NULL ) 00469 { 00470 result = (int) fread( x, 1, (size_t) nitems, pdfs->file ); 00471 pdfs->bp += (size_t) nitems; 00472 #ifdef PLPLOT_USE_TCL_CHANNELS 00473 } 00474 else if ( pdfs->tclChan != NULL ) 00475 { 00476 result = Tcl_ReadRaw( pdfs->tclChan, x, nitems ); 00477 pdfs->bp += nitems; 00478 #endif 00479 } 00480 else if ( pdfs->buffer != NULL ) 00481 { 00482 for ( i = 0; i < nitems; i++ ) 00483 { 00484 if ( pdfs->bp > pdfs->bufmax ) 00485 break; 00486 x[i] = pdfs->buffer[pdfs->bp++]; 00487 } 00488 result = i; 00489 } 00490 00491 return result; 00492 } 00493 00494 //-------------------------------------------------------------------------- 00495 // pdf_wr_header() 00496 // 00506 //-------------------------------------------------------------------------- 00507 00508 int 00509 pdf_wr_header( PDFstrm *pdfs, const char *header ) 00510 { 00511 int i; 00512 00513 dbug_enter( "pdf_wr_header" ); 00514 00515 for ( i = 0; i < 79; i++ ) 00516 { 00517 if ( header[i] == '\0' ) 00518 break; 00519 if ( pdf_putc( header[i], pdfs ) == EOF ) 00520 return PDF_WRERR; 00521 } 00522 if ( pdf_putc( '\n', pdfs ) == EOF ) 00523 return PDF_WRERR; 00524 00525 return 0; 00526 } 00527 00528 //-------------------------------------------------------------------------- 00529 // int pdf_rd_header 00530 // 00539 //-------------------------------------------------------------------------- 00540 00541 int 00542 pdf_rd_header( PDFstrm *pdfs, char *header ) 00543 { 00544 int i, c; 00545 00546 dbug_enter( "pdf_rd_header" ); 00547 00548 for ( i = 0; i < 79; i++ ) 00549 { 00550 if ( ( c = pdf_getc( pdfs ) ) == EOF ) 00551 return PDF_RDERR; 00552 00553 header[i] = (char) c; 00554 if ( header[i] == '\n' ) 00555 break; 00556 } 00557 header[i] = '\0'; // NULL terminate 00558 return 0; 00559 } 00560 00561 //-------------------------------------------------------------------------- 00562 // pdf_wr_string() 00563 // 00571 //-------------------------------------------------------------------------- 00572 00573 int 00574 pdf_wr_string( PDFstrm *pdfs, const char *string ) 00575 { 00576 int i; 00577 00578 dbug_enter( "pdf_wr_string" ); 00579 00580 for ( i = 0; i <= (int) strlen( string ); i++ ) 00581 { 00582 if ( pdf_putc( string[i], pdfs ) == EOF ) 00583 return PDF_WRERR; 00584 } 00585 00586 return 0; 00587 } 00588 00589 //-------------------------------------------------------------------------- 00590 // int pdf_rd_string 00591 // 00601 //-------------------------------------------------------------------------- 00602 00603 int 00604 pdf_rd_string( PDFstrm *pdfs, char *string, int nmax ) 00605 { 00606 int i, c; 00607 00608 dbug_enter( "pdf_rd_string" ); 00609 00610 for ( i = 0; i < nmax; i++ ) 00611 { 00612 if ( ( c = pdf_getc( pdfs ) ) == EOF ) 00613 return PDF_RDERR; 00614 00615 string[i] = (char) c; 00616 if ( c == '\0' ) 00617 break; 00618 } 00619 string[i] = '\0'; // handle boundary case 00620 return 0; 00621 } 00622 00623 //-------------------------------------------------------------------------- 00624 // int pdf_wr_1byte() 00625 // 00633 //-------------------------------------------------------------------------- 00634 00635 int 00636 pdf_wr_1byte( PDFstrm *pdfs, U_CHAR s ) 00637 { 00638 U_CHAR x[1]; 00639 00640 x[0] = s; 00641 if ( pdf_wrx( x, 1, pdfs ) != 1 ) 00642 return PDF_WRERR; 00643 00644 return 0; 00645 } 00646 00647 //-------------------------------------------------------------------------- 00648 // int pdf_rd_1byte() 00649 // 00657 //-------------------------------------------------------------------------- 00658 00659 int 00660 pdf_rd_1byte( PDFstrm *pdfs, U_CHAR *ps ) 00661 { 00662 U_CHAR x[1]; 00663 00664 if ( !pdf_rdx( x, 1, pdfs ) ) 00665 return PDF_RDERR; 00666 00667 *ps = ( (U_CHAR) x[0] ); 00668 return 0; 00669 } 00670 00671 //-------------------------------------------------------------------------- 00672 // pdf_wr_2bytes() 00673 // 00681 //-------------------------------------------------------------------------- 00682 00683 int 00684 pdf_wr_2bytes( PDFstrm *pdfs, U_SHORT s ) 00685 { 00686 U_CHAR x[2]; 00687 00688 x[0] = (U_CHAR) ( (U_LONG) ( s & (U_LONG) 0x00FF ) ); 00689 x[1] = (U_CHAR) ( (U_LONG) ( s & (U_LONG) 0xFF00 ) >> 8 ); 00690 00691 if ( pdf_wrx( x, 2, pdfs ) != 2 ) 00692 return PDF_WRERR; 00693 00694 return 0; 00695 } 00696 00697 //-------------------------------------------------------------------------- 00698 // pdf_rd_2bytes() 00699 // 00707 //-------------------------------------------------------------------------- 00708 00709 int 00710 pdf_rd_2bytes( PDFstrm *pdfs, U_SHORT *ps ) 00711 { 00712 U_CHAR x[2]; 00713 U_SHORT xs; 00714 00715 if ( !pdf_rdx( x, 2, pdfs ) ) 00716 return PDF_RDERR; 00717 00718 *ps = 0; 00719 xs = (U_SHORT) x[0]; 00720 *ps |= xs; 00721 xs = (U_SHORT) ( (U_SHORT) x[1] << 8 ); 00722 *ps |= xs; 00723 00724 return 0; 00725 } 00726 00727 //-------------------------------------------------------------------------- 00728 // pdf_wr_2nbytes() 00729 // 00738 //-------------------------------------------------------------------------- 00739 00740 int 00741 pdf_wr_2nbytes( PDFstrm *pdfs, U_SHORT *s, PLINT n ) 00742 { 00743 PLINT i; 00744 U_CHAR x[2]; 00745 00746 for ( i = 0; i < n; i++ ) 00747 { 00748 x[0] = (U_CHAR) ( (U_LONG) ( s[i] & (U_LONG) 0x00FF ) ); 00749 x[1] = (U_CHAR) ( (U_LONG) ( s[i] & (U_LONG) 0xFF00 ) >> 8 ); 00750 00751 if ( pdf_wrx( x, 2, pdfs ) != 2 ) 00752 return PDF_WRERR; 00753 } 00754 return 0; 00755 } 00756 00757 //-------------------------------------------------------------------------- 00758 // pdf_rd_2nbytes() 00759 // 00768 //-------------------------------------------------------------------------- 00769 00770 int 00771 pdf_rd_2nbytes( PDFstrm *pdfs, U_SHORT *s, PLINT n ) 00772 { 00773 PLINT i; 00774 U_CHAR x[2]; 00775 U_SHORT xs; 00776 00777 for ( i = 0; i < n; i++ ) 00778 { 00779 if ( !pdf_rdx( x, 2, pdfs ) ) 00780 return PDF_RDERR; 00781 00782 s[i] = 0; 00783 xs = (U_SHORT) x[0]; 00784 s[i] |= xs; 00785 xs = (U_SHORT) ( (U_SHORT) x[1] << 8 ); 00786 s[i] |= xs; 00787 } 00788 return 0; 00789 } 00790 00791 //-------------------------------------------------------------------------- 00792 // pdf_wr_4bytes() 00793 // 00801 //-------------------------------------------------------------------------- 00802 00803 int 00804 pdf_wr_4bytes( PDFstrm *pdfs, U_LONG s ) 00805 { 00806 U_CHAR x[4]; 00807 00808 x[0] = (U_CHAR) ( ( s & (U_LONG) 0x000000FF ) ); 00809 x[1] = (U_CHAR) ( ( s & (U_LONG) 0x0000FF00 ) >> 8 ); 00810 x[2] = (U_CHAR) ( ( s & (U_LONG) 0x00FF0000 ) >> 16 ); 00811 x[3] = (U_CHAR) ( ( s & (U_LONG) 0xFF000000 ) >> 24 ); 00812 00813 if ( pdf_wrx( x, 4, pdfs ) != 4 ) 00814 return PDF_WRERR; 00815 00816 return 0; 00817 } 00818 00819 //-------------------------------------------------------------------------- 00820 // pdf_rd_4bytes() 00821 // 00829 //-------------------------------------------------------------------------- 00830 00831 int 00832 pdf_rd_4bytes( PDFstrm *pdfs, U_LONG *ps ) 00833 { 00834 U_CHAR x[4]; 00835 00836 if ( !pdf_rdx( x, 4, pdfs ) ) 00837 return PDF_RDERR; 00838 00839 *ps = 0; 00840 *ps |= (U_LONG) x[0]; 00841 *ps |= (U_LONG) x[1] << 8; 00842 *ps |= (U_LONG) x[2] << 16; 00843 *ps |= (U_LONG) x[3] << 24; 00844 00845 return 0; 00846 } 00847 00848 //-------------------------------------------------------------------------- 00849 // Here is the IEEE floating point specification in both 32 bit and 64 bit 00850 // precisions, from page 9 of "IEEE Standard for Binary Floating-Point 00851 // Arithmetic", copyright 1985, IEEE Std 754-1985: 00852 // 00853 // 00854 // Single Format 00855 // 00856 // msb means most significant bit 00857 // lsb means least significant bit 00858 // 00859 // 1 8 23 00860 //-------------------------------------------------------------------------- 00861 // | | | | 00862 // | s | e | f | 00863 // |___|________________|______________________________________________| 00864 // msb lsb msb lsb 00865 // 00866 // 00867 // 00868 // Double Format 00869 // 00870 // msb means most significant bit 00871 // lsb means least significant bit 00872 // 00873 // 1 11 52 00874 //-------------------------------------------------------------------------- 00875 // | | | | 00876 // | s | e | f | 00877 // |___|________________|______________________________________________| 00878 // msb lsb msb lsb 00879 // 00880 // 00881 // (Thanks to: Andy Mai (mai@ncar.ucar.edu)) 00882 // 00883 // 00884 // According to "inmos: Transputer instruction set" the IEEE standard 00885 // specifies the floating format as: 00886 // 00887 // s exp frac 00888 // 00889 // Where: s = sign bit (1 bit) 00890 // exp = exponent (8 bits for 32 bit float / 11 bits for 64 bit float) 00891 // frac = fraction (23 bits for 32 bit float / 52 bits for 64 bit float) 00892 // 00893 // value of (s exp frac) = (-1)^s * 1.frac * 2^(exp-bias) ; if exp not 0 00894 // (-1)^s * 0.frac * 2^(1-bias) ; if exp = 0 00895 // 00896 // where bias = 127 for 32 bit float 00897 // bias = 1023 for 64 bit float 00898 // 00899 // (Thanks to: Tom Bjorkholm(TBJORKHOLM@abo.fi)) 00900 // 00901 //-------------------------------------------------------------------------- 00902 00903 //-------------------------------------------------------------------------- 00904 // int pdf_wr_ieeef() 00905 // 00913 //-------------------------------------------------------------------------- 00914 00915 int 00916 pdf_wr_ieeef( PDFstrm *pdfs, float f ) 00917 { 00918 double fdbl, fmant, f_new; 00919 float fsgl, f_tmp; 00920 int istat, ex, e_new, e_off; 00921 const int bias = 127; 00922 U_LONG value, s_ieee, e_ieee, f_ieee; 00923 00924 if ( f == 0.0 ) 00925 { 00926 value = 0; 00927 return ( pdf_wr_4bytes( pdfs, value ) ); 00928 } 00929 fdbl = f; 00930 fsgl = (float) fdbl; 00931 fmant = frexp( fdbl, &ex ); 00932 00933 if ( fmant < 0 ) 00934 s_ieee = 1; 00935 else 00936 s_ieee = 0; 00937 00938 fmant = fabs( fmant ); 00939 f_new = 2 * fmant; 00940 e_new = ex - 1; 00941 00942 if ( e_new < 1 - bias ) 00943 { 00944 e_off = e_new - ( 1 - bias ); 00945 e_ieee = 0; 00946 f_tmp = (float) ( f_new * pow( (double) 2.0, (double) e_off ) ); 00947 } 00948 else 00949 { 00950 e_ieee = (U_LONG) ( e_new + bias ); 00951 f_tmp = (float) ( f_new - 1 ); 00952 } 00953 f_ieee = (U_LONG) ( f_tmp * 8388608 ); // multiply by 2^23 00954 00955 if ( e_ieee > 255 ) 00956 { 00957 if ( debug ) 00958 fprintf( stderr, "pdf_wr_ieeef: Warning -- overflow\n" ); 00959 e_ieee = 255; 00960 } 00961 00962 s_ieee = s_ieee << 31; 00963 e_ieee = e_ieee << 23; 00964 00965 value = s_ieee | e_ieee | f_ieee; 00966 00967 if ( ( istat = pdf_wr_4bytes( pdfs, value ) ) ) 00968 return ( istat ); 00969 00970 if ( debug ) 00971 { 00972 fprintf( stderr, "Float value (written): %g\n", fsgl ); 00973 print_ieeef( &fsgl, &value ); 00974 } 00975 00976 return 0; 00977 } 00978 00979 //-------------------------------------------------------------------------- 00980 // int pdf_rd_ieeef() 00981 // 00989 //-------------------------------------------------------------------------- 00990 00991 int 00992 pdf_rd_ieeef( PDFstrm *pdfs, float *pf ) 00993 { 00994 double f_new, f_tmp; 00995 float fsgl; 00996 int istat, ex, bias = 127; 00997 U_LONG value, s_ieee, e_ieee, f_ieee; 00998 00999 if ( ( istat = pdf_rd_4bytes( pdfs, &value ) ) ) 01000 return ( istat ); 01001 01002 s_ieee = ( value & (U_LONG) 0x80000000 ) >> 31; 01003 e_ieee = ( value & (U_LONG) 0x7F800000 ) >> 23; 01004 f_ieee = ( value & (U_LONG) 0x007FFFFF ); 01005 01006 f_tmp = (double) f_ieee / 8388608.0; // divide by 2^23 01007 01008 if ( e_ieee == 0 ) 01009 { 01010 ex = 1 - bias; 01011 f_new = f_tmp; 01012 } 01013 else 01014 { 01015 ex = (int) e_ieee - bias; 01016 f_new = 1.0 + f_tmp; 01017 } 01018 01019 fsgl = (float) ( f_new * pow( 2.0, (double) ex ) ); 01020 if ( s_ieee == 1 ) 01021 fsgl = -fsgl; 01022 01023 *pf = fsgl; 01024 01025 if ( debug ) 01026 { 01027 fprintf( stderr, "Float value (read): %g\n", fsgl ); 01028 print_ieeef( &fsgl, &value ); 01029 } 01030 01031 return 0; 01032 } 01033 01034 //-------------------------------------------------------------------------- 01035 // print_ieeef() 01036 // 01045 //-------------------------------------------------------------------------- 01046 01047 static void 01048 print_ieeef( float *vx, U_LONG *vy ) 01049 { 01050 int i; 01051 U_LONG f, *x = (U_LONG *) vx, *y = vy; 01052 char bitrep[33]; 01053 01054 bitrep[32] = '\0'; 01055 01056 f = *x; 01057 for ( i = 0; i < 32; i++ ) 01058 { 01059 if ( f & 1 ) 01060 bitrep[32 - i - 1] = '1'; 01061 else 01062 bitrep[32 - i - 1] = '0'; 01063 f = f >> 1; 01064 } 01065 fprintf( stderr, "Binary representation: " ); 01066 fprintf( stderr, "%s\n", bitrep ); 01067 01068 f = *y; 01069 for ( i = 0; i < 32; i++ ) 01070 { 01071 if ( f & 1 ) 01072 bitrep[32 - i - 1] = '1'; 01073 else 01074 bitrep[32 - i - 1] = '0'; 01075 f = f >> 1; 01076 } 01077 fprintf( stderr, "Converted representation: " ); 01078 fprintf( stderr, "%s\n\n", bitrep ); 01079 01080 return; 01081 } 01082 01083 //-------------------------------------------------------------------------- 01084 // plAlloc2dGrid() 01085 // 01101 //-------------------------------------------------------------------------- 01102 01103 void 01104 plAlloc2dGrid( PLFLT ***f, PLINT nx, PLINT ny ) 01105 { 01106 PLINT i; 01107 01108 if ( ( *f = (PLFLT **) calloc( (size_t) nx, sizeof ( PLFLT * ) ) ) == NULL ) 01109 plexit( "Memory allocation error in \"plAlloc2dGrid\"" ); 01110 01111 for ( i = 0; i < nx; i++ ) 01112 { 01113 if ( ( ( *f )[i] = (PLFLT *) calloc( (size_t) ny, sizeof ( PLFLT ) ) ) == NULL ) 01114 plexit( "Memory allocation error in \"plAlloc2dGrid\"" ); 01115 } 01116 } 01117 01118 //-------------------------------------------------------------------------- 01119 // Free2dGrid() 01120 // 01126 //-------------------------------------------------------------------------- 01127 01128 void 01129 plFree2dGrid( PLFLT **f, PLINT nx, PLINT PL_UNUSED( ny ) ) 01130 { 01131 PLINT i; 01132 01133 for ( i = 0; i < nx; i++ ) 01134 free( (void *) f[i] ); 01135 01136 free( (void *) f ); 01137 } 01138 01139 //-------------------------------------------------------------------------- 01140 // MinMax2dGrid() 01141 // 01151 //-------------------------------------------------------------------------- 01152 01153 void 01154 plMinMax2dGrid( const PLFLT * const*f, PLINT nx, PLINT ny, PLFLT *fnmax, PLFLT *fnmin ) 01155 { 01156 int i, j; 01157 PLFLT m, M; 01158 01159 if ( !isfinite( f[0][0] ) ) 01160 { 01161 M = -HUGE_VAL; 01162 m = HUGE_VAL; 01163 } 01164 else 01165 M = m = f[0][0]; 01166 01167 for ( i = 0; i < nx; i++ ) 01168 { 01169 for ( j = 0; j < ny; j++ ) 01170 { 01171 if ( !isfinite( f[i][j] ) ) 01172 continue; 01173 if ( f[i][j] > M ) 01174 M = f[i][j]; 01175 if ( f[i][j] < m ) 01176 m = f[i][j]; 01177 } 01178 } 01179 *fnmax = M; 01180 *fnmin = m; 01181 }