| 13 |  | #endif | 
| 14 |  |  | 
| 15 |  | /* Preferred BSDF component: | 
| 16 | < | transmission, reflection front (normal side), reflection back */ | 
| 17 | < | typedef enum {RMPtrans=0, RMPreflF, RMPreflB} RMPref; | 
| 16 | > | none, transmission, reflection front (normal side), reflection back */ | 
| 17 | > | typedef enum {RMPnone=-1, RMPtrans=0, RMPreflF, RMPreflB} RMPref; | 
| 18 |  |  | 
| 19 | + | /* RMATRIX flags (usually private): | 
| 20 | + | need to swap input, we should free memory */ | 
| 21 | + | #define RMF_SWAPIN      1 | 
| 22 | + | #define RMF_FREEMEM     2 | 
| 23 | + |  | 
| 24 | + | #ifndef MAXCOMP | 
| 25 | + | #define MAXCOMP         MAXCSAMP        /* #components we support */ | 
| 26 | + | #endif | 
| 27 | + | /* Set in-core data type */ | 
| 28 | + | #if !defined(DTrmx_native) || DTrmx_native==DTfloat | 
| 29 | + | #define DTrmx_native    DTfloat | 
| 30 | + | #define rmx_dtype       float | 
| 31 | + | #define rmx_scanfmt     "%f" | 
| 32 | + | #elif DTrmx_native==DTdouble | 
| 33 | + | #define rmx_dtype       double | 
| 34 | + | #define rmx_scanfmt     "%lf" | 
| 35 | + | #endif | 
| 36 | + |  | 
| 37 |  | /* General [row][col][cmp] component matrix */ | 
| 38 |  | typedef struct { | 
| 39 | < | char    *info; | 
| 40 | < | void    *mapped; | 
| 41 | < | double  *mtx; | 
| 42 | < | COLOR   cexp; | 
| 43 | < | float   wlpart[4]; | 
| 44 | < | int     nrows, ncols; | 
| 45 | < | short   ncomp; | 
| 46 | < | uby8    dtype; | 
| 47 | < | uby8    swapin; | 
| 39 | > | char            *info; | 
| 40 | > | void            *mapped; | 
| 41 | > | rmx_dtype       *mtx; | 
| 42 | > | COLOR           cexp; | 
| 43 | > | float           wlpart[4]; | 
| 44 | > | int             nrows, ncols; | 
| 45 | > | short           ncomp; | 
| 46 | > | uby8            dtype; | 
| 47 | > | uby8            pflags; | 
| 48 |  | } RMATRIX; | 
| 49 |  |  | 
| 50 |  | #define rmx_lval(rm,r,c)        ((rm)->mtx + (rm)->ncomp*((c)+(size_t)(rm)->ncols*(r))) | 
| 51 | + | #define rmx_val                 rmx_lval | 
| 52 |  |  | 
| 53 | + | #define rmx_array_size(rm)      (sizeof(rmx_dtype)*(rm)->nrows*(rm)->ncols*(rm)->ncomp) | 
| 54 | + | #define rmx_mapped_size(rm)     ((char *)(rm)->mtx + rmx_array_size(rm) - (char *)(rm)->mapped) | 
| 55 | + |  | 
| 56 |  | /* Initialize a RMATRIX struct but don't allocate array space */ | 
| 57 |  | extern RMATRIX  *rmx_new(int nr, int nc, int n); | 
| 58 |  |  | 
| 62 |  | /* Call rmx_new() and rmx_prepare() */ | 
| 63 |  | extern RMATRIX  *rmx_alloc(int nr, int nc, int n); | 
| 64 |  |  | 
| 65 | < | /* Free a RMATRIX array */ | 
| 65 | > | /* Clear state by freeing info and matrix data */ | 
| 66 | > | extern void     rmx_reset(RMATRIX *rm); | 
| 67 | > |  | 
| 68 | > | /* Free an RMATRIX struct and data */ | 
| 69 |  | extern void     rmx_free(RMATRIX *rm); | 
| 70 |  |  | 
| 71 |  | /* Resolve data type based on two input types (returns 0 for mismatch) */ | 
| 72 |  | extern int      rmx_newtype(int dtyp1, int dtyp2); | 
| 73 |  |  | 
| 74 | + | /* Read matrix header from input stream (cannot be XML) */ | 
| 75 | + | extern int      rmx_load_header(RMATRIX *rm, FILE *fp); | 
| 76 | + |  | 
| 77 | + | /* Load next row as rmx_dtype (cannot be XML) */ | 
| 78 | + | extern int      rmx_load_row(rmx_dtype *drp, const RMATRIX *rm, FILE *fp); | 
| 79 | + |  | 
| 80 | + | /* Allocate & load post-header data from stream given type set in rm->dtype */ | 
| 81 | + | extern int      rmx_load_data(RMATRIX *rm, FILE *fp); | 
| 82 | + |  | 
| 83 |  | /* Load matrix from supported file type (NULL for stdin, '!' with command) */ | 
| 84 |  | extern RMATRIX  *rmx_load(const char *inspec, RMPref rmp); | 
| 85 |  |  | 
| 86 |  | /* Append header information associated with matrix data */ | 
| 87 |  | extern int      rmx_addinfo(RMATRIX *rm, const char *info); | 
| 88 |  |  | 
| 89 | < | /* Write matrix to file type indicated by dtype */ | 
| 89 | > | /* Finish writing header data with resolution and format, returning type used */ | 
| 90 | > | extern int      rmx_write_header(const RMATRIX *rm, int dtype, FILE *fp); | 
| 91 | > |  | 
| 92 | > | /* Write out matrix data (usually by row) */ | 
| 93 | > | extern int      rmx_write_data(const rmx_dtype *dp, int nc, int len, | 
| 94 | > | int dtype, FILE *fp); | 
| 95 | > |  | 
| 96 | > | /* Write matrix using file format indicated by dtype */ | 
| 97 |  | extern int      rmx_write(const RMATRIX *rm, int dtype, FILE *fp); | 
| 98 |  |  | 
| 99 |  | /* Allocate and assign square identity matrix with n components */ | 
| 102 |  | /* Duplicate the given matrix */ | 
| 103 |  | extern RMATRIX  *rmx_copy(const RMATRIX *rm); | 
| 104 |  |  | 
| 105 | < | /* Allocate and assign transposed matrix */ | 
| 106 | < | extern RMATRIX  *rmx_transpose(const RMATRIX *rm); | 
| 105 | > | /* Replace data in first matrix with data from second */ | 
| 106 | > | extern int      rmx_transfer_data(RMATRIX *rdst, RMATRIX *rsrc, int dometa); | 
| 107 | > |  | 
| 108 | > | /* Transpose the given matrix */ | 
| 109 | > | extern int      rmx_transpose(RMATRIX *rm); | 
| 110 |  |  | 
| 111 |  | /* Multiply (concatenate) two matrices and allocate the result */ | 
| 112 |  | extern RMATRIX  *rmx_multiply(const RMATRIX *m1, const RMATRIX *m2); |