http://imagej.273.s1.nabble.com/Image-header-256-bytes-out-tp3687288p3687292.html
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.
will discard the higher bytes.
> 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/>