Skip to content

Overlays don't show for compressed multi-page tifs #296

Description

@anabelle2001

Problem

When I open a multi-page ImageJ TIFF that embeds ROI overlays and uses LZW compression, the image loads but no overlays appear. The same file written without compression shows overlays correctly.

Minimal reproducer

Four images were generated using this python script:

import numpy as np
import roifile
import tifffile


# enable / disable compression
for compression in (None, "lzw"):
    
    # single-frame image when n=1
    # stack when n=10
    for n in (1, 10):
        path = f"overlay_test_{compression or 'uncompressed'}_{n}.tif"
        print(f"{compression=!r}, {n=!r} -> {path!r}")

        # create a rectangle roi
        overlay = roifile.ImagejRoi(
            left=10,
            top=10,
            right=40,
            bottom=40,
            name="test_roi",
            roitype=roifile.ROI_TYPE.RECT,
            stroke_color=bytes((255, 255, 255, 255)),
            version=228,
        ).tobytes()

        # write the image
        tifffile.imwrite(
            path,
            np.zeros((n, 64, 64)),
            compression=compression,
            metadata={"Overlays": [overlay]},
            imagej=True,
        )

Rois show up correctly for 3/4 examples, failing in overlay_test_lzw_10.tif

Expected:

  • Overlays embedded in the IJ metadata block (tag 50839) are displayed regardless of compression, since the overlay bytes are present in both files.

Observed:

  • Overlays show in LZW compressed single images, uncompresed image stacks, but not compressed image stacks.

Potential Cause *

  1. TiffDecoder.saveImageDescription() only sets fi.nImages from images=N when fi.compression == COMPRESSION_NONE (TiffDecoder.java ~214).

  2. With LZW, images=2 is ignored, so ImageJ reads both IFDs via Opener.openTiffStack()'s multi-IFD branch instead of the fi.nImages > 1FileOpener.openImage() path.

  3. FileOpener.openStack() calls setOverlay() when fi.overlay != null; the multi-IFD branch in Opener.openTiffStack() (~914–929) does not.

So fi.overlay appears to be parsed from metadata but never applied on the LZW / multi-IFD code path.

Potential Fix *

One approach might be to call setOverlay() in Opener.openTiffStack()'s multi-IFD branch when fi.overlay != null, similar to FileOpener.openStack(). Alternatively, setting fi.nImages from images=N regardless of compression (if that is safe for LZW contiguous stacks) could route through the existing overlay path.


* Sections marked with a trailing asterisk were written with generative AI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions