Login  Register

Re: Image header - 256 bytes out

Posted by Frederic V. Hessman on Aug 06, 2010; 1:23pm
URL: http://imagej.273.s1.nabble.com/Image-header-256-bytes-out-tp3687288p3687294.html

The simplest thing might be to translate your files into FITS, which  
has a very simple but rich keyword-value functionality (and which  
ImageJ can process: our astronomical plugins even use present and  
create new content).

Rick

On 6 Aug 2010, at 12:24, 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