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

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.rediris.es!irazu.switch.ch!switch.ch!in.100proofnews.com!in.100proofnews.com!cox.net!news-xfer.cox.net!199.224.117.12.MISMATCH!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.6@dclunie.com>
  4. Expires: 21 Jan 2004 00:00:00 GMT
  5. Subject: Medical Image Format FAQ, Part 6/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: 811
  15. Date: Sun, 21 Dec 2003 14:16:50 GMT
  16. NNTP-Posting-Host: 216.37.230.197
  17. X-Complaints-To: abuse@epix.net
  18. X-Trace: news1.epix.net 1072016210 216.37.230.197 (Sun, 21 Dec 2003 09:16:50 EST)
  19. NNTP-Posting-Date: Sun, 21 Dec 2003 09:16:50 EST
  20. Xref: senator-bedfellow.mit.edu alt.image.medical:12459 comp.protocols.dicom:11715 sci.data.formats:3064 alt.answers:70773 comp.answers:55778 sci.answers:15699 news.answers:263504
  21.  
  22. Archive-name: medical-image-faq/part6
  23. Posting-Frequency: monthly
  24. Last-modified: Sun Dec 21 09:16:50 EST 2003
  25. Version: 4.26
  26.  
  27. 4.  Host Machines
  28.  
  29.     4.1 Data General
  30.  
  31.     4.1.1 Data General Data
  32.  
  33.           4.1.1.1 Data General Integers
  34.  
  35.               Integers are 16 bit two's complement and stored in
  36.               big-endian format as on Sun Sparc and opposite to the Dec
  37.               VAX.
  38.  
  39.           4.1.1.2 Data General Floating Point
  40.  
  41.               Single precision real values are 32 bits long, in
  42.               big-endian format.  The high bit is the sign bit, followed
  43.               by a 7 bit excess 64 exponent (power to which 16 must be
  44.               raised) then a 24 bit hexadecimally normalized mantissa
  45.               with the decimal point to the left of the most significant
  46.               bit.  Double precision values just have another 32 bits
  47.               tacked on the mantissa and the same exponent format.
  48.  
  49.  
  50.         Sign
  51.        |<-->|<------ Exponent ------>|<--------- Mantissa -------->|
  52.         ______________ ______________ ______________ ______________
  53.        | | | | |
  54.        |______________|______________|______________|______________|
  55.         31 28 27 24 23 20 19 16
  56.        |<----------------------- Mantissa ------------------------>|
  57.         ______________ ______________ ______________ ______________
  58.        | | | | |
  59.        |______________|______________|______________|______________|
  60.         15 12 11 8 7 4 3 0
  61.  
  62.  
  63.  
  64.               Here is a little piece of C++ code that should run on
  65.               anything and convert Data General floats to whatever the
  66.               host's floating point format is.
  67.  
  68.  
  69.         double value; unsigned char sign; Uint16 exponent; Uint32
  70.         mantissa;
  71.  
  72.         typedef struct {
  73.             unsigned sign : 1; unsigned exponent : 7; unsigned
  74.             mantissa : 24;
  75.         } DG_FLOAT;
  76.  
  77.         DG_FLOAT number;
  78.  
  79.         unsigned char buffer[4]; instream.read(buffer,4); if (instream)
  80.         {
  81.             // DataGeneral is a Big Endian machine memcpy ((char
  82.             *)(&number),buffer,4); sign = number.sign; exponent =
  83.             number.exponent; mantissa = number.mantissa;
  84.  
  85.             value = (double) mantissa / (1 << 24) *
  86.                 pow (16.0, (long)(exponent) - 64);
  87.             value = (sign == 0) ?  value : -value;
  88.         } else {
  89.             cerr << "read failed\n" << flush; value=0;
  90.         }
  91.  
  92.     4.1.2 Data General Operating System
  93.  
  94.           4.1.2.1 Data General RDOS
  95.  
  96.               Used on the GE CT 9800 family.  Severely primitive but
  97.               then is running on an old machine that can only map 64Kb
  98.               of memory at a time after all.  It is apparently
  99.               multitasking.  Documentation may still be available from
  100.               Data General (try DG Direct) but is not supplied with the
  101.               scanner by GE.  If anyone knows where I can find it at a
  102.               reasonable price let me know.  Here is a brief command
  103.               summary culled from a nifty pocket book from GE for
  104.               SunOS/Genesis users that compares commands:
  105.  
  106.  
  107.          CHATR - file attributes CRAND - create randomly organized file
  108.          CDIR - create directory DELETE - files or directories DIR -
  109.          change directory DISK - free space FILCOM - compare files GDIR
  110.          - show working directory name GTOD - show date and time LINK -
  111.          files (symbolic) LIST - directory contents MOVE - a file RENAME
  112.          - a file SDAT - set date STOD - set time SDUMP - write files to
  113.          a device SLOAD - read dumped files SPEED - tex editor TYPE -
  114.          contents of file XFER - copy a file
  115.  
  116.          wildcards: '-' is series, '*' is single character
  117.  
  118.           4.1.2.2 Data General AOS/VS
  119.  
  120.               Used on the GE Signa 3X and 4X family.  Quite a nice
  121.               operating system with multi-tasking and hierarchical
  122.               directories.  Here is a brief command summary again culled
  123.               from a nifty pocket book from GE for SunOS/Genesis users
  124.               that compares commands:
  125.  
  126.  
  127.          ACL - access control list (ownership) BYE - exit command
  128.          process COPY - a file CREATE - a text file CREATE/DIR - a
  129.          directory CREATE/LINK - link files DELETE - files & directories
  130.          DIR - display or change working directory DUMP - to peripheral
  131.          F/AS/S - directory listing with file status DATE - show or set
  132.          HELP LOAD - DUMPed files MOVE - a file RENAME - a file PATH -
  133.          show pathname of a file PAUSE - the command line interpreter
  134.          SUPERU ON - enable superuser SED - text editor TIME - show or
  135.          set TYPE - contents of text file ?  - list processes running
  136.  
  137.          wildcards: '+' is series, '*' is single character
  138.  
  139.  
  140.               Other useful hints include the use of "^" to refer to the
  141.               next directory up (like ".." in Unix) in DIR commands.
  142.               Command options follow the command name without any spaces
  143.               and are indicated by a slash.  COPY operations specify the
  144.               destination name first and then the source name.  Devices
  145.               like the mag tape are indicated by "@", for example
  146.               "@MTB0" is tape drive zero.  Files on the tape can be
  147.               referred to as "@MTB0:nn" which is very handy.  For
  148.               example to read a file off a CT 9800 tape under AOS/VS:
  149.  
  150.  
  151.         COPY/V/IMTRSIZE=8192 B038040101.YP @MTB0:18
  152.  
  153.  
  154.               Perhaps most importantly, there is an extensive online
  155.               help system ...  use the HELP command.
  156.  
  157.     4.1.3 Data General Network
  158.  
  159.           If you have a GE Signa based on a DG then you can get the
  160.           so-called "High Speed Network" card and software from GE.  From
  161.           memory it is pretty pricey, and there used to be a "slower"
  162.           network interface that was cheaper, but I don't think this is
  163.           available anymore.
  164.  
  165.  
  166.           If you have a CT 9800 based on the DG S/140 and you need to get it
  167.           connected there are a number of solutions:
  168.  
  169.  
  170.           - Talk to GE about there ID/LINK II product ...  I gather this is
  171.           a device that hooks into the SCSI cable to the hard drive (you
  172.           need one of the Ace drives not the old Zebra drive), monitors disk
  173.           activity and snatches pieces of the conversation to make a copy of
  174.           the image data, stores it and makes it available via some network
  175.           protocol.  Sound crazy ?  Perhaps, but they tell me it works and
  176.           the price is reasonable, at least for something from GE anyway.
  177.           Get them to throw one in next time you buy something big.
  178.  
  179.           - The do-it-yourself approach.  Talk to John Clayton
  180.           (clayton@c-c.com) at Claflin and Clayton.  They supply a complete
  181.           R-level solution by providing Ethernet hardware and TCP/IP
  182.           software for 16 bit DG OS including AOS and RDOS (specifically
  183.           including the GE CT version of RDOS).  He tells me "you can expect
  184.           a file transfer rate of 25 kbytes/s for S/140 systems".  The
  185.           package consists of:
  186.  
  187.  
  188.           $2,850 - EC-10 ethernet controller $1,645 - RDOS TCP/IP software
  189.           (telnet client,ftp client/server)
  190.  
  191.  
  192.           I have not personally tried either of these approaches, and I am
  193.           sure there are others (talk to Merge or DeJarnette), but I am
  194.           getting really tired of carrying 9-track tapes around so perhaps I
  195.           will bite the bullet soon (and upgrade to a HighSpeed Advantage
  196.           !).
  197.  
  198.     4.2 Vax
  199.  
  200.     4.2.1 Vax Data
  201.  
  202.           4.2.1.1 Vax Integers
  203.  
  204.               - little endian - 8, 16, or 32 bits
  205.  
  206.           4.2.1.2 Vax Floating Point
  207.  
  208.               - little endian
  209.  
  210.               - D_float
  211.  
  212.             - 8 bytes - sign bit 15 - exponent bits 14-7 excess 128
  213.             binary - fraction MSB firstbits 6-0, 31-16, 47-32, 63-48
  214.             - normalized bit is not represented (hidden)
  215.  
  216.  
  217.               - G_float
  218.  
  219.             - 8 bytes - like D, but - exponent is bits 14-4 excess
  220.             1024 - fraction 3-0 and 63-16
  221.  
  222.  
  223.               - F_float
  224.  
  225.             - 4 bytes - like D, smaller fraction
  226.  
  227.  
  228.               - H_float
  229.  
  230.             - 16 bytes - like G, but - exponent is bits 14-0 excess
  231.             16384 - fraction is bits 127-16
  232.  
  233.               - same wierd order - bit 112 least significant
  234.  
  235.  
  236.  
  237.           4.2.1.3 Vax Strings
  238.  
  239.               - 16 bits of length - byte of type - byte of class - 32
  240.               bits of pointer
  241.  
  242.     4.2.2 Vax Operating System
  243.  
  244.           4.2.2.1 Vax VMS (See also Vax VMS Tools)
  245.  
  246.               Truely one of the world's most irritating operating
  247.               systems to use, especially if you are a unix fan.  Still
  248.               it works, has a great online help system that saves one's
  249.               butt almost often enough to be useful, and if you can
  250.               remember the directory where kermit is stored and the
  251.               weird command to invoke it one can get by (barely).
  252.  
  253.  
  254.               If you don't know VMS and the vendor doesn't supply the
  255.               manuals, get them from DEC ...  you need them bad ...
  256.               real bad.  If (like me) you throw them out everytime you
  257.               move then encounter another piece of archaic equipment,
  258.               you need the "vaxbook" which is available via ftp from
  259.               decoy.uoregon.edu, written by Joseph E St Sauver, which
  260.               summarizes commands, files and all sorts of application
  261.               specific stuff, though it is no substitute for the real
  262.               thing.
  263.  
  264.  
  265.               Recent VMS update: goddamn file formats !  Why can't VMS
  266.               behave like a real operating system and forget this file
  267.               format crap !  I have some Philips S5 MR images exported
  268.               in ACR/NEMA format and I can't get the things off the
  269.               hosts's Vax using Kermit, because though they have fixed
  270.               length 512 byte records, some cretinous program sets the
  271.               "carriage return carriage control" record attributes,
  272.               which causes kermit to send with all the '0A' characters
  273.               scrubbed out amongst other atrocities.
  274.  
  275.  
  276.               I am getting desperate and about to try using the
  277.               Hex/Dehex utility that came with Kermit to get the stuff
  278.               off and then decode the hex format !  Or perhaps even use
  279.               "dump" to make a textfile, transfer, and decipher that.
  280.               (No I don't have a C compiler for the Vax so I guess I
  281.               can't use uuencode unless someone wants to mail me a
  282.               hex'ed executable).  Any hints, or instructions as to how
  283.               to use FDL and Convert, to change it to a normal format
  284.               would be appreciated.  (Why can't they just have a "set
  285.               file record attribute xxx" command like all the other
  286.               millions of set commands ?  Grrrr.).
  287.  
  288.  
  289.               More recent VMS update: finally had an inspiration while
  290.               staring at hex dumps of these files - why not use the VMS
  291.               "DUMP" utility which produces hex dumps as a "poor man's
  292.               uuencode" by saving the dump to a file, transferring it as
  293.               an ascii file, and then decoding it at the destination ?
  294.               Of course there are no nifty line checksums or anything,
  295.               but a transfer protocol such as kermit takes care of this.
  296.  
  297.  
  298.               The DUMP output defaults to 8 32 bit long words separated
  299.               by a space per line displayed as hex, then an ascii string
  300.               (32 bytes) and then a 24 bit word hex address offset from
  301.               the start of the fixed length record.  All the data
  302.               containing lines start with a single space, where as
  303.               descriptions at the start of each record begin in the
  304.               first column, hence the data lines can be easily selected
  305.               out.  By the way, the hex version of the data is listed in
  306.               reverse order !  VMS is so bizarre !  For example, here is
  307.               a fixed length 512 byte record file from a Philips S5 MRI
  308.               (some of the hex words elided to make the line fit on the
  309.               page):
  310.  
  311.  
  312. Dump of file SYS$SYSROOT:[GYROSCAN]ABAALKHAIL02010201010001.ANI;1 ...  File ID
  313. (2419,301,0) End of file block 198 / Allocated 200
  314.  
  315. Virtual block number 1 (00000001), 512 (0200) bytes
  316.  
  317.  0000000C 00100008 ...  00000008 ..............................  000000 00083932
  318.  2E36302E ...  2D524341 ACR-NEMA 1.0..  .....1994.06.29..  000020 00600008
  319.  4D5F4553 ...  00000030 0.......@.........A.....SE_M..`.  000040 494B0000
  320.  00100080 ...  00000002 ....MR..p.....Philips ........KI 000060
  321.  
  322.  00183148 00000002 ...  32200000 ..  2........63865375........H1..  0001E0
  323. ^L Dump of file SYS$SYSROOT:[GYROSCAN]ABAALKHAIL02010201010001.ANI;1 ...  File
  324. ID (2419,301,0) End of file block 198 / Allocated 200
  325.  
  326. Virtual block number 2 (00000002), 512 (0200) bytes
  327.  
  328.  40000018 45424F52 ...  00161250 P.....AGACQ_PT_SURFACE_PROBE...@ 000000
  329.  
  330.  
  331.               And so on ...  you get the idea.  This ugly little C++
  332.               utility written quickly during this moment of inspiration
  333.               will take saved DUMP output and make it binary again:
  334.  
  335.  
  336. #include <fstream.h>
  337.  
  338. #include "MainCmd.h"
  339.  
  340. signed char hextobin(char c) {
  341.     signed char r; switch (c) {
  342.         case '0': r=0; break; case '1': r=1; break; case '2': r=2;
  343.         break; case '3': r=3; break; case '4': r=4; break; case '5':
  344.         r=5; break; case '6': r=6; break; case '7': r=7; break; case
  345.         '8': r=8; break; case '9': r=9; break; case 'A': case 'a':
  346.         r=0xa; break; case 'B': case 'b': r=0xb; break; case 'C': case
  347.         'c': r=0xc; break; case 'D': case 'd': r=0xd; break; case 'E':
  348.         case 'e': r=0xe; break; case 'F': case 'f': r=0xf; break;
  349.         default: r=-1; break;
  350.     } return r;
  351. }
  352.  
  353. int main(int argc,char **argv) {
  354.     CCOMMAND(argc,argv);
  355.  
  356.     while (1) {
  357.         const linemax=132; // only needs 113 char line[linemax];
  358.         cin.getline(line,linemax); if (!cin || cin.eof()) {
  359.             // cerr << "Bad or eof\n" << flush; break;
  360.         } unsigned count=cin.gcount(); if (count == 0 || line[0] != ' ')
  361.         continue; if (count != 113) {
  362.             cerr << "Line length " << count << "\n" << flush; break;
  363.         } unsigned i; char *ptr = line + 8*(1+8); // line is in reverse
  364.         order ...  for (i=0; i<8; ++i) {
  365.             unsigned j; for (j=0; j<4; ++j) {
  366.                 // 2 hex bytes -> 1 byte char bytelo = *--ptr;
  367.                 char bytehi = *--ptr; unsigned char byte
  368.                     = (hextobin(bytehi)<<4)
  369.                       + hextobin(bytelo);
  370.                 cout.put(byte);
  371.             } --ptr; // space between long words
  372.         }
  373.     } return 0;
  374. }
  375.  
  376.  
  377.               Note that the nature of fixed length records under VMS
  378.               means that the last record will be padded out to 512 bytes
  379.               without any indication of the "real" end-of-file.  This
  380.               means you have to cope with trailing garbage gracefully.
  381.  
  382.  
  383.               Hot VMS/Philips news: neelin@pet.mni.mcgill.ca (Peter
  384.               Neelin) tells me there is an extremely useful tool for
  385.               fiddling binary files called FILE from DECUS.  It allows
  386.               you to change a file's header information without
  387.               modifying the content of the file.  This then permits ftp,
  388.               kermit, etc.  to do the right thing with Philips .ANI
  389.               files.  It also permits wildcards and does not make a copy
  390.               of the file (so it is fast).  He says also that someone
  391.               has told him that they succeeded in using convert to fix
  392.               these files, but his general experience with it is not
  393.               positive (it will often change the content of the file and
  394.               it doesn't allow wildcards, in addition to promoting the
  395.               use of the horrible fdl editor!).  If you are interested,
  396.               you can get FILE through gopher from decus.org (look for
  397.               the DECUS software library archives, under essential
  398.               tools).  The binary is provided in case you don't have a
  399.               compiler.  FILE, and many other useful things are also
  400.               available from the sites listed in Vax VMS Tools.
  401.  
  402.  
  403.               Some other useful hints:
  404.  
  405.               - To log onto a serial terminal without executing the
  406.               login command file add "/NOCOM" to the username ...  this
  407.               way you can use the operator console login which often
  408.               won't require a password.
  409.  
  410.               - There is a kermit available for the Vax under VMS (file
  411.               prefix "vms" in area or tape b) ...  I use the "obsolete"
  412.               version written in Bliss, because it comes from the
  413.               archives at columbia with a hex encoded executable which
  414.               can be uploaded just using an ordinary text capture into a
  415.               file, and doing the same with the short Macro hex program
  416.               that can then be assembled and used to make the convert
  417.               into the real executable.  Look in places like [SYSEXE]
  418.               first though to be sure Kermit is not already there.  The
  419.               generic C version of kermit runs under VMS (file prefix
  420.               "ck" in area or tape f), but not every imaging machine
  421.               comes with a VMS C compiler, whereas Macro is always
  422.               supposed to be there I gather.  There is however also a
  423.               hex encoded executable of the C version in the archives
  424.               (ckvker.hex) which I haven't tried, and is the one that is
  425.               recommended in the kermit documentation.
  426.  
  427.               - There is apparently a zmodem for VMS but I don't know
  428.               where it comes from or how to get it.
  429.  
  430.               - Serial ports are almost always defaulted to 9600 baud.
  431.  
  432.               - "SET TERMINAL/ECHO" often isn't set.
  433.  
  434.               - Vax/VMS ftp conventions:
  435.  
  436.  
  437.             UNIX FTP server Vax/VMS FTP server
  438.  
  439.             cd dir cd [.dir] cd dir/subdir cd [.dir.subdir] cd ..
  440.             cd [-]
  441.  
  442.           4.2.2.2 ULTRIX 4.2.2.3 OSF
  443.  
  444.     4.3 Sun - Sun3 68000 and Sun4 Sparc
  445.  
  446.     4.3.1 Sun Data
  447.  
  448.           The sun3 and sun4 architectures use much the same formats.  Even
  449.           though the processors are different both are big-endian and the
  450.           float formats are IEEE.  See the Sparc Architecture Manual -
  451.           Chapter 3 - Data Formats for more details.
  452.  
  453.  
  454.           One very important difference though, is that the sun3 convention
  455.           is not to align 32 bit and 64 bit data types on 4 and 8 byte
  456.           boundaries respectively, whereas the sparc (sun4) architectures
  457.           usually does, dictated by a compile time option.  Be very careful
  458.           when using the same header files on one architecture or the other.
  459.           This drove me nuts when trying to figure out why the well
  460.           described Genesis (sun3) layout did not match the unknown
  461.           Advantage Windows (sun4) data.  It was pretty obvious when it was
  462.           pointed out though :).
  463.  
  464.           4.3.1.1 Sun Integers
  465.  
  466.               Integers are 8, 16, 32, or 64 bit unsigned or signed two's
  467.               complement and stored in big-endian format as on Data
  468.               General and opposite to the Dec VAX.  Most C compilers
  469.               treat short as 16 bits, and int and long as 32 bits.
  470.  
  471.           4.3.1.2 Sun Floating Point
  472.  
  473.               Formats conform to the IEEE 754-1985 Standard for Binary
  474.               Floating-Point Arithmetic.  Single precision real values
  475.               are 32 bits long, in big-endian format.  The high bit is
  476.               the sign bit, followed by a 8 bit excess 127 exponent
  477.               (power to which 2 must be raised) then a 23 bit normalized
  478.               mantissa with the decimal point to the left of the most
  479.               significant bit, from which 1.0 has been subtracted.
  480.               Double precision values have a 11 bit excess 1023 exponent
  481.               and a 52 bit mantissa.  Quad precision values have a 15
  482.               bit excess 16383 exponent and a 112 bit mantissa.
  483.  
  484.  
  485.         Sign
  486.        |<-->|<-------- Exponent -------->|<------- Mantissa ------>|
  487.         ______________ ______________ ______________ ______________
  488.        | | | | |
  489.        |______________|______________|______________|______________|
  490.         31 28 27 24 23 20 19 16
  491.        |<----------------------- Mantissa ------------------------>|
  492.         ______________ ______________ ______________ ______________
  493.        | | | | |
  494.        |______________|______________|______________|______________|
  495.         15 12 11 8 7 4 3 0
  496.  
  497.  
  498.  
  499.               Here is a little piece of C++ code that should run on
  500.               anything and convert Sun IEEE floats to whatever the
  501.               host's floating point format is.  It probably should take
  502.               into account a few special cases to be strictly correct:
  503.  
  504.  
  505.         unsigned char buffer[4]; instream.read(buffer,4); if (instream)
  506.         {
  507. #ifdef USESUN4NATIVEFLOAT
  508.             float fvalue; memcpy ((char *)(&fvalue),buffer,4);
  509.             value=fvalue;
  510. #else USESUN4NATIVEFLOAT
  511.             unsigned char sign; Uint16 exponent; Uint32 mantissa;
  512.  
  513.             typedef struct {
  514.                 unsigned sign : 1; unsigned exponent : 8;
  515.                 unsigned mantissa : 23;
  516.             } IEEE_FLOAT_SINGLE;
  517.  
  518.             IEEE_FLOAT_SINGLE number; // Sparc is a Big Endian
  519.             machine memcpy ((char *)(&number),buffer,4); sign =
  520.             number.sign; exponent = number.exponent; mantissa =
  521.             number.mantissa;
  522.  
  523.             if (exponent) {
  524.                 value = (1.0 + (double)mantissa / (1 << 23)) *
  525.                     pow (2.0, (long)(exponent) - 127);
  526.             } else {
  527.                 if (mantissa) {
  528.                     value = (double)mantissa / (1 << 23) *
  529.                         pow (2.0, (long)(-126));
  530.                 } else {
  531.                     value=0;
  532.                 }
  533.             } value = (sign == 0) ?  value : -value;
  534. #endif USESUN4NATIVEFLOAT
  535.         } else {
  536.             cerr << "read failed\n" << flush; value=0;
  537.         }
  538.  
  539.           4.3.1.3 Sun Strings
  540.  
  541.               Strings obey the usual C convention of null terminated
  542.               strings without a length preamble.
  543.  
  544.  
  545.     4.3.2 Sun Operating System
  546.  
  547. 5.  Compression Schemes
  548.  
  549.     5.1 Reversible Compression 5.2 Irreversible Compression
  550.     5.2.1 Perimeter Encoding
  551.     5.3 DICOM Compression
  552.  
  553.     In DICOM, compression (both reversible and irreversible) is achieved by
  554.         specifying a particular "transfer syntax" either during
  555.         negotiation of the network connection (association) or in the
  556.         media application profile for files stored on media (and
  557.         specified in the meta information header so the reader knows
  558.         which transfer syntax to switch to).
  559.  
  560.  
  561.     The compressed data stream is actually encoded as an "encapsulated" data
  562.         stream as defined in Part 5 of DICOM.  Uncompressed data
  563.         (unencapsulated) is sent in DICOM as a series of raw bytes or
  564.         words (little or big endian) in the Value field of the Pixel
  565.         Data element (7FE0,0010).  Encapsulated data on the other hand
  566.         is sent not as raw bytes or words but as Fragments contained in
  567.         Items that are the Value field of Pixel Data.  The encoding of
  568.         these Items follows the same pattern as is used to specify
  569.         Sequences in DICOM, thogh the VR (Value Representation) field of
  570.         the Pixel Data is OB not SQ.
  571.  
  572.  
  573.     The encapsulated compressed data may be a single frame or it may contain
  574.         multiple frames for those SOP Classes that allow multifram
  575.         images (such as XA, XRF, US and NM).  The rules in part 5
  576.         further specify that the first Item will either be empty or
  577.         contain a list of offsets to the beginning of the Item
  578.         containing each frame (or the only frame for a single frame
  579.         image).  Also, though a frame may be split into multiple
  580.         fragments, each fragment may contain data for only one frame.
  581.         That is a frame may be split into multiple fragments, but a
  582.         fragment may not span different frames.  The reason for the
  583.         fragments in the first place is that each fragment (each item)
  584.         must have a fixed, known length, so unless one buffers the
  585.         entire compressed frame before encoding it, one doesn't know in
  586.         advance how long it will be.  In practice, most encoders do send
  587.         one frame per fragment but all decoders must be prepared to
  588.         handle the case where a frame spans fragments.  Furthermore, all
  589.         fragments have to be of even length, and there are padding rules
  590.         in Part 5 for the last fragment of a frame (that are consistent
  591.         with the definition of padding in the JPEG standard).
  592.  
  593.  
  594.     Part 5 contains several examples of how to fill in the various fields in
  595.         Items of the encapsulated sequence-like value for Pixel Data, so
  596.         these will not be repeated here.  However the overall strategy
  597.         looks something like this for an image with two frames,the first
  598.         split across two fragments, and an empty offset table:
  599.  
  600.  
  601.         (7FE0,0010) VR=OB VL=FFFFFFFF Pixel Data (FFFE,E000) VR=
  602.         VL=00000000 Item (empty offset table, hence zero length)
  603.         (FFFE,E000) VR= VL=000004C6 Item (first fragment of first frame)
  604.         ....  compressed byte stream here (4C6 bytes) (FFFE,E000) VR=
  605.         VL=0000024A Item (first fragment of first frame) ....
  606.         compressed byte stream here (24A bytes) (FFFE,E000) VR=
  607.         VL=00000628 Item (first fragment of first frame) ....
  608.         compressed byte stream here (628 bytes) (FFFE,E0DD) VR=
  609.         VL=00000000 Sequence Delimiter
  610.  
  611.  
  612.         Note that the Item and Sequence Delimiter tags have no VR, that
  613.         the Item Delimiter tag is never used, since Items are required
  614.         to be of fixed not undefined length, and that the Sequence
  615.         Delimiter tag is always used, since the Pixel Data is always of
  616.         undefined length (that is FFFFFFFF) for encapsulated data.
  617.  
  618.  
  619.         If one is trying to decode a DICOM image encoded with an
  620.         encapsulated transfer syntax, one therefore has to get to the
  621.         Pixel Data tag, and start parsing the sequence like structure.
  622.         One cannot just pass the entire Value field of Pixel Data to a
  623.         conventional JPEG decoder for instance.  One needs to strip out
  624.         the embedded Item tags and the trailing Sequence Delimiter.  For
  625.         an example of how to do this see the source code from
  626.         dicom3tools in "libsrc/include/pixeldat/unencap.h", a simplified
  627.         version of which (without the GE bug handling) is reproduced
  628.         here.
  629.  
  630.  
  631.     size_t read(void)
  632.         {
  633.             // - non-pixel data is always LE, including fragment
  634.             delimiters and lengths // - 1st item is offset table,
  635.             may have zero VL // - other items are fragments // -
  636.             finally sequence delimitation tag (with zero VL) // -
  637.             each delimiter is 2 byte group,2 byte element, 4 byte
  638.             VL, little endian // - Item tag is (0xfffe,0xe000) // -
  639.             Seq delimiter is (0xfffe,0xe0dd)
  640.  
  641.             length=0;
  642.  
  643.             while (!lefttoreadthisfragment && !finished && !bad) {
  644.                 Uint16 group=read16(); Uint16 element=read16();
  645.                 Uint32 vl=read32(); if (group == 0xfffe) {
  646.                     if (element == 0xe0dd) { // Sequence
  647.                     Delimiter Tag
  648.                         Assert(vl == 0); finished=true;
  649.                     } else /* if (element == 0xe000) */ { //
  650.                     Item Tag
  651.                         bool vlbyteorderwrong=false; if
  652.                         (++fragmentnumber > 0) {
  653.                             Assert(vl); // Zero
  654.                             length fragments thought
  655.                             not to be legal
  656.                             lefttoreadthisfragment=vl;
  657.                         } else {
  658.                             // skip the offset table
  659.                             Assert(vl%4 == 0);
  660.                             unsigned i=0; while (vl)
  661.                             {
  662.                                 Uint32
  663.                                 offset=read32();
  664.                                 vl-=4; ++i;
  665.                             }
  666.                         }
  667.                     }
  668.                 } else {
  669.                     // bad tag group in encapsulated data
  670.                     bad=true;
  671.                 }
  672.             }
  673.  
  674.             if (lefttoreadthisfragment && !bad) {
  675.                 length=unsigned(lefttoreadthisfragment >
  676.                 maxlength ?  maxlength :
  677.                 lefttoreadthisfragment); if
  678.                 (istr->read(buffer,length)) {
  679.                     length=istr->gcount();
  680.                 } else {
  681.                     bad=true; length=0;
  682.                 } lefttoreadthisfragment-=length;
  683.             }
  684.  
  685.             return length;
  686.         }
  687.  
  688.  
  689.         An application that will take a DICOM dataset and write a pure
  690.         byte stream (having stripped off the DICOM encapsulation) is
  691.         also in dicom3tools, "dctoraw".  One can feed the output of this
  692.         utility straight to a JPEG decoder such as the Stanford PVRG
  693.         utility "jpeg -d".  If any padding is present at the end of each
  694.         frame, it should have been encoded in a manner consistent with
  695.         JPEG padding defined in ISO 10918-1 so that the JPEG decoder
  696.         won't fail if it encounters padding between the image frames.
  697.  
  698.  
  699.         Note also that the use of the terms "image" and "frame" are
  700.         slightly different in DICOM than JPEG so be careful when
  701.         comparing the two standards.
  702.  
  703.  
  704.         When using images with more than one component (that is a color
  705.         image rather than a grayscale image), take care about the color
  706.         space.  One of the features of the ISO 10918-1 JPEG standard is
  707.         that it specifies only a compressed bitstream, and not a file
  708.         format.  Even if there are three components specified in the
  709.         compressed bitstream, that does not mean they are RGB or YBR or
  710.         whatever.  This has to be signalled outside the bitstream, and
  711.         in DICOM this is done in Photometric Interpretation (this is
  712.         somewhat controversial however, and one should look at recent
  713.         proposed DICOM CPs on the matter, such as CP 143).
  714.  
  715.  
  716.         In the non-DICOM world, the color space is specified in the file
  717.         header such as the commonly used JFIF header, or its superset,
  718.         the SPIFF header as defined in ISO 10918-3.  Be especially
  719.         careful that one does not assume during decoding that a JFIF
  720.         header is present in the DICOM compressed bit stream ...  it is
  721.         not.  If one wants to feed the extracted bitstream to a JPEG
  722.         decoder that needs a JFIF header (like the IJG code), then you
  723.         need to add one.  Conversely, never create an encapsulated DICOM
  724.         image with a bitstream that contains the JFIF header ...  strip
  725.         it off first or use an encoder like Stanford PVRG JPEG that
  726.         doesn't create JFIF headers.
  727.  
  728.  
  729.         Here JPEG has been discussed, but the same principle applies to
  730.         other encapsulated data sets in DICOM, including the RLE
  731.         compression scheme popular in Ultrasound images (which is
  732.         equivalent to the TIFF PackBits compression scheme).  The
  733.         compression scheme to interpret the encapsulated bitstream is
  734.         different, but the encapsulation mechanism using Item tags and
  735.         fragments is identical.
  736.  
  737.  
  738.         This mechanism has been widely used in the cardiac angiography
  739.         world on the DICOM CDs that these devices make, on Ultrasound 90
  740.         mm MODs, and on GE's more recent CT and MR scanners that write
  741.         use the CT and MR media application profile on 130 mm MODs.
  742.         Note that early implementations of the encapsulation mechanism
  743.         and the JPEG lossless encoding contain some bugs which are
  744.         described in detail in the section on GE CTI.
  745.  
  746. 6.  Getting Connected
  747.  
  748.     6.1 Tapes
  749.  
  750.     Nine-track half-inch tapes were the old medium of choice for archiving
  751.     and image exchange and many older pieces of equipment will have these.
  752.     Unfortunately most people don't have such a drive on their workstation
  753.     or personal computer.  There are several possibilities:
  754.  
  755.  
  756.       - Use another piece of equipment that has a more modern or
  757.        networked or serial-ported host and a nine-track drive, and use it to
  758.        do the extraction.  I used to use a networked Signa 4X to do this to
  759.        extract GE 9800 CT tapes.
  760.  
  761.       - Visit your MIS department, which almost certainly has an archaic
  762.        mainframe with a tape drive.  Sometimes tough to get them to read
  763.        formats they aren't expecting though (the hosts not the people I mean
  764.        :) ).
  765.  
  766.       - Buy a nine-track for your workstation.  This may seem a ridiculous
  767.        idea given the price of new 6250 bpi drives are around $5,000, but
  768.        one can often pick up bargain primitive non-6250 or refurbished drive
  769.        that is adequate for the job.
  770.  
  771.  
  772.     The Qualstar 1054 is one such drive, that attaches to a SCSI port, and
  773.     works with the regular SunOS SCSI tape driver, once a few tables in the
  774.     kernel have been updated as follows, and the kernel rebuilt:
  775.  
  776.  
  777. {root}% pwd /usr/kvm/sys/scsi/targets
  778.  
  779. {root}% diff -c stdef.h.prequalstar stdef.h *** stdef.h.prequalstar Tue Aug 30
  780. 19:32:24 1994 --- stdef.h Tue Aug 30 19:32:24 1994 *************** *** 43,48
  781. **** --- 43,49 ----
  782.   #define ST_TYPE_FUJI 0x21 /* Fujitsu - (not tested) */ #define ST_TYPE_KENNEDY
  783.   0x22 /* Kennedy */ #define ST_TYPE_HP 0x23 /* HP */
  784. + #define ST_TYPE_QUALSTAR 0x24 /* Qualstar */
  785.   #define ST_TYPE_HIC 0x26 /* Generic 1/2" Cartridge */ #define ST_TYPE_REEL
  786.   0x27 /* Generic 1/2" Reel Tape */
  787.  
  788. {root}% diff -c st_conf.c.prequalstar st_conf.c *** st_conf.c.prequalstar Tue
  789. Aug 30 19:32:22 1994 --- st_conf.c Tue Aug 30 19:32:22 1994 *************** ***
  790. 153,158 **** --- 153,174 ----
  791.    * so our best guess as to their capabilities is * included herein.  */
  792. + /* Qualstar 1054 or 1260s scsi 9-track with 64KB buffer */ + { + "Qualstar
  793. 1054/1260s 1/2\" Reel", 7, "NCR ADP-53", ST_TYPE_QUALSTAR, 10240, + (ST_REEL |
  794. ST_VARIABLE | ST_BSF | ST_BSR), + 300, 300, + { 0x00, 0x02, 0x06, 0x03}, + { 0,
  795. 0, 0, 0 } + }, + /* Qualstar 1054 scsi 9-track with 256KB buffer */ + { +
  796. "Qualstar 1054 1/2\" Reel", 10, "QUALSTAR10", ST_TYPE_QUALSTAR, 10240, +
  797. (ST_REEL | ST_VARIABLE | ST_BSF | ST_BSR), + 300, 300, + { 0x00, 0x02, 0x06,
  798. 0x06}, + { 0, 0, 0, 0 } + },
  799.   /* Wangtek QIC-150 1/4" cartridge */ {
  800.     "Wangtek QIC-150", 14, "WANGTEK 5150ES", ST_TYPE_WANGTEK, 512, (ST_QIC |
  801.     ST_AUTODEN_OVERRIDE),
  802.  
  803.  
  804.     I got my Qualstar 1054 from Bill Power at Power Computer Services for
  805.     only $750 and have successfully read GE 9800 CT and Philips S15 MR tapes
  806.     with it so far.  See the "Sources" section for where to get one.
  807.  
  808.  
  809.     Once you have such a tape connected to the SCSI port, one can either
  810.     write simple programs to read files (easiest if the tape has variable
  811.     length records) or use shell scripts and the "dd" command with whatever
  812.     the correct block size is.  See dd(1), mt(1), and mtio(3) for more
  813.     information.  Remember that the read(2) call reads one fixed or variable
  814.     length record at a time, and returns 0 bytes read for a tape mark, and
  815.     two tape marks in a row indicates the end of the tape (normally).  If
  816.     you encounter short files with a series of records 80 bytes long chances
  817.     are you are dealing with header/end markers.  This is what ANSI standard
  818.     tapes off VAX VMS seem to look like.
  819.  
  820.  
  821.     Anyone who has any further information about tape formats and handling,
  822.     especially references to standard or on-line documents please let me
  823.     know.
  824.  
  825.     6.2 Ethernet
  826.  
  827.     6.3 Serial Ports
  828.  
  829.  
  830. The next part is part7 - information sources.
  831.  
  832.  
  833.