Login  Register

Re: Image header - 256 bytes out

Posted by Boris Epstein on Aug 06, 2010; 2:01pm
URL: http://imagej.273.s1.nabble.com/Image-header-256-bytes-out-tp3687288p3687290.html



On 08/06/2010 06:24 AM, Neil Thomson wrote:

> Dear list
>
> I'm writing (or trying) a plugin to import a proprietary medical image format. There is no trouble importing the image proper, but I'm having problems reading some of the header information, which contains demographic and image information as "keys" and "values". The structure of the header is as follows:
>
> 1.  10 bytes of preamble, which includes number of keys
> 2.  Keys and value-offsets (up to the number obtained above) in chunks of 6 bytes (2 for key number, 1 for data type, 1 unused and 2 for the byte offset of the value).
> 3.  Values of keys (The size is determined by type or, for strings, by a hand-typed look-up table referenced to the key number)
> 4.  Image
>
> In my plugin I read to the number of keys. I can then loop to query the 6 bytes key/offset block to get the value offset, use a lookup table to get more information about the key. I then add the key and value to the image info (with the later intention of doing something useful, like set dimensions). Loop until reaching the last value.
>
> This works for some keys and not for others. Many values are strings, so I can read the whole header into IJ.log and inspect it for readable characters.  I have found that when the offset reported (in the 6 byte block) is incorrect, it is always by 256 bytes.  It seems very odd to me that when it's wrong it's by the same amount and can't be random.
>
> I must be doing something wrong and would be grateful for any help with this.  Here are a couple of code snippets that demonstrated the offset reported by some keys being 256 bytes away from the values as read in as a string from the header:
>
> ------------------------------------------------
>    private boolean littleEndian = false;
>    private int location = 0, offset = 0;
>    private static final int imageOffset = 2048;
>
>    BufferedInputStream inputStream;
> ...
>
>        inputstream.read(header, 0, imageOffset);
>
>        String hdr = getString(6) + "\n";
>        IJ.log(hdr);                 // says adac01
>        short labels = getShort();
>        IJ.log(Integer.toString(labels)); // Number of labels in header
>        IJ.log(Integer.toString(getByte()));  // Number of sub-headers
>        IJ.log(Integer.toString(getByte()));  // Unused byte
>        // Should have read 10 bytes
>
>        offset = location;
>
>        // Test header output 20 chars at a time
>        for (int i=0; i<1956; i++){
>          location=i;
>          IJ.log(""+i + ": " + getString(20));
>        }
>        location = offset;
>
>        for (short i = 0; i<  labels; i++) {
>          getKeys();
>          IJ.log("Key: " + keynum + " Type: " + datTyp + " offset: " + fieldOffset + "\n");
>        }
> .......
>    void getKeys() throws IOException {
>      keynum = getShort();
>      datTyp = getByte();
>      unused = getByte();
>      fieldOffset = getShort();
>    }
>
>    String getString(int length) throws IOException {
>      byte[] buf = new byte[length];
>      System.arraycopy(header, location, buf, 0, length);
>      location += length;
>      return new String(buf);
>    }
>
>    byte getByte() throws IOException {
>      byte b = header[location];
>      ++location;
>      return b;
>    }
>
>    short getShort() throws IOException {
>      byte b0 = getByte();
>      byte b1 = getByte();
>      if (littleEndian) {
>        return (short) ((b1<<  8) + b0);
>      } else {
>        return (short)((b0<<  8) + b1);
>      }
>    }
>
> ------------------------------------
>
> Many thanks in advance, Neil
>    

Neil,

I don't know about your particular format but have you considered
converting this data into NRRD:

http://teem.sourceforge.net/nrrd/

Seems like a nice popular open source graphics format that from what you
are saying should handle all you are trying to handle leaving room for
further enhancement is necessary.

Boris.


The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Partners Compliance HelpLine at
http://www.partners.org/complianceline . If the e-mail was sent to you in error
but does not contain patient information, please contact the sender and properly
dispose of the e-mail.