TPCCLIB
Loading...
Searching...
No Matches
ecat7w.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgio.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
18 FILE *fp,
21) {
22 unsigned char buf[MatBLKSIZE];
23 int little;
24
25 if(ECAT7_TEST) printf("ecat7WriteMainheader()\n");
26 /* Check arguments */
27 if(fp==NULL || h==NULL) return(1);
28 little=little_endian();
29 /* Clear buf */
30 memset(buf, 0, MatBLKSIZE);
31
32 /* Copy header contents into buffer and change byte order if necessary */
33 memcpy(buf+0, &h->magic_number, 14);
34 memcpy(buf+14, &h->original_file_name, 32);
35 memcpy(buf+46, &h->sw_version, 2); if(little) swabip(buf+46, 2);
36 memcpy(buf+48, &h->system_type, 2); if(little) swabip(buf+48, 2);
37 memcpy(buf+50, &h->file_type, 2); if(little) swabip(buf+50, 2);
38 memcpy(buf+52, &h->serial_number, 10);
39 //printf("ecat7WriteMainheader(): scan_start_time := %d\n", h->scan_start_time);
40 memcpy(buf+62, &h->scan_start_time, 4); if(little) swawbip(buf+62, 4);
41 memcpy(buf+66, &h->isotope_name, 8);
42 memcpy(buf+74, &h->isotope_halflife, 4); if(little) swawbip(buf+74, 4);
43 memcpy(buf+78, &h->radiopharmaceutical, 32);
44 memcpy(buf+110, &h->gantry_tilt, 4); if(little) swawbip(buf+110, 4);
45 memcpy(buf+114, &h->gantry_rotation, 4); if(little) swawbip(buf+114, 4);
46 memcpy(buf+118, &h->bed_elevation, 4); if(little) swawbip(buf+118, 4);
47 memcpy(buf+122, &h->intrinsic_tilt, 4); if(little) swawbip(buf+122, 4);
48 memcpy(buf+126, &h->wobble_speed, 2); if(little) swabip(buf+126, 2);
49 memcpy(buf+128, &h->transm_source_type, 2); if(little) swabip(buf+128, 2);
50 memcpy(buf+130, &h->distance_scanned, 4); if(little) swawbip(buf+130, 4);
51 memcpy(buf+134, &h->transaxial_fov, 4); if(little) swawbip(buf+134, 4);
52 memcpy(buf+138, &h->angular_compression, 2); if(little) swabip(buf+138, 2);
53 memcpy(buf+140, &h->coin_samp_mode, 2); if(little) swabip(buf+140, 2);
54 memcpy(buf+142, &h->axial_samp_mode, 2); if(little) swabip(buf+142, 2);
55 memcpy(buf+144, &h->ecat_calibration_factor, 4); if(little) swawbip(buf+144, 4);
56 memcpy(buf+148, &h->calibration_units, 2); if(little) swabip(buf+148, 2);
57 memcpy(buf+150, &h->calibration_units_label, 2); if(little) swabip(buf+150, 2);
58 memcpy(buf+152, &h->compression_code, 2); if(little) swabip(buf+152, 2);
59 memcpy(buf+154, &h->study_type, 12);
60 memcpy(buf+166, &h->patient_id, 16);
61 memcpy(buf+182, &h->patient_name, 32);
62 memcpy(buf+214, &h->patient_sex, 1);
63 memcpy(buf+215, &h->patient_dexterity, 1);
64 memcpy(buf+216, &h->patient_age, 4); if(little) swawbip(buf+216, 4);
65 memcpy(buf+220, &h->patient_height, 4); if(little) swawbip(buf+220, 4);
66 memcpy(buf+224, &h->patient_weight, 4); if(little) swawbip(buf+224, 4);
67 memcpy(buf+228, &h->patient_birth_date, 4); if(little) swawbip(buf+228, 4);
68 memcpy(buf+232, &h->physician_name, 32);
69 memcpy(buf+264, &h->operator_name, 32);
70 memcpy(buf+296, &h->study_description, 32);
71 memcpy(buf+328, &h->acquisition_type, 2); if(little) swabip(buf+328, 2);
72 memcpy(buf+330, &h->patient_orientation, 2); if(little) swabip(buf+330, 2);
73 memcpy(buf+332, &h->facility_name, 20);
74 memcpy(buf+352, &h->num_planes, 2); if(little) swabip(buf+352, 2);
75 memcpy(buf+354, &h->num_frames, 2); if(little) swabip(buf+354, 2);
76 memcpy(buf+356, &h->num_gates, 2); if(little) swabip(buf+356, 2);
77 memcpy(buf+358, &h->num_bed_pos, 2); if(little) swabip(buf+358, 2);
78 memcpy(buf+360, &h->init_bed_position, 4); if(little) swawbip(buf+360, 4);
79 memcpy(buf+364, h->bed_position, 15*4); if(little) swawbip(buf+364, 15*4);
80 memcpy(buf+424, &h->plane_separation, 4); if(little) swawbip(buf+424, 4);
81 memcpy(buf+428, &h->lwr_sctr_thres, 2); if(little) swabip(buf+428, 2);
82 memcpy(buf+430, &h->lwr_true_thres, 2); if(little) swabip(buf+430, 2);
83 memcpy(buf+432, &h->upr_true_thres, 2); if(little) swabip(buf+432, 2);
84 memcpy(buf+434, &h->user_process_code, 10);
85 memcpy(buf+444, &h->acquisition_mode, 2); if(little) swabip(buf+444, 2);
86 memcpy(buf+446, &h->bin_size, 4); if(little) swawbip(buf+446, 4);
87 memcpy(buf+450, &h->branching_fraction, 4); if(little) swawbip(buf+450, 4);
88 memcpy(buf+454, &h->dose_start_time, 4); if(little) swawbip(buf+454, 4);
89 memcpy(buf+458, &h->dosage, 4); if(little) swawbip(buf+458, 4);
90 memcpy(buf+462, &h->well_counter_corr_factor, 4); if(little) swawbip(buf+462, 4);
91 memcpy(buf+466, &h->data_units, 32);
92 memcpy(buf+498, &h->septa_state, 2); if(little) swabip(buf+498, 2);
93 memcpy(buf+500, &h->fill_cti, 12);
94
95 /* Write main header */
96 fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(4);
97 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
98
99 return(0);
100}
101/*****************************************************************************/
102
103/*****************************************************************************/
113int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h) {
114 unsigned char buf[MatBLKSIZE];
115 int little; /* 1 if current platform is little endian (i386), else 0 */
116
117 if(ECAT7_TEST) printf("ecat7WriteImageheader(%d)\n", blk);
118 if(fp==NULL || blk<2 || h==NULL) return(1);
119 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
120 /* Clear buf */
121 memset(buf, 0, MatBLKSIZE);
125
126 /* Copy the header fields and swap if necessary */
127 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
128 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
129 memcpy(buf+4, &h->x_dimension, 2); if(little) swabip(buf+4, 2);
130 memcpy(buf+6, &h->y_dimension, 2); if(little) swabip(buf+6, 2);
131 memcpy(buf+8, &h->z_dimension, 2); if(little) swabip(buf+8, 2);
132 memcpy(buf+10, &h->x_offset, 4); if(little) swawbip(buf+10, 4);
133 memcpy(buf+14, &h->y_offset, 4); if(little) swawbip(buf+14, 4);
134 memcpy(buf+18, &h->z_offset, 4); if(little) swawbip(buf+18, 4);
135 memcpy(buf+22, &h->recon_zoom, 4); if(little) swawbip(buf+22, 4);
136 memcpy(buf+26, &h->scale_factor, 4); if(little) swawbip(buf+26, 4);
137 memcpy(buf+30, &h->image_min, 2); if(little) swabip(buf+30, 2);
138 memcpy(buf+32, &h->image_max, 2); if(little) swabip(buf+32, 2);
139 memcpy(buf+34, &h->x_pixel_size, 4); if(little) swawbip(buf+34, 4);
140 memcpy(buf+38, &h->y_pixel_size, 4); if(little) swawbip(buf+38, 4);
141 memcpy(buf+42, &h->z_pixel_size, 4); if(little) swawbip(buf+42, 4);
142 memcpy(buf+46, &h->frame_duration, 4); if(little) swawbip(buf+46, 4);
143 memcpy(buf+50, &h->frame_start_time, 4); if(little) swawbip(buf+50, 4);
144 memcpy(buf+54, &h->filter_code, 2); if(little) swabip(buf+54, 2);
145 memcpy(buf+56, &h->x_resolution, 4); if(little) swawbip(buf+56, 4);
146 memcpy(buf+60, &h->y_resolution, 4); if(little) swawbip(buf+60, 4);
147 memcpy(buf+64, &h->z_resolution, 4); if(little) swawbip(buf+64, 4);
148 memcpy(buf+68, &h->num_r_elements, 4); if(little) swawbip(buf+68, 4);
149 memcpy(buf+72, &h->num_angles, 4); if(little) swawbip(buf+72, 4);
150 memcpy(buf+76, &h->z_rotation_angle, 4); if(little) swawbip(buf+76, 4);
151 memcpy(buf+80, &h->decay_corr_fctr, 4); if(little) swawbip(buf+80, 4);
152 memcpy(buf+84, &h->processing_code, 4); if(little) swawbip(buf+84, 4);
153 memcpy(buf+88, &h->gate_duration, 4); if(little) swawbip(buf+88, 4);
154 memcpy(buf+92, &h->r_wave_offset, 4); if(little) swawbip(buf+92, 4);
155 memcpy(buf+96, &h->num_accepted_beats, 4); if(little) swawbip(buf+96, 4);
156 memcpy(buf+100, &h->filter_cutoff_frequency, 4); if(little) swawbip(buf+100, 4);
157 memcpy(buf+104, &h->filter_resolution, 4); if(little) swawbip(buf+104, 4);
158 memcpy(buf+108, &h->filter_ramp_slope, 4); if(little) swawbip(buf+108, 4);
159 memcpy(buf+112, &h->filter_order, 2); if(little) swabip(buf+112, 2);
160 memcpy(buf+114, &h->filter_scatter_fraction, 4); if(little) swawbip(buf+114, 4);
161 memcpy(buf+118, &h->filter_scatter_slope, 4); if(little) swawbip(buf+118, 4);
162 memcpy(buf+122, &h->annotation, 40);
163 memcpy(buf+162, &h->mt_1_1, 4); if(little) swawbip(buf+162, 4);
164 memcpy(buf+166, &h->mt_1_2, 4); if(little) swawbip(buf+166, 4);
165 memcpy(buf+170, &h->mt_1_3, 4); if(little) swawbip(buf+170, 4);
166 memcpy(buf+174, &h->mt_2_1, 4); if(little) swawbip(buf+174, 4);
167 memcpy(buf+178, &h->mt_2_2, 4); if(little) swawbip(buf+178, 4);
168 memcpy(buf+182, &h->mt_2_3, 4); if(little) swawbip(buf+182, 4);
169 memcpy(buf+186, &h->mt_3_1, 4); if(little) swawbip(buf+186, 4);
170 memcpy(buf+190, &h->mt_3_2, 4); if(little) swawbip(buf+190, 4);
171 memcpy(buf+194, &h->mt_3_3, 4); if(little) swawbip(buf+194, 4);
172 memcpy(buf+198, &h->rfilter_cutoff, 4); if(little) swawbip(buf+198, 4);
173 memcpy(buf+202, &h->rfilter_resolution, 4); if(little) swawbip(buf+202, 4);
174 memcpy(buf+206, &h->rfilter_code, 2); if(little) swabip(buf+206, 2);
175 memcpy(buf+208, &h->rfilter_order, 2); if(little) swabip(buf+208, 2);
176 memcpy(buf+210, &h->zfilter_cutoff, 4); if(little) swawbip(buf+210, 4);
177 memcpy(buf+214, &h->zfilter_resolution, 4); if(little) swawbip(buf+214, 4);
178 memcpy(buf+218, &h->zfilter_code, 2); if(little) swabip(buf+218, 2);
179 memcpy(buf+220, &h->zfilter_order, 2); if(little) swabip(buf+220, 2);
180 memcpy(buf+222, &h->mt_1_4, 4); if(little) swawbip(buf+222, 4);
181 memcpy(buf+226, &h->mt_2_4, 4); if(little) swawbip(buf+226, 4);
182 memcpy(buf+230, &h->mt_3_4, 4); if(little) swawbip(buf+230, 4);
183 memcpy(buf+234, &h->scatter_type, 2); if(little) swabip(buf+234, 2);
184 memcpy(buf+236, &h->recon_type, 2); if(little) swabip(buf+236, 2);
185 memcpy(buf+238, &h->recon_views, 2); if(little) swabip(buf+238, 2);
186 memcpy(buf+240, &h->fill_cti, 87);
187 memcpy(buf+414, &h->fill_user, 48);
188
189 /* Write header */
190 long long pos=(blk-1)*(long long)MatBLKSIZE;
191 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
192 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
193
194 return(0);
195}
196/*****************************************************************************/
197
198/*****************************************************************************/
208int ecat7WriteAttenheader(FILE *fp, int blk, ECAT7_attenheader *h) {
209 unsigned char buf[MatBLKSIZE];
210 int little; /* 1 if current platform is little endian (i386), else 0 */
211
212 if(ECAT7_TEST) printf("ecat7WriteAttenheader()\n");
213 if(fp==NULL || blk<2 || h==NULL) return(1);
214 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
215 /* Clear buf */
216 memset(buf, 0, MatBLKSIZE);
220
221 /* Copy the header fields and swap if necessary */
222 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
223 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
224 memcpy(buf+4, &h->attenuation_type, 2); if(little) swabip(buf+4, 2);
225 memcpy(buf+6, &h->num_r_elements, 2); if(little) swabip(buf+6, 2);
226 memcpy(buf+8, &h->num_angles, 2); if(little) swabip(buf+8, 2);
227 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
228 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
229 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
230 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
231 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
232 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
233 memcpy(buf+30, &h->scale_factor, 4); if(little) swawbip(buf+30, 4);
234 memcpy(buf+34, &h->x_offset, 4); if(little) swawbip(buf+34, 4);
235 memcpy(buf+38, &h->y_offset, 4); if(little) swawbip(buf+38, 4);
236 memcpy(buf+42, &h->x_radius, 4); if(little) swawbip(buf+42, 4);
237 memcpy(buf+46, &h->y_radius, 4); if(little) swawbip(buf+46, 4);
238 memcpy(buf+50, &h->tilt_angle, 4); if(little) swawbip(buf+50, 4);
239 memcpy(buf+54, &h->attenuation_coeff, 4); if(little) swawbip(buf+54, 4);
240 memcpy(buf+58, &h->attenuation_min, 4); if(little) swawbip(buf+58, 4);
241 memcpy(buf+62, &h->attenuation_max, 4); if(little) swawbip(buf+62, 4);
242 memcpy(buf+66, &h->skull_thickness, 4); if(little) swawbip(buf+66, 4);
243 memcpy(buf+70, &h->num_additional_atten_coeff, 2); if(little) swabip(buf+70, 2);
244 memcpy(buf+72, h->additional_atten_coeff, 8*4); if(little) swawbip(buf+72, 8*4);
245 memcpy(buf+104, &h->edge_finding_threshold, 4); if(little) swawbip(buf+104, 4);
246 memcpy(buf+108, &h->storage_order, 2); if(little) swabip(buf+108, 2);
247 memcpy(buf+110, &h->span, 2); if(little) swabip(buf+110, 2);
248 memcpy(buf+112, h->z_elements, 64*2); if(little) swabip(buf+112, 64*2);
249 memcpy(buf+240, h->fill_cti, 86*2); if(little) swabip(buf+240, 86*2);
250 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
251
252 /* Write header */
253 long long pos=(blk-1)*(long long)MatBLKSIZE;
254 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
255 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
256
257 return(0);
258}
259/*****************************************************************************/
260
261/*****************************************************************************/
271int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h) {
272 unsigned char buf[MatBLKSIZE];
273 int little; /* 1 if current platform is little endian (i386), else 0 */
274
275 if(ECAT7_TEST) printf("ecat7WritePolmapheader()\n");
276 if(fp==NULL || blk<2 || h==NULL) return(1);
277 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
278 /* Clear buf */
279 memset(buf, 0, MatBLKSIZE);
283
284 /* Copy the header fields and swap if necessary */
285 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
286 memcpy(buf+2, &h->polar_map_type, 2); if(little) swabip(buf+2, 2);
287 memcpy(buf+4, &h->num_rings, 2); if(little) swabip(buf+4, 2);
288 memcpy(buf+6, h->sectors_per_ring, 32*2); if(little) swabip(buf+6, 32*2);
289 memcpy(buf+70, h->ring_position, 32*4); if(little) swawbip(buf+70, 32*4);
290 memcpy(buf+198, h->ring_angle, 32*2); if(little) swabip(buf+198, 32*2);
291 memcpy(buf+262, &h->start_angle, 2); if(little) swabip(buf+262, 2);
292 memcpy(buf+264, h->long_axis_left, 3*2); if(little) swabip(buf+264, 3*2);
293 memcpy(buf+270, h->long_axis_right, 3*2); if(little) swabip(buf+270, 3*2);
294 memcpy(buf+276, &h->position_data, 2); if(little) swabip(buf+276, 2);
295 memcpy(buf+278, &h->image_min, 2); if(little) swabip(buf+278, 2);
296 memcpy(buf+280, &h->image_max, 2); if(little) swabip(buf+280, 2);
297 memcpy(buf+282, &h->scale_factor, 4); if(little) swawbip(buf+282, 4);
298 memcpy(buf+286, &h->pixel_size, 4); if(little) swawbip(buf+286, 4);
299 memcpy(buf+290, &h->frame_duration, 4); if(little) swawbip(buf+290, 4);
300 memcpy(buf+294, &h->frame_start_time, 4); if(little) swawbip(buf+294, 4);
301 memcpy(buf+298, &h->processing_code, 2); if(little) swabip(buf+298, 2);
302 memcpy(buf+300, &h->quant_units, 2); if(little) swabip(buf+300, 2);
303 memcpy(buf+302, h->annotation, 40);
304 memcpy(buf+342, &h->gate_duration, 4); if(little) swawbip(buf+342, 4);
305 memcpy(buf+346, &h->r_wave_offset, 4); if(little) swawbip(buf+346, 4);
306 memcpy(buf+350, &h->num_accepted_beats, 4); if(little) swawbip(buf+350, 4);
307 memcpy(buf+354, h->polar_map_protocol, 20);
308 memcpy(buf+374, h->database_name, 30);
309 memcpy(buf+404, h->fill_cti, 27*2); if(little) swabip(buf+404, 27*2);
310
311 /* Write header */
312 long long pos=(blk-1)*(long long)MatBLKSIZE;
313 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
314 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
315
316 return(0);
317}
318/*****************************************************************************/
319
320/*****************************************************************************/
330int ecat7WriteNormheader(FILE *fp, int blk, ECAT7_normheader *h) {
331 unsigned char buf[MatBLKSIZE];
332 int little; /* 1 if current platform is little endian (i386), else 0 */
333
334 if(ECAT7_TEST) printf("ecat7WriteNormheader()\n");
335 if(fp==NULL || blk<2 || h==NULL) return(1);
336 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
337 /* Clear buf */
338 memset(buf, 0, MatBLKSIZE);
342
343 /* Copy the header fields and swap if necessary */
344 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
345 memcpy(buf+2, &h->num_r_elements, 2); if(little) swabip(buf+2, 2);
346 memcpy(buf+4, &h->num_transaxial_crystals, 2); if(little) swabip(buf+4, 2);
347 memcpy(buf+6, &h->num_crystal_rings, 2); if(little) swabip(buf+6, 2);
348 memcpy(buf+8, &h->crystals_per_ring, 2); if(little) swabip(buf+8, 2);
349 memcpy(buf+10, &h->num_geo_corr_planes, 2); if(little) swabip(buf+10, 2);
350 memcpy(buf+12, &h->uld, 2); if(little) swabip(buf+12, 2);
351 memcpy(buf+14, &h->lld, 2); if(little) swabip(buf+14, 2);
352 memcpy(buf+16, &h->scatter_energy, 2); if(little) swabip(buf+16, 2);
353 memcpy(buf+18, &h->norm_quality_factor, 4); if(little) swawbip(buf+18, 4);
354 memcpy(buf+22, &h->norm_quality_factor_code, 2); if(little) swabip(buf+22, 2);
355 memcpy(buf+24, h->ring_dtcor1, 32*4); if(little) swawbip(buf+24, 32*4);
356 memcpy(buf+152, h->ring_dtcor2, 32*4); if(little) swawbip(buf+152, 32*4);
357 memcpy(buf+280, h->crystal_dtcor, 8*4); if(little) swawbip(buf+280, 8*4);
358 memcpy(buf+312, &h->span, 2); if(little) swabip(buf+312, 2);
359 memcpy(buf+314, &h->max_ring_diff, 2); if(little) swabip(buf+314, 2);
360 memcpy(buf+316, h->fill_cti, 48*2); if(little) swabip(buf+316, 48*2);
361 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
362
363 /* Write header */
364 long long pos=(blk-1)*(long long)MatBLKSIZE;
365 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
366 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
367
368 return(0);
369}
370/*****************************************************************************/
371
372/*****************************************************************************/
383int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h) {
384 unsigned char buf[2*MatBLKSIZE];
385 int little; /* 1 if current platform is little endian (i386), else 0 */
386
387 if(ECAT7_TEST) printf("ecat7WriteScanheader()\n");
388 if(fp==NULL || blk<2 || h==NULL) return(1);
389 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
390 /* Clear buf */
391 memset(buf, 0, 2*MatBLKSIZE);
395
396 /* Copy the header fields and swap if necessary */
397 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
398 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
399 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
400 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
401 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
402 memcpy(buf+10, h->num_z_elements, 64*2); if(little) swabip(buf+10, 64*2);
403 memcpy(buf+138, &h->ring_difference, 2); if(little) swabip(buf+138, 2);
404 memcpy(buf+140, &h->storage_order, 2); if(little) swabip(buf+140, 2);
405 memcpy(buf+142, &h->axial_compression, 2); if(little) swabip(buf+142, 2);
406 memcpy(buf+144, &h->x_resolution, 4); if(little) swawbip(buf+144, 4);
407 memcpy(buf+148, &h->v_resolution, 4); if(little) swawbip(buf+148, 4);
408 memcpy(buf+152, &h->z_resolution, 4); if(little) swawbip(buf+152, 4);
409 memcpy(buf+156, &h->w_resolution, 4); if(little) swawbip(buf+156, 4);
410 memcpy(buf+160, h->fill_gate, 6*2); if(little) swabip(buf+160, 6*2);
411 memcpy(buf+172, &h->gate_duration, 4); if(little) swawbip(buf+172, 4);
412 memcpy(buf+176, &h->r_wave_offset, 4); if(little) swawbip(buf+176, 4);
413 memcpy(buf+180, &h->num_accepted_beats, 4); if(little) swawbip(buf+180, 4);
414 memcpy(buf+184, &h->scale_factor, 4); if(little) swawbip(buf+184, 4);
415 memcpy(buf+188, &h->scan_min, 2); if(little) swabip(buf+188, 2);
416 memcpy(buf+190, &h->scan_max, 2); if(little) swabip(buf+190, 2);
417 memcpy(buf+192, &h->prompts, 4); if(little) swawbip(buf+192, 4);
418 memcpy(buf+196, &h->delayed, 4); if(little) swawbip(buf+196, 4);
419 memcpy(buf+200, &h->multiples, 4); if(little) swawbip(buf+200, 4);
420 memcpy(buf+204, &h->net_trues, 4); if(little) swawbip(buf+204, 4);
421 memcpy(buf+208, &h->tot_avg_cor, 4); if(little) swawbip(buf+208, 4);
422 memcpy(buf+212, &h->tot_avg_uncor, 4); if(little) swawbip(buf+212, 4);
423 memcpy(buf+216, &h->total_coin_rate, 4); if(little) swawbip(buf+216, 4);
424 memcpy(buf+220, &h->frame_start_time, 4); if(little) swawbip(buf+220, 4);
425 memcpy(buf+224, &h->frame_duration, 4); if(little) swawbip(buf+224, 4);
426 memcpy(buf+228, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+228, 4);
427 memcpy(buf+232, h->fill_cti, 90*2); if(little) swabip(buf+232, 90*2);
428 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
429 memcpy(buf+512, h->uncor_singles, 128*4); if(little) swawbip(buf+512, 128*4);
430
431 /* Write 3D scan header */
432 long long pos=(blk-1)*(long long)MatBLKSIZE;
433 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
434 if(fwrite(buf, 1, 2*MatBLKSIZE, fp) != 2*MatBLKSIZE) return(5);
435
436 return(0);
437}
438/*****************************************************************************/
439
440/*****************************************************************************/
450int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h) {
451 unsigned char buf[MatBLKSIZE];
452 int little; /* 1 if current platform is little endian (i386), else 0 */
453
454 if(ECAT7_TEST) printf("ecat7Write2DScanheader()\n");
455 if(fp==NULL || blk<2 || h==NULL) return(1);
456 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
457 /* Clear buf */
458 memset(buf, 0, MatBLKSIZE);
462
463 /* Copy the header fields and swap if necessary */
464 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
465 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
466 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
467 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
468 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
469 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
470 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
471 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
472 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
473 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
474 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
475 memcpy(buf+30, h->fill_gate, 6*2); if(little) swabip(buf+30, 6*2);
476 memcpy(buf+42, &h->gate_duration, 4); if(little) swawbip(buf+42, 4);
477 memcpy(buf+46, &h->r_wave_offset, 4); if(little) swawbip(buf+46, 4);
478 memcpy(buf+50, &h->num_accepted_beats, 4); if(little) swawbip(buf+50, 4);
479 memcpy(buf+54, &h->scale_factor, 4); if(little) swawbip(buf+54, 4);
480 memcpy(buf+58, &h->scan_min, 2); if(little) swabip(buf+58, 2);
481 memcpy(buf+60, &h->scan_max, 2); if(little) swabip(buf+60, 2);
482 memcpy(buf+62, &h->prompts, 4); if(little) swawbip(buf+62, 4);
483 memcpy(buf+66, &h->delayed, 4); if(little) swawbip(buf+66, 4);
484 memcpy(buf+70, &h->multiples, 4); if(little) swawbip(buf+70, 4);
485 memcpy(buf+74, &h->net_trues, 4); if(little) swawbip(buf+74, 4);
486 memcpy(buf+78, h->cor_singles, 16*4); if(little) swawbip(buf+78, 16*4);
487 memcpy(buf+142, h->uncor_singles, 16*4); if(little) swawbip(buf+142, 16*4);
488 memcpy(buf+206, &h->tot_avg_cor, 4); if(little) swawbip(buf+206, 4);
489 memcpy(buf+210, &h->tot_avg_uncor, 4); if(little) swawbip(buf+210, 4);
490 memcpy(buf+214, &h->total_coin_rate, 4); if(little) swawbip(buf+214, 4);
491 memcpy(buf+218, &h->frame_start_time, 4); if(little) swawbip(buf+218, 4);
492 memcpy(buf+222, &h->frame_duration, 4); if(little) swawbip(buf+222, 4);
493 memcpy(buf+226, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+226, 4);
494 memcpy(buf+230, h->physical_planes, 8*2); if(little) swabip(buf+230, 8*2);
495 memcpy(buf+246, h->fill_cti, 83*2); if(little) swabip(buf+246, 83*2);
496 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
497
498 /* Write header */
499 long long pos=(blk-1)*(long long)MatBLKSIZE;
500 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
501 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
502
503 return(0);
504}
505/*****************************************************************************/
506
507/*****************************************************************************/
517int ecat7Write2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h) {
518 unsigned char buf[MatBLKSIZE];
519 int little; /* 1 if current platform is little endian (i386), else 0 */
520
521 if(ECAT7_TEST) printf("ecat7Write2DNormheader()\n");
522 if(fp==NULL || blk<2 || h==NULL) return(1);
523 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
524 /* Clear buf */
525 memset(buf, 0, MatBLKSIZE);
529
530 /* Copy the header fields and swap if necessary */
531 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
532 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
533 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
534 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
535 memcpy(buf+8, &h->num_z_elements, 2); if(little) swabip(buf+8, 2);
536 memcpy(buf+10, &h->ring_difference, 2); if(little) swabip(buf+10, 2);
537 memcpy(buf+12, &h->scale_factor, 4); if(little) swawbip(buf+12, 4);
538 memcpy(buf+16, &h->norm_min, 4); if(little) swawbip(buf+16, 4);
539 memcpy(buf+20, &h->norm_max, 4); if(little) swawbip(buf+20, 4);
540 memcpy(buf+24, &h->fov_source_width, 4); if(little) swawbip(buf+24, 4);
541 memcpy(buf+28, &h->norm_quality_factor, 4); if(little) swawbip(buf+28, 4);
542 memcpy(buf+32, &h->norm_quality_factor_code, 2); if(little) swabip(buf+32, 2);
543 memcpy(buf+34, &h->storage_order, 2); if(little) swabip(buf+34, 2);
544 memcpy(buf+36, &h->span, 2); if(little) swabip(buf+36, 2);
545 memcpy(buf+38, h->fill_cti, 64*2); if(little) swabip(buf+38, 64*2);
546 memcpy(buf+166, h->fill_cti, 123*2); if(little) swabip(buf+166, 123*2);
547 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
548
549 /* Write header */
550 long long pos=(blk-1)*(long long)MatBLKSIZE;
551 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
552 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
553
554 return(0);
555}
556/*****************************************************************************/
557
558/*****************************************************************************/
567FILE *ecat7Create(const char *fname, ECAT7_mainheader *h) {
568 FILE *fp;
569 char tmp[FILENAME_MAX];
570 int buf[MatBLKSIZE/4];
571
572 if(ECAT7_TEST) printf("ecat7Create(%s, h)\n", fname);
573 /* Check the arguments */
574 if(fname==NULL || h==NULL) return(NULL);
575 /* Check if file exists; backup, if necessary */
576 if(access(fname, 0) != -1) {
577 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
578 if(access(tmp, 0) != -1) remove(tmp);
579 if(ECAT7_TEST) printf("Renaming %s -> %s\n", fname, tmp);
580 rename(fname, tmp);
581 }
582 /* Open file */
583 fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
584 /* Write main header */
585 if(ecat7WriteMainheader(fp, h)) return(NULL);
586 /* Construct an empty matrix list ; convert to little endian if necessary */
587 memset(buf, 0, MatBLKSIZE);
588 buf[0]=31; buf[1]=MatFirstDirBlk; if(little_endian()) swawbip(buf, MatBLKSIZE);
589 /* Write data buffer */
590 fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
591 if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
592 if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
593 /* OK, then return file pointer */
594 return(fp);
595}
596/*****************************************************************************/
597
598/*****************************************************************************/
606 float amax,
608 float *data,
610 long long nr
611) {
612 double d;
613
614 if(nr<1 || data==NULL) return(0);
615 /* scaling is necessary if all values are between -1 - 1 */
616 if(amax<0.9999) return(1);
617 /* Lets check first if at least the max value is close to integers or not */
618 if(modf(amax, &d)>0.0001) return(1);
619 /* if it is, then check all pixels */
620 for(long long i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
621 return(0);
622}
623/*****************************************************************************/
624
625/*****************************************************************************/
635int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata) {
636 int ret;
637 long long pxlNr, blkNr, nxtblk, data_size;
638 float *fptr, fmin, fmax, g, f;
639 char *mdata, *mptr;
640 short int *sptr;
641
642
643 if(ECAT7_TEST) printf("ecat7WriteImageMatrix(fp, %d, h, data)\n", matrix_id);
644 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
645 sprintf(ecat7errmsg, "invalid function parameter.\n");
646 return(1);
647 }
648 if(h->data_type!=ECAT7_SUNI2) {
649 sprintf(ecat7errmsg, "invalid data_type.\n");
650 return(2);
651 }
652 /* nr of pixels */
653 pxlNr=h->x_dimension*h->y_dimension;
654 if(h->num_dimensions>2) pxlNr*=h->z_dimension;
655 if(pxlNr<1) {
656 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
657 return(3);
658 }
659
660 /* How much memory is needed for ALL pixels */
661 data_size=pxlNr*ecat7pxlbytes(h->data_type);
662 /* block nr taken by all pixels */
663 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
664 sprintf(ecat7errmsg, "invalid block number.\n");
665 return(4);
666 }
667 /* Allocate memory for matrix data */
668 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
669 sprintf(ecat7errmsg, "out of memory.\n");
670 return(5);
671 }
672 /* Search for min and max for calculation of scale factor */
673 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
674 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
675 if(g>0) f=32766./g; else f=1.0;
676 /* Check if pixels values can be left as such with scale_factor = 1 */
677 fptr=fdata;
678 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
679 /* Scale matrix data to shorts */
680 h->scale_factor=1.0/f;
681 sptr=(short int*)mdata; fptr=fdata;
682 for(long long i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
683 /* Set header short min & max */
684 h->image_min=(short int)temp_roundf(f*fmin);
685 h->image_max=(short int)temp_roundf(f*fmax);
686 /* Get block number for matrix header and data */
687 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
688 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
689 free(mdata); return(8);
690 }
691 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
692 /* Write header */
693 ret=ecat7WriteImageheader(fp, nxtblk, h); if(ret) {
694 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
695 free(mdata); return(10);
696 }
697 /* Write matrix data */
698 mptr=mdata;
699 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
700 free(mdata);
701 if(ret) {
702 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
703 return(13);
704 }
705 return(0);
706}
707/*****************************************************************************/
708
709/*****************************************************************************/
719int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata) {
720 int ret;
721 long long i, data_size, nxtblk, blkNr, pxlNr;
722 float *fptr, fmin, fmax, g, f;
723 char *mdata, *mptr;
724 short int *sptr;
725
726
727 if(ECAT7_TEST) printf("ecat7Write2DScanMatrix(fp, %d, h, data)\n", matrix_id);
728 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
729 sprintf(ecat7errmsg, "invalid function parameter.\n");
730 return(1);
731 }
732 if(h->data_type!=ECAT7_SUNI2) {
733 sprintf(ecat7errmsg, "invalid data_type.\n");
734 return(2);
735 }
736 /* nr of pixels */
737 pxlNr=h->num_r_elements*h->num_angles;
738 if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
739 if(pxlNr<1) {
740 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
741 return(3);
742 }
743 /* How much memory is needed for ALL pixels */
744 data_size=pxlNr*ecat7pxlbytes(h->data_type);
745 /* block nr taken by all pixels */
746 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
747 sprintf(ecat7errmsg, "invalid block number.\n");
748 return(4);
749 }
750 /* Allocate memory for matrix data */
751 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
752 sprintf(ecat7errmsg, "out of memory.\n");
753 return(5);
754 }
755 /* Search for min and max for calculation of scale factor */
756 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
757 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
758 if(g>0) f=32766./g; else f=1.0;
759 /* Check if pixels values can be left as such with scale_factor = 1 */
760 fptr=fdata;
761 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
762 /* Scale matrix data to shorts */
763 h->scale_factor=1.0/f;
764 sptr=(short int*)mdata; fptr=fdata;
765 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
766 /* Set header short min & max */
767 h->scan_min=(short int)temp_roundf(f*fmin);
768 h->scan_max=(short int)temp_roundf(f*fmax);
769 /* Get block number for matrix header and data */
770 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
771 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
772 free(mdata); return(8);
773 }
774 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
775 /* Write header */
776 ret=ecat7Write2DScanheader(fp, nxtblk, h); if(ret) {
777 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
778 free(mdata); return(10);
779 }
780 /* Write matrix data */
781 mptr=mdata;
782 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
783 free(mdata);
784 if(ret) {
785 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
786 return(13);
787 }
788 return(0);
789}
790/*****************************************************************************/
791
792/*****************************************************************************/
802int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata) {
803 int ret;
804 long long i, nxtblk, blkNr, data_size, pxlNr, dimz;
805 float *fptr, fmin, fmax, g, f;
806 char *mdata, *mptr;
807 short int *sptr;
808
809
810 if(ECAT7_TEST) printf("ecat7WriteScanMatrix(fp, %d, h, data)\n", matrix_id);
811 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
812 sprintf(ecat7errmsg, "invalid function parameter.\n");
813 return(1);
814 }
815 if(h->data_type!=ECAT7_SUNI2) {
816 sprintf(ecat7errmsg, "invalid data_type.\n");
817 return(2);
818 }
819 /* nr of pixels */
820 pxlNr=h->num_r_elements*h->num_angles;
821 for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i];
822 pxlNr*=dimz;
823 if(pxlNr<1) {
824 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
825 return(3);
826 }
827 /* How much memory is needed for ALL pixels */
828 data_size=pxlNr*ecat7pxlbytes(h->data_type);
829 /* block nr taken by all pixels */
830 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
831 sprintf(ecat7errmsg, "invalid block number.\n");
832 return(4);
833 }
834 /* Allocate memory for matrix data */
835 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
836 sprintf(ecat7errmsg, "out of memory.\n");
837 return(5);
838 }
839 /* Search for min and max for calculation of scale factor */
840 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
841 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
842 if(g>0) f=32766./g; else f=1.0;
843 /* Check if pixels values can be left as such with scale_factor = 1 */
844 fptr=fdata;
845 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
846 /* Scale matrix data to shorts */
847 h->scale_factor=1.0/f;
848 sptr=(short int*)mdata; fptr=fdata;
849 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
850 /* Set header short min & max */
851 h->scan_min=(short int)temp_roundf(f*fmin);
852 h->scan_max=(short int)temp_roundf(f*fmax);
853 /* Get block number for matrix header and data */
854 /* Note that one extra block (blkNr+1) is needed for 3D scan header */
855 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr+1); if(nxtblk<1) {
856 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
857 free(mdata); return(8);
858 }
859 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
860 /* Write header */
861 ret=ecat7WriteScanheader(fp, nxtblk, h); if(ret) {
862 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
863 free(mdata); return(10);
864 }
865 /* Write matrix data */
866 /* Note that 3D scan header takes TWO blocks */
867 mptr=mdata;
868 ret=ecat7WriteMatrixdata(fp, nxtblk+2, mptr, pxlNr, ecat7pxlbytes(h->data_type));
869 free(mdata);
870 if(ret) {
871 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
872 return(13);
873 }
874 return(0);
875}
876/*****************************************************************************/
877
878/*****************************************************************************/
888int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata) {
889 int ret;
890 long long i, nxtblk, blkNr, data_size, pxlNr;
891 float *fptr, fmin, fmax, g, f;
892 char *mdata, *mptr;
893 short int *sptr;
894
895
896 if(ECAT7_TEST) printf("ecat7WritePolarmapMatrix(fp, %d, h, data)\n", matrix_id);
897 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
898 sprintf(ecat7errmsg, "invalid function parameter.\n");
899 return(1);
900 }
901 if(h->data_type!=ECAT7_SUNI2) {
902 sprintf(ecat7errmsg, "invalid data_type.\n");
903 return(2);
904 }
905 /* nr of pixels */
906 for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
907 if(pxlNr<1) {
908 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
909 return(3);
910 }
911 /* How much memory is needed for ALL pixels */
912 data_size=pxlNr*ecat7pxlbytes(h->data_type);
913 /* block nr taken by all pixels */
914 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
915 sprintf(ecat7errmsg, "invalid block number.\n");
916 return(4);
917 }
918 /* Allocate memory for matrix data */
919 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
920 sprintf(ecat7errmsg, "out of memory.\n");
921 return(5);
922 }
923 /* Search for min and max for calculation of scale factor */
924 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
925 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
926 if(g>0) f=32766./g; else f=1.0;
927 /* Check if pixels values can be left as such with scale_factor = 1 */
928 fptr=fdata;
929 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
930 /* Scale matrix data to shorts */
931 h->scale_factor=1.0/f;
932 sptr=(short int*)mdata; fptr=fdata;
933 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
934 /* Set header short min & max */
935 h->image_min=(short int)temp_roundf(f*fmin);
936 h->image_max=(short int)temp_roundf(f*fmax);
937 /* Get block number for matrix header and data */
938 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
939 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
940 free(mdata); return(8);
941 }
942 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
943 /* Write header */
944 ret=ecat7WritePolmapheader(fp, nxtblk, h); if(ret) {
945 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
946 free(mdata); return(10);
947 }
948 /* Write matrix data */
949 mptr=mdata;
950 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
951 free(mdata);
952 if(ret) {
953 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
954 return(13);
955 }
956 return(0);
957}
958/*****************************************************************************/
959
960/*****************************************************************************/
974int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size) {
975 unsigned char buf[MatBLKSIZE];
976 char *dptr;
977 int little;
978 long long i, dataSize, byteNr, blkNr;
979
980 if(ECAT7_TEST) printf("ecat7WriteMatrixdata(fp, %d, data, %lld, %d)\n",
981 start_block, pxl_nr, pxl_size);
982 if(fp==NULL || start_block<1 || data==NULL || pxl_nr<1 || pxl_size<1) return(1);
983 little=little_endian(); memset(buf, 0, MatBLKSIZE);
984 dataSize=pxl_nr*pxl_size;
985 /* block nr taken by all pixels */
986 blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
987 if(ECAT7_TEST>2) printf(" blkNr=%lld\n", blkNr);
988 /* Search the place for writing */
989 long long pos=(start_block-1)*(long long)MatBLKSIZE;
990 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
991 /* Save blocks one at a time */
992 for(i=0, dptr=data; i<blkNr && dataSize>0; i++) {
993 byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
994 memcpy(buf, dptr, byteNr);
995 /* Change matrix byte order in little endian platforms */
996 if(little) {
997 if(pxl_size==2) swabip(buf, byteNr);
998 else if(pxl_size==4) swawbip(buf, byteNr);
999 }
1000 /* Write block */
1001 if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
1002 /* Prepare for the next block */
1003 dptr+=byteNr; dataSize-=byteNr;
1004 } /* next block */
1005 return(0);
1006}
1007/*****************************************************************************/
1008
1009/*****************************************************************************/
1010
char ecat7errmsg[128]
Definition ecat7h.c:7
int ECAT7_TEST
Definition ecat7h.c:6
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition ecat7ml.c:147
int ecat7pxlbytes(short int data_type)
Definition ecat7r.c:1274
int ecat7_is_scaling_needed(float amax, float *data, long long nr)
Definition ecat7w.c:604
int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
Definition ecat7w.c:635
int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
Definition ecat7w.c:802
int ecat7WriteNormheader(FILE *fp, int blk, ECAT7_normheader *h)
Definition ecat7w.c:330
int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7w.c:383
int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7w.c:113
int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size)
Definition ecat7w.c:974
int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
Definition ecat7w.c:888
int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7w.c:271
int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7w.c:450
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition ecat7w.c:719
int ecat7Write2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h)
Definition ecat7w.c:517
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition ecat7w.c:567
int ecat7WriteAttenheader(FILE *fp, int blk, ECAT7_attenheader *h)
Definition ecat7w.c:208
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7w.c:16
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649
#define BACKUP_EXTENSION
Header file for libtpcimgio.
#define MatFirstDirBlk
#define ECAT7_IEEER4
#define ECAT7_VAXI4
#define ECAT7_SUNI4
#define ECAT7_VAXI2
#define MatBLKSIZE
#define ECAT7_VAXR4
#define ECAT7_SUNI2
void swabip(void *buf, long long int size)
Definition swap.c:72
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14
int temp_roundf(float e)
Definition petc99.c:20
short int num_dimensions
short int ring_difference
short int storage_order
short int num_z_elements
short int fill_user[50]
short int norm_quality_factor_code
short int num_r_elements
short int fill_cti[123]
short int corrections_applied
float deadtime_correction_factor
short int num_z_elements
short int num_r_elements
short int fill_user[50]
short int ring_difference
short int physical_planes[8]
short int fill_gate[6]
short int fill_cti[83]
float cor_singles[16]
float uncor_singles[16]
short int num_dimensions
short int num_r_elements
short int z_elements[64]
short int attenuation_type
short int fill_cti[86]
short int num_additional_atten_coeff
short int num_dimensions
float edge_finding_threshold
short int num_z_elements
short int data_type
short int num_angles
short int fill_user[50]
short int storage_order
short int ring_difference
float additional_atten_coeff[8]
short int fill_cti[87]
float filter_scatter_fraction
short int filter_code
short int image_max
short int image_min
short int zfilter_order
short int fill_user[49]
short int rfilter_code
float filter_cutoff_frequency
short int zfilter_code
short int filter_order
short int y_dimension
short int z_dimension
short int recon_type
short int scatter_type
short int recon_views
short int num_dimensions
short int rfilter_order
short int x_dimension
short int data_type
short int file_type
short int compression_code
float bed_position[15]
short int system_type
char facility_name[20]
short int num_frames
char operator_name[32]
short int coin_samp_mode
char data_units[32]
char magic_number[14]
float well_counter_corr_factor
char study_type[12]
char user_process_code[10]
short int angular_compression
short int calibration_units
char patient_name[32]
short int fill_cti[6]
short int septa_state
short int num_gates
short int num_planes
short int lwr_true_thres
char physician_name[32]
short int wobble_speed
short int acquisition_mode
short int calibration_units_label
char serial_number[10]
short int num_bed_pos
float ecat_calibration_factor
short int sw_version
short int transm_source_type
short int acquisition_type
char study_description[32]
short int axial_samp_mode
char patient_id[16]
char radiopharmaceutical[32]
short int patient_orientation
short int upr_true_thres
short int lwr_sctr_thres
char original_file_name[32]
short int num_r_elements
short int data_type
short int num_transaxial_crystals
short int num_geo_corr_planes
short int fill_user[50]
short int crystals_per_ring
short int max_ring_diff
float norm_quality_factor
float ring_dtcor1[32]
short int num_crystal_rings
short int norm_quality_factor_code
float ring_dtcor2[32]
float crystal_dtcor[8]
short int scatter_energy
short int fill_cti[48]
short int fill_cti[27]
short int ring_angle[32]
short int long_axis_left[3]
short int processing_code
short int sectors_per_ring[32]
char polar_map_protocol[20]
short int start_angle
short int polar_map_type
short int position_data
float ring_position[32]
short int quant_units
short int long_axis_right[3]
short int scan_min
short int num_r_elements
short int num_angles
short int data_type
float deadtime_correction_factor
short int fill_cti[90]
short int num_dimensions
short int axial_compression
short int fill_gate[6]
short int storage_order
float uncor_singles[128]
short int scan_max
short int num_z_elements[64]
short int fill_user[50]
short int ring_difference
short int corrections_applied