home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / medical-image-faq / part5 < prev    next >
Internet Message Format  |  2003-12-22  |  27KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.rediris.es!irazu.switch.ch!switch.ch!tiscali!newsfeed1.ip.tiscali.net!newshosting.com!news-xfer1.atl.newshosting.com!diablo.voicenet.com!news2.epix.net!news1.epix.net!dclunie.com
  2. Newsgroups: alt.image.medical,comp.protocols.dicom,sci.data.formats,alt.answers,comp.answers,sci.answers,news.answers
  3. Message-ID: <20031221091625.3015.5@dclunie.com>
  4. Expires: 21 Jan 2004 00:00:00 GMT
  5. Subject: Medical Image Format FAQ, Part 5/8
  6. From: dclunie@dclunie.com (David A. Clunie)
  7. Followup-To: alt.image.medical
  8. Reply-To: dclunie@dclunie.com (David A. Clunie)
  9. Approved: news-answers-request@MIT.EDU
  10. Summary: This posting contains answers to the most Frequently Asked
  11.          Question on alt.image.medical - how do I convert from image
  12.          format X from vendor Y to something I can use ? In addition
  13.          it contains information about various standard formats.
  14. Lines: 677
  15. Date: Sun, 21 Dec 2003 14:16:46 GMT
  16. NNTP-Posting-Host: 216.37.230.197
  17. X-Complaints-To: abuse@epix.net
  18. X-Trace: news1.epix.net 1072016206 216.37.230.197 (Sun, 21 Dec 2003 09:16:46 EST)
  19. NNTP-Posting-Date: Sun, 21 Dec 2003 09:16:46 EST
  20. Xref: senator-bedfellow.mit.edu alt.image.medical:12458 comp.protocols.dicom:11714 sci.data.formats:3063 alt.answers:70772 comp.answers:55777 sci.answers:15698 news.answers:263503
  21.  
  22. Archive-name: medical-image-faq/part5
  23. Posting-Frequency: monthly
  24. Last-modified: Sun Dec 21 09:16:46 EST 2003
  25. Version: 4.26
  26.  
  27.     3.4 Proprietary Workstations
  28.  
  29.     3.4.1 ISG Workstations
  30.  
  31.           3.4.1.1 Gyroview
  32.  
  33.  
  34.               The Philips Gyroview workstation is a high-resolution
  35.               graphical workstation for MR images from Gyroscan
  36.               scanners, that can also handle CT images and other
  37.               modalities, and has an optional package for three
  38.               dimensional processing of images.  It is based on a Sun
  39.               SPARC system with proprietary graphics hardware.  The
  40.               software is actually written by ISG in Canada.  The image
  41.               format is an ACR/NEMA based format with various private
  42.               tags defined, and a proprietary scheme of image
  43.               compression that has me stumped.  I am told by some that
  44.               there is no means of telling the Gyroview not to compress
  45.               the images.
  46.  
  47.  
  48.              I use compress in the sense that includes packing four 12
  49.              bit words into three 16 bit big-endian words, which appears
  50.              to be part of the scheme in use.  Unfortunately, some form
  51.              of perimeter encoding is also in use, and I just can't
  52.              figure it out :( Some people have had more luck using "the
  53.              export utility of the Gyroview" to produce just 12 bit
  54.              packed images without the perimeter encoding.  I don't know
  55.              whether this is a standard feature of the workstation or
  56.              not.  Others have suggested looking in the
  57.              "/isg/3dmr/DataRoot/tscript/" directory for hints.
  58.  
  59.  
  60.               Despite prolonged exchanges of email it seems that the
  61.               formal decision is not to release the format.  Customers
  62.               may contact ISG at harry@isgtec.com(Harry Visser) to bitch
  63.               about this and then give up and ask for information on how
  64.               to obtain a software package called the External
  65.               Developers Tool which contains a tool called xdimage which
  66.               can only be used on ISG's proprietary hardware.  This is
  67.               free to customers.  It does however only export to (and
  68.               import from) a flat file format and ascii description, not
  69.               an ACR/NEMA style file with uncompressed pixel data :(.
  70.  
  71.  
  72.               I would still prefer to know the format, as people keep
  73.               asking (these machines were pretty popular I gather), and
  74.               if anyone has any hints about the data format, I would
  75.               appreciate them.  Here follows part of a reply to one of
  76.               these people when I made an unsuccesful attempt to figure
  77.               this out:
  78.  
  79.  
  80.               Firstly, I presume this file is generated by a Philips
  81.               Gyroview workstation judging by ...
  82.  
  83.  
  84. (0008,0070) LO Manufacturer VR=<LO> VL=<8> <GYROVIEW>
  85.  
  86.  
  87.               The file says it is an MRI image ...
  88.  
  89.  
  90. (0008,0060) CS Modality VR=<CS> VL=<2> <MR>
  91.  
  92.  
  93.               and yet it is missing many of the mri attributes normally
  94.               present.  Also it includes some CT specific attributes,
  95.               notably ...
  96.  
  97.  
  98. (0018,1120) DS GantryDetectorTilt VR=<DS> VL=<2> < 0>
  99.  
  100.  
  101.               which is pretty weird.  I presume that this format is
  102.               generated by something purely for the purposes of 3D
  103.               reconstruction and only the attributes needed for that
  104.               have been preserved.
  105.  
  106.  
  107.               The image appears to be 512*512 ...
  108.  
  109.  
  110. (0028,0010) US Rows VR=<US> VL=<2> [200] (0028,0011) US Columns VR=<US> VL=<2>
  111. [200]
  112.  
  113.  
  114.               As far as the compression format is concerned ...
  115.  
  116.  
  117. (0028,0060) CS CompressionCode VR=<CS> VL=<2> < 2>
  118.  
  119.  
  120.               is not in itself a valid ACR/NEMA value, and hence some
  121.               proprietary variation is in use.  The most important clue
  122.               is ...
  123.  
  124.  
  125. (0028,0040) CS ImageFormat VR=<CS> VL=<4> <CIRC>
  126.  
  127.  
  128.               which is also not valid ACR/NEMA (only RECT is permitted).
  129.               From this I conclude that some sort of 'circular'
  130.               perimeter encoding scheme is in use that only sends the
  131.               meaningful central pixels in each row and leaves out the
  132.               background.  This is substantiated by the fact that the
  133.               image pixel data seems to be preceded by a table of 257
  134.               long words in ascending order, each value separated by
  135.               relatively low values (80-100 or so).  I suspect that
  136.               these are pointers into the data to the start of each
  137.               row...
  138.  
  139.  
  140. % od -x I011_1_001 +1404 | more 0001404 0000 0202 0000 0252 0000 02a2 0000 02f2
  141. 0001424 0000 0342 0000 0392 0000 03e2 0000 0432 0001444 0000 0482 0000 04d2 0000
  142. 0522 0000 0572 0001464 0000 05c2 0000 0612 0000 0662 0000 06b3 0001504 0000 0705
  143. 0000 0757 0000 07ab 0000 0800 0001524 0000 0857 0000 08ae 0000 0905 0000 095e
  144. ..
  145.  
  146. [0000] 000514 -> 000514 [0001] 000594 -> 000080 [0002] 000674 -> 000080 [0003]
  147. 000754 -> 000080 [0004] 000834 -> 000080 [0005] 000914 -> 000080
  148.  
  149.  ...
  150.  
  151. [0155] 015322 -> 000103 [0156] 015425 -> 000103 [0157] 015527 -> 000102 [0158]
  152. 015629 -> 000102
  153.  
  154.  ...
  155.  
  156. [0254] 024484 -> 000080 [0255] 024564 -> 000080 [0256] 024564 -> 000000
  157.  
  158.  
  159.               The first of these values seems to be a pointer in two
  160.               byte word units past the table, the entries for a series
  161.               of rows, then a final "257th" value that is the same as
  162.               the preceding with a difference of zero, possibly flagging
  163.               the end of the table.
  164.  
  165.  
  166.               What confuses me is the fact that there are 256 or so
  167.               entries rather than 512 (number of rows), and that the
  168.               difference values are relatively small for 512 columns.
  169.               Perhaps each entry applies to two successive rows though
  170.               this seems rather peculiar.
  171.  
  172.  
  173.               Furthermore, if it is true that the units are two byte
  174.               words, then the last pointer value is much lower than the
  175.               number of remaining bytes in the image pixel data
  176.               attribute, so what are all the other bytes for ?
  177.  
  178.  
  179.               The other thing that is going to make extraction difficult
  180.               is the fact that the data are supposed to be 12 bits
  181.               packed into 16 bit words ...
  182.  
  183.  
  184. (0028,0100) US BitsAllocated VR=<US> VL=<2> [c] (0028,0101) US BitsStored
  185. VR=<US> VL=<2> [c] (0028,0102) US HighBit VR=<US> VL=<2> [b]
  186.  
  187.  
  188.               Hence 3 two byte words are used to store 4 12 bit pixels.
  189.               It may not be easy to figure out in what order this
  190.               packing is performed.  The ACR/NEMA standard has an
  191.               example of its intent in this case, but the byte order was
  192.               never specified for this standard, which had a 16 bit
  193.               hardware data path and was not originally intended for
  194.               offline data storage in bytes, so there are a number of
  195.               possible permutations to deal with :(
  196.  
  197.  
  198.               Finally I don't know what to make of the "private" tags
  199.               ...
  200.  
  201.  
  202. Unrecognized (0029,0010) VR=<LT> VL=<a> <ISG shadow> Unrecognized (0029,1070)
  203. VR=<LT> VL=<6> < 49128> Unrecognized (0029,1080) VR=<LT> VL=<6> <123432>
  204. Unrecognized (0029,1090) VR=<LT> VL=<2> < 0>
  205.  
  206.  
  207.               which presumably have some significance or they wouldn't
  208.               be there !
  209.  
  210.     3.4.1 GE Workstations
  211.  
  212.           3.4.2.1 GE Advantage Windows
  213.  
  214.  
  215.               The GE Advantage Windows workstation uses the same header
  216.               layout as the Genesis CT and MR systems.  One very
  217.               important proviso though is that the same C header file to
  218.               describe the layout was compiled on the sparc (sun4)
  219.               rather than Genesis (sun3) architecture, and hence, unlike
  220.               the Genesis files, 32 bit integers (include dates and
  221.               times) and 32 bit floats are aligned on 4 byte boundaries
  222.               and 64 bit floats are aligned on 8 bit boundaries.  In
  223.               other words the sequence of fields is the same but the
  224.               offsets are different.  Very annoying.  For details see
  225.               the GE MR Signa 5.x - Genesis description.  For details of
  226.               the sun data types, see Sun.
  227.  
  228.  
  229.               The order of the headers is the same as on the archives
  230.               (DAT, WORM or OD), ie.  not the same as the ximg layout.
  231.               Furthermore, the lengths are slightly different from
  232.               Genesis, due to the word alignement business, and also
  233.               different for CT as opposed to MR (different length of the
  234.               image header), so finding the file header (pixel data
  235.               header) can be a bit of a chore.  The offsets from the
  236.               start of the file for each are as follows:
  237.  
  238.  
  239.               For CT:
  240.  
  241.                 0 Suite header
  242.               116 Exam header
  243.              1156 Series header 2184 Image header 3240 File (Pixel
  244.              Data) header
  245.  
  246.               For MR:
  247.  
  248.                 0 Suite header
  249.               116 Exam header
  250.              1156 Series header 2184 Image header 3228 File (Pixel
  251.              Data) header
  252.  
  253.  
  254.  
  255.               Identifying the files is a nuisance because the "IMGF"
  256.               string doesn't appear until offset 3240 dec for the CT and
  257.               offset 3228 dec for the MR, unlike the Genesis ximg form.
  258.  
  259.  
  260.               Also, even though the headers are in the "archive" order,
  261.               the 4 byte pixel data length field that is prepended to
  262.               the image pixel data itself in the archives, is NOT
  263.               present on Advantage Windows, just as it is absent from
  264.               Genesis ximg files.  In other words you do not have to add
  265.               4 to the file header length field to find the start of the
  266.               pixel data.  Obviously you do have to add the offset of
  267.               the file header itself though !  Don't forget to add this
  268.               to the offset of the unpack tables also.  The pixel data
  269.               itself is compressed the same way as Genesis.
  270.  
  271.  
  272.               It is recommended that you use the readily available
  273.               Genesis documentation if trying to extract information
  274.               from the headers, or use the "ximg -h" command on a
  275.               Genesis system to generate a C header.  For the truly
  276.               masochistic, or desperately impatient, here is a summary
  277.               of the some of the fields for Advantage Windows as were
  278.               described for Genesis CT and MR, with the corrections for
  279.               word alignment applied:
  280.  
  281.  
  282.     exam header:
  283.  
  284.         0 - char[4] - suite ID 8 - u_short - exam number 88 - char[13] -
  285.         patient ID 101 - char[25] - patient name 126 - short - patient
  286.         age 130 - short - patient sex 309 - char[3] - exam type - "MR"
  287.         or "CT"
  288.  
  289.     series header:
  290.  
  291.         10 - short - series number 84 - char[3] - anatomical reference
  292.         92 - char[25] - scan protocol name
  293.  
  294.     image header - common to CT and MR:
  295.  
  296.         12 - short - image number 28 - float - slice thickness mm 32 -
  297.         short - matrix size - X 34 - short - matrix size - Y 36 - float
  298.         - display field of view - X (mm) 40 - float - display field of
  299.         view - Y (mm) 44 - float - image dimension - X 48 - float -
  300.         image dimension - Y 52 - float - pixel size - X 56 - float -
  301.         pixel size - Y 60 - char[14] - pixel data ID 74 - char[17] - iv
  302.         contrast agent 91 - char[17] - oral contrast agent
  303.  
  304.         132 - float - image location 136 - float - image centre R mm
  305.         (ie.  X +ve to right) 140 - float - image centre A mm (ie.  Y
  306.         +ve to anterior) 144 - float - image centre S mm (ie.  Z +ve to
  307.         superior) 160 - float - image TLHC R mm (ie.  X +ve to right)
  308.         164 - float - image TLHC A mm (ie.  Y +ve to anterior) 168 -
  309.         float - image TLHC S mm (ie.  Z +ve to superior) 172 - float -
  310.         image TRHC R mm (ie.  X +ve to right) 176 - float - image TRHC A
  311.         mm (ie.  Y +ve to anterior) 180 - float - image TRHC S mm (ie.
  312.         Z +ve to superior) 184 - float - image BRHC R mm (ie.  X +ve to
  313.         right) 188 - float - image BRHC A mm (ie.  Y +ve to anterior)
  314.         192 - float - image BRHC S mm (ie.  Z +ve to superior)
  315.  
  316.     image header - for MR (1044 bytes long):
  317.  
  318.         200 - int - repetition time(usec) 204 - int - inversion
  319.         time(usec) 208 - int - echo time(usec) 216 - short - number of
  320.         echoes 218 - short - echo number 224 - float - NEX 320 -
  321.         char[33] - pulse sequence name 376 - char[17] - coil name 660 -
  322.         short - ETL for FSE
  323.  
  324.     image header - for CT (1056 bytes long):
  325.  
  326.         200 - float - table start Location 204 - float - table end
  327.         Location 208 - float - table speed (mm/sec) 212 - float - table
  328.         height 232 - float - gantry tilt (degrees)
  329.  
  330.     3.5 Other Proprietary Formats
  331.  
  332.     3.5.1 Analyze From Mayo
  333.  
  334.           This very popular software package is produced by the Biomedical
  335.           Imaging Resource group at the Mayo Clinic/Foundation.  I have
  336.           always thought they should give it away but they don't, it is
  337.           moderately expensive, though less so than some other alternatives.
  338.           If you want to test or buy it try contacting Denny Hanson
  339.           dph@mayo.edu who is extremely helpful.  See also the web site at
  340.           ANALYZE from Mayo.
  341.  
  342.  
  343.           Anyway, importing images into Analyze is a drag and you have to
  344.           convert your files to their format, but it isn't very difficult.
  345.           I hear that some other programs also use their format but haven't
  346.           encountered them myself.  Anyway, the package is sufficiently
  347.           commonly used that it seems appropriate to include the format
  348.           here.
  349.  
  350.  
  351.           This information is included verbatim from what was sent to me by
  352.           Ellis Workman elw@mayo.edu and if you have problems I am sure he
  353.           will be able to help.  I haven't tested it because I can't afford
  354.           to buy a copy myself :( That's a hint, Denny.
  355.  
  356.  
  357. ANALYZE IMAGE FILE FORMAT
  358.  
  359. ANALYZE image file sets consist of at least 2 files:
  360.     - an image file - a header file - a color lookup file * optional
  361.  
  362. For the Analyze image file set "foo" there are two files:
  363.     foo.img & foo.hdr (optionally foo.lkup)
  364.  
  365. The ANALYZE programs refer to this file set as a single entity.
  366.  
  367.        The Image File (foo.img)
  368.  
  369. The format of the image file is very simple; containging usually uncompressed
  370. voxel data for the images in one of the several possible voxel formats:
  371.     - 1 bit packed binary (slices begin on byte boundaries) - 8 bit
  372.     (unsigned char) gray scale unless .lkup file present - 16 bit signed
  373.     short - 32 bit signed integers or float - 24 bit RGB, 8 bits per channel
  374.  
  375. The header file is a 'C' structure which describes the dimensions and properties
  376. of the voxel data.  This structure follows:
  377.  
  378.  
  379. /*
  380.  * * (c) Copyright, 1986-1995 * Biomedical Imaging Resource * Mayo Foundation *
  381.  * dbh.h * * * database sub-definitions */
  382.  
  383. struct header_key /* header_key */
  384.     { /* off + size*/
  385.     int sizeof_hdr; /* 0 + 4 */ char data_type[10]; /* 4 + 10 */ char
  386.     db_name[18]; /* 14 + 18 */ int extents; /* 32 + 4 */ short int
  387.     session_error; /* 36 + 2 */ char regular; /* 38 + 1 */ char hkey_un0; /*
  388.     39 + 1 */
  389.     }; /* total=40 */
  390.  
  391. struct image_dimension /* image_dimension */
  392.     { /* off + size*/
  393.     short int dim[8]; /* 0 + 16 */ char vox_units[4]; /* 16 + 4 */ char
  394.     cal_units[8]; /* 20 + 4 */ short int unused1; /* 24 + 2 */ short int
  395.     datatype; /* 30 + 2 */ short int bitpix; /* 32 + 2 */ short int dim_un0;
  396.     /* 34 + 2 */ float pixdim[8]; /* 36 + 32 */
  397.             /*
  398.                 pixdim[] specifies the voxel dimensions:
  399.                 pixdim[1] - voxel width pixdim[2] - voxel height
  400.                 pixdim[3] - interslice distance
  401.                     ..etc
  402.             */
  403.     float vox_offset; /* 68 + 4 */ float roi_scale; /* 72 + 4 */ float
  404.     funused1; /* 76 + 4 */ float funused2; /* 80 + 4 */ float cal_max; /* 84
  405.     + 4 */ float cal_min; /* 88 + 4 */ int compressed; /* 92 + 4 */ int
  406.     verified; /* 96 + 4 */ int glmax, glmin; /* 100 + 8 */
  407.     }; /* total=108 */
  408.  
  409. struct data_history /* data_history */
  410.     { /* off + size*/
  411.     char descrip[80]; /* 0 + 80 */ char aux_file[24]; /* 80 + 24 */ char
  412.     orient; /* 104 + 1 */ char originator[10]; /* 105 + 10 */ char
  413.     generated[10]; /* 115 + 10 */ char scannum[10]; /* 125 + 10 */ char
  414.     patient_id[10]; /* 135 + 10 */ char exp_date[10]; /* 145 + 10 */ char
  415.     exp_time[10]; /* 155 + 10 */ char hist_un0[3]; /* 165 + 3 */ int views;
  416.     /* 168 + 4 */ int vols_added; /* 172 + 4 */ int start_field; /* 176 + 4
  417.     */ int field_skip; /* 180 + 4 */ int omax,omin; /* 184 + 8 */ int
  418.     smax,smin; /* 192 + 8 */
  419.     }; /* total=200 */
  420.  
  421. struct dsr /* dsr */
  422.     { /* off + size*/
  423.     struct header_key hk; /* 0 + 40 */ struct image_dimension dime; /* 40 +
  424.     108 */ struct data_history hist; /* 148 + 200 */
  425.     }; /* total=348 */
  426.  
  427.  
  428. Comments:
  429.     struct header_key
  430.         int sizeof_header /* must indicate size of header file */ int
  431.         extants; /* should be 16384 */ char regular; /* 'r' */
  432.  
  433.  
  434.     struct image_dimension struct decribes the organization and side of
  435.     images.  These elements enable IO routines to reference images by volume
  436.     and slice number.
  437.  
  438.         short int dim[] /* array of image dimensions */
  439.             dim[0] /* number of dimensions; usually 4 */ dim[1] /*
  440.             image width */ dim[2] /* image height */ dim[3] /*
  441.             volume depth */ dim[4] /* volumes in file */
  442.  
  443.         char vox_units[4] /* labels voxerl spatial unit */ char
  444.         cal_units[4] /* labels voxel calibration unit */ short int
  445.         datatype /* Acceptable values are */
  446.  
  447. #define DT_NONE 0 #define DT_UNKNOWN 0 #define DT_BINARY 1 #define
  448. DT_UNSIGNED_CHAR 2 #define DT_SIGNED_SHORT 4 #define DT_SIGNED_INT 8 #define
  449. DT_FLOAT 16 #define DT_COMPLEX 32 #define DT_DOUBLE 64 #define DT_RGB 128
  450. #define DT_ALL 255
  451.  
  452.         short int bitpix /* bits per pixel */ float pixdim[] /* parallel
  453.         array to dim giving voxel dimensions
  454.                    in each dimension */
  455.              pixdim[1] /* voxel width */ pixdim[2] /* voxel height
  456.              */ pixdim[3] /* voxel depth or slice thickness */
  457.  
  458.         float vox_offset; /* byte offset in the .img file at which
  459.                      voxels start.  If value is negative
  460.                      specifies that the absolute value is
  461.                      applied for every image in the file.  */
  462.  
  463.         float calibrated Max & Min /* specify range of calibration
  464.         values */ int glmax, glmin /* the max and min values for entire
  465.         data set */
  466.  
  467.  
  468. The data_history substructure is not required, but the 'orient' element is used
  469. to indicate individual slice orientation and determines whether the ANALYZE
  470. 'Movie' program will attempt to flip the images before displaying a movie
  471. sequence.
  472.     orient:
  473.             0 - transverse unflipped 1 - coronal unflipped 2 -
  474.             sagittal unflipped 3 - transverse flipped 4 - coronal
  475.             flipped 5 - sagittal flipped
  476.  
  477.  
  478.  
  479. The following 'C' program creates an Analyze .hdr file.
  480.  
  481.  
  482. /*
  483.  * (c) Copyright, 1986-1994 * Biomedical Imaging Resource * Mayo Foundation * *
  484.  */
  485.  
  486. #include #include "dbh.h"
  487.  
  488. main(argc,argv) /* file x y z t datatype max min */ int argc; char **argv; {
  489.     int i; struct dsr hdr; FILE *fp; static char DataTypes[9][12] = {"UNKNOWN",
  490.     "BINARY", "CHAR", "SHORT", "INT",
  491.                     "FLOAT", "COMPLEX", "DOUBLE", "RGB"};
  492.  
  493.  
  494.     static int DataTypeSizes[9] = {0,1,8,16,32,32,64,64,24};
  495.  
  496.     if(argc != 9) {
  497.     usage(); exit(0);
  498.     } memset(&hdr,0, sizeof(struct dsr)); for(i=0;i<8;i++)
  499.     hdr.dime.pixdim[i]=0.0;
  500.  
  501.     hdr.dime.vox_offset = 0.0; hdr.dime.roi_scale = 1.0; hdr.dime.funused1 =
  502.     0.0; hdr.dime.funused2 = 0.0; hdr.dime.cal_max = 0.0; hdr.dime.cal_min =
  503.     0.0;
  504.  
  505.  
  506.     hdr.dime.datatype = -1;
  507.  
  508.     for(i=1;i<=8;i++)
  509.     if(!strcmp(argv[6],DataTypes[i])) {
  510.         hdr.dime.datatype = (1<<(i-1)); hdr.dime.bitpix =
  511.         DataTypeSizes[i]; break;
  512.     }
  513.  
  514.     if(hdr.dime.datatype <= 0) {
  515.     printf(" is an unacceptable datatype \n\n", argv[6]); usage(); exit(0);
  516.     }
  517.  
  518.     if((fp=fopen(argv[1],"w"))==0) {
  519.     printf("unable to create: %s\n",argv[1]); exit(0);
  520.     }
  521.  
  522.     hdr.dime.dim[0] = 4; /* all Analyze images are taken as 4 dimensional */
  523.     hdr.hk.regular = 'r'; hdr.hk.sizeof_hdr = sizeof(struct dsr);
  524.  
  525.     hdr.dime.dim[1] = atoi(argv[2]); /* slice width in pixels */ hdr.dime.dim[2]
  526.     = atoi(argv[3]); /* slice height in pixels */ hdr.dime.dim[3] =
  527.     atoi(argv[4]); /* volume depth in slices */ hdr.dime.dim[4] = atoi(argv[5]);
  528.     /* number of volumes per file */
  529.  
  530.     hdr.dime.glmax = atoi(argv[7]); /* maximum voxel value */ hdr.dime.glmin =
  531.     atoi(argv[8]); /* minimum voxel value */
  532.  
  533. /* Set the voxel dimension fields:
  534.        A value of 0.0 for these fields implies that the value is unknown.
  535.      Change these values to what is appropriate for your data or pass
  536.      additional command line arguments */
  537.  
  538.     hdr.dime.pixdim[1] = 0.0; /* voxel x dimension */ hdr.dime.pixdim[2] = 0.0;
  539.     /* voxel y dimension */ hdr.dime.pixdim[3] = 0.0; /* pixel z dimension,
  540.     slice thickness */
  541.  
  542. /* Assume zero offset in .img file, byte at which pixel
  543.        data starts in the image file */
  544.  
  545.     hdr.dime.vox_offset = 0.0;
  546.  
  547. /* Planar Orientation; */ /* Movie flag OFF: 0 = transverse, 1 = coronal, 2 =
  548. sagittal
  549.      Movie flag ON: 3 = transverse, 4 = coronal, 5 = sagittal */
  550.  
  551.     hdr.hist.orient = 0;
  552.  
  553. /* up to 3 characters for the voxels units label; i.e.
  554.     mm., um., cm.  */
  555.  
  556.     strcpy(hdr.dime.vox_units," ");
  557.  
  558. /* up to 7 characters for the calibration units label; i.e.  HU */
  559.  
  560.     strcpy(hdr.dime.cal_units," ");
  561.  
  562. /* Calibration maximum and minimum values;
  563.        values of 0.0 for both fields imply that no calibration max and min
  564.        values are used */
  565.  
  566.     hdr.dime.cal_max = 0.0; hdr.dime.cal_min = 0.0;
  567.  
  568.     fwrite(&hdr,sizeof(struct dsr),1,fp); fclose(fp);
  569. }
  570.  
  571. usage() {
  572.    printf("usage: make_hdr name.hdr x y z t datatype max min \n\n"); printf("
  573.    name.hdr = the name of the header file\n"); printf(" x = width, y = height, z
  574.    = depth, t = number of volumes\n"); printf(" acceptable datatype values are:
  575.    BINARY, CHAR, SHORT,\n"); printf(" INT, FLOAT, COMPLEX, DOUBLE, and RGB\n");
  576.    printf(" max = maximum voxel value, min = minimum voxel value\n");
  577. }
  578.  
  579.  
  580. The following program displays information in an Analyze header file.
  581.  
  582. #include #include "dbh.h"
  583.  
  584. void ShowHdr(char *, struct dsr *); void swap_long(unsigned char *); void
  585. swap_short(unsigned char *);
  586.  
  587. main(argc,argv) int argc; char **argv;
  588.     { struct dsr hdr; int size; double cmax, cmin; FILE *fp;
  589.  
  590.     if((fp=fopen(argv[1],"r"))==NULL)
  591.     {
  592.     fprintf(stderr,"Can't open:\n", argv[1]); exit(0);
  593.     } fread(&hdr,1,sizeof(struct dsr),fp);
  594.  
  595.     if(hdr.dime.dim[0] 15)
  596.         swap_hdr(&hdr);
  597.  
  598.      ShowHdr(argv[1], &hdr);
  599.  
  600.  
  601.      }
  602.  
  603.  
  604.  
  605.  
  606. void ShowHdr(fileName,hdr) struct dsr *hdr; char *fileName; { int i; char
  607. string[128]; printf("Analyze Header Dump of: \n", fileName); /* Header Key */
  608. printf("sizeof_hdr: \n", hdr->hk.sizeof_hdr); printf("data_type: \n",
  609. hdr->hk.data_type); printf("db_name: \n", hdr->hk.db_name); printf("extents:
  610. \n", hdr->hk.extents); printf("session_error: \n", hdr->hk.session_error);
  611. printf("regular: \n", hdr->hk.regular); printf("hkey_un0: \n",
  612. hdr->hk.hkey_un0);
  613.  
  614. /* Image Dimension */ for(i=0;i<8;i++)
  615.     printf("dim[%d]: \n", i, hdr->dime.dim[i]);
  616.  
  617.     strncpy(string,hdr->dime.vox_units,4); printf("vox_units: \n", string);
  618.  
  619.     strncpy(string,hdr->dime.cal_units,8); printf("cal_units: \n", string);
  620.     printf("unused1: \n", hdr->dime.unused1); printf("datatype: \n",
  621.     hdr->dime.datatype); printf("bitpix: \n", hdr->dime.bitpix);
  622.  
  623. for(i=0;i<8;i++)
  624.     printf("pixdim[%d]: \n",i, hdr->dime.pixdim[i]);
  625.  
  626. printf("vox_offset: \n", hdr->dime.vox_offset); printf("funused1: \n",
  627. hdr->dime.funused1); printf("funused2: \n", hdr->dime.funused2);
  628. printf("funused3: \n", hdr->dime.funused3); printf("cal_max: \n",
  629. hdr->dime.cal_max); printf("cal_min: \n", hdr->dime.cal_min);
  630. printf("compressed: \n", hdr->dime.compressed); printf("verified: \n",
  631. hdr->dime.verified); printf("glmax: \n", hdr->dime.glmax); printf("glmin: \n",
  632. hdr->dime.glmin);
  633.  
  634. /* Data History */ strncpy(string,hdr->hist.descrip,80); printf("descrip: \n",
  635. string); strncpy(string,hdr->hist.aux_file,24); printf("aux_file: \n", string);
  636. printf("orient: \n", hdr->hist.orient);
  637.  
  638. strncpy(string,hdr->hist.originator,10); printf("originator: \n", string);
  639.  
  640. strncpy(string,hdr->hist.generated,10); printf("generated: \n", string);
  641.  
  642.  
  643. strncpy(string,hdr->hist.scannum,10); printf("scannum: \n", string);
  644.  
  645. strncpy(string,hdr->hist.patient_id,10); printf("patient_id: \n", string);
  646.  
  647. strncpy(string,hdr->hist.exp_date,10); printf("exp_date: \n", string);
  648.  
  649. strncpy(string,hdr->hist.exp_time,10); printf("exp_time: \n", string);
  650.  
  651. strncpy(string,hdr->hist.hist_un0,10); printf("hist_un0: \n", string);
  652.  
  653. printf("views: \n", hdr->hist.views); printf("vols_added: \n",
  654. hdr->hist.vols_added); printf("start_field: \n", hdr->hist.start_field);
  655. printf("field_skip: \n", hdr->hist.field_skip); printf("omax: \n",
  656. hdr->hist.omax); printf("omin: \n", hdr->hist.omin); printf("smin: \n",
  657. hdr->hist.smax); printf("smin: \n", hdr->hist.smin);
  658.  
  659. }
  660.  
  661.  
  662. swap_hdr(pntr) struct dsr *pntr;
  663.     { swap_long(&pntr->hk.sizeof_hdr) ; swap_long(&pntr->hk.extents) ;
  664.     swap_short(&pntr->hk.session_error) ; swap_short(&pntr->dime.dim[0]) ;
  665.     swap_short(&pntr->dime.dim[1]) ; swap_short(&pntr->dime.dim[2]) ;
  666.     swap_short(&pntr->dime.dim[3]) ; swap_short(&pntr->dime.dim[4]) ;
  667.     swap_short(&pntr->dime.dim[5]) ; swap_short(&pntr->dime.dim[6]) ;
  668.     swap_short(&pntr->dime.dim[7]) ; swap_short(&pntr->dime.unused1) ;
  669.     swap_short(&pntr->dime.datatype) ; swap_short(&pntr->dime.bitpix) ;
  670.     swap_long(&pntr->dime.pixdim[0]) ; swap_long(&pntr->dime.pixdim[1]) ;
  671.     swap_long(&pntr->dime.pixdim[2]) ; swap_long(&pntr->dime.pixdim[3]) ;
  672.     swap_long(&pntr->dime.pixdim[4]) ; swap_long(&pntr->dime.pixdim[5]) ;
  673.     swap_long(&pntr->dime.pixdim[6]) ; swap_long(&pntr->dime.pixdim[7]) ;
  674.     swap_long(&pntr->dime.vox_offset) ; swap_long(&pntr->dime.funused1) ;
  675.     swap_long(&pntr->dime.funused2) ; swap_long(&pntr->dime.cal_max) ;
  676.     swap_long(&pntr->dime.cal_min) ; swap_long(&pntr->dime.compressed) ;
  677.     swap_long(&pntr->dime.verified) ; swap_short(&pntr->dime.dim_un0) ;
  678.     swap_long(&pntr->dime.glmax) ; swap_long(&pntr->dime.glmin) ; }
  679.  
  680. swap_long(pntr) unsigned char *pntr;
  681.     { unsigned char b0, b1, b2, b3;
  682.  
  683.     b0 = *pntr; b1 = *(pntr+1); b2 = *(pntr+2); b3 = *(pntr+3);
  684.  
  685.     *pntr = b3; *(pntr+1) = b2; *(pntr+2) = b1; *(pntr+3) = b0; }
  686.  
  687. swap_short(pntr) unsigned char *pntr;
  688.     { unsigned char b0, b1;
  689.  
  690.     b0 = *pntr; b1 = *(pntr+1);
  691.  
  692.     *pntr = b1; *(pntr+1) = b0; }
  693.  
  694.  
  695.  
  696. The next part is part6 - hosts & compression.
  697.  
  698.  
  699.