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 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 
00038 #include "ge4_header.h"
00039 
00040 
00041 
00042 extern unsigned long THD_filesize ( char * pathname );
00043 
00044 
00045 static int swap_2      ( void * ptr );
00046 static int swap_4      ( void * ptr );
00047 static int swap_2_multi( void * ptr, int num_shorts );
00048 
00049 
00050 
00051 
00052 static char * g_ge4_sl_im_modes[] =
00053                         { "2D single", "2D multiple", "3D volume", "cine",
00054                           "spectroscopy" };
00055 static char * g_ge4_sl_pulse_seqs[] =
00056                         { "memp", "ir", "ps", "rm", "rmge", "gre", "vemp",
00057                           "mpgr", "mpgrv", "mpirs", "mpiri", "3d/gre",
00058                           "cine/gre", "spgr", "sspf", "cin/spgr", "3d/spgr",
00059                           "fse", "fve", "fspr", "fgr", "fmpspgr", "fmpgr",
00060                           "fmpir", "probe.s", "probe.p" };
00061 static char * g_ge4_sl_orient[] = { "supine", "prone", "Lt", "Rt" };
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 int ge4_read_header( ge4_header * H, char * filename, int get_image )
00078 {
00079     ge4_image_t  * ih;
00080     ge4_series_t * sh;
00081     ge4_study_t  * st;
00082     FILE         * fp;
00083     int            file_len;
00084     int            rres = 0;            
00085 
00086     if ( filename == NULL || H == NULL )
00087     {
00088         fprintf( stderr, "** rg4h : bad params: %p, %p\n", filename, H );
00089         return -1;
00090     }
00091 
00092     file_len = THD_filesize( filename );
00093 
00094     
00095     if ( file_len != (GE4_HEADER_LENGTH + GE4_IMAGE_SIZE) )
00096         return 1;
00097 
00098     
00099     memset( H, 0, sizeof(ge4_header) );
00100 
00101     if ( (fp = fopen( filename, "r" )) == NULL )
00102     {
00103         fprintf( stderr, "ge4_read_header: failed to open '%s' for reading\n",
00104                  filename);
00105         return -1;
00106     }
00107 
00108     
00109 
00110     sh = &H->ser_h;     
00111     ih = &H->im_h;      
00112     st = &H->std_h;     
00113 
00114     fseek( fp, GE4_OFF_STDY_TITLE, SEEK_SET );
00115     rres |= (1 - fread( st->title, GE4_L_STDY_TITLE, 1, fp ));
00116 
00117     fseek( fp, GE4_OFF_SER_TITLE, SEEK_SET );
00118     rres |= (1 - fread( sh->title, GE4_L_SER_TITLE, 1, fp ));
00119 
00120     fseek( fp, GE4_OFF_IMG_TITLE, SEEK_SET );
00121     rres |= (1 - fread( ih->title, GE4_L_IM_TITLE, 1, fp ));
00122 
00123     
00124     if ( rres                                                     ||
00125          strncmp( st->title, GE4_STUDY_TITLE,  GE4_L_STDY_TITLE ) ||
00126          strncmp( sh->title, GE4_SERIES_TITLE, GE4_L_SER_TITLE  ) ||
00127          strncmp( ih->title, GE4_IMAGE_TITLE,  GE4_L_IM_TITLE   )
00128        )
00129         return 1;
00130 
00131 
00132     
00133 
00134     fseek( fp, GE4_OFF_STDY_NUM, SEEK_SET );
00135     rres |= (1 - fread( st->num, GE4_L_STDY_NUM, 1, fp ));
00136 
00137     fseek( fp, GE4_OFF_STDY_DATE, SEEK_SET );
00138     rres |= (1 - fread( st->date, GE4_L_STDY_DATE, 1, fp ));
00139 
00140     fseek( fp, GE4_OFF_STDY_TIME, SEEK_SET );
00141     rres |= (1 - fread( st->time, GE4_L_STDY_TIME, 1, fp ));
00142 
00143     fseek( fp, GE4_OFF_STDY_PAT_NAME, SEEK_SET );
00144     rres |= (1 - fread( st->pat_name, GE4_L_STDY_PAT_NAME, 1, fp ));
00145 
00146     fseek( fp, GE4_OFF_STDY_PAT_ID, SEEK_SET );
00147     rres |= (1 - fread( st->pat_id, GE4_L_STDY_PAT_ID, 1, fp ));
00148 
00149     fseek( fp, GE4_OFF_STDY_AGE, SEEK_SET );
00150     rres |= (1 - fread( st->age, GE4_L_STDY_AGE, 1, fp ));
00151 
00152     fseek( fp, GE4_OFF_STDY_SEX, SEEK_SET );
00153     rres |= (1 - fread( &st->sex, 1, 1, fp ));
00154 
00155     
00156 
00157     fseek( fp, GE4_OFF_SER_SERIES_NUM, SEEK_SET );
00158     rres |= (1 - fread( sh->series_num, GE4_L_SER_SER_NUM, 1, fp ));
00159 
00160     fseek( fp, GE4_OFF_SER_PLANE_TYPE, SEEK_SET );
00161     rres |= (1 - fread( &sh->plane_type, sizeof(sh->plane_type), 1, fp ));
00162 
00163     fseek( fp, GE4_OFF_SER_PLANE_DESC, SEEK_SET );
00164     rres |= (1 - fread( sh->plane_desc, GE4_L_SER_PL_DESC, 1, fp ));
00165 
00166     fseek( fp, GE4_OFF_SER_IM_MODE, SEEK_SET );
00167     rres |= (1 - fread( &sh->im_mode, sizeof(sh->im_mode), 1, fp ));
00168 
00169     fseek( fp, GE4_OFF_SER_PULSE_SEQ, SEEK_SET );
00170     rres |= (1 - fread( &sh->pulse_seq, sizeof(sh->pulse_seq), 1, fp ));
00171 
00172     fseek( fp, GE4_OFF_SER_FOV, SEEK_SET );
00173     rres |= (1 - fread( &sh->fov, sizeof(sh->fov), 1, fp ));
00174 
00175     fseek( fp, GE4_OFF_SER_CENTER, SEEK_SET );
00176     rres |= (1 - fread( sh->center, sizeof(sh->center), 1, fp ));
00177 
00178     fseek( fp, GE4_OFF_SER_ORIENT, SEEK_SET );
00179     rres |= (1 - fread( &sh->orient, sizeof(sh->orient), 1, fp ));
00180 
00181     fseek( fp, GE4_OFF_SER_SCAN_MAT_X, SEEK_SET );
00182     rres |= (1 - fread( &sh->scan_mat_x, sizeof(sh->scan_mat_x), 1, fp ));
00183 
00184     fseek( fp, GE4_OFF_SER_SCAN_MAT_Y, SEEK_SET );
00185     rres |= (1 - fread( &sh->scan_mat_y, sizeof(sh->scan_mat_y), 1, fp ));
00186 
00187     fseek( fp, GE4_OFF_SER_IM_MAT, SEEK_SET );
00188     rres |= (1 - fread( &sh->im_mat, sizeof(sh->im_mat), 1, fp ));
00189 
00190 
00191     
00192 
00193     fseek( fp, GE4_OFF_IMG_IM_NUM, SEEK_SET );
00194     rres |= (1 - fread( ih->im_num, GE4_L_IM_NUM, 1, fp ));
00195 
00196     fseek( fp, GE4_OFF_IMG_IM_LOCN, SEEK_SET );
00197     rres |= (1 - fread( &ih->im_loc, sizeof(ih->im_loc), 1, fp ));
00198 
00199     fseek( fp, GE4_OFF_IMG_TABLE_POSN, SEEK_SET );
00200     rres |= (1 - fread( &ih->table_posn, sizeof(ih->table_posn), 1, fp ));
00201 
00202     fseek( fp, GE4_OFF_IMG_IM_THICK, SEEK_SET );
00203     rres |= (1 - fread( &ih->im_thickness, sizeof(ih->im_thickness), 1, fp ));
00204 
00205     fseek( fp, GE4_OFF_IMG_IM_SPACING, SEEK_SET );
00206     rres |= (1 - fread( &ih->im_spacing, sizeof(ih->im_spacing), 1, fp ));
00207 
00208     fseek( fp, GE4_OFF_IMG_TR, SEEK_SET );
00209     rres |= (1 - fread( &ih->tr, sizeof(ih->tr), 1, fp ));
00210 
00211     fseek( fp, GE4_OFF_IMG_TE, SEEK_SET );
00212     rres |= (1 - fread( &ih->te, sizeof(ih->te), 1, fp ));
00213 
00214     fseek( fp, GE4_OFF_IMG_TI, SEEK_SET );
00215     rres |= (1 - fread( &ih->ti, sizeof(ih->ti), 1, fp ));
00216 
00217     fseek( fp, GE4_OFF_IMG_NUM_ECHOS, SEEK_SET );
00218     rres |= (1 - fread( &ih->num_echoes, sizeof(ih->num_echoes), 1, fp ));
00219 
00220     fseek( fp, GE4_OFF_IMG_ECHO_NUM, SEEK_SET );
00221     rres |= (1 - fread( &ih->echo_num, sizeof(ih->echo_num), 1, fp ));
00222 
00223     fseek( fp, GE4_OFF_IMG_NEX_INT, SEEK_SET );
00224     rres |= (1 - fread( &ih->iNEX, sizeof(ih->iNEX), 1, fp ));
00225 
00226     fseek( fp, GE4_OFF_IMG_NEX_REAL, SEEK_SET );
00227     rres |= (1 - fread( &ih->fNEX, sizeof(ih->fNEX), 1, fp ));
00228 
00229     fseek( fp, GE4_OFF_IMG_FLIP_ANGLE, SEEK_SET );
00230     rres |= (1 - fread( &ih->flip_angle, sizeof(ih->flip_angle), 1, fp ));
00231 
00232     if ( rres )
00233     {
00234         fprintf( stderr, "** failed to read ge4 header for '%s'\n", filename );
00235         return -1;
00236     }
00237 
00238     if ( ge4_validate_header( H ) )
00239         return 1;
00240 
00241     if ( get_image )
00242     {
00243         if ( (H->image = (short *)malloc( GE4_IMAGE_SIZE )) == NULL )
00244         {
00245             fprintf( stderr, "** failed to allocate %d bytes for image\n",
00246                      GE4_IMAGE_SIZE );
00247             return -1;
00248         }
00249 
00250         fseek( fp, GE4_HEADER_LENGTH, SEEK_SET );
00251         rres = fread( H->image, GE4_IMAGE_SIZE, 1, fp );
00252 
00253         if ( rres != 1 )
00254         {
00255             fprintf( stderr, "** failed to read ge4 image for file '%s'\n",
00256                      filename );
00257             free( H->image );
00258             return -1;
00259         }
00260 
00261         H->im_bytes = GE4_IMAGE_SIZE;          
00262 
00263         if ( H->swap )
00264             swap_2_multi( H->image, GE4_IMAGE_SIZE/2 );
00265     }
00266 
00267     return 0;
00268 }
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 int ge4_validate_header( ge4_header * h )
00286 {
00287     ge4_series_t * s;
00288     ge4_image_t  * im;
00289 
00290     if ( h == NULL )
00291         return -1;
00292 
00293     s  = &h->ser_h;
00294     im = &h->im_h;
00295 
00296     
00297 
00298     if ( (s->plane_type < 0) || (s->plane_type > 4) ||
00299          (s->im_mode    < 0) || (s->im_mode    > 4) ||
00300          (s->pulse_seq  < 0) || (s->pulse_seq  > 25) )
00301     {
00302         ge4_swap_all_bytes( h );
00303     }
00304 
00305     
00306     if ( (s->plane_type < 0) || (s->plane_type > 4) ||
00307          (s->im_mode    < 0) || (s->im_mode    > 4) ||
00308          (s->pulse_seq  < 0) || (s->pulse_seq  > 25) )
00309     {
00310         return -1;
00311     }
00312 
00313     return 0;
00314 }
00315 
00316 
00317 
00318 
00319 
00320 
00321 int ge4_swap_all_bytes( ge4_header * h )
00322 {
00323     if ( h == NULL )
00324     {
00325         fprintf( stderr, "** ge4_SAB : no header!\n" );
00326         return -1;
00327     }
00328 
00329     h->swap = 1;                
00330 
00331     
00332 
00333     swap_2( &h->ser_h.plane_type );
00334     swap_2( &h->ser_h.im_mode );
00335     swap_2( &h->ser_h.pulse_seq );
00336 
00337     swap_4( &h->ser_h.fov );
00338     swap_4( &h->ser_h.center[0] );
00339     swap_4( &h->ser_h.center[1] );
00340     swap_4( &h->ser_h.center[2] );
00341 
00342     swap_2( &h->ser_h.orient );
00343     swap_2( &h->ser_h.scan_mat_x );
00344     swap_2( &h->ser_h.scan_mat_y );
00345     swap_2( &h->ser_h.im_mat );
00346 
00347     
00348 
00349     swap_4( &h->im_h.im_loc );
00350     swap_4( &h->im_h.table_posn );
00351     swap_4( &h->im_h.im_thickness );
00352     swap_4( &h->im_h.im_spacing );
00353 
00354     swap_4( &h->im_h.tr );
00355     swap_4( &h->im_h.te );
00356     swap_4( &h->im_h.ti );
00357 
00358     swap_2( &h->im_h.num_echoes );
00359     swap_2( &h->im_h.echo_num );
00360 
00361     swap_2( &h->im_h.iNEX );
00362     swap_4( &h->im_h.fNEX );
00363 
00364     swap_2( &h->im_h.flip_angle );
00365 
00366     return 0;
00367 }
00368 
00369 
00370 
00371 
00372 
00373 
00374 int idisp_ge4_study_header( char * info, ge4_study_t * st )
00375 {
00376     if ( info )
00377         fputs( info, stdout );
00378 
00379     if ( st == NULL )
00380     {
00381         printf( "r_idisp_ge4_study_t: st == NULL" );
00382         return -1;
00383     }
00384 
00385     printf( " ge4_study_t at %p :\n"
00386             "    title                    = %s\n"
00387             "    num                      = %s\n"
00388             "    date                     = %s\n"
00389             "    time                     = %s\n"
00390             "    pat_name                 = %s\n"
00391             "    pat_id                   = %s\n"
00392             "    age                      = %s\n"
00393             "    sex                      = %c\n",
00394             st, st->title, st->num, st->date, st->time,
00395             st->pat_name, st->pat_id, st->age, st->sex
00396             );
00397 
00398     return 0;
00399 }
00400 
00401 
00402 
00403 
00404 
00405 
00406 int idisp_ge4_image_header( char * info, ge4_image_t * im )
00407 {
00408     if ( info )
00409         fputs( info, stdout );
00410 
00411     if ( im == NULL )
00412     {
00413         printf( "r_idisp_ge4_image_t: im == NULL" );
00414         return -1;
00415     }
00416 
00417     printf( " ge4_image_t at %p :\n"
00418             "    title                    = %s\n"
00419             "    im_num                   = %s\n"
00420             "    im_loc                   = %.3f\n"
00421             "    table_posn               = %.3f\n"
00422             "    im_thickness             = %.3f\n"
00423             "    im_spacing               = %.3f\n"
00424             "    tr (in ms)               = %.3f\n"
00425             "    te (in ms)               = %.3f\n"
00426             "    ti (in ms)               = %.3f\n"
00427             "    num_echoes               = %d\n"
00428             "    echo_num                 = %d\n"
00429             "    iNEX                     = %d\n"
00430             "    fNEX                     = %.3f\n"
00431             "    flip_angle               = %d\n",
00432             im, im->title, im->im_num, im->im_loc, im->table_posn,
00433             im->im_thickness, im->im_spacing, im->tr, im->te, im->ti,
00434             im->num_echoes, im->echo_num, im->iNEX, im->fNEX, im->flip_angle
00435             );
00436 
00437     return 0;
00438 }
00439 
00440 
00441 
00442 
00443 
00444 
00445 int idisp_ge4_series_header( char * info, ge4_series_t * s )
00446 {
00447     if ( info )
00448         fputs( info, stdout );
00449 
00450     if ( s == NULL )
00451     {
00452         printf( "r_idisp_ge4_series_t: s == NULL" );
00453         return -1;
00454     }
00455 
00456     printf( " ge4_series_t at %p :\n"
00457             "    title                    = %s\n"
00458             "    series_num               = %s\n"
00459             "    plane_type, plane_desc   = %d, %s\n"
00460             "    image_mode               = %d (%s)\n"
00461             "    pulse_seq                = %d (%s)\n"
00462             "    FOV (in mm)              = %.3f\n"
00463             "    center[0], c[1], c[2]    = %.3f, %.3f, %.3f\n"
00464             "    orient                   = %d (%s)\n"
00465             "    scan_mat_x, scan_mat_y   = %d, %d\n"
00466             "    im_mat                   = %d\n",
00467             s, s->title, s->series_num, s->plane_type, s->plane_desc,
00468             s->im_mode, GE4M_IND2STR(s->im_mode, g_ge4_sl_im_modes),
00469             s->pulse_seq, GE4M_IND2STR(s->pulse_seq, g_ge4_sl_pulse_seqs),
00470             s->fov, s->center[0], s->center[1], s->center[2],
00471             s->orient, GE4M_IND2STR(s->orient,g_ge4_sl_orient),
00472             s->scan_mat_x, s->scan_mat_y, s->im_mat
00473             );
00474 
00475     return 0;
00476 }
00477 
00478 
00479 
00480 
00481 
00482 
00483 static int swap_2_multi( void * ptr, int num_shorts )
00484 {
00485     unsigned char * cp0, * cp1;
00486     unsigned char   tmpc;
00487     int             index;
00488 
00489     if ( ptr == NULL ) return -1;
00490 
00491     cp0 = (unsigned char *)ptr;
00492     cp1 = cp0 + 1;
00493 
00494     for ( index = 0; index < num_shorts; index++ )
00495     {
00496         tmpc = *cp0;
00497         *cp0 = *cp1;
00498         *cp1 = tmpc;
00499 
00500         cp0 += 2;
00501         cp1 += 2;
00502     }
00503 
00504     return 0;
00505 }
00506 
00507 
00508 
00509 
00510 
00511 
00512 static int swap_4( void * ptr )         
00513 {
00514    unsigned char * addr = ptr;
00515 
00516    addr[0] ^= addr[3]; addr[3] ^= addr[0]; addr[0] ^= addr[3];
00517    addr[1] ^= addr[2]; addr[2] ^= addr[1]; addr[1] ^= addr[2];
00518 
00519    return 0;
00520 }
00521 
00522 
00523 
00524 
00525 
00526 static int swap_2( void * ptr )         
00527 {
00528    unsigned char * addr = ptr;
00529 
00530    addr[0] ^= addr[1]; addr[1] ^= addr[0]; addr[0] ^= addr[1];
00531 
00532    return 0;
00533 }
00534 
00535