pointOp.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. RES = pointOp(IM, LUT, ORIGIN, INCREMENT, WARNINGS)
  3. >>> See pointOp.m for documentation <<<
  4. EPS, ported from OBVIUS, 7/96.
  5. */
  6. #define V4_COMPAT
  7. #include <matrix.h> /* Matlab matrices */
  8. #include <mex.h>
  9. #include <stddef.h> /* NULL */
  10. #define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
  11. void internal_pointop();
  12. void mexFunction(int nlhs, /* Num return vals on lhs */
  13. mxArray *plhs[], /* Matrices on lhs */
  14. int nrhs, /* Num args on rhs */
  15. const mxArray *prhs[] /* Matrices on rhs */
  16. )
  17. {
  18. double *image, *lut, *res;
  19. double origin, increment;
  20. int x_dim, y_dim, lx_dim, ly_dim;
  21. int warnings = 1;
  22. const mxArray *arg0,*arg1,*arg2,*arg3,*arg4;
  23. double *mxMat;
  24. if (nrhs < 4 ) mexErrMsgTxt("requres at least 4 args.");
  25. /* ARG 1: IMAGE */
  26. arg0 = prhs[0];
  27. if notDblMtx(arg0) mexErrMsgTxt("IMAGE arg must be a real non-sparse matrix.");
  28. image = mxGetPr(arg0);
  29. x_dim = (int) mxGetM(arg0); /* X is inner index! */
  30. y_dim = (int) mxGetN(arg0);
  31. /* ARG 2: Lookup table */
  32. arg1 = prhs[1];
  33. if notDblMtx(arg1) mexErrMsgTxt("LUT arg must be a real non-sparse matrix.");
  34. lut = mxGetPr(arg1);
  35. lx_dim = (int) mxGetM(arg1); /* X is inner index! */
  36. ly_dim = (int) mxGetN(arg1);
  37. if ( (lx_dim != 1) && (ly_dim != 1) )
  38. mexErrMsgTxt("Lookup table must be a row or column vector.");
  39. /* ARG 3: ORIGIN */
  40. arg2 = prhs[2];
  41. if notDblMtx(arg2) mexErrMsgTxt("ORIGIN arg must be a real scalar.");
  42. if (mxGetM(arg2) * mxGetN(arg2) != 1)
  43. mexErrMsgTxt("ORIGIN arg must be a real scalar.");
  44. mxMat = mxGetPr(arg2);
  45. origin = *mxMat;
  46. /* ARG 4: INCREMENT */
  47. arg3 = prhs[3];
  48. if notDblMtx(arg3) mexErrMsgTxt("INCREMENT arg must be a real scalar.");
  49. if (mxGetM(arg3) * mxGetN(arg3) != 1)
  50. mexErrMsgTxt("INCREMENT arg must be a real scalar.");
  51. mxMat = mxGetPr(arg3);
  52. increment = *mxMat;
  53. /* ARG 5: WARNINGS */
  54. if (nrhs>4)
  55. {
  56. arg4 = prhs[4];
  57. if notDblMtx(arg4) mexErrMsgTxt("WARINGS arg must be a real scalar.");
  58. if (mxGetM(arg4) * mxGetN(arg4) != 1)
  59. mexErrMsgTxt("WARNINGS arg must be a real scalar.");
  60. mxMat = mxGetPr(arg4);
  61. warnings = (int) *mxMat;
  62. }
  63. plhs[0] = (mxArray *) mxCreateDoubleMatrix(x_dim,y_dim,mxREAL);
  64. if (plhs[0] == NULL) mexErrMsgTxt("Cannot allocate result matrix");
  65. res = mxGetPr(plhs[0]);
  66. internal_pointop(image, res, x_dim*y_dim, lut, lx_dim*ly_dim,
  67. origin, increment, warnings);
  68. return;
  69. }
  70. /* Use linear interpolation on a lookup table.
  71. Taken from OBVIUS. EPS, Spring, 1987.
  72. */
  73. void internal_pointop (im, res, size, lut, lutsize, origin, increment, warnings)
  74. register double *im, *res, *lut;
  75. register double origin, increment;
  76. register int size, lutsize, warnings;
  77. {
  78. register int i, index;
  79. register double pos;
  80. register int l_unwarned = warnings;
  81. register int r_unwarned = warnings;
  82. lutsize = lutsize - 2; /* Maximum index value */
  83. if (increment > 0)
  84. for (i=0; i<size; i++)
  85. {
  86. pos = (im[i] - origin) / increment;
  87. index = (int) pos; /* Floor */
  88. if (index < 0)
  89. {
  90. index = 0;
  91. if (l_unwarned)
  92. {
  93. mexPrintf("Warning: Extrapolating to left of lookup table...\n");
  94. l_unwarned = 0;
  95. }
  96. }
  97. else if (index > lutsize)
  98. {
  99. index = lutsize;
  100. if (r_unwarned)
  101. {
  102. mexPrintf("Warning: Extrapolating to right of lookup table...\n");
  103. r_unwarned = 0;
  104. }
  105. }
  106. res[i] = lut[index] + (lut[index+1] - lut[index]) * (pos - index);
  107. }
  108. else
  109. for (i=0; i<size; i++) res[i] = *lut;
  110. }