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 #define DEBUG
00031
00032 #define NEED_PLDEBUG
00033 #include "plplotP.h"
00034 #ifdef macintosh
00035 #include "mac.h"
00036
00037 #endif
00038
00039 #ifdef DJGPP
00040 #ifdef __unix
00041 #undef __unix
00042 #endif
00043 #endif
00044
00045 #ifdef __unix
00046 #include <sys/types.h>
00047 #include <sys/stat.h>
00048 #ifdef PL_HAVE_UNISTD_H
00049 #include <unistd.h>
00050 #endif
00051 #include <errno.h>
00052 #endif
00053
00054
00055 #include "mt19937ar.h"
00056
00057 #define BUFFER_SIZE 256
00058
00059
00060
00061 #define FUZZ_EPSILON 1.e-4
00062
00063
00064
00065
00066 char PLDLLIMPEXP * plplotLibDir = 0;
00067
00068 static void
00069 color_set(PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, char *name );
00070
00071 static void
00072 strcat_delim(char *dirspec);
00073
00074 static int
00075 (*exit_handler) (const char *errormsg);
00076
00077 static void
00078 (*abort_handler) (const char *errormsg);
00079
00080 static void
00081 plcmap0_def(int imin, int imax);
00082
00083 static void
00084 plcmap1_def(void);
00085
00086 static PLFLT
00087 value(double n1, double n2, double hue);
00088
00089 static void
00090 cmap0_palette_read(const char *filename,
00091 int *number_colors, int **r, int **g, int **b, double **a);
00092
00093
00094
00095 #if defined(DJGPP)
00096 #ifndef PLLIBDEV
00097 #define PLLIBDEV "c:/plplot/lib"
00098 #endif
00099
00100 #elif defined(MSDOS)
00101 #ifndef PLLIBDEV
00102 #define PLLIBDEV "c:\\plplot\\lib"
00103 #endif
00104
00105 #else
00106
00107
00108
00109 #ifndef PLLIBDEV
00110 #define PLLIBDEV "/usr/local/plplot/lib"
00111 #endif
00112
00113 #endif
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 void
00126 c_plcol0(PLINT icol0)
00127 {
00128 if (plsc->level < 1) {
00129 plabort("plcol0: Please call plinit first");
00130 return;
00131 }
00132 if (icol0 < 0 || icol0 >= plsc->ncol0) {
00133 char buffer[BUFFER_SIZE];
00134 snprintf(buffer, BUFFER_SIZE, "plcol0: Invalid color map entry: %d", (int) icol0);
00135 plabort(buffer);
00136 return;
00137 }
00138
00139 plsc->icol0 = icol0;
00140 plsc->curcolor.r = plsc->cmap0[icol0].r;
00141 plsc->curcolor.g = plsc->cmap0[icol0].g;
00142 plsc->curcolor.b = plsc->cmap0[icol0].b;
00143 plsc->curcolor.a = plsc->cmap0[icol0].a;
00144
00145 plsc->curcmap = 0;
00146 plP_state(PLSTATE_COLOR0);
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 void
00156 c_plcol1(PLFLT col1)
00157 {
00158 PLINT icol1;
00159
00160 if (plsc->level < 1) {
00161 plabort("plcol1: Please call plinit first");
00162 return;
00163 }
00164 if (col1 < 0 || col1 > 1) {
00165 char buffer[BUFFER_SIZE];
00166 snprintf(buffer, BUFFER_SIZE, "plcol1: Invalid color map position: %f", (PLFLT) col1);
00167 plabort(buffer);
00168 return;
00169 }
00170
00171 icol1 = (PLINT)(col1 * plsc->ncol1);
00172 icol1 = MIN(icol1, plsc->ncol1-1);
00173
00174 plsc->icol1 = icol1;
00175 plsc->curcolor.r = plsc->cmap1[plsc->icol1].r;
00176 plsc->curcolor.g = plsc->cmap1[plsc->icol1].g;
00177 plsc->curcolor.b = plsc->cmap1[plsc->icol1].b;
00178 plsc->curcolor.a = plsc->cmap1[plsc->icol1].a;
00179
00180 plsc->curcmap = 1;
00181 plP_state(PLSTATE_COLOR1);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 void
00191 c_plscolbg(PLINT r, PLINT g, PLINT b)
00192 {
00193 plscol0(0, r, g, b);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void
00203 c_plscolbga(PLINT r, PLINT g, PLINT b, PLFLT a)
00204 {
00205 plscol0a(0, r, g, b, a);
00206 }
00207
00208
00209
00210
00211
00212
00213
00214 void
00215 c_plgcolbg(PLINT *r, PLINT *g, PLINT *b)
00216 {
00217 plgcol0(0, r, g, b);
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 void
00227 c_plgcolbga(PLINT *r, PLINT *g, PLINT *b, PLFLT *a)
00228 {
00229 plgcol0a(0, r, g, b, a);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 void
00240 c_plscol0(PLINT icol0, PLINT r, PLINT g, PLINT b)
00241 {
00242 if (plsc->cmap0 == NULL)
00243 plscmap0n(0);
00244 if (icol0 < 0 || icol0 >= plsc->ncol0) {
00245 char buffer[BUFFER_SIZE];
00246 snprintf(buffer, BUFFER_SIZE, "plscol0: Illegal color table value: %d", (int) icol0);
00247 plabort(buffer);
00248 return;
00249 }
00250 if ((r < 0 || r > 255) || (g < 0 || g > 255) || (b < 0 || b > 255)) {
00251 char buffer[BUFFER_SIZE];
00252 snprintf(buffer, BUFFER_SIZE, "plscol0: Invalid RGB color: %d, %d, %d",
00253 (int) r, (int) g, (int) b);
00254 plabort(buffer);
00255 return;
00256 }
00257
00258 plscol0a(icol0, r, g, b, 1.0);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268 void
00269 c_plscol0a(PLINT icol0, PLINT r, PLINT g, PLINT b, PLFLT a)
00270 {
00271 if (plsc->cmap0 == NULL)
00272 plscmap0n(0);
00273 if (icol0 < 0 || icol0 >= plsc->ncol0) {
00274 char buffer[BUFFER_SIZE];
00275 snprintf(buffer, BUFFER_SIZE, "plscol0a: Illegal color table value: %d", (int) icol0);
00276 plabort(buffer);
00277 return;
00278 }
00279 if ((r < 0 || r > 255) || (g < 0 || g > 255) || (b < 0 || b > 255) || (a < 0 || a > 1.0)) {
00280 char buffer[BUFFER_SIZE];
00281 snprintf(buffer, BUFFER_SIZE, "plscol0a: Invalid RGB color: %d, %d, %d, %f",
00282 (int) r, (int) g, (int) b, (double) a);
00283 plabort(buffer);
00284 return;
00285 }
00286
00287 plsc->cmap0[icol0].r = r;
00288 plsc->cmap0[icol0].g = g;
00289 plsc->cmap0[icol0].b = b;
00290 plsc->cmap0[icol0].a = a;
00291
00292 if (plsc->level > 0)
00293 plP_state(PLSTATE_CMAP0);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 void
00304 c_plgcol0(PLINT icol0, PLINT *r, PLINT *g, PLINT *b)
00305 {
00306 if (plsc->cmap0 == NULL)
00307 plscmap0n(0);
00308
00309 *r = -1;
00310 *g = -1;
00311 *b = -1;
00312
00313 if (icol0 < 0 || icol0 > plsc->ncol0) {
00314 char buffer[BUFFER_SIZE];
00315 snprintf(buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d", (int) icol0);
00316 plabort(buffer);
00317 return;
00318 }
00319
00320 *r = plsc->cmap0[icol0].r;
00321 *g = plsc->cmap0[icol0].g;
00322 *b = plsc->cmap0[icol0].b;
00323
00324 return;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334 void
00335 c_plgcol0a(PLINT icol0, PLINT *r, PLINT *g, PLINT *b, PLFLT *a)
00336 {
00337 if (plsc->cmap0 == NULL)
00338 plscmap0n(0);
00339
00340 *r = -1;
00341 *g = -1;
00342 *b = -1;
00343 *a = -1.0;
00344
00345 if (icol0 < 0 || icol0 > plsc->ncol0) {
00346 char buffer[BUFFER_SIZE];
00347 snprintf(buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d", (int) icol0);
00348 plabort(buffer);
00349 return;
00350 }
00351
00352 *r = plsc->cmap0[icol0].r;
00353 *g = plsc->cmap0[icol0].g;
00354 *b = plsc->cmap0[icol0].b;
00355 *a = plsc->cmap0[icol0].a;
00356
00357 return;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367 void
00368 c_plscmap0(PLINT *r, PLINT *g, PLINT *b, PLINT ncol0)
00369 {
00370 int i;
00371
00372 plscmap0n(ncol0);
00373
00374 for (i = 0; i < plsc->ncol0; i++) {
00375 if ((r[i] < 0 || r[i] > 255) ||
00376 (g[i] < 0 || g[i] > 255) ||
00377 (b[i] < 0 || b[i] > 255)) {
00378
00379 char buffer[BUFFER_SIZE];
00380 snprintf(buffer, BUFFER_SIZE, "plscmap0: Invalid RGB color: %d, %d, %d",
00381 (int) r[i], (int) g[i], (int) b[i]);
00382 plabort(buffer);
00383 return;
00384 }
00385
00386 plsc->cmap0[i].r = r[i];
00387 plsc->cmap0[i].g = g[i];
00388 plsc->cmap0[i].b = b[i];
00389 plsc->cmap0[i].a = 1.0;
00390 }
00391
00392 if (plsc->level > 0)
00393 plP_state(PLSTATE_CMAP0);
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403 void
00404 c_plscmap0a(PLINT *r, PLINT *g, PLINT *b, PLFLT *a, PLINT ncol0)
00405 {
00406 int i;
00407
00408 plscmap0n(ncol0);
00409
00410 for (i = 0; i < plsc->ncol0; i++) {
00411 if ((r[i] < 0 || r[i] > 255) ||
00412 (g[i] < 0 || g[i] > 255) ||
00413 (b[i] < 0 || b[i] > 255) ||
00414 (a[i] < 0.0 || a[i] > 1.0)) {
00415
00416 char buffer[BUFFER_SIZE];
00417 snprintf(buffer, BUFFER_SIZE, "plscmap0a: Invalid RGB color: %d, %d, %d, %f",
00418 (int) r[i], (int) g[i], (int) b[i], (double) a[i]);
00419 plabort(buffer);
00420 return;
00421 }
00422
00423 plsc->cmap0[i].r = r[i];
00424 plsc->cmap0[i].g = g[i];
00425 plsc->cmap0[i].b = b[i];
00426 plsc->cmap0[i].a = a[i];
00427 }
00428
00429 if (plsc->level > 0)
00430 plP_state(PLSTATE_CMAP0);
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440 void
00441 c_plscmap1(PLINT *r, PLINT *g, PLINT *b, PLINT ncol1)
00442 {
00443 int i;
00444
00445 plscmap1n(ncol1);
00446
00447 for (i = 0; i < plsc->ncol1; i++) {
00448 if ((r[i] < 0 || r[i] > 255) ||
00449 (g[i] < 0 || g[i] > 255) ||
00450 (b[i] < 0 || b[i] > 255)) {
00451
00452 char buffer[BUFFER_SIZE];
00453 snprintf(buffer, BUFFER_SIZE, "plscmap1: Invalid RGB color: %d, %d, %d",
00454 (int) r[i], (int) g[i], (int) b[i]);
00455 plabort(buffer);
00456 return;
00457 }
00458 plsc->cmap1[i].r = r[i];
00459 plsc->cmap1[i].g = g[i];
00460 plsc->cmap1[i].b = b[i];
00461 plsc->cmap1[i].a = 1.0;
00462 }
00463
00464 if (plsc->level > 0)
00465 plP_state(PLSTATE_CMAP1);
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475 void
00476 c_plscmap1a(PLINT *r, PLINT *g, PLINT *b, PLFLT *a, PLINT ncol1)
00477 {
00478 int i;
00479
00480 plscmap1n(ncol1);
00481
00482 for (i = 0; i < plsc->ncol1; i++) {
00483 if ((r[i] < 0 || r[i] > 255) ||
00484 (g[i] < 0 || g[i] > 255) ||
00485 (b[i] < 0 || b[i] > 255) ||
00486 (a[i] < 0.0 || a[i] > 1.0)) {
00487
00488 char buffer[BUFFER_SIZE];
00489 snprintf(buffer, BUFFER_SIZE, "plscmap1a: Invalid RGB color: %d, %d, %d, %f",
00490 (int) r[i], (int) g[i], (int) b[i], (double) a[i]);
00491 plabort(buffer);
00492 return;
00493 }
00494 plsc->cmap1[i].r = r[i];
00495 plsc->cmap1[i].g = g[i];
00496 plsc->cmap1[i].b = b[i];
00497 plsc->cmap1[i].a = a[i];
00498 }
00499
00500 if (plsc->level > 0)
00501 plP_state(PLSTATE_CMAP1);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 void
00556 c_plscmap1l(PLINT itype, PLINT npts, PLFLT *pos,
00557 PLFLT *coord1, PLFLT *coord2, PLFLT *coord3, PLINT *rev)
00558 {
00559 int n;
00560 PLFLT h, l, s, r, g, b;
00561
00562 if (npts < 2) {
00563 plabort("plscmap1l: Must specify at least two control points");
00564 return;
00565 }
00566
00567 if ( (pos[0] != 0) || (pos[npts-1] != 1)) {
00568 plabort("plscmap1l: First, last control points must lie on boundary");
00569 return;
00570 }
00571
00572 if ( npts > PL_MAX_CMAP1CP ) {
00573 plabort("plscmap1l: exceeded maximum number of control points");
00574 return;
00575 }
00576
00577
00578
00579 if (plsc->cmap1 == NULL)
00580 plscmap1n(0);
00581
00582
00583
00584 plsc->ncp1 = npts;
00585
00586 for (n = 0; n < npts; n++) {
00587
00588 if (itype == 0) {
00589 h = coord1[n];
00590 l = coord2[n];
00591 s = coord3[n];
00592 }
00593 else {
00594 r = coord1[n];
00595 g = coord2[n];
00596 b = coord3[n];
00597 c_plrgbhls(r, g, b, &h, &l, &s);
00598 }
00599
00600 plsc->cmap1cp[n].h = h;
00601 plsc->cmap1cp[n].l = l;
00602 plsc->cmap1cp[n].s = s;
00603 plsc->cmap1cp[n].p = pos[n];
00604 plsc->cmap1cp[n].a = 1.0;
00605
00606 if (rev == NULL)
00607 plsc->cmap1cp[n].rev = 0;
00608 else
00609 plsc->cmap1cp[n].rev = rev[n];
00610 }
00611
00612
00613
00614 plcmap1_calc();
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624 void
00625 c_plscmap1la(PLINT itype, PLINT npts, PLFLT *pos,
00626 PLFLT *coord1, PLFLT *coord2, PLFLT *coord3, PLFLT *a, PLINT *rev)
00627 {
00628 int n;
00629 PLFLT h, l, s, r, g, b;
00630
00631 if (npts < 2) {
00632 plabort("plscmap1la: Must specify at least two control points");
00633 return;
00634 }
00635
00636 if ( (pos[0] != 0) || (pos[npts-1] != 1)) {
00637 plabort("plscmap1la: First, last control points must lie on boundary");
00638 return;
00639 }
00640
00641 if ( npts > PL_MAX_CMAP1CP ) {
00642 plabort("plscmap1la: exceeded maximum number of control points");
00643 return;
00644 }
00645
00646
00647
00648 if (plsc->cmap1 == NULL)
00649 plscmap1n(0);
00650
00651
00652
00653 plsc->ncp1 = npts;
00654
00655 for (n = 0; n < npts; n++) {
00656
00657 if (itype == 0) {
00658 h = coord1[n];
00659 l = coord2[n];
00660 s = coord3[n];
00661 }
00662 else {
00663 r = coord1[n];
00664 g = coord2[n];
00665 b = coord3[n];
00666 c_plrgbhls(r, g, b, &h, &l, &s);
00667 }
00668
00669 plsc->cmap1cp[n].h = h;
00670 plsc->cmap1cp[n].l = l;
00671 plsc->cmap1cp[n].s = s;
00672 plsc->cmap1cp[n].p = pos[n];
00673 plsc->cmap1cp[n].a = a[n];
00674
00675 if (rev == NULL)
00676 plsc->cmap1cp[n].rev = 0;
00677 else
00678 plsc->cmap1cp[n].rev = rev[n];
00679 }
00680
00681
00682
00683 plcmap1_calc();
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693 void
00694 plcmap1_calc(void)
00695 {
00696 int i, n;
00697 PLFLT delta, dp, dh, dl, ds, da;
00698 PLFLT h, l, s, p, r, g, b, a;
00699
00700
00701
00702 for (n = 0; n < plsc->ncp1-1; n++) {
00703
00704 if ( plsc->cmap1cp[n].p == plsc->cmap1cp[n+1].p )
00705 continue;
00706
00707
00708
00709 dp = plsc->cmap1cp[n+1].p - plsc->cmap1cp[n].p;
00710 dh = plsc->cmap1cp[n+1].h - plsc->cmap1cp[n].h;
00711 dl = plsc->cmap1cp[n+1].l - plsc->cmap1cp[n].l;
00712 ds = plsc->cmap1cp[n+1].s - plsc->cmap1cp[n].s;
00713 da = plsc->cmap1cp[n+1].a - plsc->cmap1cp[n].a;
00714
00715
00716
00717 if (plsc->cmap1cp[n].rev)
00718 dh = (dh > 0) ? dh-360 : dh+360;
00719
00720
00721
00722
00723 for (i = 0; i < plsc->ncol1; i++) {
00724 p = (double) i / (plsc->ncol1 - 1.0);
00725 if ( (p < plsc->cmap1cp[n].p) ||
00726 (p > plsc->cmap1cp[n+1].p) )
00727 continue;
00728
00729
00730
00731 delta = (p - plsc->cmap1cp[n].p) / dp;
00732
00733
00734
00735 h = plsc->cmap1cp[n].h + dh * delta;
00736 l = plsc->cmap1cp[n].l + dl * delta;
00737 s = plsc->cmap1cp[n].s + ds * delta;
00738 a = plsc->cmap1cp[n].a + da * delta;
00739
00740 while (h >= 360.)
00741 h -= 360.;
00742
00743 while (h < 0.)
00744 h += 360.;
00745
00746 c_plhlsrgb(h, l, s, &r, &g, &b);
00747
00748 plsc->cmap1[i].r = MAX(0, MIN(255, (int) (256. * r)));
00749 plsc->cmap1[i].g = MAX(0, MIN(255, (int) (256. * g)));
00750 plsc->cmap1[i].b = MAX(0, MIN(255, (int) (256. * b)));
00751 plsc->cmap1[i].a = a;
00752 }
00753 }
00754
00755 if (plsc->level > 0)
00756 plP_state(PLSTATE_CMAP1);
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 void
00770 c_plscmap0n(PLINT ncol0)
00771 {
00772 int ncol, size, imin, imax;
00773
00774
00775
00776 if (ncol0 > 0 && plsc->ncol0 == ncol0)
00777 return;
00778
00779
00780
00781 if (plsc->ncol0 <= 0 && ncol0 <= 0)
00782 ncol = 16;
00783 else if (ncol0 <= 0)
00784 ncol = plsc->ncol0;
00785 else
00786 ncol = ncol0;
00787
00788 imax = ncol-1;
00789 size = ncol * sizeof(PLColor);
00790
00791
00792
00793 if (plsc->cmap0 == NULL) {
00794 if ((plsc->cmap0 = (PLColor *) calloc(1, size))==NULL)
00795 {
00796 plexit("c_plscmap0n: Insufficient memory");
00797 }
00798 imin = 0;
00799 }
00800 else {
00801 if ((plsc->cmap0 = (PLColor *) realloc(plsc->cmap0, size))==NULL)
00802 {
00803 plexit("c_plscmap0n: Insufficient memory");
00804 }
00805 imin = plsc->ncol0;
00806 }
00807
00808
00809
00810 plsc->ncol0 = ncol;
00811 plcmap0_def(imin, imax);
00812
00813 if (plsc->level > 0)
00814 plP_state(PLSTATE_CMAP0);
00815 }
00816
00817
00818
00819
00820
00821
00822
00823 void
00824 color_set(PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, char *name )
00825 {
00826 plsc->cmap0[i].r = r;
00827 plsc->cmap0[i].g = g;
00828 plsc->cmap0[i].b = b;
00829 plsc->cmap0[i].a = a;
00830 plsc->cmap0[i].name = name;
00831 }
00832
00833 #define color_def(i, r, g, b, a, n) \
00834 if (i >= imin && i <= imax) color_set(i, r, g, b, a, n);
00835
00836
00837
00838
00839
00840
00841
00842
00843 void
00844 plcmap0_def(int imin, int imax)
00845 {
00846 int i, *r, *g, *b;
00847 double *a;
00848 int number_colors;
00849 if(imin <= imax) {
00850 cmap0_palette_read("", &number_colors, &r, &g, &b, &a);
00851 for (i = imin; i <= MIN((number_colors-1),imax); i++)
00852 color_def(i, r[i], g[i], b[i], a[i],
00853 "colors defined by default cmap0 palette file");
00854 free(r);
00855 free(g);
00856 free(b);
00857 free(a);
00858
00859 } else {
00860 number_colors = 0;
00861 }
00862
00863
00864
00865 for (i = MAX(number_colors, imin); i <= imax; i++)
00866 color_def(i, 255, 0, 0, 1.0,
00867 "opaque red colour to mark not defined by palette file");
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 void
00881 c_plscmap1n(PLINT ncol1)
00882 {
00883 int ncol, size;
00884
00885
00886
00887 if (ncol1 > 0 && plsc->ncol1 == ncol1)
00888 return;
00889
00890
00891
00892 if (plsc->ncol1 <= 0 && ncol1 <= 0)
00893 ncol = 128;
00894 else if (ncol1 <= 0)
00895 ncol = plsc->ncol1;
00896 else
00897 ncol = ncol1;
00898
00899 size = ncol * sizeof(PLColor);
00900
00901
00902
00903 if (plsc->ncol1 > 0)
00904 {
00905 if ((plsc->cmap1 = (PLColor *) realloc(plsc->cmap1, size))==NULL)
00906 {
00907 plexit("c_plscmap1n: Insufficient memory");
00908 }
00909 }
00910 else
00911 {
00912 if ((plsc->cmap1 = (PLColor *) calloc(ncol, sizeof(PLColor)))==NULL)
00913 {
00914 plexit("c_plscmap1n: Insufficient memory");
00915 }
00916 }
00917
00918
00919
00920 plsc->ncol1 = ncol;
00921 if (plsc->ncp1 == 0)
00922 plcmap1_def();
00923 else
00924 plcmap1_calc();
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 void
00941 plcmap1_def(void)
00942 {
00943 PLFLT i[6], h[6], l[6], s[6], midpt = 0., vertex = 0.;
00944
00945
00946
00947 i[0] = 0;
00948 i[1] = 0.44;
00949 i[2] = 0.50;
00950 i[3] = 0.50;
00951 i[4] = 0.56;
00952 i[5] = 1;
00953
00954
00955
00956
00957 if (plsc->cmap0 != NULL)
00958 vertex = ((PLFLT) plsc->cmap0[0].r +
00959 (PLFLT) plsc->cmap0[0].g +
00960 (PLFLT) plsc->cmap0[0].b) / 3. / 255.;
00961
00962 if (vertex < 0.5) {
00963 vertex = 0.01;
00964 midpt = 0.10;
00965 } else {
00966 vertex = 0.99;
00967 midpt = 0.90;
00968 }
00969
00970
00971
00972 h[0] = 260;
00973 h[1] = 260;
00974 h[2] = 260;
00975 h[3] = 0;
00976 h[4] = 0;
00977 h[5] = 0;
00978
00979
00980
00981 l[0] = 0.5;
00982 l[1] = midpt;
00983 l[2] = vertex;
00984 l[3] = vertex;
00985 l[4] = midpt;
00986 l[5] = 0.5;
00987
00988
00989
00990 s[0] = 1;
00991 s[1] = 1;
00992 s[2] = 1;
00993 s[3] = 1;
00994 s[4] = 1;
00995 s[5] = 1;
00996
00997 c_plscmap1l(0, 6, i, h, l, s, NULL);
00998
00999 if (plsc->level > 0)
01000 plP_state(PLSTATE_CMAP1);
01001 }
01002
01003
01004
01005
01006
01007
01008
01009 void
01010 c_plscolor(PLINT color)
01011 {
01012 plsc->colorset = 1;
01013 plsc->color = color;
01014 }
01015
01016
01017
01018
01019
01020
01021
01022
01023 void
01024 c_plrgb(PLFLT r, PLFLT g, PLFLT b)
01025 {
01026 if (plsc->level < 1) {
01027 plabort("plrgb: Please call plinit first");
01028 return;
01029 }
01030
01031 plsc->icol0 = PL_RGB_COLOR;
01032 plsc->curcolor.r = MAX(0, MIN(255, (int) (256. * r)));
01033 plsc->curcolor.g = MAX(0, MIN(255, (int) (256. * g)));
01034 plsc->curcolor.b = MAX(0, MIN(255, (int) (256. * b)));
01035
01036 plsc->curcmap = 0;
01037 plP_state(PLSTATE_COLOR0);
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047 void
01048 c_plrgb1(PLINT r, PLINT g, PLINT b)
01049 {
01050 if (plsc->level < 1) {
01051 plabort("plrgb1: Please call plinit first");
01052 return;
01053 }
01054 if ((r < 0 || r > 255) || (g < 0 || g > 255) || (b < 0 || b > 255)) {
01055 plabort("plrgb1: Invalid color");
01056 return;
01057 }
01058
01059 plsc->icol0 = PL_RGB_COLOR;
01060 plsc->curcolor.r = r;
01061 plsc->curcolor.g = g;
01062 plsc->curcolor.b = b;
01063
01064 plsc->curcmap = 0;
01065 plP_state(PLSTATE_COLOR0);
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 void
01077 c_plhls(PLFLT h, PLFLT l, PLFLT s)
01078 {
01079 PLFLT r, g, b;
01080
01081 c_plhlsrgb(h, l, s, &r, &g, &b);
01082 plrgb(r, g, b);
01083 }
01084
01085
01086
01087
01088
01089
01090
01091 PLFLT
01092 value(double n1, double n2, double hue)
01093 {
01094 PLFLT val;
01095
01096 while (hue >= 360.)
01097 hue -= 360.;
01098 while (hue < 0.)
01099 hue += 360.;
01100
01101 if (hue < 60.)
01102 val = n1 + (n2 - n1) * hue / 60.;
01103 else if (hue < 180.)
01104 val = n2;
01105 else if (hue < 240.)
01106 val = n1 + (n2 - n1) * (240. - hue) / 60.;
01107 else
01108 val = n1;
01109
01110 return (val);
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 void
01128 c_plhlsrgb(PLFLT h, PLFLT l, PLFLT s, PLFLT *p_r, PLFLT *p_g, PLFLT *p_b)
01129 {
01130 PLFLT m1, m2;
01131
01132 if (l <= .5)
01133 m2 = l * (s + 1.);
01134 else
01135 m2 = l + s - l * s;
01136
01137 m1 = 2 * l - m2;
01138
01139 *p_r = value(m1, m2, h + 120.);
01140 *p_g = value(m1, m2, h);
01141 *p_b = value(m1, m2, h - 120.);
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 void
01156 c_plrgbhls(PLFLT r, PLFLT g, PLFLT b, PLFLT *p_h, PLFLT *p_l, PLFLT *p_s)
01157 {
01158 PLFLT h, l, s, d, rc, gc, bc, rgb_min, rgb_max;
01159
01160 rgb_min = MIN( r, MIN( g, b ));
01161 rgb_max = MAX( r, MAX( g, b ));
01162
01163 l = (rgb_min+rgb_max) / 2.0;
01164
01165 if (rgb_min == rgb_max) {
01166 s = 0;
01167 h = 0;
01168 }
01169 else {
01170 d = rgb_max - rgb_min;
01171 if (l < 0.5)
01172 s = 0.5 * d / l;
01173 else
01174 s = 0.5* d / (1.-l);
01175
01176 rc = (rgb_max-r) / d;
01177 gc = (rgb_max-g) / d;
01178 bc = (rgb_max-b) / d;
01179
01180 if (r == rgb_max)
01181 h = bc-gc;
01182 else if (g == rgb_max)
01183 h = rc-bc+2;
01184 else
01185 h = gc-rc-2;
01186
01187 h = h*60;
01188 if (h < 0)
01189 h = h+360;
01190 else if (h >= 360)
01191 h = h-360;
01192 }
01193 *p_h = h;
01194 *p_l = l;
01195 *p_s = s;
01196 }
01197
01198
01199
01200
01201
01202
01203
01204
01205 void
01206 cmap0_palette_read(const char *filename,
01207 int *number_colors, int **r, int **g, int **b, double **a)
01208 {
01209 int i, err = 0;
01210 char color_info[30];
01211 char msgbuf[1024];
01212 FILE *fp;
01213 char * save_locale = plsave_set_locale();
01214
01215 if(strlen(filename) == 0) {
01216 fp = plLibOpen(PL_DEFAULT_CMAP0_FILE);
01217 if (fp == NULL) {
01218 snprintf(msgbuf,1024,"Unable to open cmap0 file %s\n",PL_DEFAULT_CMAP0_FILE);
01219 plwarn(msgbuf);
01220 err = 1;
01221 }
01222 } else {
01223 fp = plLibOpen(filename);
01224 if (fp == NULL) {
01225 snprintf(msgbuf,1024,"Unable to open cmap0 file %s\n",filename);
01226 plwarn(msgbuf);
01227 err = 1;
01228 }
01229 }
01230 if (!err &&(fscanf(fp, "%d\n", number_colors) != 1 || *number_colors < 1)) {
01231 fclose(fp);
01232 snprintf(msgbuf,1024,"Unrecognized cmap0 header\n");
01233 plwarn(msgbuf);
01234 err = 1;
01235 }
01236
01237 if(!err) {
01238
01239
01240 if(((*r = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01241 ((*g = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01242 ((*b = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01243 ((*a = (double *)malloc(*number_colors * sizeof(double))) == NULL)) {
01244 fclose(fp);
01245 plexit("cmap0_palette_read: insufficient memory");
01246 }
01247
01248 for(i=0;i<*number_colors;i++){
01249 fgets(color_info, 30, fp);
01250 color_info[strlen(color_info)-1] = '\0';
01251 if(strlen(color_info) == 7){
01252 if (sscanf(color_info, "#%2x%2x%2x",
01253 (int *) (*r+i), (int *) (*g+i), (int *) (*b+i)) != 3) {
01254 err = 1;
01255 break;
01256 }
01257 *(*a+i) = 1.0;
01258 } else if(strlen(color_info) > 9) {
01259 if (sscanf(color_info, "#%2x%2x%2x %lf",
01260 (int *) (*r+i), (int *) (*g+i), (int *) (*b+i),
01261 (double *) (*a+i)) != 4) {
01262 err = 1;
01263 break;
01264 }
01265
01266 if(*(*a+i) < -FUZZ_EPSILON || *(*a+i) > (1. + FUZZ_EPSILON)) {
01267 err = 1;
01268 break;
01269 } else if(*(*a+i) < 0.) {
01270 *(*a+i) = 0.;
01271 } else if(*(*a+i) > 1.) {
01272 *(*a+i) = 1.;
01273 }
01274 } else {
01275 err = 1;
01276 break;
01277 }
01278 }
01279 fclose(fp);
01280 if(err) {
01281 snprintf(msgbuf,1024,"Unrecognized cmap0 format data line. Line is %s\n",
01282 color_info);
01283 plwarn(msgbuf);
01284 free(*r);
01285 free(*g);
01286 free(*b);
01287 free(*a);
01288 }
01289 }
01290
01291
01292 if(err) {
01293 *number_colors = 16;
01294 if(((*r = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01295 ((*g = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01296 ((*b = (int *)malloc(*number_colors * sizeof(int))) == NULL) ||
01297 ((*a = (double *)malloc(*number_colors * sizeof(double))) == NULL)) {
01298 plexit("cmap0_palette_read: insufficient memory");
01299 }
01300 **r = 255;
01301 **g = 255;
01302 **b = 255;
01303 **a = 1.;
01304 for(i=1;i<*number_colors;i++){
01305 *(*r+i) = 255;
01306 *(*g+i) = 0;
01307 *(*b+i) = 0;
01308 *(*a+i) = 1.0;
01309 }
01310 }
01311
01312 plrestore_locale(save_locale);
01313 }
01314
01315
01316
01317
01318
01319
01320
01321
01322 void
01323 c_plspal0(const char *filename)
01324 {
01325 int i, *r, *g, *b;
01326 double *a;
01327 int number_colors;
01328 cmap0_palette_read(filename, &number_colors, &r, &g, &b, &a);
01329
01330
01331 plscmap0n(0);
01332
01333 if(number_colors > plsc->ncol0) {
01334 plscmap0n(number_colors);
01335 }
01336 for(i=0;i<number_colors;i++){
01337 c_plscol0a(i, r[i], g[i], b[i], a[i]);
01338 }
01339 free(r);
01340 free(g);
01341 free(b);
01342 free(a);
01343 }
01344
01345
01346
01347
01348
01349 #define fuzzy_range_check(value, min, max, fuzz, err_number) \
01350 if(value < (min - fuzz) || value > (max + fuzz)) { \
01351 snprintf(msgbuf,1024,"Unrecognized cmap1 format data line. Error number is %d. Line is %s\n", err_number, color_info); \
01352 plwarn(msgbuf); \
01353 err = 1; \
01354 break; \
01355 } else if (value < min) { \
01356 value = min; \
01357 } else if (value > max) { \
01358 value = max; \
01359 }
01360
01361
01362
01363
01364
01365
01366
01367 void
01368 c_plspal1(const char *filename, PLBOOL interpolate)
01369 {
01370 int i;
01371 int number_colors;
01372 int format_version, err;
01373 PLBOOL rgb;
01374 char color_info[160];
01375 int r_i, g_i, b_i, pos_i, rev_i;
01376 double r_d, g_d, b_d, a_d, pos_d;
01377 PLFLT *r, *g, *b, *a, *pos;
01378 PLINT *ri, *gi, *bi;
01379 PLBOOL *rev;
01380 FILE *fp;
01381 char msgbuf[1024];
01382 char * save_locale = plsave_set_locale();
01383
01384 rgb = TRUE;
01385 err = 0;
01386 format_version = 0;
01387 if(strlen(filename) == 0) {
01388 fp = plLibOpen(PL_DEFAULT_CMAP1_FILE);
01389 if (fp == NULL) {
01390 snprintf(msgbuf,1024,"Unable to open cmap1 .pal file %s\n",PL_DEFAULT_CMAP1_FILE);
01391 plwarn(msgbuf);
01392 goto finish;
01393 }
01394 } else {
01395 fp = plLibOpen(filename);
01396 if (fp == NULL) {
01397 snprintf(msgbuf,1024,"Unable to open cmap1 .pal file %s\n",filename);
01398 plwarn(msgbuf);
01399 goto finish;
01400 }
01401 }
01402
01403 fgets(color_info, 160, fp);
01404 if (strncmp(color_info,"v2 ",2) == 0) {
01405 format_version = 1;
01406 if (strncmp(&color_info[3],"hls",3) == 0)
01407 rgb = FALSE;
01408 else if (strncmp(&color_info[3],"rgb",3) == 0)
01409 rgb = TRUE;
01410 else {
01411 snprintf(msgbuf,1024,"Invalid color space %s - assuming RGB\n",&color_info[3]);
01412 plwarn(msgbuf);
01413 rgb = TRUE;
01414 }
01415 fgets(color_info, 160, fp);
01416 }
01417
01418 if (sscanf(color_info, "%d\n", &number_colors) != 1 || number_colors < 2) {
01419 snprintf(msgbuf,1024,"Unrecognized cmap1 format (wrong number of colors) %s\n", color_info);
01420 plwarn(msgbuf);
01421 fclose(fp);
01422 goto finish;
01423 }
01424
01425 r = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01426 g = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01427 b = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01428 ri = (PLINT *)malloc(number_colors * sizeof(PLINT));
01429 gi = (PLINT *)malloc(number_colors * sizeof(PLINT));
01430 bi = (PLINT *)malloc(number_colors * sizeof(PLINT));
01431 a = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01432 pos = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01433 rev = (PLBOOL *)malloc(number_colors * sizeof(PLBOOL));
01434
01435 if (format_version == 0) {
01436 int return_sscanf, return_sscanf_old=0;
01437
01438 for(i=0;i<number_colors;i++){
01439 fgets(color_info, 160, fp);
01440
01441 color_info[159] = '\0';
01442 return_sscanf = sscanf(color_info, "#%2x%2x%2x %d %d", &r_i, &g_i, &b_i, &pos_i, &rev_i);
01443 if(return_sscanf < 4 || (return_sscanf_old != 0 && return_sscanf != return_sscanf_old)) {
01444 snprintf(msgbuf,1024,"Unrecognized cmap1 format (wrong number of items for version 1 of format) %s\n", color_info);
01445 plwarn(msgbuf);
01446 err = 1;
01447 break;
01448 }
01449 return_sscanf_old = return_sscanf;
01450
01451
01452 r[i] = (PLFLT)r_i/255.;
01453 g[i] = (PLFLT)g_i/255.;
01454 b[i] = (PLFLT)b_i/255.;
01455 a[i] = 1.0;
01456 pos[i] = 0.01*(PLFLT)pos_i;
01457 fuzzy_range_check(r[i], 0., 1., FUZZ_EPSILON, 1);
01458 fuzzy_range_check(g[i], 0., 1., FUZZ_EPSILON, 2);
01459 fuzzy_range_check(b[i], 0., 1., FUZZ_EPSILON, 3);
01460 fuzzy_range_check(pos[i], 0., 1., FUZZ_EPSILON, 4);
01461 if(return_sscanf == 5) {
01462
01463 rev[i] = (PLBOOL)rev_i;
01464 }
01465 }
01466 if(return_sscanf == 4) {
01467
01468 free(rev);
01469 rev = NULL;
01470 }
01471 }
01472 else {
01473
01474 for(i=0;i<number_colors;i++){
01475 fgets(color_info, 160, fp);
01476 if (sscanf(color_info, "%lf %lf %lf %lf %lf %d", &pos_d, &r_d, &g_d, &b_d, &a_d, &rev_i) != 6) {
01477 snprintf(msgbuf,1024,"Unrecognized cmap1 format (wrong number of items for version 2 of format) %s\n", color_info);
01478 plwarn(msgbuf);
01479 err = 1;
01480 break;
01481 }
01482
01483 r[i] = (PLFLT)r_d;
01484 g[i] = (PLFLT)g_d;
01485 b[i] = (PLFLT)b_d;
01486 a[i] = (PLFLT)a_d;
01487 pos[i] = (PLFLT)pos_d;
01488
01489
01490
01491 if(rgb) {
01492 fuzzy_range_check(r[i], 0., 1., FUZZ_EPSILON, 5);
01493 } else {
01494 fuzzy_range_check(r[i], 0., 360., (360.*FUZZ_EPSILON), 6);
01495 }
01496 fuzzy_range_check(g[i], 0., 1., FUZZ_EPSILON, 7);
01497 fuzzy_range_check(b[i], 0., 1., FUZZ_EPSILON, 8);
01498 fuzzy_range_check(a[i], 0., 1., FUZZ_EPSILON, 9);
01499 fuzzy_range_check(pos[i], 0., 1., FUZZ_EPSILON, 10);
01500
01501 rev[i] = (PLBOOL)rev_i;
01502 }
01503 }
01504 fclose(fp);
01505
01506 if (!err) {
01507 if (interpolate) {
01508 c_plscmap1la(rgb, number_colors, pos, r, g, b, a, rev);
01509 }
01510 else {
01511 for (i = 0; i < number_colors; i++) {
01512 ri[i] = r[i] * 255.0;
01513 gi[i] = g[i] * 255.0;
01514 bi[i] = b[i] * 255.0;
01515 }
01516 c_plscmap1a(ri, gi, bi, a, number_colors);
01517 }
01518 } else {
01519
01520
01521 free(r);
01522 free(g);
01523 free(b);
01524 free(pos);
01525 number_colors = 2;
01526 r = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01527 g = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01528 b = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01529 pos = (PLFLT *)malloc(number_colors * sizeof(PLFLT));
01530 r[0] = 0.;
01531 r[1] = 1.;
01532 g[0] = 0.;
01533 g[1] = 0.;
01534 b[0] = 0.;
01535 b[1] = 0.;
01536 pos[0] = 0.;
01537 pos[1] = 1.;
01538 c_plscmap1l(TRUE, number_colors, pos, r, g, b, NULL);
01539 }
01540
01541 free(r);
01542 free(g);
01543 free(b);
01544 free(ri);
01545 free(gi);
01546 free(bi);
01547 free(a);
01548 free(pos);
01549 free(rev);
01550
01551 finish: plrestore_locale(save_locale);
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 void
01565 plwarn(const char *errormsg)
01566 {
01567 int was_gfx = 0;
01568
01569 if (plsc->graphx == 1) {
01570 was_gfx = 1;
01571 pltext();
01572 }
01573
01574 fprintf(stderr, "\n*** PLPLOT WARNING ***\n");
01575 if (*errormsg != '\0')
01576 fprintf(stderr, "%s\n", errormsg);
01577
01578 if (was_gfx == 1)
01579 plgra();
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 void
01594 plabort(const char *errormsg)
01595 {
01596
01597 if (abort_handler != NULL)
01598 (*abort_handler)(errormsg);
01599
01600 if (plsc->errcode != NULL)
01601 *(plsc->errcode) = 1;
01602
01603 if (plsc->errmsg != NULL) {
01604 sprintf(plsc->errmsg, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n");
01605 if (*errormsg != '\0')
01606 sprintf(plsc->errmsg, "%s, aborting operation\n", errormsg);
01607
01608 } else {
01609 int was_gfx = 0;
01610
01611 if (plsc->graphx == 1) {
01612 was_gfx = 1;
01613 pltext();
01614 }
01615
01616 fprintf(stderr, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n");
01617 if (*errormsg != '\0')
01618 fprintf(stderr, "%s, aborting operation\n", errormsg);
01619
01620 if (was_gfx == 1)
01621 plgra();
01622 }
01623 }
01624
01625
01626
01627
01628
01629
01630
01631
01632 void
01633 plsabort(void (*handler) (const char *))
01634 {
01635 abort_handler = handler;
01636 }
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 void
01651 plexit(const char *errormsg)
01652 {
01653 int status = 1;
01654
01655 if (exit_handler != NULL)
01656 status = (*exit_handler)(errormsg);
01657
01658 plsc->nopause = 1;
01659 if (*errormsg != '\0') {
01660 fprintf(stderr, "\n*** PLPLOT ERROR, IMMEDIATE EXIT ***\n");
01661 fprintf(stderr, "%s\n", errormsg);
01662 }
01663 plend();
01664
01665 fprintf(stderr, "Program aborted\n");
01666 exit(status);
01667 }
01668
01669
01670
01671
01672
01673
01674
01675 void
01676 plsexit(int (*handler) (const char *))
01677 {
01678 exit_handler = handler;
01679 }
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 void
01692 c_plgra(void)
01693 {
01694 if (plsc->level > 0)
01695 plP_esc(PLESC_GRAPH, NULL);
01696 }
01697
01698 void
01699 c_plxormod(PLINT mode, PLINT *status)
01700 {
01701 static int ostate = 0;
01702
01703 if (!plsc->dev_xor) {
01704 *status = 0;
01705 return;
01706 }
01707
01708 if (plsc->level > 0) {
01709 plP_esc(PLESC_XORMOD, &mode);
01710 if (mode) {
01711 ostate = plsc->plbuf_write;
01712 plsc->plbuf_write = 0;
01713 } else
01714 plsc->plbuf_write = ostate;
01715 }
01716 *status = 1;
01717 }
01718
01719
01720
01721
01722
01723
01724
01725 void
01726 c_pltext(void)
01727 {
01728 if (plsc->level > 0)
01729 plP_esc(PLESC_TEXT, NULL);
01730 }
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 void
01741 pl_cmd(PLINT op, void *ptr)
01742 {
01743 plP_esc(op, ptr);
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763 char *
01764 plFindCommand(const char *fn)
01765 {
01766 char *fs = NULL, *dn;
01767
01768
01769 if (plInBuildTree() == 1) {
01770 plGetName(BUILD_DIR, "bindings/tk", fn, &fs);
01771 if ( ! plFindName(fs))
01772 return fs;
01773 else {
01774 plGetName(BUILD_DIR, "scripts", fn, &fs);
01775 if ( ! plFindName(fs))
01776 return fs;
01777 }
01778 }
01779
01780
01781
01782 #if defined(PLPLOT_BIN_ENV)
01783 if ((dn = getenv(PLPLOT_BIN_ENV)) != NULL) {
01784 plGetName(dn, "", fn, &fs);
01785 if ( ! plFindName(fs))
01786 return fs;
01787 fprintf(stderr, PLPLOT_BIN_ENV"=\"%s\"\n", dn);
01788 }
01789 #endif
01790
01791
01792
01793 plGetName(".", "", fn, &fs);
01794 if ( ! plFindName(fs))
01795 return fs;
01796
01797
01798
01799 #if defined(PLPLOT_HOME_ENV)
01800 if ((dn = getenv(PLPLOT_HOME_ENV)) != NULL) {
01801 plGetName(dn, "bin", fn, &fs);
01802 if ( ! plFindName(fs))
01803 return fs;
01804 fprintf(stderr, PLPLOT_HOME_ENV"=\"%s\"\n",dn);
01805 }
01806 #endif
01807
01808
01809
01810 #if defined (BIN_DIR)
01811 plGetName(BIN_DIR, "", fn, &fs);
01812 if ( ! plFindName(fs))
01813 return fs;
01814 #endif
01815
01816
01817
01818 free_mem(fs);
01819 fprintf(stderr, "plFindCommand: cannot locate command: %s\n", fn);
01820 #if defined (BIN_DIR)
01821 fprintf(stderr, "bin dir=\"" BIN_DIR "\"\n" );
01822 #endif
01823 return NULL;
01824 }
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 FILE *
01839 plLibOpen(const char *fn)
01840 {
01841 FILE *ret = NULL;
01842
01843 PDFstrm *pdfs = plLibOpenPdfstrm(fn);
01844 if (pdfs == NULL) {
01845 return NULL;
01846 }
01847 if (pdfs->file != NULL) {
01848 ret = pdfs->file;
01849 pdfs->file = NULL;
01850 }
01851 pdf_close(pdfs);
01852 return ret;
01853 }
01854
01855 PDFstrm *
01856 plLibOpenPdfstrm(const char *fn)
01857 {
01858 PDFstrm *file;
01859 char *fs = NULL, *dn = NULL;
01860
01861
01862
01863 if (plInBuildTree() == 1) {
01864 plGetName(SOURCE_DIR, "data", fn, &fs);
01865
01866 if ((file = pdf_fopen(fs, "rb")) != NULL)
01867 goto done;
01868 }
01869
01870
01871
01872 #if defined(PLPLOT_LIB_ENV)
01873 if ((dn = getenv(PLPLOT_LIB_ENV)) != NULL) {
01874 plGetName(dn, "", fn, &fs);
01875
01876 if ((file = pdf_fopen(fs, "rb")) != NULL)
01877 goto done;
01878 fprintf(stderr, PLPLOT_LIB_ENV"=\"%s\"\n", dn);
01879 }
01880 #endif
01881
01882
01883
01884 if ((file = pdf_fopen(fn, "rb")) != NULL){
01885 pldebug("plLibOpenPdfstr", "Found file %s in current directory.\n", fn);
01886 free_mem(fs);
01887 return (file);
01888 }
01889
01890
01891
01892 #if defined (PLPLOT_HOME_ENV)
01893 if ((dn = getenv(PLPLOT_HOME_ENV)) != NULL) {
01894 plGetName(dn, "lib", fn, &fs);
01895
01896 if ((file = pdf_fopen(fs, "rb")) != NULL)
01897 goto done;
01898 fprintf(stderr, PLPLOT_HOME_ENV"=\"%s\"\n",dn);
01899 }
01900 #endif
01901
01902
01903
01904 #if defined (DATA_DIR)
01905 plGetName(DATA_DIR, "", fn, &fs);
01906
01907 if ((file = pdf_fopen(fs, "rb")) != NULL)
01908 goto done;
01909 #endif
01910
01911
01912
01913 #ifdef PLLIBDEV
01914 plGetName(PLLIBDEV, "", fn, &fs);
01915
01916 if ((file = pdf_fopen(fs, "rb")) != NULL)
01917 goto done;
01918 #endif
01919
01920 #ifdef macintosh
01921 file = plMacLibOpen(fn);
01922 if (file != NULL)
01923 goto done;
01924 #endif
01925
01926 if (plplotLibDir != NULL) {
01927 plGetName(plplotLibDir, "", fn, &fs);
01928 if ((file = pdf_fopen(fs, "rb")) != NULL)
01929 goto done;
01930 }
01931
01932
01933 pldebug("plLibOpenPdfstr", "File %s not found.\n", fn);
01934 free_mem(fs);
01935 return NULL;
01936
01937 done:
01938 pldebug("plLibOpenPdfstr", "Found file %s\n", fs);
01939 free_mem(fs);
01940 return (file);
01941 }
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 #ifdef __unix
01962 int
01963 plFindName(char *p)
01964 {
01965 int n;
01966 char buf[PLPLOT_MAX_PATH], *cp;
01967 extern int errno;
01968 struct stat sbuf;
01969
01970 pldebug("plFindName", "Trying to find %s\n", p);
01971 while ((n = readlink(p, buf, PLPLOT_MAX_PATH)) > 0) {
01972 pldebug("plFindName", "Readlink read %d chars at: %s\n", n, p);
01973 if (buf[0] == '/') {
01974
01975
01976 strncpy(p, buf, n);
01977 p[n] = '\0';
01978 pldebug("plFindName", "Link is absolute: %s\n", p);
01979 }
01980 else {
01981
01982
01983 cp = 1 + strrchr(p, '/');
01984 strncpy(cp, buf, n);
01985 cp[n] = '\0';
01986 pldebug("plFindName",
01987 "Link is relative: %s\n\tTotal path:%s\n", cp, p);
01988 }
01989 }
01990
01991
01992
01993 #ifdef SX
01994 #define S_ISREG(mode) (mode & S_IFREG)
01995 #endif
01996
01997
01998
01999 if (errno == EINVAL || errno == ENXIO) {
02000 pldebug("plFindName", "%s may be the one...\n", p);
02001 if ((stat(p, &sbuf) == 0) && S_ISREG(sbuf.st_mode)) {
02002 pldebug("plFindName", "%s is a regular file\n", p);
02003 return (access(p, X_OK));
02004 }
02005 }
02006 pldebug("plFindName", "%s found but is not executable\n", p);
02007 return (errno ? errno : -1);
02008 }
02009
02010 #else
02011 int
02012 plFindName(char *p)
02013 {
02014 return 1;
02015 }
02016 #endif
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027 void
02028 plGetName(const char *dir, const char *subdir, const char *filename, char **filespec)
02029 {
02030 int lfilespec;
02031
02032
02033
02034 free_mem(*filespec);
02035 lfilespec = strlen(dir) + strlen(subdir) + strlen(filename) + 10;
02036 if ((*filespec = (char *) malloc(lfilespec))==NULL)
02037 {
02038 plexit("plGetName: Insufficient memory");
02039 }
02040
02041 strcpy(*filespec, dir);
02042
02043 if (*subdir != '\0') {
02044 strcat_delim(*filespec);
02045 strcat(*filespec, subdir);
02046 }
02047 if (*filename != '\0') {
02048 strcat_delim(*filespec);
02049 strcat(*filespec, filename);
02050 }
02051 pldebug("plGetName", "Length of full pathname of file to be found is %d\n", lfilespec);
02052 pldebug("plGetName", "Full pathname of file to be found is %s\n", *filespec);
02053 }
02054
02055
02056
02057
02058
02059
02060
02061
02062 void
02063 strcat_delim(char *dirspec)
02064 {
02065 int ldirspec = strlen(dirspec);
02066 #if defined (MSDOS) || defined(WIN32)
02067 if (dirspec[ldirspec-1] != '\\')
02068 strcat(dirspec, "\\");
02069 #elif defined (macintosh)
02070 if (dirspec[ldirspec-1] != ':')
02071 strcat(dirspec, ":");
02072 #else
02073 if (dirspec[ldirspec-1] != '/')
02074 strcat(dirspec, "/");
02075 #endif
02076 }
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086 void
02087 plcol_interp(PLStream *pls, PLColor *newcolor, int i, int ncol)
02088 {
02089 PLFLT x, delta;
02090 int il, ir;
02091
02092 x = (double) (i * (pls->ncol1-1)) / (double) (ncol-1);
02093 il = (int)x;
02094 ir = il + 1;
02095 delta = x - il;
02096
02097 if (ir > pls->ncol1 || il < 0)
02098 fprintf(stderr, "Invalid color\n");
02099
02100 else if (ir == pls->ncol1 || (delta == 0.)) {
02101 newcolor->r = pls->cmap1[il].r;
02102 newcolor->g = pls->cmap1[il].g;
02103 newcolor->b = pls->cmap1[il].b;
02104 newcolor->a = pls->cmap1[il].a;
02105 }
02106 else {
02107 newcolor->r = (unsigned char)((1.-delta) * pls->cmap1[il].r + delta * pls->cmap1[ir].r);
02108 newcolor->g = (unsigned char)((1.-delta) * pls->cmap1[il].g + delta * pls->cmap1[ir].g);
02109 newcolor->b = (unsigned char)((1.-delta) * pls->cmap1[il].b + delta * pls->cmap1[ir].b);
02110 newcolor->a = (1.-delta) * pls->cmap1[il].a + delta * pls->cmap1[ir].a;
02111 }
02112 }
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122 #define MAX_NUM_TRIES 10
02123 void
02124 plOpenFile(PLStream *pls)
02125 {
02126 int i = 0, count = 0;
02127 size_t len;
02128 char line[BUFFER_SIZE];
02129
02130 while (pls->OutFile == NULL) {
02131
02132
02133
02134
02135 if (pls->family && pls->BaseName != NULL)
02136 plP_getmember(pls);
02137
02138
02139
02140 if (pls->FileName == NULL) {
02141 do {
02142 fprintf(stdout, "Enter graphics output file name: ");
02143 plio_fgets(line, sizeof(line), stdin);
02144 len = strlen(line);
02145 if (len)
02146 len--;
02147 line[len] = '\0';
02148 count++;
02149 } while (!len && count < MAX_NUM_TRIES);
02150 plP_sfnam(pls, line);
02151 }
02152
02153
02154
02155 if ( ! strcmp(pls->FileName, "-")) {
02156 pls->OutFile = stdout;
02157 pls->output_type = 1;
02158 break;
02159 }
02160
02161
02162
02163 if (pls->family && pls->BaseName != NULL)
02164 plP_getmember(pls);
02165
02166 if (i++ > 10)
02167 plexit("Too many tries.");
02168
02169 if ((pls->OutFile = fopen(pls->FileName, "wb+")) == NULL)
02170 fprintf(stderr, "Can't open %s.\n", pls->FileName);
02171 else
02172 pldebug("plOpenFile", "Opened %s\n", pls->FileName);
02173 }
02174 }
02175
02176
02177
02178
02179
02180
02181
02182 void
02183 plP_getmember(PLStream *pls)
02184 {
02185 char tmp[BUFFER_SIZE];
02186 char prefix[BUFFER_SIZE];
02187 char* suffix;
02188 char num[BUFFER_SIZE];
02189 int maxlen;
02190
02191 maxlen = strlen(pls->BaseName) + 10;
02192 if (pls->FileName == NULL)
02193 {
02194 if ((pls->FileName = (char *) malloc(maxlen))==NULL)
02195 {
02196 plexit("plP_getmember: Insufficient memory");
02197 }
02198 }
02199
02200 suffix = strstr (pls->BaseName, "%n");
02201
02202 snprintf(tmp, BUFFER_SIZE, "%%0%1ii", (int) pls->fflen);
02203 snprintf(num, BUFFER_SIZE, tmp, pls->member);
02204
02205 if (suffix == NULL)
02206 snprintf (pls->FileName, maxlen, "%s.%s", pls->BaseName, num);
02207 else {
02208 strncpy (prefix, pls->BaseName, BUFFER_SIZE-1);
02209 prefix [(suffix - pls->BaseName<BUFFER_SIZE)?(suffix-pls->BaseName):BUFFER_SIZE-1] = '\0';
02210 snprintf (pls->FileName, maxlen, "%s%s%s", prefix, num, suffix + 2);
02211 }
02212
02213 }
02214
02215
02216
02217
02218
02219
02220
02221
02222 void
02223 plP_sfnam(PLStream *pls, const char *fnam)
02224 {
02225 char prefix[BUFFER_SIZE];
02226 char* suffix;
02227 int maxlen;
02228 pls->OutFile = NULL;
02229
02230 if (pls->FileName != NULL)
02231 free((void *) pls->FileName);
02232
02233 maxlen = 10 + strlen(fnam);
02234 if ((pls->FileName = (char *) malloc(maxlen))==NULL)
02235 {
02236 plexit("plP_sfnam: Insufficient memory");
02237 }
02238
02239 suffix = strstr (fnam, "%n");
02240
02241 if (suffix == NULL) {
02242 strncpy(pls->FileName, fnam, maxlen-1);
02243 pls->FileName[maxlen-1] = '\0';
02244 }
02245 else {
02246 strncpy (prefix, fnam, BUFFER_SIZE-1);
02247 prefix [(suffix - fnam)<BUFFER_SIZE?(suffix-fnam):BUFFER_SIZE-1] = '\0';
02248 snprintf (pls->FileName, maxlen, "%s%s", prefix, suffix + 2);
02249 }
02250
02251 if (pls->BaseName != NULL)
02252 free((void *) pls->BaseName);
02253
02254 if ((pls->BaseName = (char *) malloc(maxlen))==NULL)
02255 {
02256 plexit("plP_sfnam: Insufficient memory");
02257 }
02258
02259 strncpy(pls->BaseName, fnam, maxlen-1);
02260 pls->BaseName[maxlen-1] = '\0';
02261 }
02262
02263
02264
02265
02266
02267
02268
02269 void
02270 plFamInit(PLStream *pls)
02271 {
02272 if (pls->family) {
02273 pls->bytecnt = 0;
02274 if ( ! pls->member)
02275 pls->member = 1;
02276 if ( ! pls->finc)
02277 pls->finc = 1;
02278 if ( ! pls->fflen)
02279 pls->fflen = 1;
02280 if ( ! pls->bytemax)
02281 pls->bytemax = PL_FILESIZE_KB * 1000;
02282 }
02283 }
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295 void
02296 plGetFam(PLStream *pls)
02297 {
02298 PLFLT xpmm_loc, ypmm_loc;
02299 if (pls->family) {
02300 if (pls->bytecnt > pls->bytemax || pls->famadv) {
02301 PLINT local_page_status = pls->page_status;
02302 plP_tidy();
02303 pls->member += pls->finc;
02304 pls->famadv = 0;
02305 plP_init();
02306
02307
02308 pls->page_status = local_page_status;
02309
02310
02311
02312
02313 plP_gpixmm(&xpmm_loc, &ypmm_loc);
02314 plP_setpxl(xpmm_loc*plsc->caspfactor, ypmm_loc/plsc->caspfactor);
02315 return;
02316 }
02317 }
02318 }
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329 void
02330 plRotPhy(PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax,
02331 PLINT *px, PLINT *py)
02332 {
02333 int x, y;
02334
02335 x = *px;
02336 y = *py;
02337
02338 switch (orient%4) {
02339
02340 case 1:
02341 *px = xmin + (y - ymin);
02342 *py = ymin + (xmax - x);
02343 break;
02344
02345 case 2:
02346 *px = xmin + (xmax - x);
02347 *py = ymin + (ymax - y);
02348 break;
02349
02350 case 3:
02351 *px = xmin + (ymax - y);
02352 *py = ymin + (x - xmin);
02353 break;
02354
02355 default:
02356 break;
02357 }
02358 }
02359
02360
02361
02362
02363
02364
02365
02366
02367 PLDev *
02368 plAllocDev(PLStream *pls)
02369 {
02370 if (pls->dev != NULL)
02371 free((void *) pls->dev);
02372
02373 pls->dev = calloc(1, (size_t) sizeof(PLDev));
02374 if (pls->dev == NULL)
02375 plexit("plAllocDev: cannot allocate memory\n");
02376
02377 return (PLDev *) pls->dev;
02378 }
02379
02380
02381
02382
02383
02384
02385
02386 void
02387 plGinInit(PLGraphicsIn *gin)
02388 {
02389 gin->type = 0;
02390 gin->state = 0;
02391 gin->keysym = 0;
02392 gin->button = 0;
02393 gin->string[0] = '\0';
02394 gin->pX = gin->pY = -1;
02395 gin->dX = gin->dY = 0.;
02396 gin->wX = gin->wY = 0.;
02397 }
02398
02399
02400
02401
02402
02403
02404
02405 PLINT
02406 plGetInt(const char *s)
02407 {
02408 int m;
02409 int i = 0;
02410 char line[BUFFER_SIZE];
02411
02412 while (i++ < 10) {
02413 fputs(s, stdout);
02414 plio_fgets(line, sizeof(line), stdin);
02415
02416 #ifdef MSDOS
02417 m = atoi(line);
02418 return (m);
02419 #else
02420 if (sscanf(line, "%d", &m) == 1)
02421 return (m);
02422 fprintf(stdout, "No value or value out of range; please try again\n");
02423 #endif
02424 }
02425 plexit("Too many tries.");
02426 return (0);
02427 }
02428
02429
02430
02431
02432
02433
02434
02435 PLFLT
02436 plGetFlt(const char *s)
02437 {
02438 PLFLT m;
02439 double m1;
02440 int i = 0;
02441 char line[BUFFER_SIZE];
02442
02443 while (i++ < 10) {
02444 fputs(s, stdout);
02445 plio_fgets(line, sizeof(line), stdin);
02446
02447 #ifdef MSDOS
02448 m = atof(line);
02449 return (m);
02450 #else
02451 if (sscanf(line, "%lf", &m1) == 1) {
02452 m = (PLFLT) m1;
02453 return (m);
02454 }
02455 fprintf(stdout, "No value or value out of range; please try again\n");
02456 #endif
02457 }
02458 plexit("Too many tries.");
02459 return (0.);
02460 }
02461
02462
02463
02464
02465
02466
02467
02468
02469 char PLDLLIMPEXP *
02470 plstrdup(const char *src)
02471 {
02472 char *dest = (char *) malloc( (strlen(src) + 1) * sizeof(char) );
02473 if (dest != NULL)
02474 strcpy(dest, src);
02475 else
02476 plabort("Out of memory");
02477
02478 return dest;
02479 }
02480
02481 #ifndef PL_HAVE_SNPRINTF
02482
02483
02484
02485
02486
02487
02488
02489
02490 int
02491 plsnprintf(char *buffer, int n, const char *format, ...)
02492 {
02493 int ret;
02494
02495 va_list args;
02496 va_start(args, format);
02497 ret=vsprintf(buffer, fmt, args);
02498 va_end( argptr );
02499
02500
02501 if (ret > n-1)
02502 plabort("plsnprintf: buffer overrun");
02503
02504 return ret;
02505 }
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515 int
02516 plsnscanf( const char *buffer, int n, const char *format, ... )
02517 {
02518 int ret;
02519
02520 va_list argptr;
02521 va_start(argptr, format);
02522 ret=vsscanf(buffer, fmt, args);
02523 va_end(argptr);
02524
02525 return ret;
02526 }
02527
02528 #endif
02529
02530
02531
02532
02533
02534
02535
02536 void
02537 c_plseed(unsigned int s)
02538 {
02539 init_genrand(s);
02540 }
02541
02542
02543
02544
02545
02546
02547
02548 PLFLT
02549 c_plrandd(void)
02550 {
02551 return (PLFLT)(genrand_real1());
02552 }
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566 char *
02567 plsave_set_locale(void) {
02568 char * setlocale_ptr;
02569 char * saved_lc_numeric_locale;
02570
02571 if(!(saved_lc_numeric_locale = (char *) malloc(100*sizeof(char)))) {
02572 plexit("plsave_set_locale: out of memory");
02573 }
02574
02575
02576 if(!(setlocale_ptr = setlocale(LC_NUMERIC, NULL))) {
02577 plexit("plsave_set_locale: LC_NUMERIC locale could not be determined for NULL locale.\n");
02578 }
02579 strncpy(saved_lc_numeric_locale, setlocale_ptr, 100);
02580 saved_lc_numeric_locale[99] = '\0';
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590 if(!(setlocale(LC_NUMERIC, "C"))) {
02591 plexit("plsave_set_locale: LC_NUMERIC locale could not be set to \"C\"");
02592 }
02593 return saved_lc_numeric_locale;
02594 }
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604 void
02605 plrestore_locale(char *saved_lc_numeric_locale) {
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615 if(!(setlocale(LC_NUMERIC, saved_lc_numeric_locale))) {
02616 char msgbuf[1024];
02617 snprintf(msgbuf,1024,"plrestore_locale: LC_NUMERIC could not be restored to the default \"%s\" locale.\n", saved_lc_numeric_locale);
02618 plexit(msgbuf);
02619 }
02620 free(saved_lc_numeric_locale);
02621 }
02622