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