|
94 | 94 | c0[2] * (c1[0] * c2[1] - c1[1] * c2[0])); |
95 | 95 | } |
96 | 96 |
|
| 97 | + |
97 | 98 | // Now that we have the transform, need to convert it to MINC-like |
98 | 99 | // steps and direction_cosines. |
99 | 100 |
|
|
141 | 142 |
|
142 | 143 | function parseNifti1Header(raw_data, callback) { |
143 | 144 | var header = { |
144 | | - order: ["zspace", "yspace", "xspace"], |
| 145 | + order: [], |
145 | 146 | xspace: {}, |
146 | 147 | yspace: {}, |
147 | 148 | zspace: {} |
|
175 | 176 | throw new Error(error_message); |
176 | 177 | } |
177 | 178 |
|
178 | | - header.xspace.space_length = dview.getUint16(42, littleEndian); |
179 | | - header.yspace.space_length = dview.getUint16(44, littleEndian); |
180 | | - header.zspace.space_length = dview.getUint16(46, littleEndian); |
181 | 179 | var tlength = dview.getUint16(48, littleEndian); |
182 | 180 |
|
183 | 181 | var datatype = dview.getUint16(70, littleEndian); |
|
199 | 197 | var qform_code = dview.getUint16(252, littleEndian); |
200 | 198 | var sform_code = dview.getUint16(254, littleEndian); |
201 | 199 |
|
202 | | - var transform = [ |
| 200 | + var nifti_xfm = [ |
203 | 201 | [1, 0, 0, 0], |
204 | 202 | [0, 1, 0, 0], |
205 | 203 | [0, 0, 1, 0], |
|
212 | 210 | header.time.step = tstep; |
213 | 211 | header.time.start = 0; |
214 | 212 | header.time.name = "time"; |
215 | | - header.order = ["time", "zspace", "yspace", "xspace"]; |
216 | 213 | } |
217 | 214 |
|
218 | 215 | /* Record the number of bytes per voxel, and note whether we need |
|
226 | 223 | * generally assumed to correspond to some standard coordinate |
227 | 224 | * space (e.g. Talairach). |
228 | 225 | */ |
229 | | - transform[0][0] = dview.getFloat32(280, littleEndian); |
230 | | - transform[0][1] = dview.getFloat32(284, littleEndian); |
231 | | - transform[0][2] = dview.getFloat32(288, littleEndian); |
232 | | - transform[0][3] = dview.getFloat32(292, littleEndian); |
233 | | - transform[1][0] = dview.getFloat32(296, littleEndian); |
234 | | - transform[1][1] = dview.getFloat32(300, littleEndian); |
235 | | - transform[1][2] = dview.getFloat32(304, littleEndian); |
236 | | - transform[1][3] = dview.getFloat32(308, littleEndian); |
237 | | - transform[2][0] = dview.getFloat32(312, littleEndian); |
238 | | - transform[2][1] = dview.getFloat32(316, littleEndian); |
239 | | - transform[2][2] = dview.getFloat32(320, littleEndian); |
240 | | - transform[2][3] = dview.getFloat32(324, littleEndian); |
| 226 | + nifti_xfm[0][0] = dview.getFloat32(280, littleEndian); |
| 227 | + nifti_xfm[0][1] = dview.getFloat32(284, littleEndian); |
| 228 | + nifti_xfm[0][2] = dview.getFloat32(288, littleEndian); |
| 229 | + nifti_xfm[0][3] = dview.getFloat32(292, littleEndian); |
| 230 | + nifti_xfm[1][0] = dview.getFloat32(296, littleEndian); |
| 231 | + nifti_xfm[1][1] = dview.getFloat32(300, littleEndian); |
| 232 | + nifti_xfm[1][2] = dview.getFloat32(304, littleEndian); |
| 233 | + nifti_xfm[1][3] = dview.getFloat32(308, littleEndian); |
| 234 | + nifti_xfm[2][0] = dview.getFloat32(312, littleEndian); |
| 235 | + nifti_xfm[2][1] = dview.getFloat32(316, littleEndian); |
| 236 | + nifti_xfm[2][2] = dview.getFloat32(320, littleEndian); |
| 237 | + nifti_xfm[2][3] = dview.getFloat32(324, littleEndian); |
241 | 238 | } |
242 | 239 | else if (qform_code > 0) { |
243 | 240 | /* The "Qform", if present, defines a quaternion which specifies |
|
251 | 248 | var qoffset_z = dview.getFloat32(276, littleEndian); |
252 | 249 | var qfac = (dview.getFloat32(76, littleEndian) < 0) ? -1.0 : 1.0; |
253 | 250 |
|
254 | | - transform = niftiQuaternToMat44(quatern_b, quatern_c, quatern_d, |
| 251 | + nifti_xfm = niftiQuaternToMat44(quatern_b, quatern_c, quatern_d, |
255 | 252 | qoffset_x, qoffset_y, qoffset_z, |
256 | 253 | xstep, ystep, zstep, qfac); |
257 | 254 | } |
258 | 255 | else { |
259 | | - transform[0][0] = xstep; |
260 | | - transform[1][1] = ystep; |
261 | | - transform[2][2] = zstep; |
| 256 | + nifti_xfm[0][0] = xstep; |
| 257 | + nifti_xfm[1][1] = ystep; |
| 258 | + nifti_xfm[2][2] = zstep; |
| 259 | + } |
| 260 | + |
| 261 | + var i, j; |
| 262 | + var axis_index_from_file = [0, 1, 2]; |
| 263 | + var transform = [[0, 0, 0, 0], |
| 264 | + [0, 0, 0, 0], |
| 265 | + [0, 0, 0, 0], |
| 266 | + [0, 0, 0, 1]]; |
| 267 | + |
| 268 | + for (i = 0; i < 3; i++) { |
| 269 | + var c_x = Math.abs(nifti_xfm[0][i]); |
| 270 | + var c_y = Math.abs(nifti_xfm[1][i]); |
| 271 | + var c_z = Math.abs(nifti_xfm[2][i]); |
| 272 | + |
| 273 | + if (c_x > c_y && c_x > c_z) { |
| 274 | + header.order[2 - i] = "xspace"; |
| 275 | + axis_index_from_file[i] = 0; |
| 276 | + } |
| 277 | + else if (c_y > c_x && c_y > c_z) { |
| 278 | + header.order[2 - i] = "yspace"; |
| 279 | + axis_index_from_file[i] = 1; |
| 280 | + } |
| 281 | + else { |
| 282 | + header.order[2 - i] = "zspace"; |
| 283 | + axis_index_from_file[i] = 2; |
| 284 | + } |
| 285 | + } |
| 286 | + |
| 287 | + for (i = 0; i < 3; i++) { |
| 288 | + for (j = 0; j < 4; j++) { |
| 289 | + var volume_axis = j; |
| 290 | + if (j < 3) { |
| 291 | + volume_axis = axis_index_from_file[j]; |
| 292 | + } |
| 293 | + transform[i][volume_axis] = nifti_xfm[i][j]; |
| 294 | + } |
262 | 295 | } |
263 | 296 |
|
264 | 297 | VolumeViewer.utils.transformToMinc(transform, header); |
265 | 298 |
|
| 299 | + header[header.order[2]].space_length = dview.getUint16(42, littleEndian); |
| 300 | + header[header.order[1]].space_length = dview.getUint16(44, littleEndian); |
| 301 | + header[header.order[0]].space_length = dview.getUint16(46, littleEndian); |
| 302 | + |
| 303 | + if (tlength >= 1) { |
| 304 | + header.order.unshift("time"); |
| 305 | + } |
| 306 | + |
266 | 307 | header.datatype = datatype; |
267 | 308 | header.vox_offset = vox_offset; |
268 | 309 | header.scl_slope = scl_slope; |
|
0 commit comments