00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <math.h>
00043 #include <ctype.h>
00044 #include <string.h>
00045 #include <unistd.h>
00046 #include <time.h>
00047
00048 #include <swap.h>
00049 #include "include/img.h"
00050 #include "include/ecat7.h"
00051
00052
00053
00059 void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist) {
00060 mlist->matrixSpace=mlist->matrixNr=0; mlist->matdir=NULL;
00061 }
00062
00063
00064
00070 void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist) {
00071 if(mlist->matrixSpace>0) free((char*)(mlist->matdir));
00072 mlist->matrixSpace=mlist->matrixNr=0;
00073 }
00074
00075
00076
00086 int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml) {
00087 int i, err=0, little;
00088 int blk=MatFirstDirBlk, next_blk=0, nr_free, prev_blk, nr_used;
00089 size_t sn;
00090 unsigned int dirbuf[MatBLKSIZE/4];
00091
00092
00093 if(ECAT7_TEST) printf("ecat7ReadMatlist(fp, mlist)\n");
00094 if(fp==NULL) return(1);
00095 little=little_endian();
00096
00097 ecat7EmptyMatlist(ml);
00098
00099 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00100 do {
00101
00102 if(ECAT7_TEST) printf(" reading dirblock %d\n", blk);
00103 sn=fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp); if(sn<MatBLKSIZE/4) return(3);
00104
00105 if(ml->matrixSpace==0) {
00106 ml->matrixSpace=MatBLKSIZE/4;
00107 ml->matdir=(ECAT7_MatDir*)malloc(ml->matrixSpace*sizeof(ECAT7_MatDir));
00108 } else if(ml->matrixSpace<(ml->matrixNr+MatBLKSIZE/4)) {
00109 ml->matrixSpace+=MatBLKSIZE/4;
00110 ml->matdir=(ECAT7_MatDir*)realloc(ml->matdir, sizeof(ECAT7_MatDir)*ml->matrixSpace);
00111 }
00112 if(ml->matdir==NULL) return(4);
00113
00114 if(little) swawbip(dirbuf, MatBLKSIZE);
00115
00116 nr_free = dirbuf[0];
00117 next_blk = dirbuf[1];
00118 prev_blk = dirbuf[2];
00119 nr_used = dirbuf[3];
00120 if(ECAT7_TEST>1) printf("nr_free=%d next_blk=%d prev_blk=%d nr_used=%d\n", nr_free, next_blk, prev_blk, nr_used);
00121 for(i=4; i<MatBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
00122 ml->matdir[ml->matrixNr].id=dirbuf[i];
00123 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
00124 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
00125 ml->matdir[ml->matrixNr].status=dirbuf[i+3];
00126 if(ECAT7_TEST>3) {
00127 printf("matnum=%d strtblk=%d endblk=%d matstat=%d matrixNr=%d\n",
00128 ml->matdir[ml->matrixNr].id, ml->matdir[ml->matrixNr].strtblk,
00129 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].status,
00130 ml->matrixNr);
00131 }
00132 ml->matrixNr++;
00133 }
00134 blk=next_blk;
00135
00136 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) err=1;
00137 } while(err==0 && feof(fp)==0 && blk!=MatFirstDirBlk);
00138 if(err) {ecat7EmptyMatlist(ml); return(5);}
00139 return(0);
00140 }
00141
00142
00143
00149 void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml) {
00150 int i;
00151 ECAT7_Matval matval;
00152
00153 printf(" matrix pl fr gate bed startblk blknr status\n");
00154 for(i=0; i<ml->matrixNr; i++) {
00155 ecat7_id_to_val(ml->matdir[i].id, &matval);
00156 printf("%4d %8d %3d %3d %3d %3d %8d %5d ", i+1, ml->matdir[i].id,
00157 matval.plane, matval.frame, matval.gate, matval.bed,
00158 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
00159 if(ml->matdir[i].status==1) printf("read/write\n");
00160 else if(ml->matdir[i].status==0) printf("not ready\n");
00161 else if(ml->matdir[i].status==-1) printf("deleted\n");
00162 else printf("%d\n", ml->matdir[i].status);
00163 }
00164 return;
00165 }
00166
00167
00168
00184 int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr) {
00185 unsigned int i=0, dirblk, little, busy=1, nxtblk=0, oldsize;
00186 int dirbuf[MatBLKSIZE/4];
00187
00188 if(ECAT7_TEST) printf("ecat7EnterMatrix(fp, %d, %d)\n", matrix_id, block_nr);
00189
00190 if(fp==NULL || matrix_id<1 || block_nr<1) return(-1);
00191
00192 little=little_endian();
00193
00194 dirblk=MatFirstDirBlk;
00195 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
00196 if(ftell(fp)!=(dirblk-1)*MatBLKSIZE) return(-2);
00197 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-3);
00198
00199 if(little) swawbip(dirbuf, MatBLKSIZE);
00200
00201 while(busy) {
00202
00203 for(i=4, nxtblk=dirblk+1; i<MatBLKSIZE/4; i+=4) {
00204 oldsize=dirbuf[i+2]-dirbuf[i+1]+1;
00205 if(dirbuf[i]==0) {
00206 busy=0; break;
00207 } else if(dirbuf[i]==matrix_id) {
00208
00209 if(oldsize<block_nr) {
00210
00211 dirbuf[i] = 0xFFFFFFFF; dirbuf[i+3]=-1;
00212 if(little) swawbip(dirbuf, MatBLKSIZE);
00213 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
00214 if(ftell(fp)!=(dirblk-1)*MatBLKSIZE) return(-6);
00215 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-7);
00216 if(little) swawbip(dirbuf, MatBLKSIZE);
00217 nxtblk=dirbuf[i+2]+1;
00218 } else {
00219 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
00220 break;
00221 }
00222 } else {
00223
00224 if(dirbuf[i+3]==-1 && block_nr<=oldsize) {
00225
00226 dirbuf[i]=matrix_id;
00227 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
00228 break;
00229 }
00230
00231 nxtblk=dirbuf[i+2]+1;
00232 }
00233 }
00234 if(!busy) break;
00235
00236 if(dirbuf[1]!=MatFirstDirBlk) {
00237
00238 dirblk=dirbuf[1];
00239 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
00240 if(ftell(fp)!=(dirblk-1)*MatBLKSIZE) return(-9);
00241 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-10);
00242 if(little) swawbip(dirbuf, MatBLKSIZE);
00243 } else {
00244
00245 dirbuf[1]=nxtblk;
00246 if(little) swawbip(dirbuf, MatBLKSIZE);
00247 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
00248 if(ftell(fp)!=(dirblk-1)*MatBLKSIZE) return(-11);
00249 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-12);
00250
00251 dirbuf[0]=31; dirbuf[1]=MatFirstDirBlk; dirbuf[2]=dirblk;
00252 dirbuf[3]=0; dirblk=nxtblk;
00253 for(i=4; i<MatBLKSIZE/4; i++) dirbuf[i]=0;
00254 }
00255 }
00256 dirbuf[i]=matrix_id;
00257 dirbuf[i+1]=nxtblk;
00258 dirbuf[i+2]=nxtblk+block_nr;
00259 dirbuf[i+3]=1;
00260 dirbuf[0]--;
00261 dirbuf[3]++;
00262 if(little) swawbip(dirbuf, MatBLKSIZE);
00263 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
00264 if(ftell(fp)!=(dirblk-1)*MatBLKSIZE) return(-15);
00265 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-16);
00266 if(ECAT7_TEST) printf("returning %d from ecat7EnterMatrix()\n", nxtblk);
00267 return(nxtblk);
00268 }
00269
00270
00271
00282 int ecat7_val_to_id(int frame, int plane, int gate, int data, int bed) {
00283 return(
00284 ((bed & 0xF) << 12) |
00285 (frame & 0x1FF) |
00286 ((gate & 0x3F) << 24) |
00287 ((plane & 0xFF) << 16) |
00288 ((plane & 0x300) << 1) |
00289 ((data & 0x3) << 30) |
00290 ((data & 0x4) << 9)
00291 );
00292 }
00299 void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval) {
00300 matval->frame = matrix_id & 0x1FF;
00301 matval->plane = ((matrix_id >> 16) & 0xFF) + ((matrix_id >> 1) & 0x300);
00302 matval->gate = (matrix_id >> 24) & 0x3F;
00303 matval->data = ((matrix_id >> 30) & 0x3) + ((matrix_id >> 9) & 0x4);
00304 matval->bed = (matrix_id >> 12) & 0xF;
00305 }
00306
00307
00308
00314 void ecat7SortMatlistByPlane(ECAT7_MATRIXLIST *ml) {
00315 int i, j;
00316 ECAT7_Matval mv1, mv2;
00317 ECAT7_MatDir tmpMatdir;
00318
00319 for(i=0; i<ml->matrixNr-1; i++) {
00320 ecat7_id_to_val(ml->matdir[i].id, &mv1);
00321 for(j=i+1; j<ml->matrixNr; j++) {
00322 ecat7_id_to_val(ml->matdir[j].id, &mv2);
00323 if(mv2.plane<mv1.plane||(mv2.plane==mv1.plane&&mv2.frame<mv1.frame)) {
00324 tmpMatdir=ml->matdir[i];
00325 ml->matdir[i]=ml->matdir[j];
00326 ml->matdir[j]=tmpMatdir;
00327 ecat7_id_to_val(ml->matdir[i].id, &mv1);
00328 }
00329 }
00330 }
00331 }
00332
00333
00334
00340 void ecat7SortMatlistByFrame(ECAT7_MATRIXLIST *ml) {
00341 int i, j;
00342 ECAT7_Matval mv1, mv2;
00343 ECAT7_MatDir tmpMatdir;
00344
00345 for(i=0; i<ml->matrixNr-1; i++) {
00346 ecat7_id_to_val(ml->matdir[i].id, &mv1);
00347 for(j=i+1; j<ml->matrixNr; j++) {
00348 ecat7_id_to_val(ml->matdir[j].id, &mv2);
00349 if(mv2.frame<mv1.frame||(mv2.frame==mv1.frame&&mv2.plane<mv1.plane)) {
00350 tmpMatdir=ml->matdir[i];
00351 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
00352 ecat7_id_to_val(ml->matdir[i].id, &mv1);
00353 }
00354 }
00355 }
00356 }
00357
00358
00359
00366 int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml) {
00367 int i;
00368
00369 if(ml==NULL) return(1);
00370 for(i=0; i<ml->matrixNr; i++) if(ml->matdir[i].status!=1) return(1);
00371 return(0);
00372 }
00373
00374
00375
00383 int ecat7DeleteLateFrames(ECAT7_MATRIXLIST *ml, int frame_nr) {
00384 int i, del_nr=0;
00385 ECAT7_Matval matval;
00386
00387 for(i=0; i<ml->matrixNr; i++) {
00388 ecat7_id_to_val(ml->matdir[i].id, &matval);
00389 if(matval.frame>frame_nr) {del_nr++; ml->matdir[i].status=-1;}
00390 }
00391 return(del_nr);
00392 }
00393
00394
00395
00409 int ecat7GetPlaneAndFrameNr(ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr) {
00410 ECAT7_Matval matval;
00411 int m, plane, frame, prev_plane, prev_frame, fnr, pnr;
00412
00413
00414 if(mlist==NULL) return STATUS_FAULT;
00415 if(plane_nr!=NULL) *plane_nr=0;
00416 if(frame_nr!=NULL) *frame_nr=0;
00417
00418
00419 ecat7SortMatlistByPlane(mlist);
00420
00421 prev_plane=plane=-1; prev_frame=frame=-1;
00422 fnr=pnr=0;
00423 for(m=0; m<mlist->matrixNr; m++) {
00424 ecat7_id_to_val(mlist->matdir[m].id, &matval);
00425 plane=matval.plane;
00426 if(h->num_frames>=h->num_gates)
00427 frame=matval.frame;
00428 else
00429 frame=matval.gate;
00430 if(plane!=prev_plane) {
00431 fnr=1; pnr++;
00432 } else {
00433 fnr++;
00434 if(prev_frame>0 && frame!=prev_frame+1) return STATUS_MISSINGMATRIX;
00435 }
00436 prev_plane=plane; prev_frame=frame;
00437 }
00438 if(fnr*pnr != mlist->matrixNr) return STATUS_MISSINGMATRIX;
00439 if(plane_nr!=NULL) *plane_nr=pnr;
00440 if(frame_nr!=NULL) *frame_nr=fnr;
00441 return STATUS_OK;
00442 }
00443
00444
00445
00455 int ecat7GetMatrixBlockSize(ECAT7_MATRIXLIST *mlist, int *blk_nr) {
00456 int m, prev_blk, blk;
00457
00458
00459 if(mlist==NULL) return STATUS_FAULT;
00460 if(blk_nr!=NULL) *blk_nr=0;
00461
00462
00463 m=0; prev_blk=blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
00464 for(m=1; m<mlist->matrixNr; m++) {
00465 blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
00466 if(blk!=prev_blk) return STATUS_VARMATSIZE;
00467 else prev_blk=blk;
00468 }
00469 if(blk_nr!=NULL) *blk_nr=blk;
00470 return STATUS_OK;
00471 }
00472
00473
00474
00489 int ecat7GetNums(ECAT7_MATRIXLIST *ml, ECAT7_mainheader *mh, FILE *fp, short int *num_planes,
00490 short int *num_frames, short int *num_gates, short int *num_bed_pos) {
00491 int i, nmax, ret=0;
00492 ECAT7_imageheader ih;
00493 ECAT7_scanheader sh;
00494 ECAT7_Matval* matval;
00495
00496 if(ml==NULL) return(1);
00497 if(ml->matrixNr<1) return(2);
00498
00499
00500 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
00501 if(matval == NULL) return(3);
00502
00503
00504 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
00505
00506
00507 if(num_planes!=NULL) {
00508 nmax=matval[0].plane;
00509 for(i=1; i<ml->matrixNr; i++) if(matval[i].plane>nmax) nmax=matval[i].plane;
00510 *num_planes=nmax;
00511 }
00512
00513 if(num_frames!=NULL) {
00514 nmax=matval[0].frame;
00515 for(i=1; i<ml->matrixNr; i++) if(matval[i].frame>nmax) nmax=matval[i].frame;
00516 *num_frames=nmax;
00517 }
00518
00519 if(num_gates!=NULL) {
00520 nmax=matval[0].gate;
00521 for(i=1; i<ml->matrixNr; i++) if(matval[i].gate>nmax) nmax=matval[i].gate;
00522 *num_gates=nmax;
00523 }
00524
00525 if(num_bed_pos!=NULL) {
00526 nmax=matval[0].bed;
00527 for(i=1; i<ml->matrixNr; i++) if(matval[i].bed>nmax) nmax=matval[i].bed;
00528 *num_bed_pos=nmax;
00529 }
00530
00531
00532 if(num_planes!=NULL && *num_planes<=1) switch(mh->file_type) {
00533 case ECAT7_VOLUME8:
00534 case ECAT7_VOLUME16:
00535 ret=ecat7ReadImageheader(fp, ml->matdir[0].strtblk, &ih);
00536 if(ret!=0) {
00537 free(matval);
00538 return(5);
00539 }
00540 if(ih.num_dimensions>2 && ih.z_dimension>1) *num_planes=ih.z_dimension;
00541 break;
00542 case ECAT7_3DSCAN:
00543 case ECAT7_3DSCAN8:
00544 case ECAT7_3DSCANFIT:
00545 ret=ecat7ReadScanheader(fp, ml->matdir[0].strtblk, &sh);
00546 if(ret!=0) {
00547 free(matval);
00548 return(5);
00549 }
00550 for(i=0, *num_planes=0; i<64; i++) *num_planes+=sh.num_z_elements[i];
00551 break;
00552 }
00553 free(matval);
00554 return(0);
00555 }
00556
00557
00558
00572 int ecat7GatherMatlist(ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames,
00573 short int do_gates, short int do_beds) {
00574 int i, ncurr, n;
00575 ECAT7_Matval* matval;
00576
00577 if(ml==NULL) return(1);
00578 if(ml->matrixNr<1) return(0);
00579
00580
00581 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
00582 if(matval == NULL) return(3);
00583
00584
00585 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
00586
00587
00588 if(do_planes!=0) {
00589 ncurr=1;
00590 while(ncurr <= ml->matrixNr) {
00591
00592 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].plane==ncurr) {n=1; break;}
00593
00594 if(n==1) {ncurr++; continue;}
00595
00596 for(i=0, n=0; i<ml->matrixNr; i++)
00597 if(matval[i].plane>ncurr) {
00598
00599 matval[i].plane--; n++;
00600 }
00601
00602 if(n<1) break;
00603 }
00604 }
00605
00606
00607 if(do_frames!=0) {
00608 ncurr=1;
00609 while(ncurr <= ml->matrixNr) {
00610
00611 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].frame==ncurr) {n=1; break;}
00612
00613 if(n==1) {ncurr++; continue;}
00614
00615 for(i=0, n=0; i<ml->matrixNr; i++)
00616 if(matval[i].frame>ncurr) {matval[i].frame--; n++;}
00617
00618 if(n<1) break;
00619 }
00620 }
00621
00622
00623 if(do_gates!=0) {
00624 ncurr=1;
00625 while(ncurr <= ml->matrixNr) {
00626
00627 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].gate==ncurr) {n=1; break;}
00628
00629 if(n==1) {ncurr++; continue;}
00630
00631 for(i=0, n=0; i<ml->matrixNr; i++)
00632 if(matval[i].gate>ncurr) {matval[i].gate--; n++;}
00633
00634 if(n<1) break;
00635 }
00636 }
00637
00638
00639 if(do_beds!=0) {
00640 ncurr=1;
00641 while(ncurr <= ml->matrixNr) {
00642
00643 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].bed==ncurr) {n=1; break;}
00644
00645 if(n==1) {ncurr++; continue;}
00646
00647 for(i=0, n=0; i<ml->matrixNr; i++)
00648 if(matval[i].bed>ncurr) {matval[i].bed--; n++;}
00649
00650 if(n<1) break;
00651 }
00652 }
00653
00654
00655 for(i=0; i<ml->matrixNr; i++) ml->matdir[i].id=ecat7_val_to_id(
00656 matval[i].frame, matval[i].plane,
00657 matval[i].gate, matval[i].data,
00658 matval[i].bed);
00659 free(matval);
00660 return(0);
00661 }
00662
00663
00664
00665