From 8a5d1b68a9c321d54f5d8119b9a578e269f5e826 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Sat, 30 May 2026 23:50:17 -0500 Subject: [PATCH 1/6] docs/newformat: simple grid supports sparse tiles now For: https://github.com/openslide/openslide/pull/738 Signed-off-by: Benjamin Gilbert --- docs/newformat/index.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/newformat/index.md b/docs/newformat/index.md index 9fd8b13..dd54136 100644 --- a/docs/newformat/index.md +++ b/docs/newformat/index.md @@ -16,8 +16,9 @@ Your driver can use the *grid* module to map pixel coordinates to tile addresses: - The `simple` grid is suitable for slide formats that have non-overlapping, - regularly-spaced, equal-sized tiles, and do not need to record individual - information about each tile. (TIFF images often have this property.) + regularly-spaced, equal-sized tiles, possibly sparse, and do not need to + record additional information about each tile. (TIFF images often have + this property.) - The `tilemap` grid is suitable for formats in which each tile is assigned a row and column on a regular grid, but the tiles may be offset from their @@ -139,10 +140,11 @@ Your driver is also responsible for setting some `openslide.background-color` should be set with `_openslide_set_background_color_prop()`. -The `openslide.bounds-*` properties should be set for formats that do not -store image data for every pixel in the level. Drivers that use a single -`tilemap` or `range` grid per level can set these properties with -`_openslide_set_bounds_props_from_grid()`. +The `openslide.bounds-*` properties should be set for slides that omit image +data along an entire edge of level 0. Drivers that use a single grid per +level can set these properties with +`_openslide_set_bounds_props_from_grid()`, which automatically omits the +properties if the bounding box entirely covers level 0. `openslide.mpp-x`, `openslide.mpp-y`, and `openslide.objective-power` should be a copy of, or otherwise derived from, another vendor-specific property. From 75cba08612e56a29cdc13f6d3004bf5f24b9f082 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 3 Jun 2026 23:56:18 -0500 Subject: [PATCH 2/6] formats/dicom: document concatenation support For: https://github.com/openslide/openslide/pull/648 Signed-off-by: Benjamin Gilbert --- formats/dicom/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/formats/dicom/index.md b/formats/dicom/index.md index aef2297..c626ade 100644 --- a/formats/dicom/index.md +++ b/formats/dicom/index.md @@ -44,6 +44,9 @@ the file's role within the whole slide image: | Associated image | `ORIGINAL\PRIMARY\LABEL\NONE`
`ORIGINAL\PRIMARY\OVERVIEW\NONE`
`ORIGINAL\PRIMARY\THUMBNAIL\RESAMPLED`
`DERIVED\PRIMARY\LABEL\NONE`
`DERIVED\PRIMARY\OVERVIEW\NONE`
`DERIVED\PRIMARY\THUMBNAIL\RESAMPLED` | | Ignored | All others | +A slide level can be spread across multiple files that share a +_Concatenation UID_. + If multiple files in the directory have the same _SOP Instance UID_, the extra copies are ignored. From 39e45a81083246c7242fd6eadcdbed34b63b21d1 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 5 Jun 2026 01:24:54 -0500 Subject: [PATCH 3/6] formats/dicom: use only the Image Flavor to determine a file's role For: https://github.com/openslide/openslide/pull/744 Signed-off-by: Benjamin Gilbert --- formats/dicom/index.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/formats/dicom/index.md b/formats/dicom/index.md index c626ade..b656bea 100644 --- a/formats/dicom/index.md +++ b/formats/dicom/index.md @@ -35,13 +35,14 @@ to parse and load DICOM files. OpenSlide non-recursively scans the containing directory for other DICOM files with the same _Series Instance UID_ attribute value as the specified -file. It uses the _Image Type_ attribute of each matching file to determine -the file's role within the whole slide image: +file. It uses the _Image Flavor_ (value 3 of the _Image Type_ attribute) +of each matching file to determine the file's role within the whole slide +image: -| Role | Allowed _Image Type_ values | +| Role | _Image Flavor_ values | | - | - | - | -| Slide level | `ORIGINAL\PRIMARY\VOLUME\NONE`
`DERIVED\PRIMARY\VOLUME\NONE`
`DERIVED\PRIMARY\VOLUME\RESAMPLED` | -| Associated image | `ORIGINAL\PRIMARY\LABEL\NONE`
`ORIGINAL\PRIMARY\OVERVIEW\NONE`
`ORIGINAL\PRIMARY\THUMBNAIL\RESAMPLED`
`DERIVED\PRIMARY\LABEL\NONE`
`DERIVED\PRIMARY\OVERVIEW\NONE`
`DERIVED\PRIMARY\THUMBNAIL\RESAMPLED` | +| Slide level | `VOLUME` | +| Associated image | `LABEL`
`OVERVIEW`
`THUMBNAIL` | | Ignored | All others | A slide level can be spread across multiple files that share a @@ -71,11 +72,11 @@ _ICC Profile_ of the associated image. ## Associated Images -| Associated image | Allowed _Image Type_ values | +| Associated image | _Image Flavor_ | | - | - | - | -| `label` | `ORIGINAL\PRIMARY\LABEL\NONE`
`DERIVED\PRIMARY\LABEL\NONE` | -| `macro` | `ORIGINAL\PRIMARY\OVERVIEW\NONE`
`DERIVED\PRIMARY\OVERVIEW\NONE` | -| `thumbnail` | `ORIGINAL\PRIMARY\THUMBNAIL\RESAMPLED`
`DERIVED\PRIMARY\THUMBNAIL\RESAMPLED` | +| `label` | `LABEL` | +| `macro` | `OVERVIEW` | +| `thumbnail` | `THUMBNAIL` | ## Known Properties From 25115acfe258986bc1a50f5bbd8d7839ce8d4112 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 4 Jun 2026 19:01:18 -0500 Subject: [PATCH 4/6] formats/aperio: fix 33003/33005 photometric interpretation 33003 uses YCbCr without MCT, so the components we receive are YCbCr. 33005 uses MCT and OpenJPEG decodes the components to RGB for us. For: https://github.com/openslide/openslide/pull/743 Signed-off-by: Benjamin Gilbert --- formats/aperio/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/formats/aperio/index.md b/formats/aperio/index.md index 9b39d3b..719fc13 100644 --- a/formats/aperio/index.md +++ b/formats/aperio/index.md @@ -75,9 +75,9 @@ page 14: Some Aperio files use compression type 33003 or 33005. Images using this compression need to be decoded as a JPEG 2000 codestream. For -33003: YCbCr format, possibly with a chroma subsampling of 4:2:2. For -33005: RGB format. Note that the TIFF file may not encode the -colorspace or subsampling parameters in the +33003: YCbCr format with no MCT, possibly with a chroma subsampling of +4:2:2. For 33005: MCT, which OpenJPEG decodes into RGB. Note that the TIFF +file may not encode the colorspace or subsampling parameters in the `PhotometricInterpretation` field, nor the `YCbCrSubsampling` field, even though the TIFF standard seems to require this. The correct subsampling can be found in the JPEG 2000 codestream. From e5cd5de77beb1d1e7e09b7ad51422f33e648675b Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 4 Jun 2026 17:41:52 -0500 Subject: [PATCH 5/6] formats/dicom: add YBR_RCT; remove YBR_ICT from lossless transfer syntax For: https://github.com/openslide/openslide/pull/743 Signed-off-by: Benjamin Gilbert --- formats/dicom/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/formats/dicom/index.md b/formats/dicom/index.md index b656bea..6c552b8 100644 --- a/formats/dicom/index.md +++ b/formats/dicom/index.md @@ -59,8 +59,8 @@ supported: | - | - | - | | Uncompressed little-endian | `1.2.840.10008.1.2.1` | `RGB` | | JPEG baseline | `1.2.840.10008.1.2.4.50` | `RGB`
`YBR_FULL_422` | -| JPEG 2000 | `1.2.840.10008.1.2.4.91` | `RGB`
`YBR_ICT` | -| JPEG 2000 lossless | `1.2.840.10008.1.2.4.90` | `RGB`
`YBR_ICT` | +| JPEG 2000 | `1.2.840.10008.1.2.4.91` | `RGB`
`YBR_ICT`
`YBR_RCT` | +| JPEG 2000 (lossless only) | `1.2.840.10008.1.2.4.90` | `RGB`
`YBR_RCT` | ## ICC Profiles From 2cd927347832c20011a1926e942e35a7785042fa Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 5 Jun 2026 18:56:14 -0500 Subject: [PATCH 6/6] Allow deprecating testdata slides Dim them in the HTML index and omit them from the demo site. Signed-off-by: Benjamin Gilbert --- _testdata/testdata_index.py | 17 ++++++++++++----- demo/_synctiles.py | 6 ++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/_testdata/testdata_index.py b/_testdata/testdata_index.py index 2b9668d..04939e9 100755 --- a/_testdata/testdata_index.py +++ b/_testdata/testdata_index.py @@ -43,7 +43,7 @@ 'sha256', ) ) -OPTIONAL_FIELDS = frozenset(('credit',)) +OPTIONAL_FIELDS = frozenset(('credit', 'deprecated')) INDEX_TEMPLATE = """ @@ -59,6 +59,10 @@ padding-left: 10px; padding-right: 10px; } +tr.deprecated { + color: #888888; + background: #f4e8e8; +} td { padding-top: 0.5em; padding-bottom: 0.5em; @@ -88,14 +92,17 @@ Credit {% macro row(icon, href, name, size='', description='', license='', - credit='') %} - + credit='', deprecated=false) %} + {{ name }} {{ size }} - {{ description }} + + {{ description }} + {% if deprecated %}(deprecated){% endif %} + {% if license == 'distributable' %} Free to use and distribute, with or without modification @@ -122,7 +129,7 @@ {% for name, info in (files or {}).items()|sort %} {{ row('fa-file-archive-o' if name.endswith('.zip') else 'fa-file-image-o', name, name, info.size|file_size_units, info.description, - info.license, info.credit) }} + info.license, info.credit, info.deprecated) }} {% endfor %} {% for extra in extras %} {{ row('fa-file-code-o', extra.name, extra.name, diff --git a/demo/_synctiles.py b/demo/_synctiles.py index 4cb5bb4..1a9a7a0 100755 --- a/demo/_synctiles.py +++ b/demo/_synctiles.py @@ -114,6 +114,7 @@ class TestDataSlide(TypedDict): """One openslide-testdata slide from index.json.""" credit: NotRequired[str] + deprecated: NotRequired[bool] description: str format: str license: str @@ -577,6 +578,11 @@ def start_retile( r = requests.get(urljoin(DOWNLOAD_BASE_URL, DOWNLOAD_INDEX)) r.raise_for_status() slides: TestDataIndex = r.json() + slides = { + slide_relpath: slide_info + for slide_relpath, slide_info in slides.items() + if not slide_info.get('deprecated', False) + } # Initialize context for the run context: Context = {