/*------------------------------------------------------------------- * CTWriteSLC - write a slice in SLC format *------------------------------------------------------------------- */ static int CTWriteSLC(CTSlice slice) { switch (CTVolVoxelBits(slice->vol)) { case CT_8BIT: fwrite(slice->cdata, sizeof(char), CTVolXSize(slice->vol)* CTVolYSize(slice->vol), slice->vol->outfp); break; case CT_16BIT: fwrite(slice->data, sizeof(short), CTVolXSize(slice->vol)* CTVolYSize(slice->vol), slice->vol->outfp); break; } return 0; }
/*------------------------------------------------------------------- * CTReadH3D - read a slice from an H3D file *------------------------------------------------------------------- */ static int CTReadH3D(FILE *fp, CTSlice slice, int num, int x1, int y1, int x2, int y2) { if (x1==-1) { slice->x1=slice->y1=x1=y1=0; slice->x2=x2=CTSliceXSize(slice)-1; slice->y2=y2=CTSliceYSize(slice)-1; slice->fdata=(float *)malloc(sizeof(float)*(x2-x1+1)*(y2-y1+1)); memset(slice->fdata, '\0', sizeof(float)*(x2-x1+1)*(y2-y1+1)); } CTSliceWidth(slice) = x2-x1+1; CTSliceHeight(slice) = y2-y1+1; fskip(fp, sizeof(int)*3 + sizeof(double)*3 + CTVolXSize(slice->vol)*CTVolYSize(slice->vol)*(num-1)*sizeof(float)); fread(slice->fdata, sizeof(float), CTVolXSize(slice->vol)* CTVolYSize(slice->vol), fp); CTSliceCompMinMaxD(slice); return(0); }
CTVolume CTVolumeHartley3D(CTVolume vol) { CTVolume vol2; CTSlice slice; int l,m,n,L,M,N,i,j,k; #ifdef USE_PTIME int t1,t2; #endif float *d1,*d2,*X,*D,Z,*w,*w1,*w2; float *Mcas, *Lcos, *Lsin, *Ncos, *Nsin, max, min; double dL, dM, dN, s, c; /* Get source volume info. */ L = CTVolXSize(vol); M = CTVolYSize(vol); N = CTVolNumSlices(vol); dL = (double)L; dM = (double)M; dN = (double)N; /* Initialize the new volume. */ vol2 = CTVolumeCreate(CTH3D,CTVolPrefix(vol),".h3d",CTVolXSize(vol), CTVolYSize(vol),CTVolZSize(vol),CTVolXSep(vol), CTVolYSep(vol),CTVolZSep(vol),CTVolFirstSlice(vol), CTVolLastSlice(vol),1.0e10,CT_MSBF,CT_FLOAT); /* Open the new volume for writing. */ CTVolumeOpen(vol2,CTH3D,CTVolPrefix(vol2),".h3d"); /* Read in the volume data. */ D = (float *)malloc(L*M*N*sizeof(float)); switch (CTVolVoxelBits(vol)) { /* Read in and convert CT_8BIT values to CT_FLOAT. */ case CT_8BIT: for (n=0;n<N;n++) { slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1); for (l=0;l<L;l++) { for (m=0;m<M;m++) { D[n+N*(l+L*m)] = (float)CTSliceCharData(slice,l,m); } } CTSliceFree(slice); } break; /* Read in and convert CT_16BIT values to CT_FLOAT. */ case CT_16BIT: for (n=0;n<N;n++) { slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1); for (l=0;l<L;l++) { for (m=0;m<M;m++) { D[n+N*(l+L*m)] = (float)CTSliceShortData(slice,l,m); } } CTSliceFree(slice); } break; /* Read in CT_FLOAT values. */ case CT_FLOAT: for (n=0;n<N;n++) { slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1); for (l=0;l<L;l++) { for (m=0;m<M;m++) { D[n+N*(l+L*m)] = CTSliceFloatData(slice,l,m); } } CTSliceFree(slice); } break; } /* Precompute necessary sin, cos, and cas function values. */ Lcos = (float *)malloc(sizeof(float)*L*L); Lsin = (float *)malloc(sizeof(float)*L*L); Ncos = (float *)malloc(sizeof(float)*N*N); Nsin = (float *)malloc(sizeof(float)*N*N); Mcas = (float *)malloc(sizeof(float)*M*M); for (i=0;i<L*L;i++) { s = sin(2.0*M_PI*(double)i/dL); c = cos(2.0*M_PI*(double)i/dL); Lcos[i] = (float)c; Lsin[i] = (float)s; } for (i=0;i<N*N;i++) { s = sin(2.0*M_PI*(double)i/dN); c = cos(2.0*M_PI*(double)i/dN); Ncos[i] = (float)c; Nsin[i] = (float)s; } for (i=0;i<M*M;i++) { s = sin(2.0*M_PI*(double)i/dM); c = cos(2.0*M_PI*(double)i/dM); Mcas[i] = (float)(s+c); } /* Algorithm is O(LLMN+LMMN+LMNN). */ X = (float *)malloc(L*M*sizeof(float)); w1 = (float *)malloc(L*M*sizeof(float)); w2 = (float *)malloc(M*sizeof(float)); #ifdef USE_PTIME t1 = t2 = time(NULL); #endif /* Transfrom the original volume and write the new volume one slice at a time, in order. */ for (k=0;k<N;k++) { /* Initialize max and min values for each slice. */ min = 1.0e10; max = -1.0e10; /* Compute w1(i,m,n) */ d1 = D; w = w1; for (m=0;m<M;m++) { for (l=0;l<L;l++) { d2 = &D[N*((L-l)%L+L*((M-m)%M))]; *w = 0.0; for (n=0;n<N;n++) { *w += (*d1++)*Ncos[k*n]+(*d2++)*Nsin[k*n]; } w++; } } /* Compute w2(i,j,n) */ for (i=0;i<L;i++) { w = w2; d1 = w1; for (m=0;m<M;m++) { *w = 0.0; d2 = &w1[L*((M-m)%M)]; for (l=0;l<L;l++) { *w += (*d1++)*Lcos[i*l]+(*d2++)*Lsin[i*l]; } w++; } /* Compute X(i,j,k) */ for (j=0;j<M;j++) { Z = 0.0; w = w2; for (m=0;m<M;m++) { Z += (*w++)*Mcas[j*m]; } if (Z>max) max = Z; if (Z<min) min = Z; X[i+L*j] = Z; } } /* Write the transformed slice. */ slice = CTSliceCreate(L,M,min,max,vol2,k); for (i=0;i<L;i++) { for (j=0;j<M;j++) { CTSliceSetVal(slice,i,j,X[i+L*j]); } } CTSliceWrite(NULL,slice); CTSliceFree(slice); #ifdef USE_PTIME printf("Slice %d/%d, ",k+1,N); ptime((int)((float)(time(NULL)-t1)/(float)(k+1)*(float)(N-k-1))); printf("\n"); #endif } /* Done writing to the new volume. */ CTVolumeClose(vol2); #ifdef USE_PTIME t2 = time(NULL); printf("(3D)Total time: "); ptime(t2-t1); printf("\n"); #endif /* Return the transformed volume. */ return(vol2); }
/*------------------------------------------------------------------- * CTReadSLC - read a slice from an SLC file *------------------------------------------------------------------- */ static int CTReadSLC(FILE *fp, CTSlice slice, int num, int x1, int y1, int x2, int y2) { int i, remaining, current_value; unsigned int size; // unsigned int xsize, ysize, zsize, bits, magic; // float xunit, yunit, zunit; unsigned char *data_ptr; C_CompressionType compression; // C_UnitType unit; // C_DataOrigin data; // C_DataModification datamod; if (x1==-1) { slice->x1=slice->y1=x1=y1=0; slice->x2=x2=CTSliceXSize(slice)-1; slice->y2=y2=CTSliceYSize(slice)-1; slice->cdata=(unsigned char *)malloc(sizeof(char)*(x2-x1+1)*(y2-y1+1)); memset(slice->cdata, '\0', sizeof(char)*(x2-x1+1)*(y2-y1+1)); } CTSliceWidth(slice) = x2-x1+1; CTSliceHeight(slice) = y2-y1+1; /* skip header */ fskip(fp, sizeof(int)*5 + sizeof(float)*3 + sizeof(C_UnitType) + sizeof(C_DataOrigin) + sizeof(C_DataModification)); /* get compression type */ fread(&compression, sizeof(C_CompressionType), 1, fp); /* skip (num-1) slices */ if (compression == C_NO_COMPRESSION) { fskip(fp, CTVolXSize(slice->vol)*CTVolYSize(slice->vol)*(num-1)); } else { for (i=0; i<num-1; i++) { fread(&size, sizeof(int), 1, fp); fskip(fp, size); } } /* read slice */ switch (compression) { case C_NO_COMPRESSION: fread(slice->cdata, sizeof(char), CTVolXSize(slice->vol)*CTVolYSize(slice->vol), fp); break; case C_RUN_LENGTH_ENCODE: fread(&size, sizeof(int), 1, fp); data_ptr = slice->cdata; while (1) { current_value = getc(fp); if ( !(remaining = (current_value & 0x7f)) ) break; if ( current_value & 0x80 ) while (remaining--) *(data_ptr++) = getc(fp); else { current_value = getc(fp); while (remaining--) *(data_ptr++) = current_value; } } break; default: fprintf(stderr, "Error in compression type of SLC file\n"); return(-1); } CTSliceCompMinMaxD(slice); return(0); }
/*------------------------------------------------------------------- * CTWriteH3D - write a slice in H3D format *------------------------------------------------------------------- */ static int CTWriteH3D(CTSlice slice) { fwrite(slice->fdata, sizeof(float), CTVolXSize(slice->vol)* CTVolYSize(slice->vol), slice->vol->outfp); return 0; }