| 18 |  |  | 
| 19 |  | static const char       rmx_mismatch_warn[] = "WARNING: data type mismatch\n"; | 
| 20 |  |  | 
| 21 | – | #define array_size(rm)  (sizeof(double)*(rm)->nrows*(rm)->ncols*(rm)->ncomp) | 
| 22 | – | #define mapped_size(rm) ((char *)(rm)->mtx + array_size(rm) - (char *)(rm)->mapped) | 
| 23 | – |  | 
| 21 |  | /* Initialize a RMATRIX struct but don't allocate array space */ | 
| 22 |  | RMATRIX * | 
| 23 |  | rmx_new(int nr, int nc, int n) | 
| 31 |  | if (!dnew) | 
| 32 |  | return(NULL); | 
| 33 |  |  | 
| 34 | < | dnew->dtype = DTdouble; | 
| 34 | > | dnew->dtype = DTrmx_native; | 
| 35 |  | dnew->nrows = nr; | 
| 36 |  | dnew->ncols = nc; | 
| 37 |  | dnew->ncomp = n; | 
| 50 |  | return(1); | 
| 51 |  | if ((rm->nrows <= 0) | (rm->ncols <= 0) | (rm->ncomp <= 0)) | 
| 52 |  | return(0); | 
| 53 | < | rm->mtx = (double *)malloc(array_size(rm)); | 
| 53 | > | rm->mtx = (double *)malloc(rmx_array_size(rm)); | 
| 54 | > | rm->pflags |= RMF_OURMEM; | 
| 55 |  | return(rm->mtx != NULL); | 
| 56 |  | } | 
| 57 |  |  | 
| 77 |  | free(rm->info); | 
| 78 |  | rm->info = NULL; | 
| 79 |  | } | 
| 80 | < | if (rm->mtx) { | 
| 80 | > | if (rm->mtx && rm->pflags & RMF_OURMEM) { | 
| 81 |  | #ifdef MAP_FILE | 
| 82 |  | if (rm->mapped) { | 
| 83 | < | munmap(rm->mapped, mapped_size(rm)); | 
| 83 | > | munmap(rm->mapped, rmx_mapped_size(rm)); | 
| 84 |  | rm->mapped = NULL; | 
| 85 |  | } else | 
| 86 |  | #endif | 
| 87 |  | free(rm->mtx); | 
| 88 | < | rm->mtx = NULL; | 
| 88 | > | rm->pflags &= ~RMF_OURMEM; | 
| 89 |  | } | 
| 90 | + | rm->mtx = NULL; | 
| 91 |  | } | 
| 92 |  |  | 
| 93 |  | /* Free an RMATRIX struct and data */ | 
| 156 |  | return(0); | 
| 157 |  | } | 
| 158 |  | if ((i = isbigendian(s)) >= 0) { | 
| 159 | < | ip->swapin = (nativebigendian() != i); | 
| 159 | > | if (nativebigendian() != i) | 
| 160 | > | ip->pflags |= RMF_SWAPIN; | 
| 161 | > | else | 
| 162 | > | ip->pflags &= ~RMF_SWAPIN; | 
| 163 |  | return(0); | 
| 164 |  | } | 
| 165 |  | if (isexpos(s)) { | 
| 214 |  | for (j = 0; j < rm->ncols; j++) { | 
| 215 |  | if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp) | 
| 216 |  | return(0); | 
| 217 | < | if (rm->swapin) | 
| 217 | > | if (rm->pflags & RMF_SWAPIN) | 
| 218 |  | swap32((char *)val, rm->ncomp); | 
| 219 |  | for (k = 0; k < rm->ncomp; k++) | 
| 220 |  | *drp++ = val[k]; | 
| 225 |  | static int | 
| 226 |  | rmx_load_double(double *drp, const RMATRIX *rm, FILE *fp) | 
| 227 |  | { | 
| 228 | + | if (DTrmx_native != DTdouble) | 
| 229 | + | return(0); | 
| 230 |  | if (getbinary(drp, sizeof(*drp)*rm->ncomp, rm->ncols, fp) != rm->ncols) | 
| 231 |  | return(0); | 
| 232 | < | if (rm->swapin) | 
| 232 | > | if (rm->pflags & RMF_SWAPIN) | 
| 233 |  | swap64((char *)drp, rm->ncols*rm->ncomp); | 
| 234 |  | return(1); | 
| 235 |  | } | 
| 291 |  | rm->ncomp = 3; | 
| 292 |  | setcolor(rm->cexp, 1.f, 1.f, 1.f); | 
| 293 |  | memcpy(rm->wlpart, WLPART, sizeof(rm->wlpart)); | 
| 294 | < | rm->swapin = 0; | 
| 294 | > | rm->pflags = 0; | 
| 295 |  | } | 
| 296 |  | rm->dtype = DTascii;                    /* assumed w/o FORMAT */ | 
| 297 |  | if (getheader(fp, get_dminfo, rm) < 0) { | 
| 340 |  | int     i; | 
| 341 |  | #ifdef MAP_FILE | 
| 342 |  | long    pos;            /* map memory for file > 1MB if possible */ | 
| 343 | < | if ((rm->dtype == DTdouble) & !rm->swapin && array_size(rm) >= 1L<<20 && | 
| 343 | > | if ((rm->dtype == DTrmx_native) & !(rm->pflags & RMF_SWAPIN) && | 
| 344 | > | rmx_array_size(rm) >= 1L<<20 && | 
| 345 |  | (pos = ftell(fp)) >= 0 && !(pos % sizeof(double))) { | 
| 346 | < | rm->mapped = mmap(NULL, array_size(rm)+pos, PROT_READ|PROT_WRITE, | 
| 346 | > | rm->mapped = mmap(NULL, rmx_array_size(rm)+pos, PROT_READ|PROT_WRITE, | 
| 347 |  | MAP_PRIVATE, fileno(fp), 0); | 
| 348 |  | if (rm->mapped != MAP_FAILED) { | 
| 349 |  | rm->mtx = (double *)rm->mapped + pos/sizeof(double); | 
| 350 | + | rm->pflags |= RMF_OURMEM; | 
| 351 |  | return(1); | 
| 352 |  | }               /* else fall back on reading into memory */ | 
| 353 |  | rm->mapped = NULL; | 
| 355 |  | #endif | 
| 356 |  | if (!rmx_prepare(rm)) { /* need in-core matrix array */ | 
| 357 |  | fprintf(stderr, "Cannot allocate %g MByte matrix array\n", | 
| 358 | < | (1./(1L<<20))*(double)array_size(rm)); | 
| 358 | > | (1./(1L<<20))*(double)rmx_array_size(rm)); | 
| 359 |  | return(0); | 
| 360 |  | } | 
| 361 |  | for (i = 0; i < rm->nrows; i++) | 
| 399 |  | }                               /* else open it ourselves */ | 
| 400 |  | fp = fopen(inspec, "r"); | 
| 401 |  | } | 
| 402 | < | if (!fp) | 
| 402 | > | if (!fp) { | 
| 403 | > | fprintf(stderr, "Cannot open for reading: %s\n", inspec); | 
| 404 |  | return(NULL); | 
| 405 | + | } | 
| 406 |  | #ifdef getc_unlocked | 
| 407 |  | flockfile(fp); | 
| 408 |  | #endif | 
| 507 |  | if (nc < 3) return(0); | 
| 508 |  | scan = (uby8 *)tempbuffer((nc+1)*len); | 
| 509 |  | if (!scan) return(0); | 
| 510 | < | for (j = len; j--; dp += nc) { | 
| 510 | > | for (j = 0; j < len; j++, dp += nc) { | 
| 511 |  | for (k = nc; k--; ) | 
| 512 |  | scol[k] = dp[k]; | 
| 513 |  | scolor2scolr(scan+j*(nc+1), scol, nc); | 
| 547 |  | dtype = DTxyze; | 
| 548 |  | else if ((dtype == DTxyze) & (rm->dtype == DTrgbe)) | 
| 549 |  | dtype = DTrgbe; | 
| 550 | < | if ((dtype == DTspec) & (rm->ncomp < 3)) | 
| 550 | > | if ((dtype < DTspec) & (rm->ncomp > 3)) | 
| 551 | > | dtype = DTspec; | 
| 552 | > | else if ((dtype == DTspec) & (rm->ncomp <= 3)) | 
| 553 |  | return(0); | 
| 554 |  |  | 
| 555 |  | if (dtype == DTascii)                   /* set file type (WINDOWS) */ | 
| 570 |  | } | 
| 571 |  | if (dtype >= DTspec) {                  /* # components & split? */ | 
| 572 |  | fputncomp(rm->ncomp, fp); | 
| 573 | < | if (dtype == DTspec || (rm->ncomp > 3 && | 
| 574 | < | memcmp(rm->wlpart, WLPART, sizeof(WLPART)))) | 
| 573 | > | if (rm->ncomp > 3 && | 
| 574 | > | memcmp(rm->wlpart, WLPART, sizeof(WLPART))) | 
| 575 |  | fputwlsplit(rm->wlpart, fp); | 
| 576 |  | } else if ((rm->ncomp != 3) & (rm->ncomp != 1)) | 
| 577 |  | return(0);                      /* wrong # components */ | 
| 593 |  | return(rmx_write_ascii(dp, nc, len, fp)); | 
| 594 |  | case DTfloat: | 
| 595 |  | return(rmx_write_float(dp, nc*len, fp)); | 
| 596 | < | case DTdouble: | 
| 596 | > | case DTrmx_native: | 
| 597 |  | return(putbinary(dp, sizeof(*dp)*nc, len, fp) == len); | 
| 598 |  | case DTrgbe: | 
| 599 |  | case DTxyze: | 
| 617 |  | #ifdef getc_unlocked | 
| 618 |  | flockfile(fp); | 
| 619 |  | #endif | 
| 620 | < | if (dtype == DTdouble)                  /* write all at once? */ | 
| 620 | > | if (dtype == DTrmx_native)              /* write all at once? */ | 
| 621 |  | ok = rmx_write_data(rm->mtx, rm->ncomp, | 
| 622 |  | rm->nrows*rm->ncols, dtype, fp); | 
| 623 |  | else                                    /* else row by row */ | 
| 644 |  |  | 
| 645 |  | if (!rid) | 
| 646 |  | return(NULL); | 
| 647 | < | memset(rid->mtx, 0, array_size(rid)); | 
| 647 | > | memset(rid->mtx, 0, rmx_array_size(rid)); | 
| 648 |  | for (i = dim; i--; ) { | 
| 649 |  | double      *dp = rmx_lval(rid,i,i); | 
| 650 |  | for (k = n; k--; ) | 
| 669 |  | rmx_free(dnew); | 
| 670 |  | return(NULL); | 
| 671 |  | } | 
| 672 | < | memcpy(dnew->mtx, rm->mtx, array_size(dnew)); | 
| 672 | > | memcpy(dnew->mtx, rm->mtx, rmx_array_size(dnew)); | 
| 673 |  | } | 
| 674 |  | rmx_addinfo(dnew, rm->info); | 
| 675 |  | dnew->dtype = rm->dtype; | 
| 676 |  | copycolor(dnew->cexp, rm->cexp); | 
| 677 |  | memcpy(dnew->wlpart, rm->wlpart, sizeof(dnew->wlpart)); | 
| 678 |  | return(dnew); | 
| 679 | + | } | 
| 680 | + |  | 
| 681 | + | /* Replace data in first matrix with data from second */ | 
| 682 | + | int | 
| 683 | + | rmx_transfer_data(RMATRIX *rdst, RMATRIX *rsrc, int dometa) | 
| 684 | + | { | 
| 685 | + | if (!rdst | !rsrc || (rdst->nrows != rsrc->nrows) | | 
| 686 | + | (rdst->ncols != rsrc->ncols) | | 
| 687 | + | (rdst->ncomp != rsrc->ncomp)) | 
| 688 | + | return(0); | 
| 689 | + |  | 
| 690 | + | if (dometa) {           /* transfer everything? */ | 
| 691 | + | rmx_reset(rdst); | 
| 692 | + | *rdst = *rsrc; | 
| 693 | + | rsrc->info = NULL; rsrc->mapped = NULL; rsrc->mtx = NULL; | 
| 694 | + | return(1); | 
| 695 | + | } | 
| 696 | + | if (rdst->pflags & RMF_OURMEM) { | 
| 697 | + | #ifdef MAP_FILE                 /* just matrix data -- leave metadata */ | 
| 698 | + | if (rdst->mapped) | 
| 699 | + | munmap(rdst->mapped, rmx_mapped_size(rdst)); | 
| 700 | + | else | 
| 701 | + | #endif | 
| 702 | + | if (rdst->mtx) | 
| 703 | + | free(rdst->mtx); | 
| 704 | + | } | 
| 705 | + | rdst->mapped = rsrc->mapped; | 
| 706 | + | rdst->mtx = rsrc->mtx; | 
| 707 | + | if (rsrc->pflags & RMF_OURMEM) | 
| 708 | + | rdst->pflags |= RMF_OURMEM; | 
| 709 | + | else | 
| 710 | + | rdst->pflags &= ~RMF_OURMEM; | 
| 711 | + | rsrc->mapped = NULL; rsrc->mtx = NULL; | 
| 712 | + | return(1); | 
| 713 |  | } | 
| 714 |  |  | 
| 715 |  | /* Allocate and assign transposed matrix */ |