| 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 = (rmx_dtype *)malloc(rmx_array_size(rm)); | 
| 54 | > | rm->pflags |= RMF_FREEMEM; | 
| 55 |  | return(rm->mtx != NULL); | 
| 56 |  | } | 
| 57 |  |  | 
| 77 |  | free(rm->info); | 
| 78 |  | rm->info = NULL; | 
| 79 |  | } | 
| 82 | – | if (rm->mtx) { | 
| 80 |  | #ifdef MAP_FILE | 
| 81 | < | if (rm->mapped) { | 
| 82 | < | munmap(rm->mapped, mapped_size(rm)); | 
| 83 | < | rm->mapped = NULL; | 
| 84 | < | } else | 
| 81 | > | if (rm->mapped) { | 
| 82 | > | munmap(rm->mapped, rmx_mapped_size(rm)); | 
| 83 | > | rm->mapped = NULL; | 
| 84 | > | } else | 
| 85 |  | #endif | 
| 86 | < | free(rm->mtx); | 
| 87 | < | rm->mtx = NULL; | 
| 86 | > | if (rm->pflags & RMF_FREEMEM) { | 
| 87 | > | free(rm->mtx); | 
| 88 | > | rm->pflags &= ~RMF_FREEMEM; | 
| 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)) { | 
| 190 |  | } | 
| 191 |  |  | 
| 192 |  | static int | 
| 193 | < | rmx_load_ascii(double *drp, const RMATRIX *rm, FILE *fp) | 
| 193 | > | rmx_load_ascii(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 194 |  | { | 
| 195 |  | int     j, k; | 
| 196 |  |  | 
| 202 |  | } | 
| 203 |  |  | 
| 204 |  | static int | 
| 205 | < | rmx_load_float(double *drp, const RMATRIX *rm, FILE *fp) | 
| 205 | > | rmx_load_float(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 206 |  | { | 
| 207 |  | int     j, k; | 
| 208 |  | float   val[100]; | 
| 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]; | 
| 223 |  | } | 
| 224 |  |  | 
| 225 |  | static int | 
| 226 | < | rmx_load_double(double *drp, const RMATRIX *rm, FILE *fp) | 
| 226 | > | rmx_load_double(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 227 |  | { | 
| 228 |  | if (getbinary(drp, sizeof(*drp)*rm->ncomp, rm->ncols, fp) != rm->ncols) | 
| 229 |  | return(0); | 
| 230 | < | if (rm->swapin) | 
| 230 | > | if (rm->pflags & RMF_SWAPIN) | 
| 231 |  | swap64((char *)drp, rm->ncols*rm->ncomp); | 
| 232 |  | return(1); | 
| 233 |  | } | 
| 234 |  |  | 
| 235 |  | static int | 
| 236 | < | rmx_load_rgbe(double *drp, const RMATRIX *rm, FILE *fp) | 
| 236 | > | rmx_load_rgbe(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 237 |  | { | 
| 238 |  | COLR    *scan; | 
| 239 |  | COLOR   col; | 
| 256 |  | } | 
| 257 |  |  | 
| 258 |  | static int | 
| 259 | < | rmx_load_spec(double *drp, const RMATRIX *rm, FILE *fp) | 
| 259 | > | rmx_load_spec(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 260 |  | { | 
| 261 |  | uby8    *scan; | 
| 262 |  | SCOLOR  scol; | 
| 289 |  | rm->ncomp = 3; | 
| 290 |  | setcolor(rm->cexp, 1.f, 1.f, 1.f); | 
| 291 |  | memcpy(rm->wlpart, WLPART, sizeof(rm->wlpart)); | 
| 292 | < | rm->swapin = 0; | 
| 292 | > | rm->pflags = 0; | 
| 293 |  | } | 
| 294 |  | rm->dtype = DTascii;                    /* assumed w/o FORMAT */ | 
| 295 |  | if (getheader(fp, get_dminfo, rm) < 0) { | 
| 309 |  | return(1); | 
| 310 |  | } | 
| 311 |  |  | 
| 312 | < | /* Load next row as double (cannot be XML) */ | 
| 312 | > | /* Load next row as rmx_dtype (cannot be XML) */ | 
| 313 |  | int | 
| 314 | < | rmx_load_row(double *drp, const RMATRIX *rm, FILE *fp) | 
| 314 | > | rmx_load_row(rmx_dtype *drp, const RMATRIX *rm, FILE *fp) | 
| 315 |  | { | 
| 316 |  | switch (rm->dtype) { | 
| 317 |  | case DTascii: | 
| 338 |  | int     i; | 
| 339 |  | #ifdef MAP_FILE | 
| 340 |  | long    pos;            /* map memory for file > 1MB if possible */ | 
| 341 | < | if ((rm->dtype == DTdouble) & !rm->swapin && array_size(rm) >= 1L<<20 && | 
| 342 | < | (pos = ftell(fp)) >= 0 && !(pos % sizeof(double))) { | 
| 343 | < | rm->mapped = mmap(NULL, array_size(rm)+pos, PROT_READ|PROT_WRITE, | 
| 341 | > | if ((rm->dtype == DTrmx_native) & !(rm->pflags & RMF_SWAPIN) & | 
| 342 | > | (rmx_array_size(rm) >= 1L<<20) && | 
| 343 | > | (pos = ftell(fp)) >= 0 && !(pos % sizeof(rmx_dtype))) { | 
| 344 | > | rm->mapped = mmap(NULL, rmx_array_size(rm)+pos, PROT_READ|PROT_WRITE, | 
| 345 |  | MAP_PRIVATE, fileno(fp), 0); | 
| 346 |  | if (rm->mapped != MAP_FAILED) { | 
| 347 | < | rm->mtx = (double *)rm->mapped + pos/sizeof(double); | 
| 347 | > | if (rm->pflags & RMF_FREEMEM) | 
| 348 | > | free(rm->mtx); | 
| 349 | > | rm->mtx = (rmx_dtype *)rm->mapped + pos/sizeof(rmx_dtype); | 
| 350 | > | rm->pflags &= ~RMF_FREEMEM; | 
| 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++) | 
| 436 |  | (dnew->cexp[1] != 1.f) | (dnew->cexp[2] != 1.f)) { | 
| 437 |  | double  cmlt[MAXCSAMP]; | 
| 438 |  | int     i; | 
| 433 | – | cmlt[0] = 1./dnew->cexp[0]; | 
| 434 | – | cmlt[1] = 1./dnew->cexp[1]; | 
| 435 | – | cmlt[2] = 1./dnew->cexp[2]; | 
| 439 |  | if (dnew->ncomp > MAXCSAMP) { | 
| 440 |  | fprintf(stderr, "Excess spectral components in: %s\n", | 
| 441 |  | inspec); | 
| 442 |  | rmx_free(dnew); | 
| 443 |  | return(NULL); | 
| 444 |  | } | 
| 445 | + | cmlt[0] = 1./dnew->cexp[0]; | 
| 446 | + | cmlt[1] = 1./dnew->cexp[1]; | 
| 447 | + | cmlt[2] = 1./dnew->cexp[2]; | 
| 448 |  | for (i = dnew->ncomp; i-- > 3; ) | 
| 449 | < | cmlt[i] = cmlt[1]; | 
| 449 | > | cmlt[i] = cmlt[1];      /* XXX hack! */ | 
| 450 |  | rmx_scale(dnew, cmlt); | 
| 451 |  | setcolor(dnew->cexp, 1.f, 1.f, 1.f); | 
| 452 |  | } | 
| 454 |  | } | 
| 455 |  |  | 
| 456 |  | static int | 
| 457 | < | rmx_write_ascii(const double *dp, int nc, int len, FILE *fp) | 
| 457 | > | rmx_write_ascii(const rmx_dtype *dp, int nc, int len, FILE *fp) | 
| 458 |  | { | 
| 459 |  | while (len-- > 0) { | 
| 460 |  | int     k = nc; | 
| 466 |  | } | 
| 467 |  |  | 
| 468 |  | static int | 
| 469 | < | rmx_write_float(const double *dp, int len, FILE *fp) | 
| 469 | > | rmx_write_float(const rmx_dtype *dp, int len, FILE *fp) | 
| 470 |  | { | 
| 471 |  | float   val; | 
| 472 |  |  | 
| 479 |  | } | 
| 480 |  |  | 
| 481 |  | static int | 
| 482 | < | rmx_write_rgbe(const double *dp, int nc, int len, FILE *fp) | 
| 482 | > | rmx_write_rgbe(const rmx_dtype *dp, int nc, int len, FILE *fp) | 
| 483 |  | { | 
| 484 |  | COLR    *scan; | 
| 485 |  | int     j; | 
| 498 |  | } | 
| 499 |  |  | 
| 500 |  | static int | 
| 501 | < | rmx_write_spec(const double *dp, int nc, int len, FILE *fp) | 
| 501 | > | rmx_write_spec(const rmx_dtype *dp, int nc, int len, FILE *fp) | 
| 502 |  | { | 
| 503 |  | uby8    *scan; | 
| 504 |  | SCOLOR  scol; | 
| 586 |  |  | 
| 587 |  | /* Write out matrix data (usually by row) */ | 
| 588 |  | int | 
| 589 | < | rmx_write_data(const double *dp, int nc, int len, int dtype, FILE *fp) | 
| 589 | > | rmx_write_data(const rmx_dtype *dp, int nc, int len, int dtype, FILE *fp) | 
| 590 |  | { | 
| 591 |  | switch (dtype) { | 
| 592 |  | case DTascii: | 
| 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); | 
| 649 | > | rmx_dtype   *dp = rmx_lval(rid,i,i); | 
| 650 |  | for (k = n; k--; ) | 
| 651 |  | dp[k] = 1.; | 
| 652 |  | } | 
| 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; | 
| 695 |  | } | 
| 696 |  | #ifdef MAP_FILE                 /* just matrix data -- leave metadata */ | 
| 697 |  | if (rdst->mapped) | 
| 698 | < | munmap(rdst->mapped, mapped_size(rdst)); | 
| 698 | > | munmap(rdst->mapped, rmx_mapped_size(rdst)); | 
| 699 |  | else | 
| 700 |  | #endif | 
| 701 | < | if (rdst->mtx) | 
| 701 | > | if (rdst->pflags & RMF_FREEMEM) | 
| 702 |  | free(rdst->mtx); | 
| 703 |  | rdst->mapped = rsrc->mapped; | 
| 704 |  | rdst->mtx = rsrc->mtx; | 
| 705 | + | if (rsrc->pflags & RMF_FREEMEM) | 
| 706 | + | rdst->pflags |= RMF_FREEMEM; | 
| 707 | + | else | 
| 708 | + | rdst->pflags &= ~RMF_FREEMEM; | 
| 709 |  | rsrc->mapped = NULL; rsrc->mtx = NULL; | 
| 710 |  | return(1); | 
| 711 |  | } | 
| 740 |  | for (j = dnew->ncols; j--; ) | 
| 741 |  | for (i = dnew->nrows; i--; ) | 
| 742 |  | memcpy(rmx_lval(dnew,i,j), rmx_val(rm,j,i), | 
| 743 | < | sizeof(double)*dnew->ncomp); | 
| 743 | > | sizeof(rmx_dtype)*dnew->ncomp); | 
| 744 |  | return(dnew); | 
| 745 |  | } | 
| 746 |  |  | 
| 765 |  | for (i = mres->nrows; i--; ) | 
| 766 |  | for (j = mres->ncols; j--; ) | 
| 767 |  | for (k = mres->ncomp; k--; ) { | 
| 768 | < | double      d = 0; | 
| 768 | > | rmx_dtype   d = 0; | 
| 769 |  | for (h = m1->ncols; h--; ) | 
| 770 |  | d += rmx_val(m1,i,h)[k] * rmx_val(m2,h,j)[k]; | 
| 771 |  | rmx_lval(mres,i,j)[k] = d; | 
| 793 |  | for (i = m1->nrows; i--; ) | 
| 794 |  | for (j = m1->ncols; j--; ) | 
| 795 |  | if (divide) { | 
| 796 | < | double      d; | 
| 796 | > | rmx_dtype   d; | 
| 797 |  | if (m2->ncomp == 1) { | 
| 798 |  | d = rmx_val(m2,i,j)[0]; | 
| 799 |  | if (d == 0) { | 
| 816 |  | } | 
| 817 |  | } else { | 
| 818 |  | if (m2->ncomp == 1) { | 
| 819 | < | const double    d = rmx_val(m2,i,j)[0]; | 
| 819 | > | const rmx_dtype d = rmx_val(m2,i,j)[0]; | 
| 820 |  | for (k = m1->ncomp; k--; ) | 
| 821 |  | rmx_lval(m1,i,j)[k] *= d; | 
| 822 |  | } else | 
| 857 |  | rmx_addinfo(msum, rmx_mismatch_warn); | 
| 858 |  | for (i = msum->nrows; i--; ) | 
| 859 |  | for (j = msum->ncols; j--; ) { | 
| 860 | < | const double    *da = rmx_val(madd,i,j); | 
| 861 | < | double          *ds = rmx_lval(msum,i,j); | 
| 860 | > | const rmx_dtype *da = rmx_val(madd,i,j); | 
| 861 | > | rmx_dtype       *ds = rmx_lval(msum,i,j); | 
| 862 |  | for (k = msum->ncomp; k--; ) | 
| 863 |  | ds[k] += sf[k] * da[k]; | 
| 864 |  | } | 
| 877 |  | return(0); | 
| 878 |  | for (i = rm->nrows; i--; ) | 
| 879 |  | for (j = rm->ncols; j--; ) { | 
| 880 | < | double  *dp = rmx_lval(rm,i,j); | 
| 880 | > | rmx_dtype       *dp = rmx_lval(rm,i,j); | 
| 881 |  | for (k = rm->ncomp; k--; ) | 
| 882 |  | dp[k] *= sf[k]; | 
| 883 |  | } | 
| 909 |  | dnew->dtype = msrc->dtype; | 
| 910 |  | for (i = dnew->nrows; i--; ) | 
| 911 |  | for (j = dnew->ncols; j--; ) { | 
| 912 | < | const double    *ds = rmx_val(msrc,i,j); | 
| 912 | > | const rmx_dtype *ds = rmx_val(msrc,i,j); | 
| 913 |  | for (kd = dnew->ncomp; kd--; ) { | 
| 914 | < | double      d = 0; | 
| 914 | > | rmx_dtype   d = 0; | 
| 915 |  | for (ks = msrc->ncomp; ks--; ) | 
| 916 |  | d += cmat[kd*msrc->ncomp + ks] * ds[ks]; | 
| 917 |  | rmx_lval(dnew,i,j)[kd] = d; | 
| 936 |  | for (i = dnew->nrows; i--; ) | 
| 937 |  | for (j = dnew->ncols; j--; ) { | 
| 938 |  | const COLORV    *cv = cm_lval(cm,i,j); | 
| 939 | < | double          *dp = rmx_lval(dnew,i,j); | 
| 939 | > | rmx_dtype       *dp = rmx_lval(dnew,i,j); | 
| 940 |  | dp[0] = cv[0]; | 
| 941 |  | dp[1] = cv[1]; | 
| 942 |  | dp[2] = cv[2]; | 
| 958 |  | return(NULL); | 
| 959 |  | for (i = cnew->nrows; i--; ) | 
| 960 |  | for (j = cnew->ncols; j--; ) { | 
| 961 | < | const double    *dp = rmx_val(rm,i,j); | 
| 961 | > | const rmx_dtype *dp = rmx_val(rm,i,j); | 
| 962 |  | COLORV          *cv = cm_lval(cnew,i,j); | 
| 963 |  | switch (rm->ncomp) { | 
| 964 |  | case 3: |