GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/moss/xform.c Lines: 0 96 0.0 %
Date: 2017-05-26 Branches: 0 44 0.0 %

Line Branch Exec Source
1
/*
2
  Teem: Tools to process and visualize scientific data and images             .
3
  Copyright (C) 2013, 2012, 2011, 2010, 2009  University of Chicago
4
  Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5
  Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6
7
  This library is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public License
9
  (LGPL) as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
  The terms of redistributing and/or modifying this software also
12
  include exceptions to the LGPL that facilitate static linking.
13
14
  This library is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
  Lesser General Public License for more details.
18
19
  You should have received a copy of the GNU Lesser General Public License
20
  along with this library; if not, write to Free Software Foundation, Inc.,
21
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
*/
23
24
#include "moss.h"
25
#include "privateMoss.h"
26
27
/*
28
29
 0  1  2
30
 3  4  5
31
 6  7  8
32
33
 a  c  tx
34
 b  d  ty
35
 0  0  1
36
37
 0  1  2
38
 3  4  5
39
40
*/
41
42
void
43
mossMatPrint (FILE *f, double *mat) {
44
45
  fprintf(f, "% 15.7f % 15.7f % 15.7f\n",
46
          (float)mat[0], (float)mat[1], (float)mat[2]);
47
  fprintf(f, "% 15.7f % 15.7f % 15.7f\n",
48
          (float)mat[3], (float)mat[4], (float)mat[5]);
49
}
50
51
double *
52
mossMatRightMultiply (double *_mat, double *_x) {
53
  double mat[9], x[9];
54
55
  MOSS_MAT_6TO9(x, _x);
56
  MOSS_MAT_6TO9(mat, _mat);
57
  ell_3m_pre_mul_d(mat, x);
58
  MOSS_MAT_9TO6(_mat, mat);
59
  return _mat;
60
}
61
62
double *
63
mossMatLeftMultiply (double *_mat, double *_x) {
64
  double mat[9], x[9];
65
66
  MOSS_MAT_6TO9(x, _x);
67
  MOSS_MAT_6TO9(mat, _mat);
68
  ell_3m_post_mul_d(mat, x);
69
  MOSS_MAT_9TO6(_mat, mat);
70
  return _mat;
71
}
72
73
double *
74
mossMatInvert (double *inv, double *mat) {
75
  double inv9[9], mat9[9];
76
77
  MOSS_MAT_6TO9(mat9, mat);
78
  ell_3m_inv_d(inv9, mat9);
79
  MOSS_MAT_9TO6(inv, inv9);
80
  return inv;
81
}
82
83
double *
84
mossMatIdentitySet (double *mat) {
85
86
  MOSS_MAT_SET(mat, 1, 0, 0, 0, 1, 0);
87
  return mat;
88
}
89
90
double *
91
mossMatTranslateSet (double *mat, double tx, double ty) {
92
93
  MOSS_MAT_SET(mat, 1, 0, tx, 0, 1, ty);
94
  return mat;
95
}
96
97
double *
98
mossMatRotateSet (double *mat, double angle) {
99
100
  angle *= AIR_PI/180.0;
101
  MOSS_MAT_SET(mat, cos(angle), -sin(angle), 0, sin(angle), cos(angle), 0);
102
  return mat;
103
}
104
105
double *
106
mossMatFlipSet (double *mat, double angle) {
107
  double rot[6], flip[6];
108
109
  MOSS_MAT_SET(flip, -1, 0, 0, 0, 1, 0);
110
  mossMatIdentitySet(mat);
111
  mossMatLeftMultiply(mat, mossMatRotateSet(rot, -angle));
112
  mossMatLeftMultiply(mat, flip);
113
  mossMatLeftMultiply(mat, mossMatRotateSet(rot, angle));
114
  return mat;
115
}
116
117
double *
118
mossMatShearSet (double *mat, double angleFixed, double amount) {
119
  double rot[6], shear[6];
120
121
  MOSS_MAT_SET(shear, 1, amount, 0, 0, 1, 0);
122
  mossMatIdentitySet(mat);
123
  mossMatLeftMultiply(mat, mossMatRotateSet(rot, -angleFixed));
124
  mossMatLeftMultiply(mat, shear);
125
  mossMatLeftMultiply(mat, mossMatRotateSet(rot, angleFixed));
126
  return mat;
127
}
128
129
double *
130
mossMatScaleSet (double *mat, double sx, double sy) {
131
132
  MOSS_MAT_SET(mat, sx, 0, 0, 0, sy, 0);
133
  return mat;
134
}
135
136
void
137
mossMatApply (double *ox, double *oy, double *mat, double ix, double iy) {
138
139
  *ox = mat[0]*ix + mat[1]*iy + mat[2];
140
  *oy = mat[3]*ix + mat[4]*iy + mat[5];
141
}
142
143
int
144
mossLinearTransform (Nrrd *nout, Nrrd *nin, float *bg,
145
                     double *mat, mossSampler *msp,
146
                     double xMin, double xMax,
147
                     double yMin, double yMax,
148
                     int xSize, int ySize) {
149
  static const char me[]="mossLinearTransform";
150
  int ncol, xi, yi, ci, ax0, xCent, yCent;
151
  float *val, (*ins)(void *v, size_t I, float f), (*clamp)(float val);
152
  double inv[6], xInPos, xOutPos, yInPos, yOutPos;
153
154
  if (!(nout && nin && mat && msp && !mossImageCheck(nin))) {
155
    biffAddf(MOSS, "%s: got NULL pointer or bad image", me);
156
    return 1;
157
  }
158
  if (mossSamplerImageSet(msp, nin, bg) || mossSamplerUpdate(msp)) {
159
    biffAddf(MOSS, "%s: trouble with sampler", me);
160
    return 1;
161
  }
162
  if (!( xMin != xMax && yMin != yMax && xSize > 1 && ySize > 1 )) {
163
    biffAddf(MOSS, "%s: bad args: {x,y}Min == {x,y}Max or {x,y}Size <= 1", me);
164
    return 1;
165
  }
166
  ax0 = MOSS_AXIS0(nin);
167
  if (!( AIR_EXISTS(nin->axis[ax0+0].min)
168
         && AIR_EXISTS(nin->axis[ax0+0].max)
169
         && AIR_EXISTS(nin->axis[ax0+1].min)
170
         && AIR_EXISTS(nin->axis[ax0+1].max) )) {
171
    biffAddf(MOSS, "%s: input axis min,max not set on axes %d and %d", me,
172
             ax0+0, ax0+1);
173
    return 1;
174
  }
175
176
  ncol = MOSS_NCOL(nin);
177
  if (mossImageAlloc(nout, nin->type, xSize, ySize, ncol)) {
178
    biffAddf(MOSS, "%s: ", me); return 1;
179
  }
180
  val = (float*)calloc(ncol, sizeof(float));
181
  if (nrrdCenterUnknown == nout->axis[ax0+0].center)
182
    nout->axis[ax0+0].center = _mossCenter(nin->axis[ax0+0].center);
183
  xCent = nout->axis[ax0+0].center;
184
  if (nrrdCenterUnknown == nout->axis[ax0+1].center)
185
    nout->axis[ax0+1].center = _mossCenter(nin->axis[ax0+1].center);
186
  yCent = nout->axis[ax0+1].center;
187
  nout->axis[ax0+0].min = xMin;
188
  nout->axis[ax0+0].max = xMax;
189
  nout->axis[ax0+1].min = yMin;
190
  nout->axis[ax0+1].max = yMax;
191
  ins = nrrdFInsert[nin->type];
192
  clamp = nrrdFClamp[nin->type];
193
194
  if (mossSamplerSample(val, msp, 0, 0)) {
195
    biffAddf(MOSS, "%s: trouble in sampler", me);
196
    free(val); return 1;
197
  }
198
199
  mossMatInvert(inv, mat);
200
  for (yi=0; yi<ySize; yi++) {
201
    yOutPos = NRRD_POS(yCent, yMin, yMax, ySize, yi);
202
    for (xi=0; xi<xSize; xi++) {
203
      /*
204
      mossVerbose = ( (36 == xi && 72 == yi) ||
205
                      (37 == xi && 73 == yi) ||
206
                      (105 == xi && 175 == yi) );
207
      */
208
      xOutPos = NRRD_POS(xCent, xMin, xMax, xSize, xi);
209
      mossMatApply(&xInPos, &yInPos, inv, xOutPos, yOutPos);
210
      xInPos = NRRD_IDX(xCent, nin->axis[ax0+0].min, nin->axis[ax0+0].max,
211
                        nin->axis[ax0+0].size, xInPos);
212
      yInPos = NRRD_IDX(yCent, nin->axis[ax0+1].min, nin->axis[ax0+1].max,
213
                        nin->axis[ax0+1].size, yInPos);
214
      mossSamplerSample(val, msp, xInPos, yInPos);
215
      for (ci=0; ci<ncol; ci++) {
216
        ins(nout->data, ci + ncol*(xi + xSize*yi), clamp(val[ci]));
217
      }
218
    }
219
  }
220
221
  free(val);
222
  return 0;
223
}