| 137 |  | return(0); | 
| 138 |  | } | 
| 139 |  | if (isexpos(s)) { | 
| 140 | < | double  d = exposval(s); | 
| 141 | < | scalecolor(ip->cexp, d); | 
| 140 | > | float   f = exposval(s); | 
| 141 | > | scalecolor(ip->cexp, f); | 
| 142 |  | return(0); | 
| 143 |  | } | 
| 144 |  | if (iscolcor(s)) { | 
| 167 |  | if (!rmx_prepare(rm)) | 
| 168 |  | return(0); | 
| 169 |  | for (i = 0; i < rm->nrows; i++) | 
| 170 | < | for (j = 0; j < rm->ncols; j++) | 
| 170 | > | for (j = 0; j < rm->ncols; j++) { | 
| 171 | > | double  *dp = rmx_lval(rm,i,j); | 
| 172 |  | for (k = 0; k < rm->ncomp; k++) | 
| 173 | < | if (fscanf(fp, "%lf", &rmx_lval(rm,i,j,k)) != 1) | 
| 173 | > | if (fscanf(fp, "%lf", &dp[k]) != 1) | 
| 174 |  | return(0); | 
| 175 | + | } | 
| 176 |  | return(1); | 
| 177 |  | } | 
| 178 |  |  | 
| 190 |  | return(0); | 
| 191 |  | for (i = 0; i < rm->nrows; i++) | 
| 192 |  | for (j = 0; j < rm->ncols; j++) { | 
| 193 | + | double  *dp = rmx_lval(rm,i,j); | 
| 194 |  | if (getbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp) | 
| 195 |  | return(0); | 
| 196 |  | if (rm->swapin) | 
| 197 |  | swap32((char *)val, rm->ncomp); | 
| 198 |  | for (k = rm->ncomp; k--; ) | 
| 199 | < | rmx_lval(rm,i,j,k) = val[k]; | 
| 199 | > | dp[k] = val[k]; | 
| 200 |  | } | 
| 201 |  | return(1); | 
| 202 |  | } | 
| 221 |  | if (!rmx_prepare(rm)) | 
| 222 |  | return(0); | 
| 223 |  | for (i = 0; i < rm->nrows; i++) { | 
| 224 | < | if (getbinary(&rmx_lval(rm,i,0,0), sizeof(double)*rm->ncomp, | 
| 224 | > | if (getbinary(rmx_lval(rm,i,0), sizeof(double)*rm->ncomp, | 
| 225 |  | rm->ncols, fp) != rm->ncols) | 
| 226 |  | return(0); | 
| 227 |  | if (rm->swapin) | 
| 228 | < | swap64((char *)&rmx_lval(rm,i,0,0), rm->ncols*rm->ncomp); | 
| 228 | > | swap64((char *)rmx_lval(rm,i,0), rm->ncols*rm->ncomp); | 
| 229 |  | } | 
| 230 |  | return(1); | 
| 231 |  | } | 
| 241 |  | if (!rmx_prepare(rm)) | 
| 242 |  | return(0); | 
| 243 |  | for (i = 0; i < rm->nrows; i++) { | 
| 244 | + | double      *dp = rmx_lval(rm,i,j); | 
| 245 |  | if (freadscan(scan, rm->ncols, fp) < 0) { | 
| 246 |  | free(scan); | 
| 247 |  | return(0); | 
| 248 |  | } | 
| 249 | < | for (j = rm->ncols; j--; ) { | 
| 250 | < | rmx_lval(rm,i,j,0) = colval(scan[j],RED); | 
| 251 | < | rmx_lval(rm,i,j,1) = colval(scan[j],GRN); | 
| 252 | < | rmx_lval(rm,i,j,2) = colval(scan[j],BLU); | 
| 249 | > | for (j = 0; j < rm->ncols; j++, dp += 3) { | 
| 250 | > | dp[0] = colval(scan[j],RED); | 
| 251 | > | dp[1] = colval(scan[j],GRN); | 
| 252 | > | dp[2] = colval(scan[j],BLU); | 
| 253 |  | } | 
| 254 |  | } | 
| 255 |  | free(scan); | 
| 382 |  |  | 
| 383 |  | for (i = 0; i < rm->nrows; i++) { | 
| 384 |  | for (j = 0; j < rm->ncols; j++) { | 
| 385 | + | const double    *dp = rmx_lval(rm,i,j); | 
| 386 |  | for (k = 0; k < rm->ncomp; k++) | 
| 387 | < | fprintf(fp, fmt, rmx_lval(rm,i,j,k)); | 
| 387 | > | fprintf(fp, fmt, dp[k]); | 
| 388 |  | fputc('\t', fp); | 
| 389 |  | } | 
| 390 |  | fputc('\n', fp); | 
| 404 |  | } | 
| 405 |  | for (i = 0; i < rm->nrows; i++) | 
| 406 |  | for (j = 0; j < rm->ncols; j++) { | 
| 407 | + | const double    *dp = rmx_lval(rm,i,j); | 
| 408 |  | for (k = rm->ncomp; k--; ) | 
| 409 | < | val[k] = (float)rmx_lval(rm,i,j,k); | 
| 410 | < | if (putbinary(val, sizeof(val[0]), rm->ncomp, fp) != rm->ncomp) | 
| 409 | > | val[k] = (float)dp[k]; | 
| 410 | > | if (putbinary(val, sizeof(float), rm->ncomp, fp) != rm->ncomp) | 
| 411 |  | return(0); | 
| 412 |  | } | 
| 413 |  | return(1); | 
| 416 |  | static int | 
| 417 |  | rmx_write_double(const RMATRIX *rm, FILE *fp) | 
| 418 |  | { | 
| 419 | < | int     i, j; | 
| 419 | > | int     i; | 
| 420 |  |  | 
| 421 |  | for (i = 0; i < rm->nrows; i++) | 
| 422 | < | for (j = 0; j < rm->ncols; j++) | 
| 423 | < | if (putbinary(&rmx_lval(rm,i,j,0), sizeof(double), rm->ncomp, fp) != rm->ncomp) | 
| 422 | > | if (putbinary(rmx_lval(rm,i,0), sizeof(double)*rm->ncomp, | 
| 423 | > | rm->ncols, fp) != rm->ncols) | 
| 424 |  | return(0); | 
| 425 |  | return(1); | 
| 426 |  | } | 
| 434 |  | if (!scan) | 
| 435 |  | return(0); | 
| 436 |  | for (i = 0; i < rm->nrows; i++) { | 
| 437 | < | for (j = rm->ncols; j--; ) | 
| 438 | < | setcolr(scan[j],        rmx_lval(rm,i,j,0), | 
| 439 | < | rmx_lval(rm,i,j,1), | 
| 440 | < | rmx_lval(rm,i,j,2)      ); | 
| 437 | > | for (j = rm->ncols; j--; ) { | 
| 438 | > | const double    *dp = rmx_lval(rm,i,j); | 
| 439 | > | if (rm->ncomp == 1) | 
| 440 | > | setcolr(scan[j], dp[0], dp[0], dp[0]); | 
| 441 | > | else | 
| 442 | > | setcolr(scan[j], dp[0], dp[1], dp[2]); | 
| 443 | > | } | 
| 444 |  | if (fwritecolrs(scan, rm->ncols, fp) < 0) { | 
| 445 |  | free(scan); | 
| 446 |  | return(0); | 
| 471 |  | int | 
| 472 |  | rmx_write(const RMATRIX *rm, int dtype, FILE *fp) | 
| 473 |  | { | 
| 465 | – | RMATRIX *mydm = NULL; | 
| 474 |  | int     ok = 1; | 
| 475 |  |  | 
| 476 | < | if (!rm | !fp) | 
| 476 | > | if (!rm | !fp || !rm->mtx) | 
| 477 |  | return(0); | 
| 478 |  | #ifdef getc_unlocked | 
| 479 |  | flockfile(fp); | 
| 492 |  | fprintf(fp, "NROWS=%d\n", rm->nrows); | 
| 493 |  | fprintf(fp, "NCOLS=%d\n", rm->ncols); | 
| 494 |  | fprintf(fp, "NCOMP=%d\n", rm->ncomp); | 
| 495 | < | } else if (rm->ncomp != 3) {            /* wrong # components? */ | 
| 496 | < | double  cmtx[3]; | 
| 489 | < | if (rm->ncomp != 1)             /* only convert grayscale */ | 
| 490 | < | return(0); | 
| 491 | < | cmtx[0] = cmtx[1] = cmtx[2] = 1; | 
| 492 | < | mydm = rmx_transform(rm, 3, cmtx); | 
| 493 | < | if (!mydm) | 
| 494 | < | return(0); | 
| 495 | < | rm = mydm; | 
| 496 | < | } | 
| 495 | > | } else if ((rm->ncomp != 3) & (rm->ncomp != 1)) | 
| 496 | > | return(0);                      /* wrong # components */ | 
| 497 |  | if ((dtype == DTfloat) | (dtype == DTdouble)) | 
| 498 |  | fputendian(fp);                 /* important to record */ | 
| 499 |  | fputformat(cm_fmt_id[dtype], fp); | 
| 520 |  | #ifdef getc_unlocked | 
| 521 |  | funlockfile(fp); | 
| 522 |  | #endif | 
| 523 | – | if (mydm) | 
| 524 | – | rmx_free(mydm); | 
| 523 |  | return(ok); | 
| 524 |  | } | 
| 525 |  |  | 
| 532 |  |  | 
| 533 |  | if (!rid) | 
| 534 |  | return(NULL); | 
| 535 | < | memset(rid->mtx, 0, sizeof(rid->mtx[0])*n*dim*dim); | 
| 536 | < | for (i = dim; i--; ) | 
| 535 | > | memset(rid->mtx, 0, array_size(rid)); | 
| 536 | > | for (i = dim; i--; ) { | 
| 537 | > | double      *dp = rmx_lval(rid,i,i); | 
| 538 |  | for (k = n; k--; ) | 
| 539 | < | rmx_lval(rid,i,i,k) = 1; | 
| 539 | > | dp[k] = 1.; | 
| 540 | > | } | 
| 541 |  | return(rid); | 
| 542 |  | } | 
| 543 |  |  | 
| 554 |  | return(NULL); | 
| 555 |  | rmx_addinfo(dnew, rm->info); | 
| 556 |  | dnew->dtype = rm->dtype; | 
| 557 | < | memcpy(dnew->mtx, rm->mtx, | 
| 558 | < | sizeof(rm->mtx[0])*rm->ncomp*rm->nrows*rm->ncols); | 
| 557 | > | memcpy(dnew->mtx, rm->mtx, array_size(dnew)); | 
| 558 |  | return(dnew); | 
| 559 |  | } | 
| 560 |  |  | 
| 563 |  | rmx_transpose(const RMATRIX *rm) | 
| 564 |  | { | 
| 565 |  | RMATRIX *dnew; | 
| 566 | < | int     i, j, k; | 
| 566 | > | int     i, j; | 
| 567 |  |  | 
| 568 |  | if (!rm) | 
| 569 |  | return(0); | 
| 585 |  | dnew->dtype = rm->dtype; | 
| 586 |  | for (i = dnew->nrows; i--; ) | 
| 587 |  | for (j = dnew->ncols; j--; ) | 
| 588 | < | for (k = dnew->ncomp; k--; ) | 
| 589 | < | rmx_lval(dnew,i,j,k) = rmx_lval(rm,j,i,k); | 
| 588 | > | memcpy(rmx_lval(dnew,i,j), rmx_lval(rm,j,i), | 
| 589 | > | sizeof(double)*dnew->ncomp); | 
| 590 |  | return(dnew); | 
| 591 |  | } | 
| 592 |  |  | 
| 610 |  | for (i = mres->nrows; i--; ) | 
| 611 |  | for (j = mres->ncols; j--; ) | 
| 612 |  | for (k = mres->ncomp; k--; ) { | 
| 613 | < | long double d = 0; | 
| 613 | > | double      d = 0; | 
| 614 |  | for (h = m1->ncols; h--; ) | 
| 615 | < | d += rmx_lval(m1,i,h,k) * rmx_lval(m2,h,j,k); | 
| 616 | < | rmx_lval(mres,i,j,k) = (double)d; | 
| 615 | > | d += rmx_lval(m1,i,h)[k] * rmx_lval(m2,h,j)[k]; | 
| 616 | > | rmx_lval(mres,i,j)[k] = d; | 
| 617 |  | } | 
| 618 |  | return(mres); | 
| 619 |  | } | 
| 639 |  | if (divide) { | 
| 640 |  | double      d; | 
| 641 |  | if (m2->ncomp == 1) { | 
| 642 | < | d = rmx_lval(m2,i,j,0); | 
| 642 | > | d = rmx_lval(m2,i,j)[0]; | 
| 643 |  | if (d == 0) { | 
| 644 |  | ++zeroDivides; | 
| 645 |  | for (k = m1->ncomp; k--; ) | 
| 646 | < | rmx_lval(m1,i,j,k) = 0; | 
| 646 | > | rmx_lval(m1,i,j)[k] = 0; | 
| 647 |  | } else { | 
| 648 |  | d = 1./d; | 
| 649 |  | for (k = m1->ncomp; k--; ) | 
| 650 | < | rmx_lval(m1,i,j,k) *= d; | 
| 650 | > | rmx_lval(m1,i,j)[k] *= d; | 
| 651 |  | } | 
| 652 |  | } else | 
| 653 |  | for (k = m1->ncomp; k--; ) { | 
| 654 | < | d = rmx_lval(m2,i,j,k); | 
| 654 | > | d = rmx_lval(m2,i,j)[k]; | 
| 655 |  | if (d == 0) { | 
| 656 |  | ++zeroDivides; | 
| 657 | < | rmx_lval(m1,i,j,k) = 0; | 
| 657 | > | rmx_lval(m1,i,j)[k] = 0; | 
| 658 |  | } else | 
| 659 | < | rmx_lval(m1,i,j,k) /= d; | 
| 659 | > | rmx_lval(m1,i,j)[k] /= d; | 
| 660 |  | } | 
| 661 |  | } else { | 
| 662 |  | if (m2->ncomp == 1) { | 
| 663 | < | const double    d = rmx_lval(m2,i,j,0); | 
| 663 | > | const double    d = rmx_lval(m2,i,j)[0]; | 
| 664 |  | for (k = m1->ncomp; k--; ) | 
| 665 | < | rmx_lval(m1,i,j,k) *= d; | 
| 665 | > | rmx_lval(m1,i,j)[k] *= d; | 
| 666 |  | } else | 
| 667 |  | for (k = m1->ncomp; k--; ) | 
| 668 | < | rmx_lval(m1,i,j,k) *= rmx_lval(m2,i,j,k); | 
| 668 | > | rmx_lval(m1,i,j)[k] *= rmx_lval(m2,i,j)[k]; | 
| 669 |  | } | 
| 670 |  | if (zeroDivides) { | 
| 671 |  | rmx_addinfo(m1, "WARNING: zero divide(s) corrupted results\n"); | 
| 700 |  | else | 
| 701 |  | rmx_addinfo(msum, rmx_mismatch_warn); | 
| 702 |  | for (i = msum->nrows; i--; ) | 
| 703 | < | for (j = msum->ncols; j--; ) | 
| 703 | > | for (j = msum->ncols; j--; ) { | 
| 704 | > | const double    *da = rmx_lval(madd,i,j); | 
| 705 | > | double          *ds = rmx_lval(msum,i,j); | 
| 706 |  | for (k = msum->ncomp; k--; ) | 
| 707 | < | rmx_lval(msum,i,j,k) += sf[k] * rmx_lval(madd,i,j,k); | 
| 707 | > | ds[k] += sf[k] * da[k]; | 
| 708 | > | } | 
| 709 |  | if (mysf) | 
| 710 |  | free(mysf); | 
| 711 |  | return(1); | 
| 720 |  | if (!rm | !sf) | 
| 721 |  | return(0); | 
| 722 |  | for (i = rm->nrows; i--; ) | 
| 723 | < | for (j = rm->ncols; j--; ) | 
| 723 | > | for (j = rm->ncols; j--; ) { | 
| 724 | > | double  *dp = rmx_lval(rm,i,j); | 
| 725 |  | for (k = rm->ncomp; k--; ) | 
| 726 | < | rmx_lval(rm,i,j,k) *= sf[k]; | 
| 727 | < |  | 
| 726 | > | dp[k] *= sf[k]; | 
| 727 | > | } | 
| 728 |  | if (rm->info) | 
| 729 |  | rmx_addinfo(rm, "Applied scalar\n"); | 
| 730 |  | return(1); | 
| 751 |  | } | 
| 752 |  | dnew->dtype = msrc->dtype; | 
| 753 |  | for (i = dnew->nrows; i--; ) | 
| 754 | < | for (j = dnew->ncols; j--; ) | 
| 754 | > | for (j = dnew->ncols; j--; ) { | 
| 755 | > | const double    *ds = rmx_lval(msrc,i,j); | 
| 756 |  | for (kd = dnew->ncomp; kd--; ) { | 
| 757 |  | double      d = 0; | 
| 758 |  | for (ks = msrc->ncomp; ks--; ) | 
| 759 | < | d += cmat[kd*msrc->ncomp + ks] * rmx_lval(msrc,i,j,ks); | 
| 760 | < | rmx_lval(dnew,i,j,kd) = d; | 
| 759 | > | d += cmat[kd*msrc->ncomp + ks] * ds[ks]; | 
| 760 | > | rmx_lval(dnew,i,j)[kd] = d; | 
| 761 |  | } | 
| 762 | + | } | 
| 763 |  | return(dnew); | 
| 764 |  | } | 
| 765 |  |  | 
| 779 |  | for (i = dnew->nrows; i--; ) | 
| 780 |  | for (j = dnew->ncols; j--; ) { | 
| 781 |  | const COLORV    *cv = cm_lval(cm,i,j); | 
| 782 | < | rmx_lval(dnew,i,j,0) = cv[0]; | 
| 783 | < | rmx_lval(dnew,i,j,1) = cv[1]; | 
| 784 | < | rmx_lval(dnew,i,j,2) = cv[2]; | 
| 782 | > | double          *dp = rmx_lval(dnew,i,j); | 
| 783 | > | dp[0] = cv[0]; | 
| 784 | > | dp[1] = cv[1]; | 
| 785 | > | dp[2] = cv[2]; | 
| 786 |  | } | 
| 787 |  | return(dnew); | 
| 788 |  | } | 
| 794 |  | int     i, j; | 
| 795 |  | CMATRIX *cnew; | 
| 796 |  |  | 
| 797 | < | if (!rm || rm->ncomp != 3) | 
| 797 | > | if (!rm || !rm->mtx | ((rm->ncomp != 3) & (rm->ncomp != 1))) | 
| 798 |  | return(NULL); | 
| 799 |  | cnew = cm_alloc(rm->nrows, rm->ncols); | 
| 800 |  | if (!cnew) | 
| 801 |  | return(NULL); | 
| 802 |  | for (i = cnew->nrows; i--; ) | 
| 803 |  | for (j = cnew->ncols; j--; ) { | 
| 804 | < | COLORV  *cv = cm_lval(cnew,i,j); | 
| 805 | < | cv[0] = (COLORV)rmx_lval(rm,i,j,0); | 
| 806 | < | cv[1] = (COLORV)rmx_lval(rm,i,j,1); | 
| 807 | < | cv[2] = (COLORV)rmx_lval(rm,i,j,2); | 
| 804 | > | const double    *dp = rmx_lval(rm,i,j); | 
| 805 | > | COLORV          *cv = cm_lval(cnew,i,j); | 
| 806 | > | if (rm->ncomp == 1) | 
| 807 | > | setcolor(cv, dp[0], dp[0], dp[0]); | 
| 808 | > | else | 
| 809 | > | setcolor(cv, dp[0], dp[1], dp[2]); | 
| 810 |  | } | 
| 811 |  | return(cnew); | 
| 812 |  | } |