00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define NEED_PLDEBUG
00036 #include "plplotP.h"
00037
00038 static void print_ieeef( void *, void * );
00039 static int pdf_wrx( const U_CHAR *x, long nitems, PDFstrm *pdfs );
00040
00041 static int debug = 0;
00042
00043
00044
00045
00046
00047
00048
00049 void
00050 pdf_set( char *option, int value )
00051 {
00052 if ( !strcmp( option, "debug" ) )
00053 debug = value;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063 PDFstrm *
00064 pdf_fopen( const char *filename, const char *mode )
00065 {
00066 PDFstrm *pdfs;
00067
00068 dbug_enter( "pdf_fopen" );
00069
00070 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) );
00071
00072 if ( pdfs != NULL )
00073 {
00074 pdfs->buffer = NULL;
00075 pdfs->file = NULL;
00076 pdfs->bp = 0;
00077 #ifdef PLPLOT_USE_TCL_CHANNELS
00078 pdfs->tclChan = NULL;
00079 if ( 1 )
00080 {
00081 char new_mode[3];
00082 int binary = 0;
00083 char *m, *p;
00084
00085
00086 for ( m = mode, p = new_mode; *m != 0; m++ )
00087 {
00088 if ( *m == 'b' )
00089 {
00090 binary = 1;
00091 }
00092 else
00093 {
00094 *p = *m;
00095 p++;
00096 }
00097 }
00098 *p = 0;
00099
00100 pdfs->tclChan = Tcl_OpenFileChannel( NULL, filename, new_mode, 0 );
00101 if ( pdfs->tclChan == NULL )
00102 {
00103 pdf_close( pdfs );
00104 pdfs = NULL;
00105 }
00106 else
00107 {
00108 if ( binary )
00109 {
00110 Tcl_SetChannelOption( NULL, pdfs->tclChan, "-translation",
00111 "binary" );
00112 }
00113 }
00114 }
00115 #else
00116 pdfs->file = fopen( filename, mode );
00117 if ( pdfs->file == NULL )
00118 {
00119 pdf_close( pdfs );
00120 pdfs = NULL;
00121 }
00122 #endif
00123 }
00124
00125 return pdfs;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 PDFstrm *
00136 pdf_bopen( U_CHAR *buffer, long bufmax )
00137 {
00138 PDFstrm *pdfs;
00139
00140 dbug_enter( "pdf_bopen" );
00141
00142 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) );
00143
00144 if ( pdfs != NULL )
00145 {
00146 pdfs->file = NULL;
00147 #ifdef PLPLOT_USE_TCL_CHANNELS
00148 pdfs->tclChan = NULL;
00149 #endif
00150 pdfs->bp = 0;
00151
00152 if ( buffer == NULL )
00153 {
00154 if ( bufmax > 0 )
00155 pdfs->bufmax = bufmax;
00156 else
00157 pdfs->bufmax = 2048;
00158
00159 pdfs->buffer = (U_CHAR *) malloc( pdfs->bufmax );
00160 if ( pdfs->buffer == NULL )
00161 {
00162 pdf_close( pdfs );
00163 pdfs = NULL;
00164 }
00165 }
00166 else
00167 {
00168 pdfs->bufmax = bufmax;
00169 pdfs->buffer = buffer;
00170 }
00171 }
00172
00173 return pdfs;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 PDFstrm *
00184 pdf_finit( FILE *file )
00185 {
00186 PDFstrm *pdfs;
00187
00188 dbug_enter( "pdf_finit" );
00189
00190 pdfs = (PDFstrm *) malloc( sizeof ( PDFstrm ) );
00191
00192 if ( pdfs != NULL )
00193 {
00194 pdfs->buffer = NULL;
00195 pdfs->file = file;
00196 #ifdef PLPLOT_USE_TCL_CHANNELS
00197 pdfs->tclChan = NULL;
00198 #endif
00199 pdfs->bp = 0;
00200 }
00201
00202 return pdfs;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 int
00213 pdf_close( PDFstrm *pdfs )
00214 {
00215 dbug_enter( "pdf_close" );
00216
00217 if ( pdfs != NULL )
00218 {
00219 if ( pdfs->file != NULL )
00220 {
00221 fclose( pdfs->file );
00222 #ifdef PLPLOT_USE_TCL_CHANNELS
00223 }
00224 else if ( pdfs->tclChan != NULL )
00225 {
00226 Tcl_Close( NULL, pdfs->tclChan );
00227 #endif
00228 }
00229 else if ( pdfs->buffer != NULL )
00230 {
00231 free( (void *) pdfs->buffer );
00232 }
00233 free( (void *) pdfs );
00234 }
00235 return 0;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 int
00245 pdf_putc( int c, PDFstrm *pdfs )
00246 {
00247 int result = EOF;
00248
00249 if ( pdfs->file != NULL )
00250 {
00251 result = putc( c, pdfs->file );
00252 pdfs->bp++;
00253 #ifdef PLPLOT_USE_TCL_CHANNELS
00254 }
00255 else if ( pdfs->tclChan != NULL )
00256 {
00257 result = Tcl_WriteChars( pdfs->tclChan, &c, 1 );
00258 pdfs->bp++;
00259 #endif
00260 }
00261 else if ( pdfs->buffer != NULL )
00262 {
00263 if ( pdfs->bp >= pdfs->bufmax )
00264 {
00265 pldebug( "pdf_putc",
00266 "Increasing buffer to %d bytes\n", pdfs->bufmax );
00267 pdfs->bufmax += 512;
00268 if ( ( pdfs->buffer = (U_CHAR *) realloc( (void *) pdfs->buffer, pdfs->bufmax ) ) == NULL )
00269 {
00270 plexit( "pdf_putc: Insufficient memory" );
00271 }
00272 }
00273 pdfs->buffer[pdfs->bp++] = c;
00274 result = c;
00275 }
00276 else
00277 plexit( "pdf_putc: Illegal operation" );
00278
00279 return result;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 int
00289 pdf_getc( PDFstrm *pdfs )
00290 {
00291 int result = EOF;
00292
00293 if ( pdfs->file != NULL )
00294 {
00295 result = getc( pdfs->file );
00296 pdfs->bp++;
00297 #ifdef PLPLOT_USE_TCL_CHANNELS
00298 }
00299 else if ( pdfs->tclChan != NULL )
00300 {
00301 result = Tcl_Read( pdfs->tclChan, &result, 1 );
00302 pdfs->bp++;
00303 #endif
00304 }
00305 else if ( pdfs->buffer != NULL )
00306 {
00307 if ( pdfs->bp < pdfs->bufmax )
00308 result = pdfs->buffer[pdfs->bp++];
00309 }
00310 else
00311 plexit( "pdf_getc: Illegal operation" );
00312
00313 return result;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 int
00323 pdf_ungetc( int c, PDFstrm *pdfs )
00324 {
00325 int result = EOF;
00326
00327 if ( pdfs->file != NULL )
00328 {
00329 result = ungetc( c, pdfs->file );
00330 if ( pdfs->bp > 0 )
00331 pdfs->bp--;
00332 #ifdef PLPLOT_USE_TCL_CHANNELS
00333 }
00334 else if ( pdfs->tclChan != NULL )
00335 {
00336 result = Tcl_Ungets( pdfs->tclChan, &c, 1, 0 );
00337 if ( pdfs->bp > 0 )
00338 pdfs->bp--;
00339 #endif
00340 }
00341 else if ( pdfs->buffer != NULL )
00342 {
00343 if ( pdfs->bp > 0 )
00344 {
00345 pdfs->buffer[--pdfs->bp] = c;
00346 result = c;
00347 }
00348 }
00349 else
00350 plexit( "pdf_ungetc: Illegal operation" );
00351
00352 return result;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 static int
00362 pdf_wrx( const U_CHAR *x, long nitems, PDFstrm *pdfs )
00363 {
00364 int i, result = 0;
00365
00366 if ( pdfs->file != NULL )
00367 {
00368 result = fwrite( x, 1, nitems, pdfs->file );
00369 pdfs->bp += nitems;
00370 #ifdef PLPLOT_USE_TCL_CHANNELS
00371 }
00372 else if ( pdfs->tclChan != NULL )
00373 {
00374 result = Tcl_Write( pdfs->tclChan, x, nitems );
00375 pdfs->bp += nitems;
00376 #endif
00377 }
00378 else if ( pdfs->buffer != NULL )
00379 {
00380 for ( i = 0; i < nitems; i++ )
00381 {
00382 if ( pdfs->bp >= pdfs->bufmax )
00383 {
00384 pldebug( "pdf_wrx",
00385 "Increasing buffer to %d bytes\n", pdfs->bufmax );
00386 pdfs->bufmax += 512;
00387 if ( ( pdfs->buffer = (U_CHAR *)
00388 realloc( (void *) ( pdfs->buffer ), pdfs->bufmax ) ) == NULL )
00389 {
00390 plexit( "pdf_wrx: Insufficient memory" );
00391 }
00392 }
00393 pdfs->buffer[pdfs->bp++] = x[i];
00394 }
00395 result = i;
00396 }
00397
00398 return result;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407 int
00408 pdf_rdx( U_CHAR *x, long nitems, PDFstrm *pdfs )
00409 {
00410 int i, result = 0;
00411
00412 if ( pdfs->file != NULL )
00413 {
00414 result = fread( x, 1, nitems, pdfs->file );
00415 pdfs->bp += nitems;
00416 #ifdef PLPLOT_USE_TCL_CHANNELS
00417 }
00418 else if ( pdfs->tclChan != NULL )
00419 {
00420 result = Tcl_ReadRaw( pdfs->tclChan, x, nitems );
00421 pdfs->bp += nitems;
00422 #endif
00423 }
00424 else if ( pdfs->buffer != NULL )
00425 {
00426 for ( i = 0; i < nitems; i++ )
00427 {
00428 if ( pdfs->bp > pdfs->bufmax )
00429 break;
00430 x[i] = pdfs->buffer[pdfs->bp++];
00431 }
00432 result = i;
00433 }
00434
00435 return result;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 int
00447 pdf_wr_header( PDFstrm *pdfs, char *header )
00448 {
00449 int i;
00450
00451 dbug_enter( "pdf_wr_header" );
00452
00453 for ( i = 0; i < 79; i++ )
00454 {
00455 if ( header[i] == '\0' )
00456 break;
00457 if ( pdf_putc( header[i], pdfs ) == EOF )
00458 return PDF_WRERR;
00459 }
00460 if ( pdf_putc( '\n', pdfs ) == EOF )
00461 return PDF_WRERR;
00462
00463 return 0;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 int
00474 pdf_rd_header( PDFstrm *pdfs, char *header )
00475 {
00476 int i, c;
00477
00478 dbug_enter( "pdf_rd_header" );
00479
00480 for ( i = 0; i < 79; i++ )
00481 {
00482 if ( ( c = pdf_getc( pdfs ) ) == EOF )
00483 return PDF_RDERR;
00484
00485 header[i] = c;
00486 if ( header[i] == '\n' )
00487 break;
00488 }
00489 header[i] = '\0';
00490 return 0;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 int
00500 pdf_wr_string( PDFstrm *pdfs, const char *string )
00501 {
00502 int i;
00503
00504 dbug_enter( "pdf_wr_string" );
00505
00506 for ( i = 0; i <= (int) strlen( string ); i++ )
00507 {
00508 if ( pdf_putc( string[i], pdfs ) == EOF )
00509 return PDF_WRERR;
00510 }
00511
00512 return 0;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522 int
00523 pdf_rd_string( PDFstrm *pdfs, char *string, int nmax )
00524 {
00525 int i, c;
00526
00527 dbug_enter( "pdf_rd_string" );
00528
00529 for ( i = 0; i < nmax; i++ )
00530 {
00531 if ( ( c = pdf_getc( pdfs ) ) == EOF )
00532 return PDF_RDERR;
00533
00534 string[i] = c;
00535 if ( c == '\0' )
00536 break;
00537 }
00538 string[i] = '\0';
00539 return 0;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548 int
00549 pdf_wr_1byte( PDFstrm *pdfs, U_CHAR s )
00550 {
00551 U_CHAR x[1];
00552
00553 x[0] = s;
00554 if ( pdf_wrx( x, 1, pdfs ) != 1 )
00555 return PDF_WRERR;
00556
00557 return 0;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566 int
00567 pdf_rd_1byte( PDFstrm *pdfs, U_CHAR *ps )
00568 {
00569 U_CHAR x[1];
00570
00571 if ( !pdf_rdx( x, 1, pdfs ) )
00572 return PDF_RDERR;
00573
00574 *ps = ( (U_CHAR) x[0] );
00575 return 0;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 int
00585 pdf_wr_2bytes( PDFstrm *pdfs, U_SHORT s )
00586 {
00587 U_CHAR x[2];
00588
00589 x[0] = (U_CHAR) ( (U_LONG) ( s & (U_LONG) 0x00FF ) );
00590 x[1] = (U_CHAR) ( (U_LONG) ( s & (U_LONG) 0xFF00 ) >> 8 );
00591
00592 if ( pdf_wrx( x, 2, pdfs ) != 2 )
00593 return PDF_WRERR;
00594
00595 return 0;
00596 }
00597
00598
00599
00600
00601
00602
00603
00604 int
00605 pdf_rd_2bytes( PDFstrm *pdfs, U_SHORT *ps )
00606 {
00607 U_CHAR x[2];
00608
00609 if ( !pdf_rdx( x, 2, pdfs ) )
00610 return PDF_RDERR;
00611
00612 *ps = 0;
00613 *ps |= (U_LONG) x[0];
00614 *ps |= (U_LONG) x[1] << 8;
00615
00616 return 0;
00617 }
00618
00619
00620
00621
00622
00623
00624
00625 int
00626 pdf_wr_2nbytes( PDFstrm *pdfs, U_SHORT *s, PLINT n )
00627 {
00628 PLINT i;
00629 U_CHAR x[2];
00630
00631 for ( i = 0; i < n; i++ )
00632 {
00633 x[0] = (U_CHAR) ( (U_LONG) ( s[i] & (U_LONG) 0x00FF ) );
00634 x[1] = (U_CHAR) ( (U_LONG) ( s[i] & (U_LONG) 0xFF00 ) >> 8 );
00635
00636 if ( pdf_wrx( x, 2, pdfs ) != 2 )
00637 return PDF_WRERR;
00638 }
00639 return 0;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648 int
00649 pdf_rd_2nbytes( PDFstrm *pdfs, U_SHORT *s, PLINT n )
00650 {
00651 PLINT i;
00652 U_CHAR x[2];
00653
00654 for ( i = 0; i < n; i++ )
00655 {
00656 if ( !pdf_rdx( x, 2, pdfs ) )
00657 return PDF_RDERR;
00658
00659 s[i] = 0;
00660 s[i] |= (U_SHORT) x[0];
00661 s[i] |= (U_SHORT) x[1] << 8;
00662 }
00663 return 0;
00664 }
00665
00666
00667
00668
00669
00670
00671
00672 int
00673 pdf_wr_4bytes( PDFstrm *pdfs, U_LONG s )
00674 {
00675 U_CHAR x[4];
00676
00677 x[0] = (U_CHAR) ( ( s & (U_LONG) 0x000000FF ) );
00678 x[1] = (U_CHAR) ( ( s & (U_LONG) 0x0000FF00 ) >> 8 );
00679 x[2] = (U_CHAR) ( ( s & (U_LONG) 0x00FF0000 ) >> 16 );
00680 x[3] = (U_CHAR) ( ( s & (U_LONG) 0xFF000000 ) >> 24 );
00681
00682 if ( pdf_wrx( x, 4, pdfs ) != 4 )
00683 return PDF_WRERR;
00684
00685 return 0;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694 int
00695 pdf_rd_4bytes( PDFstrm *pdfs, U_LONG *ps )
00696 {
00697 U_CHAR x[4];
00698
00699 if ( !pdf_rdx( x, 4, pdfs ) )
00700 return PDF_RDERR;
00701
00702 *ps = 0;
00703 *ps |= (U_LONG) x[0];
00704 *ps |= (U_LONG) x[1] << 8;
00705 *ps |= (U_LONG) x[2] << 16;
00706 *ps |= (U_LONG) x[3] << 24;
00707
00708 return 0;
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 int
00773 pdf_wr_ieeef( PDFstrm *pdfs, float f )
00774 {
00775 double fdbl, fmant, f_new;
00776 float fsgl, f_tmp;
00777 int istat, exp, e_new, e_off, bias = 127;
00778 U_LONG value, s_ieee, e_ieee, f_ieee;
00779
00780 if ( f == 0.0 )
00781 {
00782 value = 0;
00783 return ( pdf_wr_4bytes( pdfs, value ) );
00784 }
00785 fdbl = f;
00786 fsgl = (float) fdbl;
00787 fmant = frexp( fdbl, &exp );
00788
00789 if ( fmant < 0 )
00790 s_ieee = 1;
00791 else
00792 s_ieee = 0;
00793
00794 fmant = fabs( fmant );
00795 f_new = 2 * fmant;
00796 e_new = exp - 1;
00797
00798 if ( e_new < 1 - bias )
00799 {
00800 e_off = e_new - ( 1 - bias );
00801 e_ieee = 0;
00802 f_tmp = (float) ( f_new * pow( (double) 2.0, (double) e_off ) );
00803 }
00804 else
00805 {
00806 e_ieee = e_new + bias;
00807 f_tmp = (float) ( f_new - 1 );
00808 }
00809 f_ieee = (U_LONG) ( f_tmp * 8388608 );
00810
00811 if ( e_ieee > 255 )
00812 {
00813 if ( debug )
00814 fprintf( stderr, "pdf_wr_ieeef: Warning -- overflow\n" );
00815 e_ieee = 255;
00816 }
00817
00818 s_ieee = s_ieee << 31;
00819 e_ieee = e_ieee << 23;
00820
00821 value = s_ieee | e_ieee | f_ieee;
00822
00823 if ( ( istat = pdf_wr_4bytes( pdfs, value ) ) )
00824 return ( istat );
00825
00826 if ( debug )
00827 {
00828 fprintf( stderr, "Float value (written): %g\n", fsgl );
00829 print_ieeef( &fsgl, &value );
00830 }
00831
00832 return 0;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841 int
00842 pdf_rd_ieeef( PDFstrm *pdfs, float *pf )
00843 {
00844 double f_new, f_tmp;
00845 float fsgl;
00846 int istat, exp, bias = 127;
00847 U_LONG value, s_ieee, e_ieee, f_ieee;
00848
00849 if ( ( istat = pdf_rd_4bytes( pdfs, &value ) ) )
00850 return ( istat );
00851
00852 s_ieee = ( value & (U_LONG) 0x80000000 ) >> 31;
00853 e_ieee = ( value & (U_LONG) 0x7F800000 ) >> 23;
00854 f_ieee = ( value & (U_LONG) 0x007FFFFF );
00855
00856 f_tmp = (double) f_ieee / 8388608.0;
00857
00858 if ( e_ieee == 0 )
00859 {
00860 exp = 1 - bias;
00861 f_new = f_tmp;
00862 }
00863 else
00864 {
00865 exp = (int) e_ieee - bias;
00866 f_new = 1.0 + f_tmp;
00867 }
00868
00869 fsgl = (float) ( f_new * pow( 2.0, (double) exp ) );
00870 if ( s_ieee == 1 )
00871 fsgl = -fsgl;
00872
00873 *pf = fsgl;
00874
00875 if ( debug )
00876 {
00877 fprintf( stderr, "Float value (read): %g\n", fsgl );
00878 print_ieeef( &fsgl, &value );
00879 }
00880
00881 return 0;
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 static void
00894 print_ieeef( void *vx, void *vy )
00895 {
00896 int i;
00897 U_LONG f, *x = (U_LONG *) vx, *y = (U_LONG *) vy;
00898 char bitrep[33];
00899
00900 bitrep[32] = '\0';
00901
00902 f = *x;
00903 for ( i = 0; i < 32; i++ )
00904 {
00905 if ( f & 1 )
00906 bitrep[32 - i - 1] = '1';
00907 else
00908 bitrep[32 - i - 1] = '0';
00909 f = f >> 1;
00910 }
00911 fprintf( stderr, "Binary representation: " );
00912 fprintf( stderr, "%s\n", bitrep );
00913
00914 f = *y;
00915 for ( i = 0; i < 32; i++ )
00916 {
00917 if ( f & 1 )
00918 bitrep[32 - i - 1] = '1';
00919 else
00920 bitrep[32 - i - 1] = '0';
00921 f = f >> 1;
00922 }
00923 fprintf( stderr, "Converted representation: " );
00924 fprintf( stderr, "%s\n\n", bitrep );
00925
00926 return;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 void
00945 plAlloc2dGrid( PLFLT ***f, PLINT nx, PLINT ny )
00946 {
00947 PLINT i;
00948
00949 if ( ( *f = (PLFLT **) calloc( nx, sizeof ( PLFLT * ) ) ) == NULL )
00950 plexit( "Memory allocation error in \"plAlloc2dGrid\"" );
00951
00952 for ( i = 0; i < nx; i++ )
00953 {
00954 if ( ( ( *f )[i] = (PLFLT *) calloc( ny, sizeof ( PLFLT ) ) ) == NULL )
00955 plexit( "Memory allocation error in \"plAlloc2dGrid\"" );
00956 }
00957 }
00958
00959
00960
00961
00962
00963
00964
00965 void
00966 plFree2dGrid( PLFLT **f, PLINT nx, PLINT ny )
00967 {
00968 PLINT i;
00969
00970 for ( i = 0; i < nx; i++ )
00971 free( (void *) f[i] );
00972
00973 free( (void *) f );
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983 void
00984 plMinMax2dGrid( const PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmax, PLFLT *fmin )
00985 {
00986 int i, j;
00987 PLFLT m, M;
00988
00989 if ( !finite( f[0][0] ) )
00990 {
00991 M = -HUGE_VAL;
00992 m = HUGE_VAL;
00993 }
00994 else
00995 M = m = f[0][0];
00996
00997 for ( i = 0; i < nx; i++ )
00998 {
00999 for ( j = 0; j < ny; j++ )
01000 {
01001 if ( !finite( f[i][j] ) )
01002 continue;
01003 if ( f[i][j] > M )
01004 M = f[i][j];
01005 if ( f[i][j] < m )
01006 m = f[i][j];
01007 }
01008 }
01009 *fmax = M;
01010 *fmin = m;
01011 }