TPCCLIB
Loading...
Searching...
No Matches
ecat63w.c
Go to the documentation of this file.
1
11/*****************************************************************************/
12#include "libtpcimgio.h"
13/*****************************************************************************/
14
15/*****************************************************************************/
25 FILE *fp, ECAT63_mainheader *h
26) {
27 char buf[MatBLKSIZE];
28 int little, tovax;
29
30
31 if(ECAT63_TEST) printf("ecat63WriteMainheader()\n");
32 little=little_endian();
33 /* Clear buf */
34 memset(buf, 0, MatBLKSIZE);
35 /* Check arguments */
36 if(fp==NULL || h->data_type<1 || h->data_type>7) return(1);
37 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
38 tovax=1; else tovax=0;
39
40 /* Copy short ints to buf */
41 memcpy(buf+50, &h->data_type, 2); memcpy(buf+48, &h->sw_version, 2);
42 memcpy(buf+52, &h->system_type, 2); memcpy(buf+54, &h->file_type, 2);
43 memcpy(buf+66, &h->scan_start_day, 2); memcpy(buf+68, &h->scan_start_month, 2);
44 memcpy(buf+70, &h->scan_start_year, 2); memcpy(buf+72, &h->scan_start_hour, 2);
45 memcpy(buf+74, &h->scan_start_minute, 2);
46 memcpy(buf+76, &h->scan_start_second, 2);
47 memcpy(buf+134, &h->rot_source_speed, 2); memcpy(buf+136, &h->wobble_speed, 2);
48 memcpy(buf+138, &h->transm_source_type, 2);
49 memcpy(buf+148, &h->transaxial_samp_mode, 2);
50 memcpy(buf+150, &h->coin_samp_mode, 2); memcpy(buf+152, &h->axial_samp_mode, 2);
51 memcpy(buf+158, &h->calibration_units, 2);
52 memcpy(buf+160, &h->compression_code, 2);
53 memcpy(buf+350, &h->acquisition_type, 2); memcpy(buf+352, &h->bed_type, 2);
54 memcpy(buf+354, &h->septa_type, 2); memcpy(buf+376, &h->num_planes, 2);
55 memcpy(buf+378, &h->num_frames, 2); memcpy(buf+380, &h->num_gates, 2);
56 memcpy(buf+382, &h->num_bed_pos, 2); memcpy(buf+452, &h->lwr_sctr_thres, 2);
57 memcpy(buf+454, &h->lwr_true_thres, 2); memcpy(buf+456, &h->upr_true_thres, 2);
58 memcpy(buf+472, h->fill2, 40);
59 /* big to little endian if necessary */
60 if(!little) swabip(buf, MatBLKSIZE);
61
62 /* Copy floats to buf */
63 ecat63wFloat(&h->isotope_halflife, buf+86, tovax, little);
64 ecat63wFloat(&h->gantry_tilt, buf+122, tovax, little);
65 ecat63wFloat(&h->gantry_rotation, buf+126, tovax, little);
66 ecat63wFloat(&h->bed_elevation, buf+130, tovax, little);
67 ecat63wFloat(&h->axial_fov, buf+140, tovax, little);
68 ecat63wFloat(&h->transaxial_fov, buf+144, tovax, little);
69 ecat63wFloat(&h->calibration_factor, buf+154, tovax, little);
70 ecat63wFloat(&h->init_bed_position, buf+384, tovax, little);
71 for(int i=0; i<15; i++) ecat63wFloat(&h->bed_offset[i], buf+388+4*i, tovax, little);
72 ecat63wFloat(&h->plane_separation, buf+448, tovax, little);
73 ecat63wFloat(&h->init_bed_position, buf+458, tovax, little);
74
75 /* Copy chars */
76 /*memcpy(buf+0, h->ecat_format, 14);*/
77 memcpy(buf+14, h->fill1, 14);
78 memcpy(buf+28, h->original_file_name, 20); memcpy(buf+56, h->node_id, 10);
79 memcpy(buf+78, h->isotope_code, 8); memcpy(buf+90, h->radiopharmaceutical, 32);
80 memcpy(buf+162, h->study_name, 12); memcpy(buf+174, h->patient_id, 16);
81 memcpy(buf+190, h->patient_name, 32); buf[222]=h->patient_sex;
82 memcpy(buf+223, h->patient_age, 10); memcpy(buf+233, h->patient_height, 10);
83 memcpy(buf+243, h->patient_weight, 10); buf[253]=h->patient_dexterity;
84 memcpy(buf+254, h->physician_name, 32); memcpy(buf+286, h->operator_name, 32);
85 memcpy(buf+318, h->study_description, 32); memcpy(buf+356, h->facility_name, 20);
86 memcpy(buf+462, h->user_process_code, 10);
87
88 /* Write main header */
89 fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(2);
90 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
91
92 return(0);
93}
94/*****************************************************************************/
95
96/*****************************************************************************/
107 FILE *fp, int block, ECAT63_imageheader *h
108) {
109 char buf[MatBLKSIZE];
110 int little, tovax;
111
112
113 if(ECAT63_TEST) printf("ecat63WriteImageheader(fp, %d, ih)\n", block);
114 little=little_endian();
115 /* Clear buf */
116 memset(buf, 0, MatBLKSIZE);
117 /* Check arguments */
118 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
119 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
120 tovax=1; else tovax=0;
121
122 /* Copy short ints to buf */
123 memcpy(buf+126, &h->data_type, 2);
124 memcpy(buf+128, &h->num_dimensions, 2);
125 memcpy(buf+132, &h->dimension_1, 2);
126 memcpy(buf+134, &h->dimension_2, 2);
127 memcpy(buf+176, &h->image_min, 2);
128 memcpy(buf+178, &h->image_max, 2);
129 memcpy(buf+200, &h->slice_location, 2);
130 memcpy(buf+202, &h->recon_start_hour, 2);
131 memcpy(buf+204, &h->recon_start_min, 2);
132 memcpy(buf+206, &h->recon_start_sec, 2);
133 memcpy(buf+236, &h->filter_code, 2);
134 memcpy(buf+376, &h->processing_code, 2);
135 memcpy(buf+380, &h->quant_units, 2);
136 memcpy(buf+382, &h->recon_start_day, 2);
137 memcpy(buf+384, &h->recon_start_month, 2);
138 memcpy(buf+386, &h->recon_start_year, 2);
139 memcpy(buf+460, h->fill2, 52);
140 /* big to little endian if necessary */
141 if(!little) swabip(buf, MatBLKSIZE);
142
143 /* Copy floats to buf */
144 ecat63wFloat(&h->x_origin, buf+160, tovax, little);
145 ecat63wFloat(&h->y_origin, buf+164, tovax, little);
146 ecat63wFloat(&h->recon_scale, buf+168, tovax, little);
147 ecat63wFloat(&h->quant_scale, buf+172, tovax, little);
148 ecat63wFloat(&h->pixel_size, buf+184, tovax, little);
149 ecat63wFloat(&h->slice_width, buf+188, tovax, little);
150 ecat63wFloat(&h->image_rotation, buf+296, tovax, little);
151 ecat63wFloat(&h->plane_eff_corr_fctr, buf+300, tovax, little);
152 ecat63wFloat(&h->decay_corr_fctr, buf+304, tovax, little);
153 ecat63wFloat(&h->loss_corr_fctr, buf+308, tovax, little);
154 ecat63wFloat(&h->intrinsic_tilt, buf+312, tovax, little);
155 ecat63wFloat(&h->ecat_calibration_fctr, buf+388, tovax, little);
156 ecat63wFloat(&h->well_counter_cal_fctr, buf+392, tovax, little);
157 for(int i=0; i<6; i++)
158 ecat63wFloat(&h->filter_params[i], buf+396+4*i, tovax, little);
159
160 /* Copy ints to buf */
161 ecat63wInt(&h->frame_duration, buf+192, tovax, little);
162 ecat63wInt(&h->frame_start_time, buf+196, tovax, little);
163 ecat63wInt(&h->scan_matrix_num, buf+238, tovax, little);
164 ecat63wInt(&h->norm_matrix_num, buf+242, tovax, little);
165 ecat63wInt(&h->atten_cor_mat_num, buf+246, tovax, little);
166
167 /* Copy chars */
168 memcpy(buf+0, h->fill1, 126);
169 memcpy(buf+420, h->annotation, 40);
170
171 /* Write subheader */
172 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
173 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
174 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
175
176 return(0);
177}
178/*****************************************************************************/
179
180/*****************************************************************************/
191 FILE *fp, int block, ECAT63_attnheader *h
192) {
193 unsigned char buf[MatBLKSIZE];
194 int little, tovax;
195
196 if(ECAT63_TEST) printf("ecat63WriteAttnheader(fp, %d, ah)\n", block);
197 little=little_endian();
198 /* Clear buf */
199 memset(buf, 0, MatBLKSIZE);
200 /* Check arguments */
201 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
202 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
203 tovax=1; else tovax=0;
204
205 /* Copy short ints to buf */
206 memcpy(buf+126, &h->data_type, 2);
207 memcpy(buf+128, &h->attenuation_type, 2);
208 memcpy(buf+132, &h->dimension_1, 2);
209 memcpy(buf+134, &h->dimension_2, 2);
210 /* big to little endian if necessary */
211 if(!little) swabip(buf, MatBLKSIZE);
212
213 /* Copy floats to buf */
214 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
215 ecat63wFloat(&h->x_origin, buf+186, tovax, little);
216 ecat63wFloat(&h->y_origin, buf+190, tovax, little);
217 ecat63wFloat(&h->x_radius, buf+194, tovax, little);
218 ecat63wFloat(&h->y_radius, buf+198, tovax, little);
219 ecat63wFloat(&h->tilt_angle, buf+202, tovax, little);
220 ecat63wFloat(&h->attenuation_coeff, buf+206, tovax, little);
221 ecat63wFloat(&h->sample_distance, buf+210, tovax, little);
222
223 /* Write subheader */
224 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
225 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
226 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
227
228 return(0);
229}
230/*****************************************************************************/
231
232/*****************************************************************************/
243 FILE *fp, int block, ECAT63_scanheader *h
244) {
245 unsigned char buf[MatBLKSIZE];
246 int little, tovax;
247
248
249 if(ECAT63_TEST) printf("ecat63WriteScanheader(fp, %d, ih)\n", block);
250 little=little_endian();
251 /* Clear buf */
252 memset(buf, 0, MatBLKSIZE);
253 /* Check arguments */
254 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
255 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
256 tovax=1; else tovax=0;
257
258 /* Copy short ints to buf */
259 memcpy(buf+126, &h->data_type, 2);
260 memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
261 memcpy(buf+136, &h->smoothing, 2); memcpy(buf+138, &h->processing_code, 2);
262 memcpy(buf+170, &h->frame_duration_sec, 2);
263 memcpy(buf+192, &h->scan_min, 2); memcpy(buf+194, &h->scan_max, 2);
264 memcpy(buf+468, h->fill2, 44);
265 /* big to little endian if necessary */
266 if(!little) swabip(buf, MatBLKSIZE);
267
268 /* Copy floats to buf */
269 ecat63wFloat(&h->sample_distance, buf+146, tovax, little);
270 ecat63wFloat(&h->isotope_halflife, buf+166, tovax, little);
271 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
272 for(int i=0; i<16; i++) {
273 ecat63wFloat(&h->cor_singles[i], buf+316+4*i, tovax, little);
274 ecat63wFloat(&h->uncor_singles[i], buf+380+4*i, tovax, little);
275 }
276 ecat63wFloat(&h->tot_avg_cor, buf+444, tovax, little);
277 ecat63wFloat(&h->tot_avg_uncor, buf+448, tovax, little);
278 ecat63wFloat(&h->loss_correction_fctr, buf+464, tovax, little);
279
280 /* Copy ints to buf */
281 ecat63wInt(&h->gate_duration, buf+172, tovax, little);
282 ecat63wInt(&h->r_wave_offset, buf+176, tovax, little);
283 ecat63wInt(&h->prompts, buf+196, tovax, little);
284 ecat63wInt(&h->delayed, buf+200, tovax, little);
285 ecat63wInt(&h->multiples, buf+204, tovax, little);
286 ecat63wInt(&h->net_trues, buf+208, tovax, little);
287 ecat63wInt(&h->total_coin_rate, buf+452, tovax, little);
288 ecat63wInt(&h->frame_start_time, buf+456, tovax, little);
289 ecat63wInt(&h->frame_duration, buf+460, tovax, little);
290
291 /* Copy chars */
292 memcpy(buf+0, h->fill1, 126);
293
294 /* Write subheader */
295 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
296 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
297 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
298
299 return(0);
300}
301/*****************************************************************************/
302
303/*****************************************************************************/
314 FILE *fp, int block, ECAT63_normheader *h
315) {
316 unsigned char buf[MatBLKSIZE];
317 int little, tovax;
318
319 if(ECAT63_TEST) printf("ecat63WriteNormheader(fp, %d, nh)\n", block);
320 little=little_endian();
321 /* Clear buf */
322 memset(buf, 0, MatBLKSIZE);
323 /* Check arguments */
324 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
325 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
326 tovax=1; else tovax=0;
327
328 /* Copy short ints to buf */
329 memcpy(buf+126, &h->data_type, 2);
330 memcpy(buf+132, &h->dimension_1, 2);
331 memcpy(buf+134, &h->dimension_2, 2);
332 memcpy(buf+372, &h->norm_hour, 2);
333 memcpy(buf+376, &h->norm_minute, 2);
334 memcpy(buf+380, &h->norm_second, 2);
335 memcpy(buf+384, &h->norm_day, 2);
336 memcpy(buf+388, &h->norm_month, 2);
337 memcpy(buf+392, &h->norm_year, 2);
338 /* big to little endian if necessary */
339 if(!little) swabip(buf, MatBLKSIZE);
340
341 /* Copy floats to buf */
342 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
343 ecat63wFloat(&h->fov_source_width, buf+198, tovax, little);
344
345 /* Write subheader */
346 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
347 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
348 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
349
350 return(0);
351}
352/*****************************************************************************/
353
354/*****************************************************************************/
366 const char *fname, ECAT63_mainheader *h
367) {
368 FILE *fp;
369 char tmp[FILENAME_MAX];
370 int buf[MatBLKSIZE/4];
371
372 if(ECAT63_TEST) printf("ecat63Create()\n");
373 /* Check the arguments */
374 if(fname==NULL || h==NULL) return(NULL);
375 /* Check if file exists; backup, if necessary */
376 if(access(fname, 0) != -1) {
377 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
378 if(access(tmp, 0) != -1) remove(tmp);
379 if(ECAT63_TEST) printf("Renaming %s -> %s\n", fname, tmp);
380 rename(fname, tmp);
381 }
382 /* Open file */
383 fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
384 /* Write main header */
385 if(ecat63WriteMainheader(fp, h)) return(NULL);
386 /* Construct an empty matrix list ; convert to little endian if necessary */
387 memset(buf, 0, MatBLKSIZE);
388 buf[0]=31; buf[1]=2; if(!little_endian()) swawbip(buf, MatBLKSIZE);
389 /* Write data buffer */
390 fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
391 if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
392 if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
393 /* OK, then return file pointer */
394 return(fp);
395}
396/*****************************************************************************/
397
398/*****************************************************************************/
411 FILE *fp, int matnum, ECAT63_imageheader *h, void *data
412) {
413 int nxtblk, blkNr, pxlSize, ret;
414
415 if(ECAT63_TEST) printf("ecat63WriteImage(fp, %d, ih, data)\n", matnum);
416 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
417 /* nr of pixels */
418 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(2);
419 /* mem taken by one pixel */
420 switch(h->data_type) {
421 case BYTE_TYPE: pxlSize=1;
422 break;
423 case VAX_I2:
424 case SUN_I2: pxlSize=2;
425 break;
426 case VAX_I4: return(3);
427 case VAX_R4: return(3);
428 case IEEE_R4:
429 case SUN_I4: pxlSize=4;
430 break;
431 default: return(2);
432 }
433 /* mem taken by all pixels */
434 long long data_size=pxlNr*pxlSize;
435 /* block nr taken by all pixels */
436 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
437 /* Get block number for matrix header and data */
438 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
439 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
440 /* Write header */
441 ret=ecat63WriteImageheader(fp, nxtblk, h); if(ret) return(40+ret);
442 /* Write matrix data */
443 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
444 if(ret) return(50+ret);
445 return 0;
446}
447/*****************************************************************************/
448
449/*****************************************************************************/
462 FILE *fp, int matnum, ECAT63_scanheader *h, void *data
463) {
464 int nxtblk, blkNr, pxlSize, ret;
465
466 if(ECAT63_TEST) printf("ecat63WriteScan(fp, %d, sh, data)\n", matnum);
467 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
468 /* nr of pixels */
469 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
470 /* mem taken by one pixel */
471 switch(h->data_type) {
472 case BYTE_TYPE: pxlSize=1;
473 break;
474 case VAX_I2:
475 case SUN_I2: pxlSize=2;
476 break;
477 case VAX_I4: return(3);
478 case VAX_R4: return(3);
479 case IEEE_R4:
480 case SUN_I4: pxlSize=4;
481 break;
482 default: return(2);
483 }
484 /* mem taken by all pixels */
485 long long data_size=pxlNr*pxlSize;
486 /* block nr taken by all pixels */
487 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
488 /* Get block number for matrix header and data */
489 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
490 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
491 /* Write header */
492 ret=ecat63WriteScanheader(fp, nxtblk, h); if(ret) return(40+ret);
493 /* Write matrix data */
494 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
495 if(ret) return(50+ret);
496 return 0;
497}
498/*****************************************************************************/
499
500/*****************************************************************************/
513 FILE *fp, int matnum, ECAT63_normheader *h, void *data
514) {
515 int nxtblk, blkNr, pxlSize, ret;
516
517 if(ECAT63_TEST) printf("ecat63WriteNorm(fp, %d, nh, data)\n", matnum);
518 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
519 /* nr of pixels */
520 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
521 /* mem taken by one pixel */
522 switch(h->data_type) {
523 case BYTE_TYPE: pxlSize=1;
524 break;
525 case VAX_I2:
526 case SUN_I2: pxlSize=2;
527 break;
528 case VAX_I4: return(3);
529 case VAX_R4: return(3);
530 case IEEE_R4:
531 case SUN_I4: pxlSize=4;
532 break;
533 default: return(2);
534 }
535 /* mem taken by all pixels */
536 long long data_size=pxlNr*pxlSize;
537 /* block nr taken by all pixels */
538 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
539 /* Get block number for matrix header and data */
540 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
541 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
542 /* Write header */
543 ret=ecat63WriteNormheader(fp, nxtblk, h); if(ret) return(40+ret);
544 /* Write matrix data */
545 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
546 if(ret) return(50+ret);
547 return 0;
548}
549/*****************************************************************************/
550
551/*****************************************************************************/
564 FILE *fp, int matnum, ECAT63_attnheader *h, void *data
565) {
566 int nxtblk, blkNr, pxlSize, ret;
567
568 if(ECAT63_TEST) printf("ecat63WriteAttn(fp, %d, ah, data)\n", matnum);
569 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
570 /* nr of pixels */
571 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
572 /* mem taken by one pixel */
573 switch(h->data_type) {
574 case BYTE_TYPE: pxlSize=1;
575 break;
576 case VAX_I2:
577 case SUN_I2: pxlSize=2;
578 break;
579 case VAX_I4: return(3);
580 case VAX_R4: return(3);
581 case IEEE_R4:
582 case SUN_I4: pxlSize=4;
583 break;
584 default: return(2);
585 }
586 /* mem taken by all pixels */
587 long long data_size=pxlNr*pxlSize;
588 /* block nr taken by all pixels */
589 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
590 /* Get block number for matrix header and data */
591 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
592 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
593 /* Write header */
594 ret=ecat63WriteAttnheader(fp, nxtblk, h); if(ret) return(40+ret);
595 /* Write matrix data */
596 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
597 if(ret) return(50+ret);
598 return 0;
599}
600/*****************************************************************************/
601
602/*****************************************************************************/
619 FILE *fp, int strtblk, char *data, long long pxlNr, int pxlSize
620) {
621 unsigned char buf[MatBLKSIZE];
622 char *dptr;
623 int blkNr, byteNr;
624
625 if(ECAT63_TEST)
626 printf("ecat63WriteMatdata(fp, %d, data, %lld, %d)\n", strtblk, pxlNr, pxlSize);
627 if(fp==NULL || strtblk<1 || data==NULL || pxlNr<1 || pxlSize<1) return(1);
628 memset(buf, 0, MatBLKSIZE);
629 long long dataSize=pxlNr*pxlSize; if(dataSize<1) return(1);
630 /* block nr taken by all pixels */
631 blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
632 if(ECAT63_TEST>1) printf(" blkNr=%d\n", blkNr);
633 /* Search the place for writing */
634 fseeko(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET);
635 if(ftello(fp)!=(strtblk-1)*MatBLKSIZE) return(2);
636 /* Save blocks one at a time */
637 dptr=data;
638 for(int i=0; i<blkNr && dataSize>0; i++) {
639 byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
640 memcpy(buf, dptr, byteNr);
641 /* Change matrix byte order in big endian platforms */
642 if(!little_endian()) {
643 if(pxlSize==2) swabip(buf, byteNr);
644 else if(pxlSize==4) swawbip(buf, byteNr);
645 }
646 /* Write block */
647 if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
648 /* Prepare for the next block */
649 dptr+=byteNr;
650 dataSize-=byteNr;
651 } /* next block */
652 return(0);
653}
654/*****************************************************************************/
655
656/*****************************************************************************/
664 float amax,
666 float *data,
668 long long nr
669) {
670 double d;
671
672 if(nr<1 || data==NULL) return(0);
673 /* scaling is necessary if all values are between -1 - 1 */
674 if(amax<0.9999) return(1);
675 /* Lets check first if at least the max value is close to integers or not */
676 if(modf(amax, &d)>0.0001) return(1);
677 /* if it is, then check all pixels */
678 for(long long i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
679 return(0);
680}
681/*****************************************************************************/
682
683/*****************************************************************************/
698 FILE *fp, int matnum, ECAT63_imageheader *h, float *fdata
699) {
700 int nxtblk, blkNr, ret;
701 float *fptr, fmin, fmax, g, f;
702 char *mdata, *mptr;
703 short int *sptr;
704
705
706
707 if(ECAT63_TEST) printf("ecat63WriteImageMatrix(fp, %d, h, data)\n", matnum);
708 if(fp==NULL || matnum<1 || h==NULL || fdata==NULL) {
709 sprintf(ecat63errmsg, "invalid function parameter.\n");
710 return(1);
711 }
712 /* nr of pixels */
713 long long pxlNr=h->dimension_1*h->dimension_2;
714 if(pxlNr<1) {
715 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
716 return(3);
717 }
718 /* How much memory is needed for ALL pixels */
719 long long data_size=pxlNr*ecat63pxlbytes(h->data_type);
720 /* block nr taken by all pixels */
721 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
722 sprintf(ecat63errmsg, "invalid block number.\n");
723 return(4);
724 }
725 /* Allocate memory for matrix data */
726 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
727 sprintf(ecat63errmsg, "out of memory.\n");
728 return(5);
729 }
730 /* Search for min and max for calculation of scale factor */
731 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
732 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
733 if(g>0) f=32766./g; else f=1.0;
734 /* Check if pixels values can be left as such with scale_factor = 1 */
735 fptr=fdata;
736 if(f>=1.0 && ecat63_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
737 /* Scale matrix data to shorts */
738 h->quant_scale=1.0/f;
739 sptr=(short int*)mdata; fptr=fdata;
740 for(long long i=0; i<pxlNr; i++, sptr++, fptr++)
741 *sptr=(short int)temp_roundf(f*(*fptr));
742 /* Set header short min & max */
743 h->image_min=(short int)temp_roundf(f*fmin);
744 h->image_max=(short int)temp_roundf(f*fmax);
745 /* Get block number for matrix header and data */
746 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) {
747 sprintf(ecat63errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
748 free(mdata); return(8);
749 }
750 if(ECAT63_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
751 /* Write header */
752 ret=ecat63WriteImageheader(fp, nxtblk, h); if(ret) {
753 sprintf(ecat63errmsg, "cannot write subheader (%d).\n", ret);
754 free(mdata); return(10);
755 }
756 /* Write matrix data */
757 mptr=mdata;
758 ret=ecat63WriteMatdata(fp, nxtblk+1, mptr, pxlNr, ecat63pxlbytes(h->data_type));
759 free(mdata);
760 if(ret) {
761 sprintf(ecat63errmsg, "cannot write matrix data (%d).\n", ret);
762 return(13);
763 }
764 return(0);
765}
766/*****************************************************************************/
767
768/*****************************************************************************/
782 FILE *fp, int matnum, ECAT63_scanheader *h, float *fdata
783) {
784 int nxtblk, blkNr, ret;
785 float *fptr, fmin, fmax, g, f;
786 char *mdata, *mptr;
787 short int *sptr;
788
789
790 if(ECAT63_TEST) printf("ecat63WriteScanMatrix(fp, %d, h, data)\n", matnum);
791 if(fp==NULL || matnum<1 || h==NULL || fdata==NULL) {
792 sprintf(ecat63errmsg, "invalid function parameter.\n");
793 return(1);
794 }
795 /* nr of pixels */
796 long long pxlNr=h->dimension_1*h->dimension_2;
797 if(pxlNr<1) {
798 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
799 return(3);
800 }
801 /* How much memory is needed for ALL pixels */
802 long long data_size=pxlNr*ecat63pxlbytes(h->data_type);
803 /* block nr taken by all pixels */
804 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
805 sprintf(ecat63errmsg, "invalid block number.\n");
806 return(4);
807 }
808 /* Allocate memory for matrix data */
809 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
810 sprintf(ecat63errmsg, "out of memory.\n");
811 return(5);
812 }
813 /* Search for min and max for calculation of scale factor */
814 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
815 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
816 if(g>0) f=32766./g; else f=1.0;
817 /* Check if pixels values can be left as such with scale_factor = 1 */
818 fptr=fdata;
819 if(f>=1.0 && ecat63_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
820 /* Scale matrix data to shorts */
821 h->scale_factor=1.0/f;
822 sptr=(short int*)mdata; fptr=fdata;
823 for(long long i=0; i<pxlNr; i++, sptr++, fptr++)
824 *sptr=(short int)temp_roundf(f*(*fptr));
825 /* Set header short min & max */
826 h->scan_min=(short int)temp_roundf(f*fmin);
827 h->scan_max=(short int)temp_roundf(f*fmax);
828 /* Get block number for matrix header and data */
829 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) {
830 sprintf(ecat63errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
831 free(mdata); return(8);
832 }
833 if(ECAT63_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
834 /* Write header */
835 ret=ecat63WriteScanheader(fp, nxtblk, h); if(ret) {
836 sprintf(ecat63errmsg, "cannot write subheader (%d).\n", ret);
837 free(mdata); return(10);
838 }
839 /* Write matrix data */
840 mptr=mdata;
841 ret=ecat63WriteMatdata(fp, nxtblk+1, mptr, pxlNr, ecat63pxlbytes(h->data_type));
842 free(mdata);
843 if(ret) {
844 sprintf(ecat63errmsg, "cannot write matrix data (%d).\n", ret);
845 return(13);
846 }
847 return(0);
848}
849/*****************************************************************************/
850
851/*****************************************************************************/
861 float *bufi, void *bufo, int tovax, int islittle
862) {
863 unsigned int ul;
864
865 memcpy(&ul, bufi, 4); if(ul==0) {memcpy(bufo, bufi, 4); return;}
866 if(tovax) { /* If VAX format is needed */
867 ul+=(2L<<23); /* increase exp by 2 */
868 /* Swap words on i386 and bytes on SUN */
869 if(islittle) swawip(&ul, 4); else swabip(&ul, 4);
870 } else {
871 if(!islittle) swawbip(&ul, 4); /* Switch words and bytes on SUN */
872 }
873 memcpy(bufo, &ul, 4);
874}
884void ecat63wInt(int *bufi, void *bufo, int tovax, int islittle) {
885 int i;
886
887 if(tovax==0) {} // to prevent compiler warning
888 /* Swap both words and bytes on SUN */
889 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
890 memcpy(bufo, &i, 4);
891}
892/*****************************************************************************/
893
894/*****************************************************************************/
902 const ECAT63_mainheader *h,
904 struct tm *tm
905) {
906 if(tm==NULL || h==NULL) return(NULL);
907 memset(tm, 0, sizeof(struct tm));
908 tm->tm_mday=h->scan_start_day;
909 tm->tm_mon=h->scan_start_month-1;
910 tm->tm_year=h->scan_start_year-1900;
911 tm->tm_hour=h->scan_start_hour;
912 tm->tm_min=h->scan_start_minute;
913 tm->tm_sec=h->scan_start_second;
914 tm->tm_isdst=-1;
915 if(timegm(tm)==-1) return(NULL);
916 return(tm);
917}
918/*****************************************************************************/
919
920/*****************************************************************************/
927 const ECAT63_mainheader *h
928) {
929 if(h==NULL) return((time_t)-1);
930 struct tm tm;
931 tm.tm_mday=h->scan_start_day;
932 tm.tm_mon=h->scan_start_month-1;
933 tm.tm_year=h->scan_start_year-1900;
934 tm.tm_hour=h->scan_start_hour;
935 tm.tm_min=h->scan_start_minute;
936 tm.tm_sec=h->scan_start_second;
937 tm.tm_isdst=-1;
938 return(timegm(&tm));
939}
940/*****************************************************************************/
941
942/*****************************************************************************/
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69
char ecat63errmsg[128]
Definition ecat63h.c:7
int ECAT63_TEST
Definition ecat63h.c:6
int ecat63Matenter(FILE *fp, int matnum, int blkNr)
Definition ecat63ml.c:159
int ecat63pxlbytes(short int data_type)
Definition ecat63r.c:973
int ecat63WriteScan(FILE *fp, int matnum, ECAT63_scanheader *h, void *data)
Definition ecat63w.c:461
int ecat63_is_scaling_needed(float amax, float *data, long long nr)
Definition ecat63w.c:662
int ecat63WriteImageheader(FILE *fp, int block, ECAT63_imageheader *h)
Definition ecat63w.c:106
int ecat63WriteScanMatrix(FILE *fp, int matnum, ECAT63_scanheader *h, float *fdata)
Definition ecat63w.c:781
int ecat63WriteMatdata(FILE *fp, int strtblk, char *data, long long pxlNr, int pxlSize)
Definition ecat63w.c:618
int ecat63WriteAttnheader(FILE *fp, int block, ECAT63_attnheader *h)
Definition ecat63w.c:190
void ecat63wFloat(float *bufi, void *bufo, int tovax, int islittle)
Definition ecat63w.c:860
int ecat63WriteScanheader(FILE *fp, int block, ECAT63_scanheader *h)
Definition ecat63w.c:242
int ecat63WriteAttn(FILE *fp, int matnum, ECAT63_attnheader *h, void *data)
Definition ecat63w.c:563
int ecat63WriteNorm(FILE *fp, int matnum, ECAT63_normheader *h, void *data)
Definition ecat63w.c:512
int ecat63WriteImageMatrix(FILE *fp, int matnum, ECAT63_imageheader *h, float *fdata)
Definition ecat63w.c:697
int ecat63WriteNormheader(FILE *fp, int block, ECAT63_normheader *h)
Definition ecat63w.c:313
int ecat63WriteImage(FILE *fp, int matnum, ECAT63_imageheader *h, void *data)
Definition ecat63w.c:410
FILE * ecat63Create(const char *fname, ECAT63_mainheader *h)
Definition ecat63w.c:365
void ecat63wInt(int *bufi, void *bufo, int tovax, int islittle)
Definition ecat63w.c:884
struct tm * ecat63ScanstarttimeToTm(const ECAT63_mainheader *h, struct tm *tm)
Convert scan_start_time in ECAT 6.3 main header into a struct tm.
Definition ecat63w.c:900
int ecat63WriteMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63w.c:24
time_t ecat63Scanstarttime(const ECAT63_mainheader *h)
Get calendar time from ECAT 6.3 main header.
Definition ecat63w.c:925
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 SUN_I4
#define VAX_R4
#define IEEE_R4
#define BYTE_TYPE
#define VAX_I4
#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
int temp_roundf(float e)
Definition petc99.c:20
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]