| 389 |  |  | 
| 390 |  | /* Load matrix from supported file type */ | 
| 391 |  | RMATRIX * | 
| 392 | < | rmx_load(const char *inspec, RMPref rmp) | 
| 392 | > | rmx_load(const char *inspec) | 
| 393 |  | { | 
| 394 |  | FILE            *fp; | 
| 395 |  | RMATRIX         *dnew; | 
| 403 |  | fp = stdin; | 
| 404 |  | else if (inspec[0] == '!') | 
| 405 |  | fp = popen(inspec+1, "r"); | 
| 406 | < | else {                                  /* check suffix */ | 
| 407 | < | const char      *sp = strrchr(inspec, '.'); | 
| 408 | < | if (sp > inspec && !strcasecmp(sp+1, "XML")) {  /* BSDF? */ | 
| 409 | < | CMATRIX *cm = rmp==RMPnone ? (CMATRIX *)NULL : | 
| 410 | < | rmp==RMPtrans ? cm_loadBTDF(inspec) : | 
| 411 | < | cm_loadBRDF(inspec, rmp==RMPreflB) ; | 
| 412 | < | if (!cm) | 
| 413 | < | return(NULL); | 
| 414 | < | dnew = rmx_from_cmatrix(cm); | 
| 415 | < | cm_free(cm); | 
| 416 | < | dnew->dtype = DTascii; | 
| 417 | < | return(dnew);           /* return here */ | 
| 418 | < | }                               /* else open it ourselves */ | 
| 406 | > | else | 
| 407 |  | fp = fopen(inspec, "r"); | 
| 420 | – | } | 
| 408 |  | if (!fp) { | 
| 409 |  | fprintf(stderr, "Cannot open for reading: %s\n", inspec); | 
| 410 |  | return(NULL); | 
| 424 |  |  | 
| 425 |  | if (fp != stdin) {                      /* close input stream */ | 
| 426 |  | if (inspec[0] == '!') | 
| 427 | < | pclose(fp); | 
| 427 | > | ok &= pclose(fp)==0; | 
| 428 |  | else | 
| 429 |  | fclose(fp); | 
| 430 |  | } | 
| 778 |  | #define bmop(r,c, op)   (bmbyte(r,c) op bmbit(r,c)) | 
| 779 |  | #define bmtest(r,c)     bmop(r,c,&) | 
| 780 |  | #define bmset(r,c)      bmop(r,c,|=) | 
| 781 | < | /* create completion bitmap */ | 
| 781 | > | /* loop completion bitmap */ | 
| 782 |  | bmap = (uby8 *)calloc(((size_t)rm->nrows*rm->ncols+7)>>3, 1); | 
| 783 |  | if (!bmap) | 
| 784 |  | return(0); | 
| 785 |  | dold = *rm; | 
| 786 |  | rm->ncols = dold.nrows; rm->nrows = dold.ncols; | 
| 787 | < | for (i = rm->nrows; i--; ) | 
| 787 | > | for (i = rm->nrows; i--; )      /* try every starting point */ | 
| 788 |  | for (j = rm->ncols; j--; ) { | 
| 789 |  | int     i0, j0; | 
| 790 |  | int     i1 = i; | 
| 791 |  | size_t  j1 = j; | 
| 792 |  | if (bmtest(i, j)) | 
| 793 | < | continue; | 
| 793 | > | continue;       /* traversed loop earlier */ | 
| 794 |  | memcpy(val, rmx_val(rm,i,j), | 
| 795 |  | sizeof(rmx_dtype)*rm->ncomp); | 
| 796 | < | bmset(i, j); | 
| 810 | < | for ( ; ; ) {           /* value transpose loop */ | 
| 796 | > | for ( ; ; ) {           /* new transpose loop */ | 
| 797 |  | const rmx_dtype     *ds; | 
| 798 |  | i0 = i1; j0 = j1; | 
| 799 |  | ds = rmx_val(&dold, j0, i0); | 
| 800 |  | j1 = (ds - dold.mtx)/dold.ncomp; | 
| 801 |  | i1 = j1 / rm->ncols; | 
| 802 |  | j1 -= (size_t)i1*rm->ncols; | 
| 803 | + | bmset(i1, j1);      /* mark as done */ | 
| 804 |  | if ((i1 == i) & (j1 == j)) | 
| 805 | < | break;          /* back to start */ | 
| 805 | > | break;          /* back at start */ | 
| 806 |  | memcpy(rmx_lval(rm,i0,j0), ds, | 
| 807 |  | sizeof(rmx_dtype)*rm->ncomp); | 
| 821 | – | bmset(i1, j1); | 
| 808 |  | }                       /* complete the loop */ | 
| 809 |  | memcpy(rmx_lval(rm,i0,j0), val, | 
| 810 |  | sizeof(rmx_dtype)*rm->ncomp); | 
| 995 |  | return(dnew); | 
| 996 |  | } | 
| 997 |  |  | 
| 1012 | – | /* Convert a color matrix to newly allocated RMATRIX buffer */ | 
| 1013 | – | RMATRIX * | 
| 1014 | – | rmx_from_cmatrix(const CMATRIX *cm) | 
| 1015 | – | { | 
| 1016 | – | RMATRIX *dnew; | 
| 1017 | – |  | 
| 1018 | – | if (!cm) | 
| 1019 | – | return(NULL); | 
| 1020 | – | dnew = rmx_alloc(cm->nrows, cm->ncols, 3); | 
| 1021 | – | if (!dnew) | 
| 1022 | – | return(NULL); | 
| 1023 | – |  | 
| 1024 | – | dnew->dtype = sizeof(COLORV)==sizeof(float) ? | 
| 1025 | – | DTfloat : DTdouble; | 
| 1026 | – |  | 
| 1027 | – | if (sizeof(COLORV) == sizeof(rmx_dtype)) { | 
| 1028 | – | memcpy(dnew->mtx, cm->cmem, rmx_array_size(dnew)); | 
| 1029 | – | } else { | 
| 1030 | – | int     i, j; | 
| 1031 | – | for (i = dnew->nrows; i--; ) | 
| 1032 | – | for (j = dnew->ncols; j--; ) { | 
| 1033 | – | const COLORV    *cv = cm_lval(cm,i,j); | 
| 1034 | – | rmx_dtype       *dp = rmx_lval(dnew,i,j); | 
| 1035 | – | dp[0] = cv[0]; | 
| 1036 | – | dp[1] = cv[1]; | 
| 1037 | – | dp[2] = cv[2]; | 
| 1038 | – | } | 
| 1039 | – | } | 
| 1040 | – | return(dnew); | 
| 1041 | – | } | 
| 1042 | – |  | 
| 1043 | – | /* Convert general matrix to newly allocated CMATRIX buffer */ | 
| 1044 | – | CMATRIX * | 
| 1045 | – | cm_from_rmatrix(const RMATRIX *rm) | 
| 1046 | – | { | 
| 1047 | – | CMATRIX *cnew; | 
| 1048 | – |  | 
| 1049 | – | if (!rm || !rm->mtx | (rm->ncomp == 2) | (rm->ncomp > MAXCOMP)) | 
| 1050 | – | return(NULL); | 
| 1051 | – | cnew = cm_alloc(rm->nrows, rm->ncols); | 
| 1052 | – | if (!cnew) | 
| 1053 | – | return(NULL); | 
| 1054 | – | if ((sizeof(COLORV) == sizeof(rmx_dtype)) & (rm->ncomp == 3)) { | 
| 1055 | – | memcpy(cnew->cmem, rm->mtx, rmx_array_size(rm)); | 
| 1056 | – | } else { | 
| 1057 | – | int     i, j; | 
| 1058 | – | for (i = cnew->nrows; i--; ) | 
| 1059 | – | for (j = cnew->ncols; j--; ) { | 
| 1060 | – | const rmx_dtype *dp = rmx_val(rm,i,j); | 
| 1061 | – | COLORV          *cv = cm_lval(cnew,i,j); | 
| 1062 | – | switch (rm->ncomp) { | 
| 1063 | – | case 3: | 
| 1064 | – | setcolor(cv, dp[0], dp[1], dp[2]); | 
| 1065 | – | break; | 
| 1066 | – | case 1: | 
| 1067 | – | setcolor(cv, dp[0], dp[0], dp[0]); | 
| 1068 | – | break; | 
| 1069 | – | default: | 
| 1070 | – | if (sizeof(COLORV) == sizeof(rmx_dtype)) { | 
| 1071 | – | scolor2color(cv, (const COLORV *)dp, | 
| 1072 | – | rm->ncomp, rm->wlpart); | 
| 1073 | – | } else { | 
| 1074 | – | COLORV  scol[MAXCOMP]; | 
| 1075 | – | int     k = rm->ncomp; | 
| 1076 | – | while (k--) scol[k] = dp[k]; | 
| 1077 | – | scolor2color(cv, scol, rm->ncomp, rm->wlpart); | 
| 1078 | – | } | 
| 1079 | – | break; | 
| 1080 | – | } | 
| 1081 | – | } | 
| 1082 | – | } | 
| 1083 | – | return(cnew); | 
| 1084 | – | } |