TPCCLIB
Loading...
Searching...
No Matches
ecat63r.c
Go to the documentation of this file.
1
14/*****************************************************************************/
15#include "libtpcimgio.h"
16/*****************************************************************************/
17
18/*****************************************************************************/
27 FILE *fp,
30) {
31 unsigned char buf[MatBLKSIZE];
32 int little; /* 1 if current platform is little endian (i386), else 0 */
33 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
34
35 if(ECAT63_TEST>0) {printf("ecat63ReadMainheader()\n"); fflush(stdout);}
36 if(fp==NULL || h==NULL) return(1);
37 little=little_endian(); if(ECAT63_TEST>1) {printf("little := %d\n", little); fflush(stdout);}
38 /* Seek the first block */
39 fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(1);
40 /* Read the main header block */
41 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(2);
42
43 /* Copy char data to header structure */
44 memcpy(h->ecat_format, buf+0, 14);
45 memcpy(h->fill1, buf+14, 14);
46 memcpy(h->original_file_name, buf+28, 20);
47 if(ECAT63_TEST>10) {
48 printf("original_file_name := '%.20s'\n", h->original_file_name); fflush(stdout);}
49 memcpy(h->node_id, buf+56, 10);
50 memcpy(h->isotope_code, buf+78, 8);
51 memcpy(h->radiopharmaceutical, buf+90, 32);
52 memcpy(h->study_name, buf+162, 12);
53 memcpy(h->patient_id, buf+174, 16);
54 memcpy(h->patient_name, buf+190, 32);
55 h->patient_sex=buf[222];
56 memcpy(h->patient_age, buf+223, 10);
57 memcpy(h->patient_height, buf+233, 10);
58 memcpy(h->patient_weight, buf+243, 10);
59 h->patient_dexterity=buf[253];
60 memcpy(h->physician_name, buf+254, 32);
61 memcpy(h->operator_name, buf+286, 32);
62 memcpy(h->study_description, buf+318, 32);
63 memcpy(h->facility_name, buf+356, 20);
64 memcpy(h->user_process_code, buf+462, 10);
65
66 /* Copy short ints; in big endian platform, change byte order */
67 if(!little) swabip(buf+50, 2);
68 memcpy(&h->data_type, buf+50, 2);
69 if(ECAT63_TEST>10) {printf("main_header.data_type=%d\n", h->data_type); fflush(stdout);}
70 if(h->data_type<1) {
71 if(ECAT63_TEST>1) {printf("invalid data_type; assuming VAX_I2\n"); fflush(stdout);}
73 }
74 if(h->data_type>4) vaxdata=0;
75
76 if(!little) swabip(buf+48, 2);
77 memcpy(&h->sw_version, buf+48, 2);
78 if(!little) swabip(buf+52, 2);
79 memcpy(&h->system_type, buf+52, 2);
80 if(!little) swabip(buf+54, 2);
81 memcpy(&h->file_type, buf+54, 2);
82 if(ECAT63_TEST>10) {printf("main_header.file_type=%d\n", h->file_type); fflush(stdout);}
83 if(!little) swabip(buf+66, 2);
84 memcpy(&h->scan_start_day, buf+66, 2);
85 if(!little) swabip(buf+68, 2);
86 memcpy(&h->scan_start_month, buf+68, 2);
87 if(!little) swabip(buf+70, 2);
88 memcpy(&h->scan_start_year, buf+70, 2);
89 if(!little) swabip(buf+72, 2);
90 memcpy(&h->scan_start_hour, buf+72, 2);
91 if(!little) swabip(buf+74, 2);
92 memcpy(&h->scan_start_minute, buf+74, 2);
93 if(!little) swabip(buf+76, 2);
94 memcpy(&h->scan_start_second, buf+76, 2);
95 if(!little) swabip(buf+134, 2);
96 memcpy(&h->rot_source_speed, buf+134, 2);
97 if(!little) swabip(buf+136, 2);
98 memcpy(&h->wobble_speed, buf+136, 2);
99 if(!little) swabip(buf+138, 2);
100 memcpy(&h->transm_source_type, buf+138, 2);
101 if(!little) swabip(buf+148, 2);
102 memcpy(&h->transaxial_samp_mode, buf+148, 2);
103 if(!little) swabip(buf+150, 2);
104 memcpy(&h->coin_samp_mode, buf+150, 2);
105 if(!little) swabip(buf+152, 2);
106 memcpy(&h->axial_samp_mode, buf+152, 2);
107 if(!little) swabip(buf+158, 2);
108 memcpy(&h->calibration_units, buf+158, 2);
109 if(!little) swabip(buf+160, 2);
110 memcpy(&h->compression_code, buf+160, 2);
111 if(!little) swabip(buf+350, 2);
112 memcpy(&h->acquisition_type, buf+350, 2);
113 if(!little) swabip(buf+352, 2);
114 memcpy(&h->bed_type, buf+352, 2);
115 if(!little) swabip(buf+354, 2);
116 memcpy(&h->septa_type, buf+354, 2);
117 if(!little) swabip(buf+376, 2);
118 memcpy(&h->num_planes, buf+376, 2);
119 if(!little) swabip(buf+378, 2);
120 memcpy(&h->num_frames, buf+378, 2);
121 if(!little) swabip(buf+380, 2);
122 memcpy(&h->num_gates, buf+380, 2);
123 if(!little) swabip(buf+382, 2);
124 memcpy(&h->num_bed_pos, buf+382, 2);
125 if(!little) swabip(buf+452, 2);
126 memcpy(&h->lwr_sctr_thres, buf+452, 2);
127 if(!little) swabip(buf+454, 2);
128 memcpy(&h->lwr_true_thres, buf+454, 2);
129 if(!little) swabip(buf+456, 2);
130 memcpy(&h->upr_true_thres, buf+456, 2);
131 if(!little) swabip(buf+472, 40);
132 memcpy(h->fill2, buf+472, 40);
133
134 /* Copy floats */
135 h->isotope_halflife=ecat63rFloat(buf+86, vaxdata, little);
136 h->gantry_tilt=ecat63rFloat(buf+122, vaxdata, little);
137 h->gantry_rotation=ecat63rFloat(buf+126, vaxdata, little);
138 h->bed_elevation=ecat63rFloat(buf+130, vaxdata, little);
139 h->axial_fov=ecat63rFloat(buf+140, vaxdata, little);
140 h->transaxial_fov=ecat63rFloat(buf+144, vaxdata, little);
141 h->calibration_factor=ecat63rFloat(buf+154, vaxdata, little);
142 h->init_bed_position=ecat63rFloat(buf+384, vaxdata, little);
143 for(int i=0; i<15; i++) h->bed_offset[i]=ecat63rFloat(buf+388+i*4, vaxdata, little);
144 h->plane_separation=ecat63rFloat(buf+448, vaxdata, little);
145 h->collimator=ecat63rFloat(buf+458, vaxdata, little);
146
147 /* Check file format and platform */
148 if(ECAT63_TEST>1) {printf("ecat_format='%.14s'\n", h->ecat_format); fflush(stdout);}
149 /* if format is not specified, ECAT63 is assumed */
150 if(h->ecat_format[0]==(char)0) {
151 strcpy(h->ecat_format, "ECAT63");
152 }
153 /* only ECAT63 format is approved here */
154 if(ECAT63_TEST>1) {printf("ecat_format='%.14s'\n", h->ecat_format); fflush(stdout);}
155 if(strncmp(h->ecat_format, "ECAT63", 6)!=0) return(3);
156
157 /* Check that most important contents are ok */
158 if(ECAT63_TEST>3) {
159 printf(" mhdr.data_type := %s\n", ecat63Datatype(h->data_type));
160 fflush(stdout);
161 }
162 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
163 if(ECAT63_TEST>1) {printf("Invalid data types; probable conversion error.\n"); fflush(stdout);}
164 return(5);
165 }
166 if(h->calibration_factor<0.0 || h->calibration_factor>1.0e12) {
167 if(ECAT63_TEST>1) {
168 printf("Invalid calibration factor; possible conversion error.\n"); fflush(stdout);}
169 return(6);
170 }
171 if(h->file_type!=RAW_DATA && h->file_type!=IMAGE_DATA &&
173 if(ECAT63_TEST>1) {printf("Invalid file types; probable conversion error.\n"); fflush(stdout);}
174 return(7);
175 }
176
177 return(0);
178}
179/*****************************************************************************/
180
181/*****************************************************************************/
189 FILE *fp,
191 int blk,
195 int verbose,
197 char *errmsg
198) {
199 unsigned char buf[MatBLKSIZE];
200 int little; /* 1 if current platform is little endian (i386), else 0 */
201 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
202
203 if(verbose>0) {printf("ecat63ReadImageheader(fp, %d ih)\n", blk); fflush(stdout);}
204 if(fp==NULL || blk<2 || h==NULL) {
205 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
206 if(verbose>0) {fprintf(stderr, "Invalid input.\n"); fflush(stderr);}
207 return(1);
208 }
209 little=little_endian();
210 /* Seek the subheader block */
211 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
212 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
213 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
214 if(verbose>0) {fprintf(stderr, "Failed to find block %d.\n", blk); fflush(stderr);}
215 return(2);
216 }
217 /* Read the subheader block */
218 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
219 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
220 if(verbose>0) {fprintf(stderr, "Failed to read block %d.\n", blk); fflush(stderr);}
221 return(3);
222 }
223
224 /* Copy char data to header structure */
225 memcpy(h->fill1, buf+0, 126); memcpy(h->annotation, buf+420, 40);
226
227 /* Copy short ints */
228 /* in big endian platform, change byte order temporarily */
229 if(!little) swabip(buf, MatBLKSIZE);
230 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
231 if(verbose>10) printf("data_type=%d\n", h->data_type);
232 memcpy(&h->num_dimensions, buf+128, 2);
233 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
234 memcpy(&h->image_min, buf+176, 2); memcpy(&h->image_max, buf+178, 2);
235 memcpy(&h->slice_location, buf+200, 2); memcpy(&h->recon_start_hour, buf+202, 2);
236 memcpy(&h->recon_start_min, buf+204, 2); memcpy(&h->recon_start_sec, buf+206, 2);
237 memcpy(&h->filter_code, buf+236, 2); memcpy(&h->processing_code, buf+376, 2);
238 memcpy(&h->quant_units, buf+380, 2); memcpy(&h->recon_start_day, buf+382, 2);
239 memcpy(&h->recon_start_month, buf+384, 2); memcpy(&h->recon_start_year, buf+386, 2);
240 memcpy(h->fill2, buf+460, 52);
241 /* Change back the byte order */
242 if(!little) swabip(buf, MatBLKSIZE);
243
244 /* Copy ints */
245 h->frame_duration=ecat63rInt(buf+192, vaxdata, little);
246 h->frame_start_time=ecat63rInt(buf+196, vaxdata, little);
247 h->recon_duration=ecat63rInt(buf+208, vaxdata, little);
248 h->scan_matrix_num=ecat63rInt(buf+238, vaxdata, little);
249 h->norm_matrix_num=ecat63rInt(buf+242, vaxdata, little);
250 h->atten_cor_mat_num=ecat63rInt(buf+246, vaxdata, little);
251
252 /* Copy floats */
253 h->x_origin=ecat63rFloat(buf+160, vaxdata, little);
254 h->y_origin=ecat63rFloat(buf+164, vaxdata, little);
255 h->recon_scale=ecat63rFloat(buf+168, vaxdata, little);
256 h->quant_scale=ecat63rFloat(buf+172, vaxdata, little);
257 h->pixel_size=ecat63rFloat(buf+184, vaxdata, little);
258 h->slice_width=ecat63rFloat(buf+188, vaxdata, little);
259 h->image_rotation=ecat63rFloat(buf+296, vaxdata, little);
260 h->plane_eff_corr_fctr=ecat63rFloat(buf+300, vaxdata, little);
261 h->decay_corr_fctr=ecat63rFloat(buf+304, vaxdata, little);
262 h->loss_corr_fctr=ecat63rFloat(buf+308, vaxdata, little);
263 h->intrinsic_tilt=ecat63rFloat(buf+312, vaxdata, little);
264 h->ecat_calibration_fctr=ecat63rFloat(buf+388, vaxdata, little);
265 h->well_counter_cal_fctr=ecat63rFloat(buf+392, vaxdata, little);
266 for(int i=0; i<6; i++) h->filter_params[i]=ecat63rFloat(buf+396+i*4, vaxdata, little);
267
268 /* Check that most important contents are ok */
269 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
270 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
271 if(verbose>0) {fprintf(stderr, "Invalid data types; probable conversion error.\n"); fflush(stderr);}
272 if(verbose>1) {printf("data_type := %d\n", h->data_type); fflush(stdout);}
273 return(4);
274 }
275 if(h->ecat_calibration_fctr<0.0 || h->ecat_calibration_fctr>1.0e10) {
276 if(errmsg!=NULL) strcpy(errmsg, "invalid calibration factor; probable conversion error");
277 if(verbose>0) {fprintf(stderr, "Invalid calibration factor; probable conversion error.\n"); fflush(stderr);}
278 return(5);
279 }
280 if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
281 if(errmsg!=NULL) strcpy(errmsg, "invalid frame duration; probable conversion error");
282 if(verbose>0) {fprintf(stderr, "Invalid frame duration; probable conversion error.\n"); fflush(stderr);}
283 return(6);
284 }
285 if(errmsg!=NULL) strcpy(errmsg, "ok");
286
287 return(0);
288}
289/*****************************************************************************/
290
291/*****************************************************************************/
298 FILE *fp,
300 int blk,
304 int verbose,
306 char *errmsg
307) {
308 unsigned char buf[MatBLKSIZE];
309 int little; /* 1 if current platform is little endian (i386), else 0 */
310 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
311
312 if(ECAT63_TEST) printf("ecat63ReadAttnheader(fp, %d, ah)\n", blk);
313 if(fp==NULL || blk<2 || h==NULL) {
314 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
315 if(verbose>0) fprintf(stderr, "Invalid input.\n");
316 return(1);
317 }
318 little=little_endian();
319 /* Seek the subheader block */
320 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
321 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
322 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
323 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
324 return(2);
325 }
326 /* Read the subheader block */
327 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
328 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
329 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
330 return(3);
331 }
332
333 /* Copy short ints */
334 /* in big endian platform, change byte order temporarily */
335 if(!little) swabip(buf, MatBLKSIZE);
336 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
337 /*printf("data_type=%d\n", h->data_type);*/
338 memcpy(&h->attenuation_type, buf+128, 2);
339 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
340 /* Change back the byte order */
341 if(!little) swabip(buf, MatBLKSIZE);
342
343 /* Copy floats */
344 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
345 h->x_origin=ecat63rFloat(buf+186, vaxdata, little);
346 h->y_origin=ecat63rFloat(buf+190, vaxdata, little);
347 h->x_radius=ecat63rFloat(buf+194, vaxdata, little);
348 h->y_radius=ecat63rFloat(buf+198, vaxdata, little);
349 h->tilt_angle=ecat63rFloat(buf+202, vaxdata, little);
350 h->attenuation_coeff=ecat63rFloat(buf+206, vaxdata, little);
351 h->sample_distance=ecat63rFloat(buf+210, vaxdata, little);
352
353 /* Check that most important contents are ok */
354 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
355 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
356 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
357 if(verbose>1) printf("data_type := %d\n", h->data_type);
358 return(4);
359 }
360 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
361 if(errmsg!=NULL) strcpy(errmsg, "invalid scale factor; probable conversion error");
362 if(verbose>0) fprintf(stderr, "Invalid scale factor; probable conversion error.\n");
363 return(5);
364 }
365 if(errmsg!=NULL) strcpy(errmsg, "ok");
366
367 return(0);
368}
369/*****************************************************************************/
370
371/*****************************************************************************/
379 FILE *fp,
381 int blk,
385 int verbose,
387 char *errmsg
388) {
389 unsigned char buf[MatBLKSIZE];
390 int little; /* 1 if current platform is little endian (i386), else 0 */
391 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
392
393 if(ECAT63_TEST) printf("ecat63ReadScanheader(fp, %d, sh)\n", blk);
394 if(fp==NULL || blk<2 || h==NULL) {
395 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
396 if(verbose>0) fprintf(stderr, "Invalid input.\n");
397 return(1);
398 }
399 little=little_endian();
400 /* Seek the subheader block */
401 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
402 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
403 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
404 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
405 return(2);
406 }
407 /* Read the subheader block */
408 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
409 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
410 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
411 return(3);
412 }
413
414 /* Copy char data to header structure */
415 memcpy(h->fill1, buf+0, 126);
416
417 /* Copy short ints */
418 /* in big endian platform, change byte order temporarily */
419 if(!little) swabip(buf, MatBLKSIZE);
420 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
421 /*printf("data_type=%d\n", h->data_type);*/
422 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
423 memcpy(&h->smoothing, buf+136, 2); memcpy(&h->processing_code, buf+138, 2);
424 memcpy(&h->frame_duration_sec, buf+170, 2);
425 memcpy(&h->scan_min, buf+192, 2); memcpy(&h->scan_max, buf+194, 2);
426 memcpy(h->fill2, buf+468, 44);
427 /* Change back the byte order */
428 if(!little) swabip(buf, MatBLKSIZE);
429
430 /* Copy ints */
431 h->gate_duration=ecat63rInt(buf+172, vaxdata, little);
432 h->r_wave_offset=ecat63rInt(buf+176, vaxdata, little);
433 h->prompts=ecat63rInt(buf+196, vaxdata, little);
434 h->delayed=ecat63rInt(buf+200, vaxdata, little);
435 h->multiples=ecat63rInt(buf+204, vaxdata, little);
436 h->net_trues=ecat63rInt(buf+208, vaxdata, little);
437 h->total_coin_rate=ecat63rInt(buf+452, vaxdata, little);
438 h->frame_start_time=ecat63rInt(buf+456, vaxdata, little);
439 h->frame_duration=ecat63rInt(buf+460, vaxdata, little);
440
441 /* Copy floats */
442 h->sample_distance=ecat63rFloat(buf+146, vaxdata, little);
443 h->isotope_halflife=ecat63rFloat(buf+166, vaxdata, little);
444 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
445 for(int i=0; i<16; i++) h->cor_singles[i]=ecat63rFloat(buf+316+i*4, vaxdata, little);
446 for(int i=0; i<16; i++) h->uncor_singles[i]=ecat63rFloat(buf+380+i*4, vaxdata, little);
447 h->tot_avg_cor=ecat63rFloat(buf+444, vaxdata, little);
448 h->tot_avg_uncor=ecat63rFloat(buf+448, vaxdata, little);
449 h->loss_correction_fctr=ecat63rFloat(buf+464, vaxdata, little);
450
451 /* Check that most important contents are ok */
452 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
453 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
454 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
455 if(verbose>1) printf("data_type := %d\n", h->data_type);
456 return(4);
457 }
458 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
459 if(errmsg!=NULL) strcpy(errmsg, "invalid calibration factor; probable conversion error");
460 if(verbose>0) fprintf(stderr, "Invalid calibration factor; probable conversion error.\n");
461 return(5);
462 }
463 if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
464 if(errmsg!=NULL) strcpy(errmsg, "invalid frame duration; probable conversion error");
465 if(verbose>0) fprintf(stderr, "Invalid frame duration; probable conversion error.\n");
466 return(6);
467 }
468 if(errmsg!=NULL) strcpy(errmsg, "ok");
469
470 return(0);
471}
472/*****************************************************************************/
473
474/*****************************************************************************/
485 FILE *fp,
487 int blk,
491 int verbose,
493 char *errmsg
494) {
495 unsigned char buf[MatBLKSIZE];
496 int little; /* 1 if current platform is little endian (i386), else 0 */
497 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
498
499 if(ECAT63_TEST) printf("ecat63ReadNormheader(fp, %d, nh)\n", blk);
500 if(fp==NULL || blk<2 || h==NULL) {
501 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
502 if(verbose>0) fprintf(stderr, "Invalid input.\n");
503 return(1);
504 }
505 little=little_endian();
506 /* Seek the subheader block */
507 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
508 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
509 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
510 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
511 return(2);
512 }
513 /* Read the subheader block */
514 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
515 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
516 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
517 return(3);
518 }
519
520 /* Copy short ints */
521 /* in big endian platform, change byte order temporarily */
522 if(!little) swabip(buf, MatBLKSIZE);
523 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
524 if(verbose>10) printf("data_type=%d\n", h->data_type);
525 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
526 memcpy(&h->norm_hour, buf+186, 2); memcpy(&h->norm_minute, buf+188, 2);
527 memcpy(&h->norm_second, buf+190, 2); memcpy(&h->norm_day, buf+192, 2);
528 memcpy(&h->norm_month, buf+194, 2); memcpy(&h->norm_year, buf+196, 2);
529 /* Change back the byte order */
530 if(!little) swabip(buf, MatBLKSIZE);
531
532 /* Copy floats */
533 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
534 h->fov_source_width=ecat63rFloat(buf+198, vaxdata, little);
535
536 /* Check that most important contents are ok */
537 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
538 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
539 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
540 if(verbose>1) printf("data_type := %d\n", h->data_type);
541 return(4);
542 }
543 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
544 if(errmsg!=NULL) strcpy(errmsg, "invalid scale factor; probable conversion error");
545 if(verbose>0) fprintf(stderr, "Invalid scale factor; probable conversion error.\n");
546 return(5);
547 }
548 if(errmsg!=NULL) strcpy(errmsg, "ok");
549
550 return(0);
551}
552/*****************************************************************************/
553
554/*****************************************************************************/
568int ecat63ReadMatdata(FILE *fp, int strtblk, int blkNr, char *data, int dtype) {
569 int n, little, err=0;
570 char *cptr;
571 float f;
572
573
574 if(ECAT63_TEST) printf("ecat63ReadMatdata(fp, %d, %d, data, %d)\n", strtblk, blkNr, dtype);
575 /* Check the arguments */
576 if(blkNr<=0 || strtblk<1 || data==NULL) return(1);
577 /* Seek the first data block */
578 fseeko(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET);
579 if(ftello(fp)!=(strtblk-1)*MatBLKSIZE) return(9);
580 /* Read the data blocks */
581 if(fread(data, MatBLKSIZE, blkNr, fp) < (unsigned int)blkNr) return(2);
582 /* Translate data if necessary */
583 little=little_endian();
584 switch(dtype) {
585 case BYTE_TYPE: /* byte format...no translation necessary */
586 break;
587 case VAX_I2: /* byte conversion necessary on big endian platform */
588 if(!little) {cptr=data; swabip(cptr, blkNr*MatBLKSIZE);}
589 break;
590 case VAX_I4:
591 cptr=data;
592 for(long long int i=0; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
593 n=ecat63rInt(cptr, 1, little); memcpy(cptr, &n, 4);
594 }
595 break;
596 case VAX_R4:
597 cptr=data;
598 for(long long i=0; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
599 f=ecat63rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
600 }
601 break;
602 case IEEE_R4: /* IEEE float ; byte conversion necessary on big end platforms */
603 case SUN_I4: /* SUN int ; byte conversion necessary on big end platforms */
604 if(!little) swawbip(data, blkNr*MatBLKSIZE);
605 break;
606 case SUN_I2: /* SUN short ; byte conversion necessary on big end platforms */
607 if(!little) swabip(data, blkNr*MatBLKSIZE);
608 break;
609 default: /* if something else, for now think it as an error */
610 err=2;
611 break;
612 }
613 return(err);
614}
615/*****************************************************************************/
616
617/*****************************************************************************/
629 FILE *fp,
631 int first_block,
633 int last_block,
638 float **fdata
639) {
640 int ret, blockNr;
641 char *mdata, *mptr, errmsg[128];
642 float *_fdata, *fptr;
643 short int *sptr;
644 int *iptr;
645
646
647 if(ECAT63_TEST) printf("ecat63ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
648 first_block, last_block);
649 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
650 sprintf(ecat63errmsg, "invalid function parameter.\n");
651 return(1);
652 }
653 *fdata=(float*)NULL;
654
655 /* Read subheader */
656 ret=ecat63ReadImageheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
657 if(ret) {
658 strcpy(ecat63errmsg, errmsg);
659 return(5);
660 }
661 if(ECAT63_TEST>4) ecat63PrintImageheader(h, stdout);
662 long long pxlNr=h->dimension_1*h->dimension_2;
663 if(pxlNr<=0) {
664 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
665 return(6);
666 }
667
668 /* Read matrix data */
669 blockNr=last_block-first_block; if(blockNr<1) return(0);
670 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
671 if(mdata==NULL) {
672 sprintf(ecat63errmsg, "cannot allocate memory.\n");
673 return(8);
674 }
675 mptr=mdata;
676 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
677 if(ret || mdata==NULL) {
678 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
679 free(mdata); return(9);
680 }
681
682 /* Allocate memory for float data */
683 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
684 if(_fdata==NULL) {
685 sprintf(ecat63errmsg, "cannot allocate memory.\n");
686 free(mdata); return(11);
687 }
688
689 /* Convert matrix data to floats */
691 fptr=_fdata; mptr=mdata;
692 if(h->data_type==BYTE_TYPE) {
693 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
694 *fptr=h->quant_scale*(float)(*mptr);
695 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
696 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
697 sptr=(short int*)mptr;
698 *fptr=h->quant_scale*(float)(*sptr);
699 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
700 }
701 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
702 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
703 iptr=(int*)mptr;
704 *fptr=h->quant_scale*(float)(*iptr);
705 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
706 }
707 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
708 memcpy(fptr, mptr, pxlNr*4);
709 for(long long i=0; i<pxlNr; i++, fptr++) {
710 *fptr *= h->quant_scale;
711 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
712 }
713 }
714 free(mdata);
715 *fdata=_fdata;
716
717 return(0);
718}
719/*****************************************************************************/
720
721/*****************************************************************************/
733 FILE *fp,
735 int first_block,
737 int last_block,
743 float **fdata
744) {
745 int ret, blockNr;
746 char *mdata, *mptr, errmsg[128];
747 float *_fdata, *fptr;
748 short int *sptr;
749 int *iptr;
750
751
752 if(ECAT63_TEST) printf("ecat63ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
753 first_block, last_block);
754 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
755 sprintf(ecat63errmsg, "invalid function parameter.\n");
756 return(1);
757 }
758 *fdata=(float*)NULL;
759
760 /* Read subheader */
761 ret=ecat63ReadScanheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
762 if(ret) {
763 strcpy(ecat63errmsg, errmsg);
764 return(5);
765 }
766 if(ECAT63_TEST>4) ecat63PrintScanheader(h, stdout);
767 long long pxlNr=h->dimension_1*h->dimension_2;
768 if(pxlNr<=0) {
769 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
770 return(6);
771 }
772
773 /* Read matrix data */
774 blockNr=last_block-first_block; if(blockNr<1) return(0);
775 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
776 if(mdata==NULL) {
777 sprintf(ecat63errmsg, "cannot allocate memory.\n");
778 return(8);
779 }
780 mptr=mdata;
781 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
782 if(ret || mdata==NULL) {
783 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
784 free(mdata); return(9);
785 }
786
787 /* Allocate memory for float data */
788 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
789 if(_fdata==NULL) {
790 sprintf(ecat63errmsg, "cannot allocate memory.\n");
791 free(mdata); return(11);
792 }
793
794 /* Convert matrix data to floats */
795 fptr=_fdata; mptr=mdata;
796 if(h->data_type==BYTE_TYPE) {
797 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
798 *fptr=h->scale_factor*(float)(*mptr);
799 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
800 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
801 sptr=(short int*)mptr;
802 *fptr=h->scale_factor*(float)(*sptr);
803 }
804 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
805 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
806 iptr=(int*)mptr;
807 *fptr=h->scale_factor*(float)(*iptr);
808 }
809 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
810 memcpy(fptr, mptr, pxlNr*4);
811 for(long long i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
812 }
813 free(mdata);
814 *fdata=_fdata;
815
816 return(0);
817}
818/*****************************************************************************/
819
820/*****************************************************************************/
832 FILE *fp,
834 int first_block,
836 int last_block,
842 float **fdata
843) {
844 int ret, blockNr;
845 char *mdata, *mptr, errmsg[128];
846 float *_fdata, *fptr;
847 short int *sptr;
848 int *iptr;
849
850
851 if(ECAT63_TEST) printf("ecat63ReadAttnMatrix(fp, %d, %d, hdr, fdata)\n",
852 first_block, last_block);
853 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
854 sprintf(ecat63errmsg, "invalid function parameter.\n");
855 return(1);
856 }
857 *fdata=(float*)NULL;
858
859 /* Read subheader */
860 ret=ecat63ReadAttnheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
861 if(ret) {
862 strcpy(ecat63errmsg, errmsg);
863 return(5);
864 }
865 if(ECAT63_TEST>4) ecat63PrintAttnheader(h, stdout);
866 long long pxlNr=h->dimension_1*h->dimension_2;
867 if(pxlNr<=0) {
868 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
869 return(6);
870 }
871
872 /* Read matrix data */
873 blockNr=last_block-first_block; if(blockNr<1) return(0);
874 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
875 if(mdata==NULL) {
876 sprintf(ecat63errmsg, "cannot allocate memory.\n");
877 return(8);
878 }
879 mptr=mdata;
880 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
881 if(ret || mdata==NULL) {
882 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
883 free(mdata); return(9);
884 }
885
886 /* Allocate memory for float data */
887 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
888 if(_fdata==NULL) {
889 sprintf(ecat63errmsg, "cannot allocate memory.\n");
890 free(mdata); return(11);
891 }
892
893 /* Convert matrix data to floats */
894 fptr=_fdata; mptr=mdata;
895 if(h->data_type==BYTE_TYPE) {
896 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
897 *fptr=h->scale_factor*(float)(*mptr);
898 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
899 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
900 sptr=(short int*)mptr;
901 *fptr=h->scale_factor*(float)(*sptr);
902 }
903 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
904 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
905 iptr=(int*)mptr;
906 *fptr=h->scale_factor*(float)(*iptr);
907 }
908 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
909 memcpy(fptr, mptr, pxlNr*4);
910 for(long long i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
911 }
912 free(mdata);
913 *fdata=_fdata;
914
915 return(0);
916}
917/*****************************************************************************/
918
919/*****************************************************************************/
929void *bufi, int isvax, int islittle
930) {
931 union {unsigned int ul; float f;} t;
932
933 memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
934 if(isvax) { /* if input is in VAX format */
935 /* Swap words on i386 and bytes on SUN */
936 if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
937 t.ul-=(2L<<23); /* subtract 2 from exp */
938 } else { /* input is in i386 format */
939 if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
940 }
941 return(t.f);
942}
943
954void *bufi, int isvax, int islittle
955) {
956 int i;
957
958 if(isvax==0) {} // just to prevent compiler warning
959 /* Swap both words and bytes on SUN */
960 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
961 return(i);
962}
963/*****************************************************************************/
964
965/*****************************************************************************/
974 short int data_type
975) {
976 int byteNr=0;
977 switch(data_type) {
978 case BYTE_TYPE: byteNr=1; break;
979 case VAX_I2:
980 case SUN_I2: byteNr=2; break;
981 case VAX_I4:
982 case VAX_R4:
983 case IEEE_R4:
984 case SUN_I4: byteNr=4; break;
985 }
986 return(byteNr);
987}
988/*****************************************************************************/
989
990/*****************************************************************************/
char ecat63errmsg[128]
Definition ecat63h.c:7
int ECAT63_TEST
Definition ecat63h.c:6
char * ecat63Datatype(short int dtype)
Definition ecat63p.c:218
void ecat63PrintImageheader(ECAT63_imageheader *h, FILE *fp)
Definition ecat63p.c:94
void ecat63PrintScanheader(ECAT63_scanheader *h, FILE *fp)
Definition ecat63p.c:137
void ecat63PrintAttnheader(ECAT63_attnheader *h, FILE *fp)
Definition ecat63p.c:173
float ecat63rFloat(void *bufi, int isvax, int islittle)
Definition ecat63r.c:928
int ecat63rInt(void *bufi, int isvax, int islittle)
Definition ecat63r.c:953
int ecat63ReadNormheader(FILE *fp, int blk, ECAT63_normheader *h, int verbose, char *errmsg)
Definition ecat63r.c:483
int ecat63ReadScanheader(FILE *fp, int blk, ECAT63_scanheader *h, int verbose, char *errmsg)
Definition ecat63r.c:377
int ecat63ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT63_imageheader *h, float **fdata)
Definition ecat63r.c:627
int ecat63ReadMatdata(FILE *fp, int strtblk, int blkNr, char *data, int dtype)
Definition ecat63r.c:568
int ecat63ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT63_scanheader *h, float **fdata)
Definition ecat63r.c:731
int ecat63ReadAttnMatrix(FILE *fp, int first_block, int last_block, ECAT63_attnheader *h, float **fdata)
Definition ecat63r.c:830
int ecat63ReadAttnheader(FILE *fp, int blk, ECAT63_attnheader *h, int verbose, char *errmsg)
Definition ecat63r.c:296
int ecat63ReadImageheader(FILE *fp, int blk, ECAT63_imageheader *h, int verbose, char *errmsg)
Definition ecat63r.c:187
int ecat63pxlbytes(short int data_type)
Definition ecat63r.c:973
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63r.c:25
Header file for libtpcimgio.
#define MatFirstDirBlk
#define SUN_I4
#define ATTN_DATA
#define VAX_R4
#define IEEE_R4
#define RAW_DATA
#define BYTE_TYPE
#define VAX_I4
#define NORM_DATA
#define IMAGE_DATA
#define VAX_I2
#define MatBLKSIZE
#define SUN_I2
void swawip(void *buf, long long int size)
Definition swap.c:114
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
short int dimension_1
short int dimension_2
short int attenuation_type
short int recon_start_month
short int fill2[26]
short int recon_start_day
short int slice_location
short int processing_code
short int recon_start_min
short int recon_start_year
short int num_dimensions
short int recon_start_hour
short int recon_start_sec
char radiopharmaceutical[32]
short int scan_start_month
short int coin_samp_mode
short int lwr_true_thres
short int compression_code
char patient_height[10]
short int fill2[20]
short int wobble_speed
short int scan_start_second
short int num_bed_pos
short int transaxial_samp_mode
short int rot_source_speed
short int acquisition_type
short int calibration_units
short int scan_start_year
char original_file_name[20]
char study_description[32]
short int scan_start_day
short int transm_source_type
short int scan_start_minute
char user_process_code[10]
char patient_weight[10]
short int lwr_sctr_thres
short int axial_samp_mode
short int scan_start_hour
short int upr_true_thres
char physician_name[32]
short int system_type
short int dimension_1
short int norm_second
short int dimension_2
short int norm_minute
short int dimension_2
float uncor_singles[16]
short int processing_code
short int fill2[22]
short int dimension_1
short int frame_duration_sec
float cor_singles[16]