Skip to content

Conversation

tblock79
Copy link
Contributor

@tblock79 tblock79 commented Oct 9, 2025

Context

JPEG 8bit color images are currently decoded using a browser built-in algorithm. To this end, the pixel data is stored in a Blob and copied into an HTML image object (in file decodeJPEGBaseline8BitColor.ts). However, when loading a large number of color images (e.g., a long series of US captures), the processing becomes slow and leads to blocking of the UI. One reason is that the decoding is done by the browser's UI thread instead of a webworker (which is necessary because DOM elements and functions are not available from webworkers).

This PR introduces an option to the dicomImageLoader's decodeConfig that enables using the (existing) webworker-based JPEG decoder also for 8bit color images, resulting in much faster processing times. The change allows specifying during application initialization that the browser-based decoding should not be used.

Changes & Results

  • Added a condition to decodeImageFrame.ts that checks if decodeOption.useJPEGBaseline8BitColorWebWorker was set during the init call
  • If the flag is set, all JPEG decoding tasks are delegated to the webworker, including 8bit color images, which are otherwise decoded with the browser-based code

Testing

  • Load a large series of JPEG color images (e.g., captures from an US scanner) into a stack viewport with enabled prefetching.
  • Scroll through the stack and compare responsiveness.

Checklist

PR

  • My Pull Request title is descriptive, accurate and follows the
    semantic-release format and guidelines.

Code

  • My code has been well-documented (function documentation, inline comments,
    etc.)

Public Documentation Updates

  • The documentation page has been updated as necessary for any public API
    additions or removals.

Tested Environment

  • "OS: Windows 11"
  • "Node version: 22.17.0"
  • "Browser: Chrome 142.0, Firefox 143.0"

@sedghi
Copy link
Member

sedghi commented Oct 10, 2025

This is a great pull request! How can we test it out? Could you share some anonymized data? Also, do our web workers already have a way to decode these images? Which one should handle it if the config is set to skip the browser?

@vitblock
Copy link
Contributor

Will take a look if we have phantom data that I can share (most cases are captures from US machines, which have burned-in PHI).

Yes, the existing webworker code is able to decode these images, and I haven't noticed a difference (except that the decoding is faster). This is the original logic in the code:

    case '1.2.840.10008.1.2.4.50':
      // JPEG Baseline lossy process 1 (8 bit)

      // Handle 8-bit JPEG Baseline color images using the browser's built-in
      // JPEG decoding
      if (
        imageFrame.bitsAllocated === 8 &&
        (imageFrame.samplesPerPixel === 3 || imageFrame.samplesPerPixel === 4)
      ) {
        return decodeJPEGBaseline8BitColor(imageFrame, pixelData, canvas);
      }

      return processDecodeTask(
        imageFrame,
        transferSyntax,
        pixelData,
        options,
        decodeConfig
      );

The PR adds the option to disable the "if" condition that checks for color images, so that all JPEG 8-bit cases are routed to the "processDecodeTask" function (which delegates to the webworker).

It would probably be OK to remove the browser-internal decoding all-together, but it might be safer for now to keep it in there and make it configurable.

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

Successfully merging this pull request may close these issues.

3 participants