Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IWI sample image data buffers #1239

Open
neurolabusc opened this issue Sep 18, 2024 · 2 comments
Open

IWI sample image data buffers #1239

neurolabusc opened this issue Sep 18, 2024 · 2 comments

Comments

@neurolabusc
Copy link

neurolabusc commented Sep 18, 2024

I was able to create sensible IWI images with Python:

import itk

image = itk.imread('fslmean.nii.gz')
itk.imwrite(image, 'fslmean.iwi.cbor')

However, the validation itk-wasm test datasets seem odd, specifically

  • 197kb 24-bit RGB itk-wasm\test\pipelines\median-filter-pipeline\cthead1.iwi.cbor
  • 66kb 8-bit @itk-wasm\dam\test\data\cthead1.iwi.cbor

When I decode each, the data.buffer.bytelength is larger than the data.byteLength, with the latter being the number of bytes described by the header (while the former is >200 bytes too large). While padding datasets for byte alignment seems understandable, the strange thing is the the padding is at the start of the array, not the end. This makes fast reading of byte data as Uint8Array regardless of datatype (e.g. Float32Array, etc) ungainly. My best guess is these validation versions were created by beta software and should be updated to reflect the standard, but it might be worth understanding the origin of this discrepancy.

import { decode } from 'cbor-x'

export function iwi2nii(arrayBuffer) {
    // decode from cbor to JS object
    let iwi = decode(new Uint8Array(arrayBuffer))
    if (iwi.data.buffer.byteLength > iwi.data.byteLength) {
      console.log(`!buffer larger than data ${iwi.data.buffer.byteLength} vs ${iwi.data.byteLength} bytes`)
    }
    // note padding at the start!
    const img8 = new Uint8Array(iwi.data.buffer, iwi.data.buffer.byteLength-iwi.data.byteLength, iwi.data.byteLength)
    // this also works, but only if data is Uint8Array, not Float32Array:
    const imgOK = new Uint8Array(iwi.data.slice())
}
@neurolabusc
Copy link
Author

The best universal solution I have found is to use byteOffset, but I am not sure why this is not zero in these validation datasets:

    const img8 = new Uint8Array(iwi.data.buffer, iwi.data.byteOffset, iwi.data.byteLength)

@thewtex
Copy link
Member

thewtex commented Sep 19, 2024

My best guess is these validation versions were created by beta software and should be updated to reflect the standard, but it might be worth understanding the origin of this discrepancy.

Yes, I expect this also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants