Image header - 256 bytes out

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Image header - 256 bytes out

Thomson Neil (EAST KENT HOSPITALS UNIVERSITY NHS FOUNDATION
              TRUST)
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
Reply | Threaded
Open this post in threaded view
|

Re: Image header - 256 bytes out

Frederic V. Hessman
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
Reply | Threaded
Open this post in threaded view
|

Antwort: Image header - 256 bytes out

Joachim Wesner
In reply to this post by Thomson Neil (EAST KENT HOSPITALS UNIVERSITY NHS FOUNDATION TRUST)
Hi Neil,

I think in getshort(), b0 and especially b1 must already be short,
otherwise b1 <<8 makes no sense and will not do what you expect, also
adding the supposedly shifted b1 to b0,
the casting (short) only works AFTER the operation, when the upper bits are
already lost IMHO!

Mit freundlichen Grüßen / Best regards

Joachim Wesner
____________________________________________

Leica Microsystems CMS GmbH | GmbH mit Sitz in Wetzlar | Amtsgericht
Wetzlar  HRB 2432
Geschäftsführer:  Dr. Stefan Traeger | Dr. David Roy Martyr | Colin Davis
www.leica-microsystems.com



                                                                           
             Neil Thomson                                                  
             <neil.thomson2@NH                                            
             S.NET>                                                     An
             Gesendet von:              [hidden email]                
             ImageJ Interest                                         Kopie
             Group                                                        
             <[hidden email].                                       Thema
             GOV>                       Image header - 256 bytes out      
                                                                           
                                                                           
             06.08.2010 12:24                                              
                                                                           
                                                                           
              Bitte antworten                                              
                    an                                                    
              ImageJ Interest                                              
                   Group                                                  
             <[hidden email].                                            
                   GOV>                                                    
                                                                           
                                                                           




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



______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________
Reply | Threaded
Open this post in threaded view
|

Re: Image header - 256 bytes out

Boris Epstein
In reply to this post by Thomson Neil (EAST KENT HOSPITALS UNIVERSITY NHS FOUNDATION TRUST)


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.
Reply | Threaded
Open this post in threaded view
|

Re: Image header - 256 bytes out

Andreas Maier
Hi Neil,

I think writing a Plugin to read your fileformat is definitely the right
way to go. If your plugin is extends ImagePlus you can even add it to
the HandleExtraFileTypes.java in your plugin directory. Then your ImageJ
will become fully compatible with your format and you can even use the
drag and drop functionality in ImageJ.

I completely agree with Joachim Wesner's comment. You should cast to
short before you shift your bits:

    short getShort() throws IOException {
      byte b0 = getByte();
      byte b1 = getByte();
      if (littleEndian) {
        return  ((((short)b1)<<  8) + b0);
      } else {
        return ((((short)b0)<<  8) + b1);
      }
    }

Another thing which may be wrong, is that your current index in your
header points to the wrong position for some reason. Without example
files and the complete code, it's difficult to find the issue.

Best,

Andreas

Am 8/6/2010 7:01 AM, schrieb Boris Epstein:

>
>
> 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.


--
Dr.-Ing. Andreas Maier
Stanford University
Department of Radiology
The Lucas Center for Imaging
Mail Code 5488, Route 8
Stanford, CA  94305
http://med.stanford.edu/profiles/Andreas_Maier/
Reply | Threaded
Open this post in threaded view
|

Re: Image header - 256 bytes out

Michael Schmid
Hi Neil,

it is not a matter of typecast, it is cast to int anyhow: in Java, there
are no byte or short operations like '+' or '<<'.
It rather is a problem of Java having only signed data types. E.g., byte
0xff is interpreted as -1, and converted to int -1 = 0xffffffff.

Thus, at least the lower byte needs an '&' operation to mask out the lower
8 bits:
   (b1 << 8) + (b0 & 0xff);
You don't need to mask out the upper byte because the typecast to short
will discard the higher bytes.

Michael
_________________________________________________________________

On Fri, August 6, 2010 19:13, Andreas Maier wrote:

> Hi Neil,
>
> I think writing a Plugin to read your fileformat is definitely the right
> way to go. If your plugin is extends ImagePlus you can even add it to
> the HandleExtraFileTypes.java in your plugin directory. Then your ImageJ
> will become fully compatible with your format and you can even use the
> drag and drop functionality in ImageJ.
>
> I completely agree with Joachim Wesner's comment. You should cast to
> short before you shift your bits:
>
>     short getShort() throws IOException {
>       byte b0 = getByte();
>       byte b1 = getByte();
>       if (littleEndian) {
>         return  ((((short)b1)<<  8) + b0);
>       } else {
>         return ((((short)b0)<<  8) + b1);
>       }
>     }
>
> Another thing which may be wrong, is that your current index in your
> header points to the wrong position for some reason. Without example
> files and the complete code, it's difficult to find the issue.
>
> Best,
>
> Andreas
>
> Am 8/6/2010 7:01 AM, schrieb Boris Epstein:
>>
>>
>> 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.
>
>
> --
> Dr.-Ing. Andreas Maier
> Stanford University
> Department of Radiology
> The Lucas Center for Imaging
> Mail Code 5488, Route 8
> Stanford, CA  94305
> http://med.stanford.edu/profiles/Andreas_Maier/
>
Reply | Threaded
Open this post in threaded view
|

Re: Image header - 256 bytes out

Thomson Neil (EAST KENT HOSPITALS UNIVERSITY NHS FOUNDATION
              TRUST)
In reply to this post by Thomson Neil (EAST KENT HOSPITALS UNIVERSITY NHS FOUNDATION TRUST)
Thanks to all  who replied,

 (b1 << 8) + (b0 & 0xff) fixed the problem.

This now raises another question; I based my original code on the DICOM.java plugin. The implication is that the getShort() method is incorrect in that class, but I haven't noticed any problems using it.

Neil