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