fix: Better handle octet stream case (#5789)

* Better handle octet stream case

* Use data source config stack options

* Use immutability helper

* Use immutability helper (update)

---------

Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
This commit is contained in:
Igor Octaviano 2026-02-10 07:50:41 -05:00 committed by GitHub
parent 5837e6507e
commit 037402f7f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 7 deletions

View File

@ -63,10 +63,10 @@
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "34.15.1",
"html2canvas": "1.4.1",
"immutability-helper": "3.1.1",
"lodash.compact": "3.0.1",
"lodash.debounce": "4.0.8",
"lodash.flatten": "4.4.0",
"lodash.merge": "4.6.2",
"lodash.zip": "4.2.0",
"shader-loader": "1.3.1",
"worker-loader": "3.0.8"

View File

@ -59,6 +59,7 @@ import utils from './utils';
import { useMeasurementTracking } from './hooks/useMeasurementTracking';
import { setUpSegmentationEventHandlers } from './utils/setUpSegmentationEventHandlers';
import { setUpAnnotationEventHandlers } from './utils/setUpAnnotationEventHandlers';
import update from 'immutability-helper';
export * from './components';
const { imageRetrieveMetadataProvider } = cornerstone.utilities;
@ -75,7 +76,7 @@ const OHIFCornerstoneViewport = props => {
);
};
const stackRetrieveOptions = {
const DEFAULT_STACK_RETRIEVE_OPTIONS = {
retrieveOptions: {
single: {
streaming: true,
@ -84,6 +85,12 @@ const stackRetrieveOptions = {
},
};
/** Normalize to immutability-helper spec: plain object → $merge, otherwise use as-is. */
const toUpdateSpec = (obj: object) =>
obj != null && typeof obj === 'object' && Object.keys(obj).some(k => k.startsWith('$'))
? obj
: { $merge: (obj ?? {}) as object };
const unsubscriptions = [];
/**
*
@ -94,7 +101,11 @@ const cornerstoneExtension: Types.Extensions.Extension = {
*/
id,
onModeEnter: ({ servicesManager, commandsManager }: withAppTypes): void => {
onModeEnter: ({
servicesManager,
commandsManager,
extensionManager,
}: withAppTypes): void => {
const { cornerstoneViewportService, toolbarService, segmentationService } =
servicesManager.services;
@ -131,10 +142,17 @@ const cornerstoneExtension: Types.Extensions.Extension = {
'volume',
cornerstone.ProgressiveRetrieveImages.interleavedRetrieveStages
);
// The default stack loading option is to progressive load HTJ2K images
// There are other possible options, but these need more thought about
// how to define them.
imageRetrieveMetadataProvider.add('stack', stackRetrieveOptions);
/**
* Stack retrieve options: read from active data source configuration.
* Pass an immutability-helper spec (e.g. { $merge: {...} } or { $set: {...} }) in
* stackRetrieveOptions to customize. Plain object is treated as $merge for backward compat.
* Set streaming: false for uncompressed DICOM that requires full file before decode.
*/
const sourceConfig = extensionManager?.getActiveDataSource?.()?.[0]?.getConfig?.() ?? {};
const config = sourceConfig.stackRetrieveOptions ?? {};
const stackOptions = update(DEFAULT_STACK_RETRIEVE_OPTIONS, toUpdateSpec(config)) as typeof DEFAULT_STACK_RETRIEVE_OPTIONS;
imageRetrieveMetadataProvider.add('stack', stackOptions);
},
getPanelModule,
onModeExit: ({ servicesManager }: withAppTypes): void => {

View File

@ -312,6 +312,18 @@ reasons:
However, if you would like to get compressed data in a specific transfer syntax, you can modify the `acceptHeader` configuration or
`requestTransferSyntaxUID` configuration.
### Data Source: stackRetrieveOptions
At the data source configuration level, you can set `stackRetrieveOptions` to customize Cornerstone stack image retrieval. Merged with defaults; only specify overrides. For example, set `streaming: false` when the data source returns uncompressed DICOM (e.g. `application/octet-stream` only) to avoid black image on load:
```js
configuration: {
acceptHeader: ['application/octet-stream'],
stackRetrieveOptions: {
retrieveOptions: { single: { streaming: false } },
},
}
```
## Environment Variables
We use environment variables at build and dev time to change the Viewer's