My Project
ecat7r.c
Go to the documentation of this file.
1/******************************************************************************
2
3 Copyright (c) 2003-2010 Turku PET Centre
4
5 Library file: ecat7r.c
6 Description: Functions for reading ECAT 7.x format.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 See the GNU Lesser General Public License for more details:
17 http://www.gnu.org/copyleft/lesser.html
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library/program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi
24
25 Modification history:
26 2003-07-24 Vesa Oikonen
27 First created.
28 2003-09-08 VO
29 Added support for 3D sinograms, ecat7ReadScanMatrix().
30 2004-05-23 VO
31 Comments changed into Doxygen format.
32 2004-06-21 VO
33 ecat7ReadScanMatrix():
34 Before: reads datablocks based on matrix list.
35 After: if block number based on bin nr is smaller, then read only those
36 Reason: simulated file with erroneous matrix list.
37 2004-09-20 VO
38 Doxygen style comments are corrected.
39 2004-11-10 VO
40 Calculation of trueblockNr simplified in ecat7ReadScanMatrix().
41 2006-02-07 Jarkko Johansson
42 Comments added in ecat7ReadScanMatrix().
43 2007-03-21 VO
44 ecat7ReadImageheader(): fill_cti[] and fill_user[] are read correctly.
45 2007-03-27 VO
46 Added ecat7ReadPolarmapMatrix().
47 2010-08-19 VO
48 Main header field patient_birth_date can be in two different int formats,
49 either YYYYMMDD or as seconds from start of year 1970. In latter case
50 the number can be negative, which is not identified correctly by all C
51 library versions. Therefore those are converted to YYYYMMDD format.
52
53
54******************************************************************************/
55#include <locale.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <math.h>
59#include <ctype.h>
60#include <string.h>
61#include <unistd.h>
62#include <time.h>
63/*****************************************************************************/
64#include <swap.h>
65#include <datetime.h>
66#include "include/ecat7.h"
67/*****************************************************************************/
68
69/*****************************************************************************/
79 unsigned char buf[MatBLKSIZE];
80 int little; /* 1 if current platform is little endian (i386), else 0 */
81 struct tm st;
82
83 if(ECAT7_TEST) printf("ecat7ReadMainheader()\n");
84 if(fp==NULL || h==NULL) return(1);
85 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
86
87 /* Seek the first block */
88 fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(2);
89 /* Read the header block */
90 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
91
92 /* Copy the header fields and swap if necessary */
93 memcpy(&h->magic_number, buf+0, 14);
94 memcpy(&h->original_file_name, buf+14, 32);
95 if(little) swabip(buf+46, 2); memcpy(&h->sw_version, buf+46, 2);
96 if(little) swabip(buf+48, 2); memcpy(&h->system_type, buf+48, 2);
97 if(little) swabip(buf+50, 2); memcpy(&h->file_type, buf+50, 2);
98 memcpy(&h->serial_number, buf+52, 10);
99 if(little) swawbip(buf+62, 4); memcpy(&h->scan_start_time, buf+62, 4);
100 memcpy(&h->isotope_name, buf+66, 8);
101 if(little) swawbip(buf+74, 4); memcpy(&h->isotope_halflife, buf+74, 4);
102 memcpy(&h->radiopharmaceutical, buf+78, 32);
103 if(little) swawbip(buf+110, 4); memcpy(&h->gantry_tilt, buf+110, 4);
104 if(little) swawbip(buf+114, 4); memcpy(&h->gantry_rotation, buf+114, 4);
105 if(little) swawbip(buf+118, 4); memcpy(&h->bed_elevation, buf+118, 4);
106 if(little) swawbip(buf+122, 4); memcpy(&h->intrinsic_tilt, buf+122, 4);
107 if(little) swabip(buf+126, 2); memcpy(&h->wobble_speed, buf+126, 2);
108 if(little) swabip(buf+128, 2); memcpy(&h->transm_source_type, buf+128, 2);
109 if(little) swawbip(buf+130, 4); memcpy(&h->distance_scanned, buf+130, 4);
110 if(little) swawbip(buf+134, 4); memcpy(&h->transaxial_fov, buf+134, 4);
111 if(little) swabip(buf+138, 2); memcpy(&h->angular_compression, buf+138, 2);
112 if(little) swabip(buf+140, 2); memcpy(&h->coin_samp_mode, buf+140, 2);
113 if(little) swabip(buf+142, 2); memcpy(&h->axial_samp_mode, buf+142, 2);
114 if(little) swawbip(buf+144, 4); memcpy(&h->ecat_calibration_factor, buf+144, 4);
115 if(little) swabip(buf+148, 2); memcpy(&h->calibration_units, buf+148, 2);
116 if(little) swabip(buf+150, 2); memcpy(&h->calibration_units_label, buf+150, 2);
117 if(little) swabip(buf+152, 2); memcpy(&h->compression_code, buf+152, 2);
118 memcpy(&h->study_type, buf+154, 12);
119 memcpy(&h->patient_id, buf+166, 16);
120 memcpy(&h->patient_name, buf+182, 32);
121 memcpy(&h->patient_sex, buf+214, 1);
122 memcpy(&h->patient_dexterity, buf+215, 1);
123 if(little) swawbip(buf+216, 4); memcpy(&h->patient_age, buf+216, 4);
124 if(little) swawbip(buf+220, 4); memcpy(&h->patient_height, buf+220, 4);
125 if(little) swawbip(buf+224, 4); memcpy(&h->patient_weight, buf+224, 4);
126 if(little) swawbip(buf+228, 4); memcpy(&h->patient_birth_date, buf+228, 4);
127 memcpy(&h->physician_name, buf+232, 32);
128 memcpy(&h->operator_name, buf+264, 32);
129 memcpy(&h->study_description, buf+296, 32);
130 if(little) swabip(buf+328, 2); memcpy(&h->acquisition_type, buf+328, 2);
131 if(little) swabip(buf+330, 2); memcpy(&h->patient_orientation, buf+330, 2);
132 memcpy(&h->facility_name, buf+332, 20);
133 if(little) swabip(buf+352, 2); memcpy(&h->num_planes, buf+352, 2);
134 if(little) swabip(buf+354, 2); memcpy(&h->num_frames, buf+354, 2);
135 if(little) swabip(buf+356, 2); memcpy(&h->num_gates, buf+356, 2);
136 if(little) swabip(buf+358, 2); memcpy(&h->num_bed_pos, buf+358, 2);
137 if(little) swawbip(buf+360, 4); memcpy(&h->init_bed_position, buf+360, 4);
138 if(little) swawbip(buf+364, 15*4); memcpy(h->bed_position, buf+364, 15*4);
139 if(little) swawbip(buf+424, 4); memcpy(&h->plane_separation, buf+424, 4);
140 if(little) swabip(buf+428, 2); memcpy(&h->lwr_sctr_thres, buf+428, 2);
141 if(little) swabip(buf+430, 2); memcpy(&h->lwr_true_thres, buf+430, 2);
142 memcpy(&h->upr_true_thres, buf+432, 2); if(little) swabip(&h->upr_true_thres, 2);
143 memcpy(&h->user_process_code, buf+434, 10);
144 if(little) swabip(buf+444, 2); memcpy(&h->acquisition_mode, buf+444, 2);
145 if(little) swawbip(buf+446, 4); memcpy(&h->bin_size, buf+446, 4);
146 if(little) swawbip(buf+450, 4); memcpy(&h->branching_fraction, buf+450, 4);
147 if(little) swawbip(buf+454, 4); memcpy(&h->dose_start_time, buf+454, 4);
148 if(little) swawbip(buf+458, 4); memcpy(&h->dosage, buf+458, 4);
149 if(little) swawbip(buf+462, 4); memcpy(&h->well_counter_corr_factor, buf+462, 4);
150 memcpy(&h->data_units, buf+466, 32);
151 if(little) swabip(buf+498, 2); memcpy(&h->septa_state, buf+498, 2);
152 memcpy(&h->fill_cti, buf+500, 12);
153
154 /* Patient birth date can have been saved in two different int formats,
155 either YYYYMMDD or as seconds from start of year 1970. In latter case
156 the number can be negative. */
157 /* Seconds from start of year 1970 are converted to YYYYMMDD format */
158 if(isdate4(h->patient_birth_date, NULL, NULL, NULL)!=0) {
159 time_to_tm((time_t)h->patient_birth_date, 12*3600-timezone, &st);
160 h->patient_birth_date=10000*(st.tm_year+1900)+100*(st.tm_mon+1)+st.tm_mday;
161 }
162
163 return(0);
164}
165/*****************************************************************************/
166
167/*****************************************************************************/
177int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h) {
178 unsigned char buf[MatBLKSIZE];
179 int little; /* 1 if current platform is little endian (i386), else 0 */
180
181 if(ECAT7_TEST) printf("ecat7ReadImageheader()\n");
182 if(fp==NULL || h==NULL) return(1);
183 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
184
185 /* Seek the subheader block */
186 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
187 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
188 /* Read the header block */
189 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
190
191 /* Copy the header fields and swap if necessary */
192 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
193 if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
194 if(little) swabip(buf+4, 2); memcpy(&h->x_dimension, buf+4, 2);
195 if(little) swabip(buf+6, 2); memcpy(&h->y_dimension, buf+6, 2);
196 if(little) swabip(buf+8, 2); memcpy(&h->z_dimension, buf+8, 2);
197 if(little) swawbip(buf+10, 4); memcpy(&h->x_offset, buf+10, 4);
198 if(little) swawbip(buf+14, 4); memcpy(&h->y_offset, buf+14, 4);
199 if(little) swawbip(buf+18, 4); memcpy(&h->z_offset, buf+18, 4);
200 if(little) swawbip(buf+22, 4); memcpy(&h->recon_zoom, buf+22, 4);
201 if(little) swawbip(buf+26, 4); memcpy(&h->scale_factor, buf+26, 4);
202 if(little) swabip(buf+30, 2); memcpy(&h->image_min, buf+30, 2);
203 if(little) swabip(buf+32, 2); memcpy(&h->image_max, buf+32, 2);
204 if(little) swawbip(buf+34, 4); memcpy(&h->x_pixel_size, buf+34, 4);
205 if(little) swawbip(buf+38, 4); memcpy(&h->y_pixel_size, buf+38, 4);
206 if(little) swawbip(buf+42, 4); memcpy(&h->z_pixel_size, buf+42, 4);
207 if(little) swawbip(buf+46, 4); memcpy(&h->frame_duration, buf+46, 4);
208 if(little) swawbip(buf+50, 4); memcpy(&h->frame_start_time, buf+50, 4);
209 if(little) swabip(buf+54, 2); memcpy(&h->filter_code, buf+54, 2);
210 if(little) swawbip(buf+56, 4); memcpy(&h->x_resolution, buf+56, 4);
211 if(little) swawbip(buf+60, 4); memcpy(&h->y_resolution, buf+60, 4);
212 if(little) swawbip(buf+64, 4); memcpy(&h->z_resolution, buf+64, 4);
213 if(little) swawbip(buf+68, 4); memcpy(&h->num_r_elements, buf+68, 4);
214 if(little) swawbip(buf+72, 4); memcpy(&h->num_angles, buf+72, 4);
215 if(little) swawbip(buf+76, 4); memcpy(&h->z_rotation_angle, buf+76, 4);
216 if(little) swawbip(buf+80, 4); memcpy(&h->decay_corr_fctr, buf+80, 4);
217 if(little) swawbip(buf+84, 4); memcpy(&h->processing_code, buf+84, 4);
218 if(little) swawbip(buf+88, 4); memcpy(&h->gate_duration, buf+88, 4);
219 if(little) swawbip(buf+92, 4); memcpy(&h->r_wave_offset, buf+92, 4);
220 if(little) swawbip(buf+96, 4); memcpy(&h->num_accepted_beats, buf+96, 4);
221 if(little) swawbip(buf+100, 4); memcpy(&h->filter_cutoff_frequency, buf+100, 4);
222 if(little) swawbip(buf+104, 4); memcpy(&h->filter_resolution, buf+104, 4);
223 if(little) swawbip(buf+108, 4); memcpy(&h->filter_ramp_slope, buf+108, 4);
224 if(little) swabip(buf+112, 2); memcpy(&h->filter_order, buf+112, 2);
225 if(little) swawbip(buf+114, 4); memcpy(&h->filter_scatter_fraction, buf+114, 4);
226 if(little) swawbip(buf+118, 4); memcpy(&h->filter_scatter_slope, buf+118, 4);
227 memcpy(&h->annotation, buf+122, 40);
228 if(little) swawbip(buf+162, 4); memcpy(&h->mt_1_1, buf+162, 4);
229 if(little) swawbip(buf+166, 4); memcpy(&h->mt_1_2, buf+166, 4);
230 if(little) swawbip(buf+170, 4); memcpy(&h->mt_1_3, buf+170, 4);
231 if(little) swawbip(buf+174, 4); memcpy(&h->mt_2_1, buf+174, 4);
232 if(little) swawbip(buf+178, 4); memcpy(&h->mt_2_2, buf+178, 4);
233 if(little) swawbip(buf+182, 4); memcpy(&h->mt_2_3, buf+182, 4);
234 if(little) swawbip(buf+186, 4); memcpy(&h->mt_3_1, buf+186, 4);
235 if(little) swawbip(buf+190, 4); memcpy(&h->mt_3_2, buf+190, 4);
236 if(little) swawbip(buf+194, 4); memcpy(&h->mt_3_3, buf+194, 4);
237 if(little) swawbip(buf+198, 4); memcpy(&h->rfilter_cutoff, buf+198, 4);
238 if(little) swawbip(buf+202, 4); memcpy(&h->rfilter_resolution, buf+202, 4);
239 if(little) swabip(buf+206, 2); memcpy(&h->rfilter_code, buf+206, 2);
240 if(little) swabip(buf+208, 2); memcpy(&h->rfilter_order, buf+208, 2);
241 if(little) swawbip(buf+210, 4); memcpy(&h->zfilter_cutoff, buf+210, 4);
242 if(little) swawbip(buf+214, 4); memcpy(&h->zfilter_resolution, buf+214, 4);
243 if(little) swabip(buf+218, 2); memcpy(&h->zfilter_code, buf+218, 2);
244 if(little) swabip(buf+220, 2); memcpy(&h->zfilter_order, buf+220, 2);
245 if(little) swawbip(buf+222, 4); memcpy(&h->mt_1_4, buf+222, 4);
246 if(little) swawbip(buf+226, 4); memcpy(&h->mt_2_4, buf+226, 4);
247 if(little) swawbip(buf+230, 4); memcpy(&h->mt_3_4, buf+230, 4);
248 if(little) swabip(buf+234, 2); memcpy(&h->scatter_type, buf+234, 2);
249 if(little) swabip(buf+236, 2); memcpy(&h->recon_type, buf+236, 2);
250 if(little) swabip(buf+238, 2); memcpy(&h->recon_views, buf+238, 2);
251 memcpy(&h->fill_cti, buf+240, 174);
252 memcpy(&h->fill_user, buf+414, 96);
253
254 return(0);
255}
256/*****************************************************************************/
257
258/*****************************************************************************/
268int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h) {
269 unsigned char buf[MatBLKSIZE];
270 int little; /* 1 if current platform is little endian (i386), else 0 */
271
272 if(ECAT7_TEST) printf("ecat7ReadAttenheader()\n");
273 if(fp==NULL || h==NULL) return(1);
274 little=little_endian();
275
276 /* Seek the subheader block */
277 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
278 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
279 /* Read the header block */
280 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
281 /* Copy the header fields and swap if necessary */
282 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
283 if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
284 if(little) swabip(buf+4, 2); memcpy(&h->attenuation_type, buf+4, 2);
285 if(little) swabip(buf+6, 2); memcpy(&h->num_r_elements, buf+6, 2);
286 if(little) swabip(buf+8, 2); memcpy(&h->num_angles, buf+8, 2);
287 if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
288 if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
289 if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
290 if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
291 if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
292 if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
293 if(little) swawbip(buf+30, 4); memcpy(&h->scale_factor, buf+30, 4);
294 if(little) swawbip(buf+34, 4); memcpy(&h->x_offset, buf+34, 4);
295 if(little) swawbip(buf+38, 4); memcpy(&h->y_offset, buf+38, 4);
296 if(little) swawbip(buf+42, 4); memcpy(&h->x_radius, buf+42, 4);
297 if(little) swawbip(buf+46, 4); memcpy(&h->y_radius, buf+46, 4);
298 if(little) swawbip(buf+50, 4); memcpy(&h->tilt_angle, buf+50, 4);
299 if(little) swawbip(buf+54, 4); memcpy(&h->attenuation_coeff, buf+54, 4);
300 if(little) swawbip(buf+58, 4); memcpy(&h->attenuation_min, buf+58, 4);
301 if(little) swawbip(buf+62, 4); memcpy(&h->attenuation_max, buf+62, 4);
302 if(little) swawbip(buf+66, 4); memcpy(&h->skull_thickness, buf+66, 4);
303 if(little) swabip(buf+70, 2); memcpy(&h->num_additional_atten_coeff, buf+70, 2);
304 if(little) swawbip(buf+72, 8*4); memcpy(h->additional_atten_coeff, buf+72, 8*4);
305 if(little) swawbip(buf+104, 4); memcpy(&h->edge_finding_threshold, buf+104, 4);
306 if(little) swabip(buf+108, 2); memcpy(&h->storage_order, buf+108, 2);
307 if(little) swabip(buf+110, 2); memcpy(&h->span, buf+110, 2);
308 if(little) swabip(buf+112, 64*2); memcpy(h->z_elements, buf+112, 64*2);
309 if(little) swabip(buf+240, 86*2); memcpy(h->fill_cti, buf+240, 86*2);
310 if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
311 return(0);
312}
313/*****************************************************************************/
314
315/*****************************************************************************/
325int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h) {
326 unsigned char buf[MatBLKSIZE];
327 int little; /* 1 if current platform is little endian (i386), else 0 */
328
329 if(ECAT7_TEST) printf("ecat7ReadPolarmapheader()\n");
330 if(fp==NULL || h==NULL) return(1);
331 little=little_endian();
332
333 /* Seek the subheader block */
334 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
335 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
336 /* Read the header block */
337 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
338 /* Copy the header fields and swap if necessary */
339 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
340 if(little) swabip(buf+2, 2); memcpy(&h->polar_map_type, buf+2, 2);
341 if(little) swabip(buf+4, 2); memcpy(&h->num_rings, buf+4, 2);
342 if(little) swabip(buf+6, 32*2); memcpy(h->sectors_per_ring, buf+6, 32*2);
343 if(little) swawbip(buf+70, 32*4); memcpy(h->ring_position, buf+70, 32*4);
344 if(little) swabip(buf+198, 32*2); memcpy(h->ring_angle, buf+198, 32*2);
345 if(little) swabip(buf+262, 2); memcpy(&h->start_angle, buf+262, 2);
346 if(little) swabip(buf+264, 3*2); memcpy(h->long_axis_left, buf+264, 3*2);
347 if(little) swabip(buf+270, 3*2); memcpy(h->long_axis_right, buf+270, 3*2);
348 if(little) swabip(buf+276, 2); memcpy(&h->position_data, buf+276, 2);
349 if(little) swabip(buf+278, 2); memcpy(&h->image_min, buf+278, 2);
350 if(little) swabip(buf+280, 2); memcpy(&h->image_max, buf+280, 2);
351 if(little) swawbip(buf+282, 4); memcpy(&h->scale_factor, buf+282, 4);
352 if(little) swawbip(buf+286, 4); memcpy(&h->pixel_size, buf+286, 4);
353 if(little) swawbip(buf+290, 4); memcpy(&h->frame_duration, buf+290, 4);
354 if(little) swawbip(buf+294, 4); memcpy(&h->frame_start_time, buf+294, 4);
355 if(little) swabip(buf+298, 2); memcpy(&h->processing_code, buf+298, 2);
356 if(little) swabip(buf+300, 2); memcpy(&h->quant_units, buf+300, 2);
357 memcpy(h->annotation, buf+302, 40);
358 if(little) swawbip(buf+342, 4); memcpy(&h->gate_duration, buf+342, 4);
359 if(little) swawbip(buf+346, 4); memcpy(&h->r_wave_offset, buf+346, 4);
360 if(little) swawbip(buf+350, 4); memcpy(&h->num_accepted_beats, buf+350, 4);
361 memcpy(h->polar_map_protocol, buf+354, 20);
362 memcpy(h->database_name, buf+374, 30);
363 if(little) swabip(buf+404, 27*2); memcpy(h->fill_cti, buf+404, 27*2);
364 return(0);
365}
366/*****************************************************************************/
367
368/*****************************************************************************/
378int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h) {
379 unsigned char buf[MatBLKSIZE];
380 int little; /* 1 if current platform is little endian (i386), else 0 */
381
382 if(ECAT7_TEST) printf("ecat7ReadNormheader()\n");
383 if(fp==NULL || h==NULL) return(1);
384 little=little_endian();
385
386 /* Seek the subheader block */
387 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
388 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
389 /* Read the header block */
390 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
391 /* Copy the header fields and swap if necessary */
392 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
393 if(little) swabip(buf+2, 2); memcpy(&h->num_r_elements, buf+2, 2);
394 if(little) swabip(buf+4, 2); memcpy(&h->num_transaxial_crystals, buf+4, 2);
395 if(little) swabip(buf+6, 2); memcpy(&h->num_crystal_rings, buf+6, 2);
396 if(little) swabip(buf+8, 2); memcpy(&h->crystals_per_ring, buf+8, 2);
397 if(little) swabip(buf+10, 2); memcpy(&h->num_geo_corr_planes, buf+10, 2);
398 if(little) swabip(buf+12, 2); memcpy(&h->uld, buf+12, 2);
399 if(little) swabip(buf+14, 2); memcpy(&h->lld, buf+14, 2);
400 if(little) swabip(buf+16, 2); memcpy(&h->scatter_energy, buf+16, 2);
401 if(little) swawbip(buf+18, 4); memcpy(&h->norm_quality_factor, buf+18, 4);
402 if(little) swabip(buf+22, 2); memcpy(&h->norm_quality_factor_code, buf+22, 2);
403 if(little) swawbip(buf+24, 32*4); memcpy(h->ring_dtcor1, buf+24, 32*4);
404 if(little) swawbip(buf+152, 32*4); memcpy(h->ring_dtcor2, buf+152, 32*4);
405 if(little) swawbip(buf+280, 8*4); memcpy(h->crystal_dtcor, buf+280, 8*4);
406 if(little) swabip(buf+312, 2); memcpy(&h->span, buf+312, 2);
407 if(little) swabip(buf+314, 2); memcpy(&h->max_ring_diff, buf+314, 2);
408 if(little) swabip(buf+316, 48*2); memcpy(h->fill_cti, buf+316, 48*2);
409 if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
410 return(0);
411}
412/*****************************************************************************/
413
414/*****************************************************************************/
424int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h) {
425 unsigned char buf[2*MatBLKSIZE];
426 int little; /* 1 if current platform is little endian (i386), else 0 */
427
428 if(ECAT7_TEST) printf("ecat7ReadScanheader()\n");
429 if(fp==NULL || h==NULL) return(1);
430 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
431
432 /* Seek the subheader block */
433 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
434 /* Read the header block */
435 if(fread(buf, MatBLKSIZE, 2, fp)<1) return(3);
436
437 /* Copy the header fields and swap if necessary */
438 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
439 if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
440 if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
441 if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
442 if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
443 if(little) swabip(buf+10, 64*2); memcpy(h->num_z_elements, buf+10, 64*2);
444 if(little) swabip(buf+138, 2); memcpy(&h->ring_difference, buf+138, 2);
445 if(little) swabip(buf+140, 2); memcpy(&h->storage_order, buf+140, 2);
446 if(little) swabip(buf+142, 2); memcpy(&h->axial_compression, buf+142, 2);
447 if(little) swawbip(buf+144, 4); memcpy(&h->x_resolution, buf+144, 4);
448 if(little) swawbip(buf+148, 4); memcpy(&h->v_resolution, buf+148, 4);
449 if(little) swawbip(buf+152, 4); memcpy(&h->z_resolution, buf+152, 4);
450 if(little) swawbip(buf+156, 4); memcpy(&h->w_resolution, buf+156, 4);
451 if(little) swabip(buf+160, 6*2); memcpy(h->fill_gate, buf+160, 6*2);
452 if(little) swawbip(buf+172, 4); memcpy(&h->gate_duration, buf+172, 4);
453 if(little) swawbip(buf+176, 4); memcpy(&h->r_wave_offset, buf+176, 4);
454 if(little) swawbip(buf+180, 4); memcpy(&h->num_accepted_beats, buf+180, 4);
455 if(little) swawbip(buf+184, 4); memcpy(&h->scale_factor, buf+184, 4);
456 if(little) swabip(buf+188, 2); memcpy(&h->scan_min, buf+188, 2);
457 if(little) swabip(buf+190, 2); memcpy(&h->scan_max, buf+190, 2);
458 if(little) swawbip(buf+192, 4); memcpy(&h->prompts, buf+192, 4);
459 if(little) swawbip(buf+196, 4); memcpy(&h->delayed, buf+196, 4);
460 if(little) swawbip(buf+200, 4); memcpy(&h->multiples, buf+200, 4);
461 if(little) swawbip(buf+204, 4); memcpy(&h->net_trues, buf+204, 4);
462 if(little) swawbip(buf+208, 4); memcpy(&h->tot_avg_cor, buf+208, 4);
463 if(little) swawbip(buf+212, 4); memcpy(&h->tot_avg_uncor, buf+212, 4);
464 if(little) swawbip(buf+216, 4); memcpy(&h->total_coin_rate, buf+216, 4);
465 if(little) swawbip(buf+220, 4); memcpy(&h->frame_start_time, buf+220, 4);
466 if(little) swawbip(buf+224, 4); memcpy(&h->frame_duration, buf+224, 4);
467 if(little) swawbip(buf+228, 4); memcpy(&h->deadtime_correction_factor, buf+228, 4);
468 if(little) swabip(buf+232, 90*2); memcpy(h->fill_cti, buf+232, 90*2);
469 if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
470 if(little) swawbip(buf+512, 128*4); memcpy(h->uncor_singles, buf+512, 128*4);
471 return(0);
472}
473/*****************************************************************************/
474
475/*****************************************************************************/
485int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h) {
486 unsigned char buf[MatBLKSIZE];
487 int little; /* 1 if current platform is little endian (i386), else 0 */
488
489 if(ECAT7_TEST) printf("ecat7Read2DScanheader()\n");
490 if(fp==NULL || h==NULL) return(1);
491 little=little_endian();
492
493 /* Seek the subheader block */
494 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
495 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
496 /* Read the header block */
497 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
498 /* Copy the header fields and swap if necessary */
499 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
500 if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
501 if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
502 if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
503 if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
504 if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
505 if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
506 if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
507 if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
508 if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
509 if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
510 if(little) swabip(buf+30, 6*2); memcpy(h->fill_gate, buf+30, 6*2);
511 if(little) swawbip(buf+42, 4); memcpy(&h->gate_duration, buf+42, 4);
512 if(little) swawbip(buf+46, 4); memcpy(&h->r_wave_offset, buf+46, 4);
513 if(little) swawbip(buf+50, 4); memcpy(&h->num_accepted_beats, buf+50, 4);
514 if(little) swawbip(buf+54, 4); memcpy(&h->scale_factor, buf+54, 4);
515 if(little) swabip(buf+58, 2); memcpy(&h->scan_min, buf+58, 2);
516 if(little) swabip(buf+60, 2); memcpy(&h->scan_max, buf+60, 2);
517 if(little) swawbip(buf+62, 4); memcpy(&h->prompts, buf+62, 4);
518 if(little) swawbip(buf+66, 4); memcpy(&h->delayed, buf+66, 4);
519 if(little) swawbip(buf+70, 4); memcpy(&h->multiples, buf+70, 4);
520 if(little) swawbip(buf+74, 4); memcpy(&h->net_trues, buf+74, 4);
521 if(little) swawbip(buf+78, 16*4); memcpy(h->cor_singles, buf+78, 16*4);
522 if(little) swawbip(buf+142, 16*4); memcpy(h->uncor_singles, buf+142, 16*4);
523 if(little) swawbip(buf+206, 4); memcpy(&h->tot_avg_cor, buf+206, 4);
524 if(little) swawbip(buf+210, 4); memcpy(&h->tot_avg_uncor, buf+210, 4);
525 if(little) swawbip(buf+214, 4); memcpy(&h->total_coin_rate, buf+214, 4);
526 if(little) swawbip(buf+218, 4); memcpy(&h->frame_start_time, buf+218, 4);
527 if(little) swawbip(buf+222, 4); memcpy(&h->frame_duration, buf+222, 4);
528 if(little) swawbip(buf+226, 4); memcpy(&h->deadtime_correction_factor, buf+226, 4);
529 if(little) swabip(buf+230, 8*2); memcpy(h->physical_planes, buf+230, 8*2);
530 if(little) swabip(buf+246, 83*2); memcpy(h->fill_cti, buf+246, 83*2);
531 if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
532 return(0);
533}
534/*****************************************************************************/
535
536/*****************************************************************************/
546int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h) {
547 unsigned char buf[MatBLKSIZE];
548 int little; /* 1 if current platform is little endian (i386), else 0 */
549
550 if(ECAT7_TEST) printf("ecat7Read2Dnormheader()\n");
551 if(fp==NULL || h==NULL) return(1);
552 little=little_endian();
553
554 /* Seek the subheader block */
555 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
556 if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
557 /* Read the header block */
558 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
559 /* Copy the header fields and swap if necessary */
560 if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
561 if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
562 if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
563 if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
564 if(little) swabip(buf+8, 2); memcpy(&h->num_z_elements, buf+8, 2);
565 if(little) swabip(buf+10, 2); memcpy(&h->ring_difference, buf+10, 2);
566 if(little) swawbip(buf+12, 4); memcpy(&h->scale_factor, buf+12, 4);
567 if(little) swawbip(buf+16, 4); memcpy(&h->norm_min, buf+16, 4);
568 if(little) swawbip(buf+20, 4); memcpy(&h->norm_max, buf+20, 4);
569 if(little) swawbip(buf+24, 4); memcpy(&h->fov_source_width, buf+24, 4);
570 if(little) swawbip(buf+28, 4); memcpy(&h->norm_quality_factor, buf+28, 4);
571 if(little) swabip(buf+32, 2); memcpy(&h->norm_quality_factor_code, buf+32, 2);
572 if(little) swabip(buf+34, 2); memcpy(&h->storage_order, buf+34, 2);
573 if(little) swabip(buf+36, 2); memcpy(&h->span, buf+36, 2);
574 if(little) swabip(buf+38, 64*2); memcpy(h->fill_cti, buf+38, 64*2);
575 if(little) swabip(buf+166, 123*2); memcpy(h->fill_cti, buf+166, 123*2);
576 if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
577 return(0);
578}
579/*****************************************************************************/
580
581/*****************************************************************************/
595int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype) {
596 int i, n, little, err=0;
597 char *cptr;
598 float f;
599
600 if(ECAT7_TEST) printf("ecat7ReadMatrixdata(fp, %d, %d, data, %d)\n",
601 start_block, block_nr, dtype);
602 /* Check the arguments */
603 if(block_nr<=0 || start_block<1 || data==NULL) return(1);
604 /* Seek the first data block */
605 fseek(fp, (start_block-1)*MatBLKSIZE, SEEK_SET);
606 if(ftell(fp)!=(start_block-1)*MatBLKSIZE) return(9);
607 /* Read the data blocks */
608 if(fread(data, MatBLKSIZE, block_nr, fp) < block_nr) return(2);
609 /* Translate data if necessary */
610 little=little_endian();
611 switch(dtype) {
612 case ECAT7_BYTE: /* byte format...no translation necessary */
613 break;
614 case ECAT7_VAXI2: /* byte conversion necessary on big endian platform */
615 if(!little) {cptr=data; swabip(cptr, block_nr*MatBLKSIZE);}
616 break;
617 case ECAT7_VAXI4:
618 for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
619 n=ecat7rInt(cptr, 1, little); memcpy(cptr, &n, 4);
620 }
621 break;
622 case ECAT7_VAXR4:
623 for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
624 f=ecat7rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
625 }
626 break;
627 case ECAT7_IEEER4: /* IEEE float ; byte conversion necessary on little endian platforms */
628 case ECAT7_SUNI4: /* SUN int ; byte conversion necessary on little endian platforms */
629 if(little) swawbip(data, block_nr*MatBLKSIZE);
630 break;
631 case ECAT7_SUNI2: /* SUN short ; byte conversion necessary on little endian platforms */
632 if(little) swabip(data, block_nr*MatBLKSIZE);
633 break;
634 default: /* if something else, for now think it as an error */
635 err=2;
636 break;
637 }
638 return(err);
639}
640/*****************************************************************************/
641
642/*****************************************************************************/
656int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata) {
657 int i, ret, blockNr, pxlNr;
658 char *mdata, *mptr;
659 float *_fdata, *fptr;
660 short int *sptr;
661 int *iptr;
662
663
664 if(ECAT7_TEST) printf("ecat7ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
665 first_block, last_block);
666 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
667 sprintf(ecat7errmsg, "invalid function parameter.\n");
668 return(1);
669 }
670 *fdata=(float*)NULL;
671
672 /* Read subheader */
673 ret=ecat7ReadImageheader(fp, first_block, h);
674 if(ret) {
675 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
676 return(5);
677 }
678 if(ECAT7_TEST>4) ecat7PrintImageheader(h, stdout);
679 pxlNr=h->x_dimension*h->y_dimension;
680 if(h->num_dimensions>2) pxlNr*=h->z_dimension;
681 if(pxlNr<=0) {
682 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
683 return(6);
684 }
685
686 /* Read matrix data */
687 blockNr=last_block-first_block; if(blockNr<1) return(0);
688 mdata=(char*)malloc(blockNr*MatBLKSIZE);
689 if(mdata==NULL) {
690 sprintf(ecat7errmsg, "cannot allocate memory.\n");
691 return(8);
692 }
693 mptr=mdata;
694 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
695 if(ret || mdata==NULL) {
696 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
697 free(mdata); return(9);
698 }
699
700 /* Allocate memory for float data */
701 _fdata=(float*)malloc(pxlNr*sizeof(float));
702 if(_fdata==NULL) {
703 sprintf(ecat7errmsg, "cannot allocate memory.\n");
704 free(mdata); return(11);
705 }
706
707 /* Convert matrix data to floats */
708 fptr=_fdata; mptr=mdata;
709 if(h->data_type==ECAT7_BYTE) {
710 for(i=0; i<pxlNr; i++, mptr++, fptr++)
711 *fptr=h->scale_factor*(float)(*mptr);
712 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
713 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
714 sptr=(short int*)mptr;
715 *fptr=h->scale_factor*(float)(*sptr);
716 }
717 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
718 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
719 iptr=(int*)mptr;
720 *fptr=h->scale_factor*(float)(*iptr);
721 }
722 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
723 memcpy(fptr, mptr, pxlNr*4);
724 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
725 }
726 free(mdata);
727 *fdata=_fdata;
728
729 return(0);
730}
731/*****************************************************************************/
732
733/*****************************************************************************/
749int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block,
750 ECAT7_2Dscanheader *h, float **fdata) {
751 int i, ret, blockNr, pxlNr;
752 char *mdata, *mptr;
753 float *_fdata, *fptr;
754 short int *sptr;
755 int *iptr;
756
757
758 if(ECAT7_TEST) printf("ecat7Read2DScanMatrix(fp, %d, %d, hdr, fdata)\n",
759 first_block, last_block);
760 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
761 sprintf(ecat7errmsg, "invalid function parameter.\n");
762 return(1);
763 }
764 *fdata=(float*)NULL;
765
766 /* Read subheader */
767 ret=ecat7Read2DScanheader(fp, first_block, h);
768 if(ret) {
769 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
770 return(5);
771 }
772 if(ECAT7_TEST>4) ecat7Print2DScanheader(h, stdout);
773 pxlNr=h->num_r_elements*h->num_angles;
774 if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
775 if(pxlNr<=0) {
776 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
777 return(6);
778 }
779
780 /* Read matrix data */
781 blockNr=last_block-first_block; if(blockNr<1) return(0);
782 mdata=(char*)malloc(blockNr*MatBLKSIZE);
783 if(mdata==NULL) {
784 sprintf(ecat7errmsg, "cannot allocate memory.\n");
785 return(8);
786 }
787 mptr=mdata;
788 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
789 if(ret || mdata==NULL) {
790 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
791 free(mdata); return(9);
792 }
793
794 /* Allocate memory for float data */
795 _fdata=(float*)malloc(pxlNr*sizeof(float));
796 if(_fdata==NULL) {
797 sprintf(ecat7errmsg, "cannot allocate memory.\n");
798 free(mdata); return(11);
799 }
800
801 /* Convert matrix data to floats */
802 fptr=_fdata; mptr=mdata;
803 if(h->data_type==ECAT7_BYTE) {
804 for(i=0; i<pxlNr; i++, mptr++, fptr++)
805 *fptr=h->scale_factor*(float)(*mptr);
806 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
807 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
808 sptr=(short int*)mptr;
809 *fptr=h->scale_factor*(float)(*sptr);
810 }
811 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
812 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
813 iptr=(int*)mptr;
814 *fptr=h->scale_factor*(float)(*iptr);
815 }
816 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
817 memcpy(fptr, mptr, pxlNr*4);
818 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
819 }
820 free(mdata);
821 *fdata=_fdata;
822
823 return(0);
824}
825/*****************************************************************************/
826
827/*****************************************************************************/
844int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata) {
845 int i, ret, blockNr, trueblockNr, pxlNr, dimz;
846 char *mdata, *mptr;
847 float *_fdata, *fptr;
848 short int *sptr;
849 int *iptr;
850
851
852 if(ECAT7_TEST) printf("ecat7ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
853 first_block, last_block);
854 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
855 sprintf(ecat7errmsg, "invalid function parameter.\n");
856 return(1);
857 }
858 *fdata=(float*)NULL;
859
860 /* Read subheader */
861 ret=ecat7ReadScanheader(fp, first_block, h);
862 if(ret) {
863 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
864 return(5);
865 }
866 if(ECAT7_TEST>4) ecat7PrintScanheader(h, stdout);
867 pxlNr=h->num_r_elements*h->num_angles;
868 for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i]; pxlNr*=dimz;
869 if(pxlNr<=0) {
870 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
871 return(6);
872 }
873 trueblockNr=pxlNr*ecat7pxlbytes(h->data_type);
874 trueblockNr=(trueblockNr+MatBLKSIZE-1)/MatBLKSIZE;
875
876 /* Read matrix data; note that header takes 2 blocks */
877 blockNr=last_block-first_block-1; if(blockNr<1) return(0);
878 if(blockNr<trueblockNr) trueblockNr=blockNr;
879 mdata=(char*)malloc(blockNr*MatBLKSIZE);
880 if(mdata==NULL) {
881 sprintf(ecat7errmsg, "cannot allocate memory.\n");
882 return(8);
883 }
884 mptr=mdata; /* note that only true block nr is read! */
885 ret=ecat7ReadMatrixdata(fp, first_block+2, trueblockNr, mptr, h->data_type);
886 if(ret || mdata==NULL) {
887 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
888 free(mdata); return(9);
889 }
890
891 /* Allocate memory for float data */
892 _fdata=(float*)malloc(pxlNr*sizeof(float));
893 if(_fdata==NULL) {
894 sprintf(ecat7errmsg, "cannot allocate memory.\n");
895 free(mdata); return(11);
896 }
897
898 /* Convert matrix data to floats */
899 fptr=_fdata; mptr=mdata;
900 if(h->data_type==ECAT7_BYTE) {
901 for(i=0; i<pxlNr; i++, mptr++, fptr++)
902 *fptr=h->scale_factor*(float)(*mptr);
903 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
904 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
905 sptr=(short int*)mptr;
906 *fptr=h->scale_factor*(float)(*sptr);
907 }
908 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
909 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
910 iptr=(int*)mptr;
911 *fptr=h->scale_factor*(float)(*iptr);
912 }
913 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
914 memcpy(fptr, mptr, pxlNr*4);
915 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
916 }
917 free(mdata);
918 *fdata=_fdata;
919
920 return(0);
921}
922/*****************************************************************************/
923
924/*****************************************************************************/
939int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata) {
940 int i, ret, blockNr, pxlNr;
941 char *mdata, *mptr;
942 float *_fdata, *fptr;
943 short int *sptr;
944 int *iptr;
945
946
947 if(ECAT7_TEST) printf("ecat7ReadPolarmapMatrix(fp, %d, %d, hdr, fdata)\n",
948 first_block, last_block);
949 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) return 1;
950 *fdata=(float*)NULL;
951
952 /* Read subheader */
953 ret=ecat7ReadPolmapheader(fp, first_block, h);
954 if(ret) {
955 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
956 return 2;
957 }
958 if(ECAT7_TEST>4) ecat7PrintPolmapheader(h, stdout);
959 for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
960 if(pxlNr<=0) return 3;
961
962 /* Read matrix data */
963 blockNr=last_block-first_block; if(blockNr<1) return 0;
964 mdata=(char*)malloc(blockNr*MatBLKSIZE);
965 if(mdata==NULL) return 4;
966 mptr=mdata;
967 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
968 if(ret || mdata==NULL) {
969 if(mdata!=NULL) free(mdata);
970 return 5;
971 }
972
973 /* Allocate memory for float data */
974 _fdata=(float*)malloc(pxlNr*sizeof(float));
975 if(_fdata==NULL) {
976 sprintf(ecat7errmsg, "cannot allocate memory.\n");
977 free(mdata); return 4;
978 }
979
980 /* Convert matrix data to floats */
981 fptr=_fdata; mptr=mdata;
982 if(h->data_type==ECAT7_BYTE) {
983 for(i=0; i<pxlNr; i++, mptr++, fptr++)
984 *fptr=h->scale_factor*(float)(*mptr);
985 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
986 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
987 sptr=(short int*)mptr;
988 *fptr=h->scale_factor*(float)(*sptr);
989 }
990 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
991 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
992 iptr=(int*)mptr;
993 *fptr=h->scale_factor*(float)(*iptr);
994 }
995 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
996 memcpy(fptr, mptr, pxlNr*4);
997 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
998 }
999 free(mdata);
1000 *fdata=_fdata;
1001
1002 return 0;
1003}
1004/*****************************************************************************/
1005
1006/*****************************************************************************/
1015float ecat7rFloat(void *bufi, int isvax, int islittle) {
1016 union {unsigned int ul; float f;} t;
1017
1018 memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
1019 if(isvax) { /* if input is in VAX format */
1020 /* Swap words on i386 and bytes on SUN */
1021 if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
1022 t.ul-=(2L<<23); /* subtract 2 from exp */
1023 } else { /* input is in i386 format */
1024 if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
1025 }
1026 return(t.f);
1027}
1028
1038int ecat7rInt(void *bufi, int isvax, int islittle) {
1039 int i;
1040
1041 /* Swap both words and bytes on SUN */
1042 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
1043 return(i);
1044}
1045/*****************************************************************************/
1046
1047/*****************************************************************************/
1055int ecat7pxlbytes(short int data_type) {
1056 int byteNr=0;
1057 switch(data_type) {
1058 case ECAT7_BYTE: byteNr=1; break;
1059 case ECAT7_VAXI2:
1060 case ECAT7_SUNI2: byteNr=2; break;
1061 case ECAT7_VAXI4:
1062 case ECAT7_VAXR4:
1063 case ECAT7_IEEER4:
1064 case ECAT7_SUNI4: byteNr=4; break;
1065 }
1066 return(byteNr);
1067}
1068/*****************************************************************************/
1069
1070/*****************************************************************************/
1071
#define MatFirstDirBlk
Definition ecat63.h:28
#define MatBLKSIZE
Definition ecat63.h:27
#define ECAT7_IEEER4
Definition ecat7.h:62
#define ECAT7_VAXI4
Definition ecat7.h:60
char ecat7errmsg[128]
Definition ecat7.h:99
#define ECAT7_SUNI4
Definition ecat7.h:64
#define ECAT7_BYTE
Definition ecat7.h:58
#define ECAT7_VAXI2
Definition ecat7.h:59
#define ECAT7_VAXR4
Definition ecat7.h:61
int ECAT7_TEST
Definition ecat7.h:101
#define ECAT7_SUNI2
Definition ecat7.h:63
void ecat7PrintImageheader(ECAT7_imageheader *h, FILE *fp)
Definition ecat7p.c:137
void ecat7PrintPolmapheader(ECAT7_polmapheader *h, FILE *fp)
Definition ecat7p.c:310
void ecat7Print2DScanheader(ECAT7_2Dscanheader *h, FILE *fp)
Definition ecat7p.c:396
void ecat7PrintScanheader(ECAT7_scanheader *h, FILE *fp)
Definition ecat7p.c:215
int ecat7pxlbytes(short int data_type)
Definition ecat7r.c:1055
int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
Definition ecat7r.c:749
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7r.c:424
float ecat7rFloat(void *bufi, int isvax, int islittle)
Definition ecat7r.c:1015
int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7r.c:325
int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype)
Definition ecat7r.c:595
int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h)
Definition ecat7r.c:378
int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h)
Definition ecat7r.c:268
int ecat7rInt(void *bufi, int isvax, int islittle)
Definition ecat7r.c:1038
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7r.c:78
int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
Definition ecat7r.c:939
int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7r.c:485
int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
Definition ecat7r.c:656
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7r.c:177
int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h)
Definition ecat7r.c:546
int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
Definition ecat7r.c:844
short int fill_cti[123]
Definition ecat7.h:474
short int storage_order
Definition ecat7.h:471
short int fill_user[50]
Definition ecat7.h:475
short int num_dimensions
Definition ecat7.h:460
float scale_factor
Definition ecat7.h:465
float norm_quality_factor
Definition ecat7.h:469
short int num_angles
Definition ecat7.h:462
float fov_source_width
Definition ecat7.h:468
short int num_z_elements
Definition ecat7.h:463
short int span
Definition ecat7.h:472
short int norm_quality_factor_code
Definition ecat7.h:470
short int num_r_elements
Definition ecat7.h:461
short int ring_difference
Definition ecat7.h:464
short int data_type
Definition ecat7.h:459
short int fill_user[50]
Definition ecat7.h:455
int num_accepted_beats
Definition ecat7.h:437
short int physical_planes[8]
Definition ecat7.h:453
float tot_avg_uncor
Definition ecat7.h:448
short int fill_gate[6]
Definition ecat7.h:434
short int num_dimensions
Definition ecat7.h:424
short int num_z_elements
Definition ecat7.h:428
short int ring_difference
Definition ecat7.h:429
short int scan_min
Definition ecat7.h:439
float x_resolution
Definition ecat7.h:430
float deadtime_correction_factor
Definition ecat7.h:452
short int corrections_applied
Definition ecat7.h:427
float w_resolution
Definition ecat7.h:433
short int data_type
Definition ecat7.h:423
float tot_avg_cor
Definition ecat7.h:447
float y_resolution
Definition ecat7.h:431
short int scan_max
Definition ecat7.h:440
short int num_angles
Definition ecat7.h:426
short int fill_cti[83]
Definition ecat7.h:454
short int num_r_elements
Definition ecat7.h:425
float uncor_singles[16]
Definition ecat7.h:446
float scale_factor
Definition ecat7.h:438
float z_resolution
Definition ecat7.h:432
float cor_singles[16]
Definition ecat7.h:445
short int data_type
Definition ecat7.h:480
short int num_dimensions
Definition ecat7.h:482
float edge_finding_threshold
Definition ecat7.h:526
float z_resolution
Definition ecat7.h:498
short int span
Definition ecat7.h:530
short int attenuation_type
Definition ecat7.h:484
short int num_angles
Definition ecat7.h:488
float attenuation_min
Definition ecat7.h:516
float scale_factor
Definition ecat7.h:502
short int num_z_elements
Definition ecat7.h:490
short int fill_cti[86]
Definition ecat7.h:534
float tilt_angle
Definition ecat7.h:512
float w_resolution
Definition ecat7.h:500
float y_resolution
Definition ecat7.h:496
short int ring_difference
Definition ecat7.h:492
short int num_r_elements
Definition ecat7.h:486
float additional_atten_coeff[8]
Definition ecat7.h:524
short int fill_user[50]
Definition ecat7.h:536
float attenuation_max
Definition ecat7.h:518
short int num_additional_atten_coeff
Definition ecat7.h:522
float attenuation_coeff
Definition ecat7.h:514
float x_resolution
Definition ecat7.h:494
float skull_thickness
Definition ecat7.h:520
short int storage_order
Definition ecat7.h:528
short int z_elements[64]
Definition ecat7.h:532
float num_angles
Definition ecat7.h:274
short int recon_type
Definition ecat7.h:344
short int image_max
Definition ecat7.h:252
short int filter_order
Definition ecat7.h:294
short int y_dimension
Definition ecat7.h:236
float filter_scatter_slope
Definition ecat7.h:298
short int scatter_type
Definition ecat7.h:342
float scale_factor
Definition ecat7.h:248
short int rfilter_code
Definition ecat7.h:324
short int x_dimension
Definition ecat7.h:234
float x_pixel_size
Definition ecat7.h:254
float z_pixel_size
Definition ecat7.h:258
float zfilter_cutoff
Definition ecat7.h:328
int frame_start_time
Definition ecat7.h:262
int processing_code
Definition ecat7.h:280
short int fill_cti[87]
Definition ecat7.h:348
float recon_zoom
Definition ecat7.h:246
float decay_corr_fctr
Definition ecat7.h:278
short int z_dimension
Definition ecat7.h:238
short int rfilter_order
Definition ecat7.h:326
float num_r_elements
Definition ecat7.h:272
float y_resolution
Definition ecat7.h:268
short int zfilter_order
Definition ecat7.h:334
float filter_resolution
Definition ecat7.h:290
float x_resolution
Definition ecat7.h:266
int num_accepted_beats
Definition ecat7.h:286
short int data_type
Definition ecat7.h:230
float z_resolution
Definition ecat7.h:270
float filter_ramp_slope
Definition ecat7.h:292
float zfilter_resolution
Definition ecat7.h:330
float rfilter_resolution
Definition ecat7.h:322
short int fill_user[49]
Definition ecat7.h:350
float filter_scatter_fraction
Definition ecat7.h:296
float z_rotation_angle
Definition ecat7.h:276
short int num_dimensions
Definition ecat7.h:232
short int image_min
Definition ecat7.h:250
short int filter_code
Definition ecat7.h:264
char annotation[40]
Definition ecat7.h:300
short int recon_views
Definition ecat7.h:346
short int zfilter_code
Definition ecat7.h:332
float y_pixel_size
Definition ecat7.h:256
float rfilter_cutoff
Definition ecat7.h:320
float filter_cutoff_frequency
Definition ecat7.h:288
char serial_number[10]
Definition ecat7.h:115
char patient_name[32]
Definition ecat7.h:158
char study_description[32]
Definition ecat7.h:178
float well_counter_corr_factor
Definition ecat7.h:219
short int compression_code
Definition ecat7.h:152
char physician_name[32]
Definition ecat7.h:174
short int patient_orientation
Definition ecat7.h:183
short int file_type
Definition ecat7.h:113
char isotope_name[8]
Definition ecat7.h:119
int scan_start_time
Definition ecat7.h:117
float distance_scanned
Definition ecat7.h:137
char original_file_name[32]
Definition ecat7.h:107
char facility_name[20]
Definition ecat7.h:185
char patient_id[16]
Definition ecat7.h:156
float transaxial_fov
Definition ecat7.h:139
short int sw_version
Definition ecat7.h:109
short int num_gates
Definition ecat7.h:191
short int upr_true_thres
Definition ecat7.h:205
short int angular_compression
Definition ecat7.h:141
short int calibration_units
Definition ecat7.h:148
short int fill_cti[6]
Definition ecat7.h:225
float patient_weight
Definition ecat7.h:168
float gantry_tilt
Definition ecat7.h:125
short int transm_source_type
Definition ecat7.h:135
short int wobble_speed
Definition ecat7.h:133
char magic_number[14]
Definition ecat7.h:105
float plane_separation
Definition ecat7.h:199
int dose_start_time
Definition ecat7.h:215
short int num_frames
Definition ecat7.h:189
float gantry_rotation
Definition ecat7.h:127
float init_bed_position
Definition ecat7.h:195
short int coin_samp_mode
Definition ecat7.h:143
short int acquisition_type
Definition ecat7.h:181
float bed_elevation
Definition ecat7.h:129
float isotope_halflife
Definition ecat7.h:121
char user_process_code[10]
Definition ecat7.h:207
short int axial_samp_mode
Definition ecat7.h:145
char operator_name[32]
Definition ecat7.h:176
short int calibration_units_label
Definition ecat7.h:150
char data_units[32]
Definition ecat7.h:221
short int num_planes
Definition ecat7.h:187
short int acquisition_mode
Definition ecat7.h:209
float patient_height
Definition ecat7.h:166
char radiopharmaceutical[32]
Definition ecat7.h:123
int patient_birth_date
Definition ecat7.h:172
short int septa_state
Definition ecat7.h:223
float bin_size
Definition ecat7.h:211
float intrinsic_tilt
Definition ecat7.h:131
float branching_fraction
Definition ecat7.h:213
char patient_dexterity
Definition ecat7.h:162
short int num_bed_pos
Definition ecat7.h:193
float patient_age
Definition ecat7.h:164
float ecat_calibration_factor
Definition ecat7.h:146
short int lwr_true_thres
Definition ecat7.h:203
short int lwr_sctr_thres
Definition ecat7.h:201
short int system_type
Definition ecat7.h:111
char patient_sex
Definition ecat7.h:160
char study_type[12]
Definition ecat7.h:154
float bed_position[15]
Definition ecat7.h:197
short int num_crystal_rings
Definition ecat7.h:546
short int lld
Definition ecat7.h:553
float norm_quality_factor
Definition ecat7.h:557
short int norm_quality_factor_code
Definition ecat7.h:559
short int scatter_energy
Definition ecat7.h:555
short int num_geo_corr_planes
Definition ecat7.h:549
short int max_ring_diff
Definition ecat7.h:569
short int span
Definition ecat7.h:567
float ring_dtcor1[32]
Definition ecat7.h:561
short int num_transaxial_crystals
Definition ecat7.h:544
short int uld
Definition ecat7.h:551
short int crystals_per_ring
Definition ecat7.h:547
short int fill_user[50]
Definition ecat7.h:573
float ring_dtcor2[32]
Definition ecat7.h:563
float crystal_dtcor[8]
Definition ecat7.h:565
short int fill_cti[48]
Definition ecat7.h:571
short int num_r_elements
Definition ecat7.h:542
short int data_type
Definition ecat7.h:540
short int fill_cti[27]
Definition ecat7.h:601
short int processing_code
Definition ecat7.h:593
short int polar_map_type
Definition ecat7.h:578
float ring_position[32]
Definition ecat7.h:581
short int image_max
Definition ecat7.h:588
short int num_rings
Definition ecat7.h:579
char database_name[30]
Definition ecat7.h:600
short int sectors_per_ring[32]
Definition ecat7.h:580
short int data_type
Definition ecat7.h:577
char annotation[40]
Definition ecat7.h:595
short int quant_units
Definition ecat7.h:594
short int long_axis_left[3]
Definition ecat7.h:584
int num_accepted_beats
Definition ecat7.h:598
char polar_map_protocol[20]
Definition ecat7.h:599
short int image_min
Definition ecat7.h:587
float scale_factor
Definition ecat7.h:589
short int start_angle
Definition ecat7.h:583
short int position_data
Definition ecat7.h:586
short int ring_angle[32]
Definition ecat7.h:582
short int long_axis_right[3]
Definition ecat7.h:585
short int corrections_applied
Definition ecat7.h:363
float z_resolution
Definition ecat7.h:377
float uncor_singles[128]
Definition ecat7.h:419
float w_resolution
Definition ecat7.h:379
float v_resolution
Definition ecat7.h:375
float x_resolution
Definition ecat7.h:373
short int fill_cti[90]
Definition ecat7.h:415
short int num_dimensions
Definition ecat7.h:357
short int num_angles
Definition ecat7.h:361
int gate_duration
Definition ecat7.h:383
short int scan_max
Definition ecat7.h:393
short int num_z_elements[64]
Definition ecat7.h:365
int frame_start_time
Definition ecat7.h:409
float scale_factor
Definition ecat7.h:389
float tot_avg_uncor
Definition ecat7.h:405
short int fill_user[50]
Definition ecat7.h:417
float deadtime_correction_factor
Definition ecat7.h:413
float tot_avg_cor
Definition ecat7.h:403
short int data_type
Definition ecat7.h:355
short int axial_compression
Definition ecat7.h:371
short int fill_gate[6]
Definition ecat7.h:381
short int ring_difference
Definition ecat7.h:367
int r_wave_offset
Definition ecat7.h:385
int frame_duration
Definition ecat7.h:411
int num_accepted_beats
Definition ecat7.h:387
short int scan_min
Definition ecat7.h:391
short int num_r_elements
Definition ecat7.h:359
short int storage_order
Definition ecat7.h:369
int total_coin_rate
Definition ecat7.h:407