Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

object_io.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 1993,1994,1995 David MacDonald, 00004 McConnell Brain Imaging Centre, 00005 Montreal Neurological Institute, McGill University. 00006 Permission to use, copy, modify, and distribute this 00007 software and its documentation for any purpose and without 00008 fee is hereby granted, provided that the above copyright 00009 notice appear in all copies. The author and McGill University 00010 make no representations about the suitability of this 00011 software for any purpose. It is provided "as is" without 00012 express or implied warranty. 00013 ---------------------------------------------------------------------------- */ 00014 00015 #include <volume_io/internal_volume_io.h> 00016 #include <bicpl/objects.h> 00017 #include <bicpl/geom.h> 00018 00019 #ifndef lint 00020 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Objects/object_io.c,v 1.29 2001/10/19 19:59:23 stever Exp $"; 00021 #endif 00022 00023 00169 private Status io_vectors( 00170 FILE *file, 00171 IO_types io_flag, 00172 File_formats format, 00173 int n, 00174 Vector *vectors[] ); 00175 private Status io_line_thickness( 00176 FILE *file, 00177 IO_types io_flag, 00178 File_formats format, 00179 float *line_thickness ); 00180 private Status io_end_indices( 00181 FILE *file, 00182 IO_types io_flag, 00183 File_formats format, 00184 int n_items, 00185 int *end_indices[], 00186 int min_size ); 00187 private Status io_points( 00188 FILE *file, 00189 IO_types io_flag, 00190 File_formats format, 00191 int n, 00192 Point *points[] ); 00193 00194 /* ----------------------------- MNI Header ----------------------------------- 00195 @NAME : io_lines 00196 @INPUT : file 00197 io_flag 00198 format 00199 lines 00200 @OUTPUT : (lines) 00201 @RETURNS : OK or ERROR 00202 @DESCRIPTION: Reads or writes a lines structure in ascii or binary format. 00203 @METHOD : 00204 @GLOBALS : 00205 @CALLS : 00206 @CREATED : 1993 David MacDonald 00207 @MODIFIED : 00208 ---------------------------------------------------------------------------- */ 00209 00210 public Status io_lines( 00211 FILE *file, 00212 IO_types io_flag, 00213 File_formats format, 00214 lines_struct *lines ) 00215 { 00216 Status status; 00217 00218 status = OK; 00219 00220 if( io_flag == READ_FILE ) 00221 { 00222 initialize_lines( lines, WHITE ); 00223 FREE( lines->colours ); 00224 } 00225 00226 if( io_flag == READ_FILE || 00227 (lines->n_points > 0 && lines->n_items > 0) ) 00228 { 00229 status = io_object_type( file, io_flag, format, LINES ); 00230 00231 if( status == OK ) 00232 status = io_line_thickness( file, io_flag, format, 00233 &lines->line_thickness ); 00234 00235 if( status == OK ) 00236 status = io_int( file, io_flag, format, &lines->n_points ); 00237 00238 if( status == OK ) 00239 status = io_newline( file, io_flag, format ); 00240 00241 if( status == OK ) 00242 { 00243 status = io_points( file, io_flag, format, 00244 lines->n_points, &lines->points ); 00245 } 00246 00247 if( status == OK ) 00248 status = io_newline( file, io_flag, format ); 00249 00250 if( status == OK ) 00251 status = io_int( file, io_flag, format, &lines->n_items ); 00252 00253 if( status == OK ) 00254 status = io_newline( file, io_flag, format ); 00255 00256 if( status == OK ) 00257 { 00258 status = io_colours( file, io_flag, format, &lines->colour_flag, 00259 lines->n_items, lines->n_points, 00260 &lines->colours ); 00261 } 00262 00263 if( status == OK ) 00264 status = io_newline( file, io_flag, format ); 00265 00266 if( status == OK ) 00267 { 00268 status = io_end_indices( file, io_flag, format, 00269 lines->n_items, &lines->end_indices, 1 ); 00270 } 00271 00272 if( status == OK ) 00273 status = io_newline( file, io_flag, format ); 00274 00275 if( status == OK ) 00276 { 00277 status = io_ints( file, io_flag, format, 00278 NUMBER_INDICES(*lines), 00279 &lines->indices ); 00280 } 00281 } 00282 00283 return( status ); 00284 } 00285 00286 /* ----------------------------- MNI Header ----------------------------------- 00287 @NAME : io_marker 00288 @INPUT : file 00289 io_flag 00290 format 00291 marker 00292 @OUTPUT : (marker) 00293 @RETURNS : OK or ERROR 00294 @DESCRIPTION: Reads or writes a marker structure in ascii or binary format. 00295 @METHOD : 00296 @GLOBALS : 00297 @CALLS : 00298 @CREATED : 1993 David MacDonald 00299 @MODIFIED : 00300 ---------------------------------------------------------------------------- */ 00301 00302 public Status io_marker( 00303 FILE *file, 00304 IO_types io_flag, 00305 File_formats format, 00306 marker_struct *marker ) 00307 { 00308 Status status; 00309 00310 status = io_object_type( file, io_flag, format, MARKER ); 00311 00312 if( status == OK ) 00313 status = io_int( file, io_flag, format, (int *) &marker->type ); 00314 00315 if( status == OK ) 00316 status = io_real( file, io_flag, format, &marker->size ); 00317 00318 if( status == OK ) 00319 status = io_colour( file, io_flag, format, &marker->colour ); 00320 00321 if( status == OK ) 00322 status = io_point( file, io_flag, format, &marker->position ); 00323 00324 if( status == OK ) 00325 status = io_int( file, io_flag, format, &marker->structure_id ); 00326 00327 if( status == OK ) 00328 status = io_int( file, io_flag, format, &marker->patient_id ); 00329 00330 if( status == OK ) 00331 status = io_quoted_string( file, io_flag, format, &marker->label ); 00332 00333 if( status == OK ) 00334 status = io_newline( file, io_flag, format ); 00335 00336 return( status ); 00337 } 00338 00339 /* ----------------------------- MNI Header ----------------------------------- 00340 @NAME : io_model 00341 @INPUT : file 00342 io_flag 00343 format 00344 model 00345 @OUTPUT : (model) 00346 @RETURNS : OK or ERROR 00347 @DESCRIPTION: Reads or writes a model structure in ascii or binary format. 00348 Rather than writing all the objects in the model, it simply 00349 writes the name of the file containing the objects. A 00350 separate call (e.g. output_graphics_file) must be made to 00351 input or output the objects in the model. 00352 @METHOD : 00353 @GLOBALS : 00354 @CALLS : 00355 @CREATED : 1993 David MacDonald 00356 @MODIFIED : 00357 ---------------------------------------------------------------------------- */ 00358 00359 public Status io_model( 00360 FILE *file, 00361 IO_types io_flag, 00362 File_formats format, 00363 model_struct *model ) 00364 { 00365 Status status; 00366 00367 status = io_object_type( file, io_flag, format, MODEL ); 00368 00369 if( status == OK ) 00370 status = io_quoted_string( file, io_flag, format, &model->filename ); 00371 00372 if( status == OK ) 00373 status = io_newline( file, io_flag, format ); 00374 00375 return( status ); 00376 } 00377 00378 /* ----------------------------- MNI Header ----------------------------------- 00379 @NAME : io_pixels 00380 @INPUT : file 00381 io_flag 00382 format 00383 pixels 00384 @OUTPUT : (pixels) 00385 @RETURNS : OK or ERROR 00386 @DESCRIPTION: Reads or writes a pixels structure in ascii or binary format. 00387 @METHOD : 00388 @GLOBALS : 00389 @CALLS : 00390 @CREATED : 1993 David MacDonald 00391 @MODIFIED : 00392 ---------------------------------------------------------------------------- */ 00393 00394 public Status io_pixels( 00395 FILE *file, 00396 IO_types io_flag, 00397 File_formats format, 00398 pixels_struct *pixels ) 00399 { 00400 Status status; 00401 int n_pixels; 00402 00403 status = OK; 00404 00405 if( io_flag == READ_FILE || (pixels->x_size > 0 && pixels->y_size > 0) ) 00406 { 00407 status = io_object_type( file, io_flag, format, PIXELS ); 00408 00409 if( status == OK ) 00410 status = io_int( file, io_flag, format, (int *)&pixels->pixel_type); 00411 00412 if( status == OK ) 00413 status = io_int( file, io_flag, format, &pixels->x_size ); 00414 00415 if( status == OK ) 00416 status = io_int( file, io_flag, format, &pixels->y_size ); 00417 00418 if( status == OK && io_flag == READ_FILE ) 00419 { 00420 pixels->x_position = 0; 00421 pixels->y_position = 0; 00422 pixels->x_zoom = 1.0; 00423 pixels->y_zoom = 1.0; 00424 } 00425 00426 if( status == OK ) 00427 { 00428 n_pixels = pixels->x_size * pixels->y_size; 00429 00430 switch( pixels->pixel_type ) 00431 { 00432 case COLOUR_INDEX_8BIT_PIXEL: 00433 status = io_unsigned_chars( file, io_flag, format, n_pixels, 00434 &pixels->data.pixels_8bit_colour_index ); 00435 break; 00436 00437 case COLOUR_INDEX_16BIT_PIXEL: 00438 if( io_flag == READ_FILE ) 00439 ALLOC( pixels->data.pixels_16bit_colour_index, n_pixels ); 00440 00441 status = io_binary_data( file, io_flag, 00442 (void *) (&pixels->data.pixels_16bit_colour_index), 00443 sizeof(pixels->data.pixels_16bit_colour_index[0]), 00444 n_pixels ); 00445 break; 00446 00447 case RGB_PIXEL: 00448 status = io_pixel_colours( file, io_flag, format, n_pixels, 00449 &pixels->data.pixels_rgb ); 00450 break; 00451 00452 default: 00453 print_error( "Error, unrecognized pixel type %d.\n", 00454 pixels->pixel_type ); 00455 status = ERROR; 00456 } 00457 } 00458 } 00459 00460 return( status ); 00461 } 00462 00463 static BOOLEAN use_compressed = FALSE; 00464 static BOOLEAN compressed_initialized = FALSE; 00465 00466 private BOOLEAN use_compressed_polygons( void ) 00467 { 00468 if( !compressed_initialized ) 00469 { 00470 compressed_initialized = TRUE; 00471 use_compressed = getenv( "USE_COMPRESSED_POLYGONS" ) != NULL; 00472 } 00473 00474 return( use_compressed ); 00475 } 00476 00477 public void set_use_compressed_polygons_flag( 00478 BOOLEAN value ) 00479 { 00480 use_compressed = value; 00481 compressed_initialized = TRUE; 00482 } 00483 00484 public BOOLEAN get_use_compressed_polygons_flag( void ) 00485 { 00486 return( use_compressed_polygons() ); 00487 } 00488 00489 /* ----------------------------- MNI Header ----------------------------------- 00490 @NAME : io_polygons 00491 @INPUT : file 00492 io_flag 00493 format 00494 polygons 00495 @OUTPUT : (polygons) 00496 @RETURNS : OK or ERROR 00497 @DESCRIPTION: Reads or writes a polygons structure in ascii or binary format. 00498 @METHOD : 00499 @GLOBALS : 00500 @CALLS : 00501 @CREATED : 1993 David MacDonald 00502 @MODIFIED : Mar. 23, 1997 D. MacDonald - added compressed polygons. 00503 ---------------------------------------------------------------------------- */ 00504 00505 public Status io_polygons( 00506 FILE *file, 00507 IO_types io_flag, 00508 File_formats format, 00509 polygons_struct *polygons ) 00510 { 00511 int n_items; 00512 Status status; 00513 Surfprop save_surfprop; 00514 Point centre; 00515 BOOLEAN compressed_format; 00516 00517 status = OK; 00518 00519 if( io_flag == READ_FILE ) 00520 { 00521 initialize_polygons( polygons, WHITE, NULL ); 00522 FREE( polygons->colours ); 00523 } 00524 00525 if( io_flag == READ_FILE || 00526 (polygons->n_points > 0 && polygons->n_items > 0) ) 00527 { 00528 status = io_object_type( file, io_flag, format, POLYGONS ); 00529 00530 if( status == OK ) 00531 status = io_surfprop( file, io_flag, format, &polygons->surfprop ); 00532 00533 compressed_format = FALSE; 00534 00535 if( status == OK ) 00536 { 00537 if( io_flag == WRITE_FILE && use_compressed_polygons() && 00538 is_this_tetrahedral_topology(polygons) ) 00539 { 00540 n_items = -polygons->n_items; 00541 status = io_int( file, io_flag, format, &n_items ); 00542 compressed_format = TRUE; 00543 } 00544 else 00545 status = io_int( file, io_flag, format, &polygons->n_points ); 00546 } 00547 00548 if( status == OK ) 00549 status = io_newline( file, io_flag, format ); 00550 00551 if( io_flag == READ_FILE && polygons->n_points < 0 ) 00552 { 00553 n_items = -polygons->n_points; 00554 compressed_format = TRUE; 00555 fill_Point( centre, 0.0, 0.0, 0.0 ); 00556 save_surfprop = polygons->surfprop; 00557 create_tetrahedral_sphere( &centre, 1.0, 1.0, 1.0, n_items, 00558 polygons ); 00559 polygons->surfprop = save_surfprop; 00560 FREE( polygons->points ); 00561 } 00562 00563 if( status == OK ) 00564 { 00565 status = io_points( file, io_flag, format, 00566 polygons->n_points, &polygons->points ); 00567 } 00568 00569 if( status == OK ) 00570 status = io_newline( file, io_flag, format ); 00571 00572 if( !compressed_format ) 00573 { 00574 if( status == OK ) 00575 { 00576 status = io_vectors( file, io_flag, format, 00577 polygons->n_points, &polygons->normals ); 00578 } 00579 00580 if( status == OK ) 00581 status = io_newline( file, io_flag, format ); 00582 00583 if( status == OK ) 00584 status = io_int( file, io_flag, format, &polygons->n_items ); 00585 00586 if( status == OK ) 00587 status = io_newline( file, io_flag, format ); 00588 } 00589 00590 if( status == OK ) 00591 { 00592 status = io_colours( file, io_flag, format, &polygons->colour_flag, 00593 polygons->n_items, polygons->n_points, 00594 &polygons->colours ); 00595 00596 if( status == OK ) 00597 status = io_newline( file, io_flag, format ); 00598 } 00599 00600 if( !compressed_format ) 00601 { 00602 if( status == OK ) 00603 { 00604 status = io_end_indices( file, io_flag, format, 00605 polygons->n_items, &polygons->end_indices, 00606 3 ); 00607 } 00608 00609 if( status == OK ) 00610 status = io_newline( file, io_flag, format ); 00611 00612 if( status == OK ) 00613 { 00614 status = io_ints( file, io_flag, format, 00615 NUMBER_INDICES(*polygons), 00616 &polygons->indices ); 00617 } 00618 00619 if( status == OK ) 00620 status = io_newline( file, io_flag, format ); 00621 } 00622 00623 if( io_flag == READ_FILE && compressed_format ) 00624 compute_polygon_normals( polygons ); 00625 00626 if( io_flag == READ_FILE ) 00627 polygons->line_thickness = 1.0f; 00628 } 00629 00630 return( status ); 00631 } 00632 00633 /* ----------------------------- MNI Header ----------------------------------- 00634 @NAME : io_quadmesh 00635 @INPUT : file 00636 io_flag 00637 format 00638 quadmesh 00639 @OUTPUT : (quadmesh) 00640 @RETURNS : OK or ERROR 00641 @DESCRIPTION: Reads or writes a quadmesh structure in ascii or binary format. 00642 @METHOD : 00643 @GLOBALS : 00644 @CALLS : 00645 @CREATED : 1993 David MacDonald 00646 @MODIFIED : 00647 ---------------------------------------------------------------------------- */ 00648 00654 public Status io_quadmesh( 00655 FILE *file, 00656 IO_types io_flag, 00657 File_formats format, 00658 quadmesh_struct *quadmesh ) 00659 { 00660 Status status; 00661 00662 status = OK; 00663 00664 if( io_flag == READ_FILE ) 00665 { 00666 initialize_quadmesh( quadmesh, WHITE, NULL, 0, 0 ); 00667 FREE( quadmesh->colours ); 00668 } 00669 00670 if( io_flag == READ_FILE || 00671 (quadmesh->m > 1 && quadmesh->n > 1) ) 00672 { 00673 status = io_object_type( file, io_flag, format, QUADMESH ); 00674 00675 if( status == OK ) 00676 status = io_surfprop( file, io_flag, format, &quadmesh->surfprop ); 00677 00678 if( status == OK ) 00679 status = io_int( file, io_flag, format, &quadmesh->m ); 00680 00681 if( status == OK ) 00682 status = io_int( file, io_flag, format, &quadmesh->n ); 00683 00684 if( status == OK ) 00685 status = io_boolean( file, io_flag, format, &quadmesh->m_closed ); 00686 00687 if( status == OK ) 00688 status = io_boolean( file, io_flag, format, &quadmesh->n_closed ); 00689 00690 if( status == OK ) 00691 status = io_newline( file, io_flag, format ); 00692 00693 if( status == OK ) 00694 status = io_colours( file, io_flag, format, &quadmesh->colour_flag, 00695 (quadmesh->m-1) * (quadmesh->n-1), 00696 quadmesh->m * quadmesh->n, 00697 &quadmesh->colours ); 00698 00699 if( status == OK ) 00700 status = io_newline( file, io_flag, format ); 00701 00702 if( status == OK ) 00703 { 00704 status = io_points( file, io_flag, format, 00705 quadmesh->m * quadmesh->n, &quadmesh->points ); 00706 } 00707 00708 if( status == OK ) 00709 status = io_newline( file, io_flag, format ); 00710 00711 if( status == OK ) 00712 { 00713 status = io_vectors( file, io_flag, format, 00714 quadmesh->m * quadmesh->n, &quadmesh->normals ); 00715 } 00716 00717 if( status == OK ) 00718 status = io_newline( file, io_flag, format ); 00719 } 00720 00721 return( status ); 00722 } 00723 00724 /* ----------------------------- MNI Header ----------------------------------- 00725 @NAME : io_text 00726 @INPUT : file 00727 io_flag 00728 format 00729 text 00730 @OUTPUT : (text) 00731 @RETURNS : OK or ERROR 00732 @DESCRIPTION: Reads or writes a text structure in ascii or binary format. 00733 @METHOD : 00734 @GLOBALS : 00735 @CALLS : 00736 @CREATED : 1993 David MacDonald 00737 @MODIFIED : 00738 ---------------------------------------------------------------------------- */ 00739 00740 public Status io_text( 00741 FILE *file, 00742 IO_types io_flag, 00743 File_formats format, 00744 text_struct *text ) 00745 { 00746 Status status; 00747 00748 status = io_object_type( file, io_flag, format, TEXT ); 00749 00750 if( status == OK ) 00751 status = io_int( file, io_flag, format, (int *) &text->font ); 00752 00753 if( status == OK ) 00754 status = io_real( file, io_flag, format, &text->size ); 00755 00756 if( status == OK ) 00757 status = io_colour( file, io_flag, format, &text->colour ); 00758 00759 if( status == OK ) 00760 status = io_point( file, io_flag, format, &text->origin ); 00761 00762 if( status == OK ) 00763 status = io_quoted_string( file, io_flag, format, &text->string ); 00764 00765 if( status == OK ) 00766 status = io_newline( file, io_flag, format ); 00767 00768 return( status ); 00769 } 00770 00771 /* ----------------------------- MNI Header ----------------------------------- 00772 @NAME : io_point 00773 @INPUT : file 00774 io_flag 00775 format 00776 point 00777 @OUTPUT : (point) 00778 @RETURNS : OK or ERROR 00779 @DESCRIPTION: Reads or writes a point structure in ascii or binary format. 00780 @METHOD : 00781 @GLOBALS : 00782 @CALLS : 00783 @CREATED : 1993 David MacDonald 00784 @MODIFIED : 00785 ---------------------------------------------------------------------------- */ 00786 00787 public Status io_point( 00788 FILE *file, 00789 IO_types io_flag, 00790 File_formats format, 00791 Point *point ) 00792 { 00793 Status status; 00794 00795 status = OK; 00796 00797 if( format == ASCII_FORMAT ) 00798 { 00799 status = io_float( file, io_flag, format, &Point_x(*point) ); 00800 00801 if( status == OK ) 00802 status = io_float( file, io_flag, format, &Point_y(*point) ); 00803 00804 if( status == OK ) 00805 status = io_float( file, io_flag, format, &Point_z(*point) ); 00806 } 00807 else 00808 { 00809 status = io_binary_data( file, io_flag, (void *) point, 00810 sizeof(*point), 1 ); 00811 } 00812 00813 return( status ); 00814 } 00815 00816 /* ----------------------------- MNI Header ----------------------------------- 00817 @NAME : io_vector 00818 @INPUT : file 00819 io_flag 00820 format 00821 vector 00822 @OUTPUT : (vector) 00823 @RETURNS : OK or ERROR 00824 @DESCRIPTION: Reads or writes a vector structure in ascii or binary format. 00825 @METHOD : 00826 @GLOBALS : 00827 @CALLS : 00828 @CREATED : 1993 David MacDonald 00829 @MODIFIED : 00830 ---------------------------------------------------------------------------- */ 00831 00832 public Status io_vector( 00833 FILE *file, 00834 IO_types io_flag, 00835 File_formats format, 00836 Vector *v ) 00837 { 00838 Status status; 00839 00840 status = OK; 00841 00842 if( format == ASCII_FORMAT ) 00843 { 00844 status = io_float( file, io_flag, format, &Vector_x(*v) ); 00845 00846 if( status == OK ) 00847 status = io_float( file, io_flag, format, &Vector_y(*v)); 00848 00849 if( status == OK ) 00850 status = io_float( file, io_flag, format, &Vector_z(*v)); 00851 } 00852 else 00853 { 00854 status = io_binary_data( file, io_flag, (void *) v, sizeof(*v), 1 ); 00855 } 00856 00857 return( status ); 00858 } 00859 00860 /* ----------------------------- MNI Header ----------------------------------- 00861 @NAME : io_colour 00862 @INPUT : file 00863 io_flag 00864 format 00865 colour 00866 @OUTPUT : (colour) 00867 @RETURNS : OK or ERROR 00868 @DESCRIPTION: Reads or writes a colour in ascii or binary format. 00869 @METHOD : 00870 @GLOBALS : 00871 @CALLS : 00872 @CREATED : 1993 David MacDonald 00873 @MODIFIED : 00874 ---------------------------------------------------------------------------- */ 00875 00876 public Status io_colour( 00877 FILE *file, 00878 IO_types io_flag, 00879 File_formats format, 00880 Colour *colour ) 00881 { 00882 float r, g, b, a; 00883 unsigned char comps[4]; 00884 Status status; 00885 00886 status = OK; 00887 00888 if( format == ASCII_FORMAT ) 00889 { 00890 if( io_flag == WRITE_FILE ) 00891 { 00892 r = (float) get_Colour_r_0_1( *colour ); 00893 g = (float) get_Colour_g_0_1( *colour ); 00894 b = (float) get_Colour_b_0_1( *colour ); 00895 a = (float) get_Colour_a_0_1( *colour ); 00896 } 00897 00898 status = io_float( file, io_flag, ASCII_FORMAT, &r ); 00899 if( status == OK ) 00900 status = io_float( file, io_flag, ASCII_FORMAT, &g ); 00901 if( status == OK ) 00902 status = io_float( file, io_flag, ASCII_FORMAT, &b ); 00903 if( status == OK ) 00904 status = io_float( file, io_flag, ASCII_FORMAT, &a ); 00905 00906 if( io_flag == READ_FILE ) 00907 *colour = make_rgba_Colour_0_1( (Real) r, (Real) g, 00908 (Real) b, (Real) a ); 00909 } 00910 else 00911 { 00912 if( io_flag == WRITE_FILE ) 00913 { 00914 comps[3] = (unsigned char) get_Colour_r( *colour ); 00915 comps[2] = (unsigned char) get_Colour_g( *colour ); 00916 comps[1] = (unsigned char) get_Colour_b( *colour ); 00917 comps[0] = (unsigned char) get_Colour_a( *colour ); 00918 } 00919 00920 status = io_binary_data( file, io_flag, (void *) comps, 00921 sizeof(comps[0]), 4 ); 00922 00923 if( io_flag == READ_FILE ) 00924 { 00925 *colour = make_rgba_Colour( (int) comps[3], (int) comps[2], 00926 (int) comps[1], (int) comps[0]); 00927 } 00928 } 00929 00930 return( status ); 00931 } 00932 00933 /* ----------------------------- MNI Header ----------------------------------- 00934 @NAME : io_colours 00935 @INPUT : file 00936 io_flag 00937 format 00938 colour_flag 00939 n_items 00940 n_points 00941 colours 00942 @OUTPUT : (colours) 00943 @RETURNS : OK or ERROR 00944 @DESCRIPTION: Reads or writes a colour_flag and list of colours, where the 00945 number of colours depends on the colour flag. 00946 @METHOD : 00947 @GLOBALS : 00948 @CALLS : 00949 @CREATED : 1993 David MacDonald 00950 @MODIFIED : 00951 ---------------------------------------------------------------------------- */ 00952 00953 public Status io_colours( 00954 FILE *file, 00955 IO_types io_flag, 00956 File_formats format, 00957 Colour_flags *colour_flag, 00958 int n_items, 00959 int n_points, 00960 Colour **colours ) 00961 { 00962 int i, n_colours; 00963 Status status; 00964 00965 status = io_int( file, io_flag, format, (int *) colour_flag ); 00966 00967 if( status == OK ) 00968 { 00969 switch( *colour_flag ) 00970 { 00971 case ONE_COLOUR: n_colours = 1; break; 00972 case PER_ITEM_COLOURS: n_colours = n_items; break; 00973 case PER_VERTEX_COLOURS: n_colours = n_points; break; 00974 default: 00975 print_error( "Error inputting colour flag.\n" ); 00976 status = ERROR; 00977 break; 00978 } 00979 } 00980 00981 if( status == OK && io_flag == READ_FILE && n_colours > 0 ) 00982 ALLOC( *colours, n_colours ); 00983 00984 if( status == OK ) 00985 { 00986 for_less( i, 0, n_colours ) 00987 { 00988 status = io_colour( file, io_flag, format, &(*colours)[i] ); 00989 00990 if( status == OK ) 00991 status = io_newline( file, io_flag, format ); 00992 } 00993 } 00994 00995 return( status ); 00996 } 00997 00998 /* ----------------------------- MNI Header ----------------------------------- 00999 @NAME : io_surfprop 01000 @INPUT : file 01001 io_flag 01002 format 01003 surfprop 01004 @OUTPUT : (surfprop) 01005 @RETURNS : OK or ERROR 01006 @DESCRIPTION: Reads or writes a surfprop structure in ascii or binary format. 01007 @METHOD : 01008 @GLOBALS : 01009 @CALLS : 01010 @CREATED : 1993 David MacDonald 01011 @MODIFIED : 01012 ---------------------------------------------------------------------------- */ 01013 01014 public Status io_surfprop( 01015 FILE *file, 01016 IO_types io_flag, 01017 File_formats format, 01018 Surfprop *surfprop ) 01019 { 01020 Status status; 01021 01022 status = OK; 01023 01024 if( format == ASCII_FORMAT ) 01025 { 01026 status = io_float( file, io_flag, format, 01027 &Surfprop_a(*surfprop) ); 01028 01029 if( status == OK ) 01030 status = io_float( file, io_flag, format, &Surfprop_d(*surfprop) ); 01031 01032 if( status == OK ) 01033 status = io_float( file, io_flag, format, &Surfprop_s(*surfprop) ); 01034 01035 if( status == OK ) 01036 status = io_float( file, io_flag, format, &Surfprop_se(*surfprop) ); 01037 01038 if( status == OK ) 01039 status = io_float( file, io_flag, format, &Surfprop_t(*surfprop) ); 01040 01041 } 01042 else 01043 { 01044 status = io_binary_data( file, io_flag, (void *) surfprop, 01045 sizeof(*surfprop), 1 ); 01046 } 01047 01048 if( io_flag == READ_FILE && Surfprop_t(*surfprop) == 0.0f ) 01049 Surfprop_t(*surfprop) = 1.0f; 01050 01051 return( status ); 01052 } 01053 01054 /* ----------------------------- MNI Header ----------------------------------- 01055 @NAME : io_points 01056 @INPUT : file 01057 io_flag 01058 format 01059 n 01060 points 01061 @OUTPUT : (points) 01062 @RETURNS : OK or ERROR 01063 @DESCRIPTION: Reads or writes a list of points in ascii or binary format. 01064 @METHOD : 01065 @GLOBALS : 01066 @CALLS : 01067 @CREATED : 1993 David MacDonald 01068 @MODIFIED : 01069 ---------------------------------------------------------------------------- */ 01070 01071 private Status io_points( 01072 FILE *file, 01073 IO_types io_flag, 01074 File_formats format, 01075 int n, 01076 Point *points[] ) 01077 { 01078 Status status; 01079 int i; 01080 01081 status = OK; 01082 01083 if( io_flag == READ_FILE ) 01084 { 01085 ALLOC( *points, n ); 01086 } 01087 01088 if( status == OK ) 01089 { 01090 if( format == ASCII_FORMAT ) 01091 { 01092 for_less( i, 0, n ) 01093 { 01094 status = io_point( file, io_flag, format, &(*points)[i]); 01095 01096 if( status == OK ) 01097 status = io_newline( file, io_flag, format ); 01098 01099 if( status == ERROR ) 01100 break; 01101 } 01102 } 01103 else 01104 { 01105 status = io_binary_data( file, io_flag, (void *) (*points), 01106 sizeof((*points)[0]), n ); 01107 } 01108 } 01109 01110 return( status ); 01111 } 01112 01113 /* ----------------------------- MNI Header ----------------------------------- 01114 @NAME : io_vectors 01115 @INPUT : file 01116 io_flag 01117 format 01118 n 01119 vectors 01120 @OUTPUT : (vectors) 01121 @RETURNS : OK or ERROR 01122 @DESCRIPTION: Reads or writes a list of vectors in ascii or binary format. 01123 @METHOD : 01124 @GLOBALS : 01125 @CALLS : 01126 @CREATED : 1993 David MacDonald 01127 @MODIFIED : 01128 ---------------------------------------------------------------------------- */ 01129 01130 private Status io_vectors( 01131 FILE *file, 01132 IO_types io_flag, 01133 File_formats format, 01134 int n, 01135 Vector *vectors[] ) 01136 { 01137 Status status; 01138 int i; 01139 01140 status = OK; 01141 01142 if( io_flag == READ_FILE ) 01143 { 01144 ALLOC( *vectors, n ); 01145 } 01146 01147 if( format == ASCII_FORMAT ) 01148 { 01149 for_less( i, 0, n ) 01150 { 01151 status = io_vector( file, io_flag, format, &(*vectors)[i] ); 01152 01153 if( status == OK ) 01154 status = io_newline( file, io_flag, format ); 01155 01156 if( status == ERROR ) 01157 break; 01158 } 01159 } 01160 else 01161 { 01162 status = io_binary_data( file, io_flag, (void *) (*vectors), 01163 sizeof((*vectors)[0]), n ); 01164 } 01165 01166 return( status ); 01167 } 01168 01169 /* ----------------------------- MNI Header ----------------------------------- 01170 @NAME : io_object_type 01171 @INPUT : file 01172 io_flag 01173 format 01174 type 01175 @OUTPUT : 01176 @RETURNS : OK or ERROR 01177 @DESCRIPTION: Either writes an object type or if reading, does not read 01178 anything. 01179 @METHOD : 01180 @GLOBALS : 01181 @CALLS : 01182 @CREATED : 1993 David MacDonald 01183 @MODIFIED : 01184 ---------------------------------------------------------------------------- */ 01185 01186 public Status io_object_type( 01187 FILE *file, 01188 IO_types io_flag, 01189 File_formats format, 01190 Object_types type ) 01191 { 01192 int ch; 01193 Status status; 01194 01195 status = OK; 01196 01197 if( io_flag == WRITE_FILE ) 01198 { 01199 switch( type ) 01200 { 01201 case LINES: ch = 'l'; break; 01202 case MARKER: ch = 'm'; break; 01203 case MODEL: ch = 'f'; break; 01204 case PIXELS: ch = 'x'; break; 01205 case POLYGONS: ch = 'p'; break; 01206 case QUADMESH: ch = 'q'; break; 01207 case TEXT: ch = 't'; break; 01208 default: 01209 print_error( "io_object_type: object type %d not handled.\n", type ); 01210 return ERROR; 01211 } 01212 01213 if( format == ASCII_FORMAT ) 01214 { 01215 ch += 'A' - 'a'; 01216 } 01217 01218 if( fputc( ch, file ) == EOF ) 01219 { 01220 print_error( "Error outputting char.\n" ); 01221 status = ERROR; 01222 } 01223 } 01224 01225 return( status ); 01226 } 01227 01228 /* ----------------------------- MNI Header ----------------------------------- 01229 @NAME : input_object_type 01230 @INPUT : file 01231 @OUTPUT : type 01232 format 01233 eof 01234 @RETURNS : OK or ERROR 01235 @DESCRIPTION: Reads the object type, passing it back, as well as whether 01236 it is in ascii or binary format, and an eof flag. 01237 @METHOD : 01238 @GLOBALS : 01239 @CALLS : 01240 @CREATED : 1993 David MacDonald 01241 @MODIFIED : 01242 ---------------------------------------------------------------------------- */ 01243 01244 public Status input_object_type( 01245 FILE *file, 01246 Object_types *type, 01247 File_formats *format, 01248 BOOLEAN *eof ) 01249 { 01250 char ch; 01251 Status status; 01252 01253 status = OK; 01254 *eof = FALSE; 01255 01256 status = input_nonwhite_character( file, &ch ); 01257 01258 if( status == OK ) 01259 { 01260 if( ch >= 'A' && ch <= 'Z' ) 01261 { 01262 *format = ASCII_FORMAT; 01263 ch -= 'A' - 'a'; 01264 } 01265 else 01266 { 01267 *format = BINARY_FORMAT; 01268 } 01269 01270 switch( ch ) 01271 { 01272 case 'l': *type = LINES; break; 01273 case 'm': *type = MARKER; break; 01274 case 'f': *type = MODEL; break; 01275 case 'x': *type = PIXELS; break; 01276 case 'p': *type = POLYGONS; break; 01277 case 'q': *type = QUADMESH; break; 01278 case 't': *type = TEXT; break; 01279 /* 01280 case 'v': *type = VOLUME; break; 01281 */ 01282 01283 default: 01284 print_error( "Unrecognized object type in file.\n" ); 01285 status = ERROR; 01286 } 01287 } 01288 else 01289 { 01290 *eof = TRUE; 01291 status = OK; 01292 } 01293 01294 return( status ); 01295 } 01296 01297 #define PIXELS_PER_LINE 1 01298 #define BUFFER_SIZE 256 01299 01300 /* ----------------------------- MNI Header ----------------------------------- 01301 @NAME : io_pixel_colours 01302 @INPUT : file 01303 io_flag 01304 format 01305 n 01306 pixel_colours 01307 @OUTPUT : (pixel_colours) 01308 @RETURNS : OK or ERROR 01309 @DESCRIPTION: Reads or writes a list of pixel colours in ascii or binary format. 01310 @METHOD : 01311 @GLOBALS : 01312 @CALLS : 01313 @CREATED : 1993 David MacDonald 01314 @MODIFIED : 01315 ---------------------------------------------------------------------------- */ 01316 01317 public Status io_pixel_colours( 01318 FILE *file, 01319 IO_types io_flag, 01320 File_formats format, 01321 int n, 01322 Colour *pixel_colours[] ) 01323 { 01324 Status status; 01325 unsigned char buffer[3*BUFFER_SIZE]; 01326 Colour pixel_colour; 01327 int i, block, n_blocks, n_to_do, start_pixel_index; 01328 01329 status = OK; 01330 01331 if( io_flag == READ_FILE ) 01332 ALLOC( *pixel_colours, n ); 01333 01334 if( status == OK ) 01335 { 01336 if( format == ASCII_FORMAT ) 01337 { 01338 for_less( i, 0, n ) 01339 { 01340 status = io_pixel_colour( file, io_flag, format, 01341 &(*pixel_colours)[i] ); 01342 01343 if( status == OK ) 01344 { 01345 if( i == n - 1 || (i+1) % PIXELS_PER_LINE == 0 ) 01346 { 01347 status = io_newline( file, io_flag, format ); 01348 } 01349 } 01350 01351 if( status != OK ) 01352 break; 01353 } 01354 } 01355 else 01356 { 01357 n_blocks = n / BUFFER_SIZE; 01358 if( n % BUFFER_SIZE != 0 ) 01359 ++n_blocks; 01360 01361 for_less( block, 0, n_blocks ) 01362 { 01363 start_pixel_index = block * BUFFER_SIZE; 01364 n_to_do = BUFFER_SIZE; 01365 if( start_pixel_index + n_to_do > n ) 01366 n_to_do = n - start_pixel_index; 01367 01368 if( io_flag == WRITE_FILE ) 01369 { 01370 for_less( i, 0, n_to_do ) 01371 { 01372 pixel_colour = (*pixel_colours)[start_pixel_index+i]; 01373 buffer[3*i+0] = (unsigned char) 01374 get_Colour_r(pixel_colour); 01375 buffer[3*i+1] = (unsigned char) 01376 get_Colour_g(pixel_colour); 01377 buffer[3*i+2] = (unsigned char) 01378 get_Colour_b(pixel_colour); 01379 } 01380 } 01381 01382 status = io_binary_data( file, io_flag, (void *) buffer, 01383 sizeof(buffer[0]), 3 * n_to_do ); 01384 01385 if( io_flag == READ_FILE ) 01386 { 01387 for_less( i, 0, n_to_do ) 01388 { 01389 pixel_colour = make_Colour( (int) buffer[3*i+0], 01390 (int) buffer[3*i+1], 01391 (int) buffer[3*i+2] ); 01392 (*pixel_colours)[start_pixel_index+i] = pixel_colour; 01393 } 01394 } 01395 } 01396 } 01397 } 01398 01399 return( status ); 01400 } 01401 01402 /* ----------------------------- MNI Header ----------------------------------- 01403 @NAME : io_pixel_colour 01404 @INPUT : file 01405 io_flag 01406 format 01407 pixel_colour 01408 @OUTPUT : (pixel_colour) 01409 @RETURNS : OK or ERROR 01410 @DESCRIPTION: Reads or writes a pixel colour in ascii or binary format. 01411 @METHOD : 01412 @GLOBALS : 01413 @CALLS : 01414 @CREATED : 1993 David MacDonald 01415 @MODIFIED : 01416 ---------------------------------------------------------------------------- */ 01417 01418 public Status io_pixel_colour( 01419 FILE *file, 01420 IO_types io_flag, 01421 File_formats format, 01422 Colour *pixel_colour ) 01423 { 01424 int r, g, b; 01425 Status status; 01426 01427 status = OK; 01428 01429 if( format == ASCII_FORMAT ) 01430 { 01431 if( io_flag == WRITE_FILE ) 01432 { 01433 r = get_Colour_r( *pixel_colour ); 01434 g = get_Colour_g( *pixel_colour ); 01435 b = get_Colour_b( *pixel_colour ); 01436 } 01437 01438 status = io_int( file, io_flag, format, &r ); 01439 01440 if( status == OK ) 01441 status = io_int( file, io_flag, format, &g ); 01442 01443 if( status == OK ) 01444 status = io_int( file, io_flag, format, &b ); 01445 01446 if( io_flag == READ_FILE && status == OK ) 01447 *pixel_colour = make_Colour( r, g, b ); 01448 } 01449 else 01450 { 01451 status = io_binary_data( file, io_flag, (void *) pixel_colour, 01452 sizeof(*pixel_colour), 1 ); 01453 } 01454 01455 return( status ); 01456 } 01457 01458 /* ----------------------------- MNI Header ----------------------------------- 01459 @NAME : io_line_thickness 01460 @INPUT : file 01461 io_flag 01462 format 01463 line_thickness 01464 @OUTPUT : (line_thickness) 01465 @RETURNS : OK or ERROR 01466 @DESCRIPTION: Reads or writes a line thickness in ascii or binary format. 01467 @METHOD : 01468 @GLOBALS : 01469 @CALLS : 01470 @CREATED : 1993 David MacDonald 01471 @MODIFIED : 01472 ---------------------------------------------------------------------------- */ 01473 01474 private Status io_line_thickness( 01475 FILE *file, 01476 IO_types io_flag, 01477 File_formats format, 01478 float *line_thickness ) 01479 { 01480 Status status; 01481 01482 status = io_float( file, io_flag, format, line_thickness ); 01483 01484 if( status == OK && io_flag == READ_FILE && format == BINARY_FORMAT && 01485 (*line_thickness <= 0.001f || *line_thickness > 20.0f) ) 01486 *line_thickness = 1.0f; 01487 01488 return( status ); 01489 } 01490 01491 /* ----------------------------- MNI Header ----------------------------------- 01492 @NAME : input_object 01493 @INPUT : directory 01494 file 01495 @OUTPUT : format 01496 object 01497 eof 01498 @RETURNS : OK or ERROR 01499 @DESCRIPTION: Inputs an object from a file. 01500 @METHOD : 01501 @GLOBALS : 01502 @CALLS : 01503 @CREATED : 1993 David MacDonald 01504 @MODIFIED : 01505 ---------------------------------------------------------------------------- */ 01506 01507 public Status input_object( 01508 STRING directory, 01509 FILE *file, 01510 File_formats *format, 01511 object_struct **object, 01512 BOOLEAN *eof ) 01513 { 01514 Status status; 01515 File_formats sub_format; 01516 Object_types type; 01517 STRING abs_filename; 01518 01519 status = input_object_type( file, &type, format, eof ); 01520 01521 if( status == OK && !(*eof) ) 01522 { 01523 *object = create_object( type ); 01524 01525 switch( type ) 01526 { 01527 case LINES: 01528 status = io_lines( file, READ_FILE, *format, 01529 get_lines_ptr(*object) ); 01530 break; 01531 01532 case MARKER: 01533 status = io_marker( file, READ_FILE, *format, 01534 get_marker_ptr(*object) ); 01535 break; 01536 01537 case MODEL: 01538 status = io_model( file, READ_FILE, *format, 01539 get_model_ptr(*object) ); 01540 01541 abs_filename = get_absolute_filename( 01542 get_model_ptr(*object)->filename, 01543 directory ); 01544 01545 if( status == OK ) 01546 { 01547 status = input_graphics_file( abs_filename, &sub_format, 01548 &get_model_ptr(*object)->n_objects, 01549 &get_model_ptr(*object)->objects ); 01550 } 01551 01552 delete_string( abs_filename ); 01553 01554 break; 01555 01556 case PIXELS: 01557 status = io_pixels( file, READ_FILE, *format, 01558 get_pixels_ptr(*object) ); 01559 break; 01560 01561 case POLYGONS: 01562 status = io_polygons( file, READ_FILE, *format, 01563 get_polygons_ptr( *object ) ); 01564 01565 break; 01566 01567 case QUADMESH: 01568 status = io_quadmesh( file, READ_FILE, *format, 01569 get_quadmesh_ptr( *object ) ); 01570 break; 01571 01572 case TEXT: 01573 status = io_text( file, READ_FILE, *format, 01574 get_text_ptr( *object ) ); 01575 break; 01576 01577 default: 01578 print_error( "Unrecognized object type %d\n", type ); 01579 status = ERROR; 01580 } 01581 } 01582 01583 return( status ); 01584 } 01585 01586 /* ----------------------------- MNI Header ----------------------------------- 01587 @NAME : output_object 01588 @INPUT : file 01589 format 01590 object 01591 @OUTPUT : 01592 @RETURNS : OK or ERROR 01593 @DESCRIPTION: Writes an object to a file in ascii or binary format. 01594 @METHOD : 01595 @GLOBALS : 01596 @CALLS : 01597 @CREATED : 1993 David MacDonald 01598 @MODIFIED : 01599 ---------------------------------------------------------------------------- */ 01600 01601 public Status output_object( 01602 FILE *file, 01603 File_formats format, 01604 object_struct *object ) 01605 { 01606 Status status; 01607 01608 switch( object->object_type ) 01609 { 01610 case LINES: 01611 status = io_lines( file, WRITE_FILE, format, get_lines_ptr(object) ); 01612 break; 01613 01614 case MARKER: 01615 status = io_marker( file, WRITE_FILE, format, get_marker_ptr(object) ); 01616 break; 01617 01618 case MODEL: 01619 status = io_model( file, WRITE_FILE, format, get_model_ptr(object) ); 01620 break; 01621 01622 case PIXELS: 01623 status = io_pixels( file, WRITE_FILE, format, get_pixels_ptr(object) ); 01624 break; 01625 01626 case POLYGONS: 01627 status = io_polygons( file, WRITE_FILE, format, 01628 get_polygons_ptr(object) ); 01629 break; 01630 01631 case QUADMESH: 01632 status = io_quadmesh( file, WRITE_FILE, format, 01633 get_quadmesh_ptr(object) ); 01634 break; 01635 01636 case TEXT: 01637 status = io_text( file, WRITE_FILE, format, get_text_ptr(object) ); 01638 break; 01639 01640 default: 01641 status = ERROR; 01642 } 01643 01644 return( status ); 01645 } 01646 01647 /* ----------------------------- MNI Header ----------------------------------- 01648 @NAME : io_end_indices 01649 @INPUT : file 01650 io_flag 01651 format 01652 n_items 01653 end_indices 01654 min_size 01655 @OUTPUT : 01656 @RETURNS : ERROR or OK 01657 @DESCRIPTION: Converts between old file format of cumulative sizes of 01658 individual polygons to new format of outputting each size. 01659 It tries to detect on input whether it is new format or old 01660 format by assuming it is cumulative sizes and checking for 01661 any individual size less than min_size. This is not foolproof 01662 but should work for most files. 01663 @METHOD : 01664 @GLOBALS : 01665 @CALLS : 01666 @CREATED : Jul. 31, 1996 David MacDonald 01667 @MODIFIED : 01668 ---------------------------------------------------------------------------- */ 01669 01670 private Status io_end_indices( 01671 FILE *file, 01672 IO_types io_flag, 01673 File_formats format, 01674 int n_items, 01675 int *end_indices[], 01676 int min_size ) 01677 { 01678 int *sizes, item; 01679 Status status; 01680 01681 if( io_flag == WRITE_FILE ) 01682 { 01683 if( getenv( "NEW_OBJ_FORMAT" ) != NULL ) 01684 { 01685 ALLOC( sizes, n_items ); 01686 sizes[0] = (*end_indices)[0]; 01687 for_less( item, 1, n_items ) 01688 sizes[item] = (*end_indices)[item] - (*end_indices)[item-1]; 01689 01690 status = io_ints( file, io_flag, format, n_items, &sizes ); 01691 01692 FREE( sizes ); 01693 } 01694 else 01695 status = io_ints( file, io_flag, format, n_items, end_indices ); 01696 } 01697 else 01698 { 01699 status = io_ints( file, io_flag, format, n_items, end_indices ); 01700 01701 if( status != OK ) 01702 return( status ); 01703 01704 for_less( item, 1, n_items ) 01705 { 01706 if( (*end_indices)[item] - (*end_indices)[item-1] < min_size ) 01707 break; 01708 } 01709 01710 if( item < n_items ) 01711 { 01712 for_less( item, 1, n_items ) 01713 (*end_indices)[item] += (*end_indices)[item-1]; 01714 } 01715 } 01716 01717 return( status ); 01718 }

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7