Metadata-Version: 2.5
Name: tmapslide
Version: 0.2.0
Summary: Pure Python UNIC TMAP whole-slide image reader with OpenSlide-compatible API
Project-URL: Homepage, https://github.com/yifanfeng97/tmapslide
Project-URL: Documentation, https://github.com/yifanfeng97/tmapslide#readme
Project-URL: Repository, https://github.com/yifanfeng97/tmapslide
Project-URL: Issues, https://github.com/yifanfeng97/tmapslide/issues
Author-email: Yifan Feng <evanfeng97@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: digital-pathology,openslide,pathology,tmap,tmapslide,unic,whole-slide-image,wsi
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Image Processing
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.10
Requires-Dist: pillow>=9.0.0
Provides-Extra: dev
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# TmapSlide

![tmapslide — TMAP whole-slide images in pure Python](docs/hero.jpg)

Pure Python reader for **UNIC TMAP** whole-slide images (WSI) with an
[OpenSlide](https://openslide.org/)-compatible API — the companion library to
[kfbslide](https://github.com/yifanfeng97/kfbslide) (KFB format).

```python
import tmapslide

slide = tmapslide.OpenSlide("sample.TMAP")

print(slide.dimensions)          # (71424, 72704)
print(slide.level_count)         # 10
print(slide.level_downsamples)   # (1.0, 2.0, 4.0, ...)

region = slide.read_region((512, 512), 0, (1024, 1024))  # RGBA PIL image
thumb = slide.get_thumbnail((512, 512))
macro = slide.associated_images["macro"]
```

## Features

- **Pure Python** — no vendor SDK, no native dependencies; only Pillow.
- **OpenSlide-compatible API** — drop-in for code written against
  `openslide`/`kfbslide`: `read_region`, `get_thumbnail`, `dimensions`,
  `level_count`, `level_dimensions`, `level_downsamples`, `properties`,
  `associated_images`.
- **Both known TMAP variants**: `TMAP06` (single pixel level, 612x512
  overlapping tiles) and `TMAP07` (full pyramid, up to 10 levels, 256x256
  tiles).
- **Fork-safe file handles** — safe to use from PyTorch `DataLoader` workers.
- LRU tile cache for fast repeated reads.

## Installation

```bash
pip install tmapslide
# or from source
pip install git+https://github.com/yifanfeng97/tmapslide.git
```

## Supported formats

| Format  | Extension | Vendor             | Backend     |
| ------- | --------- | ------------------ | ----------- |
| TMAP 06 | `.TMAP`   | UNIC (United Imaging) | Pure Python |
| TMAP 07 | `.TMAP`   | UNIC (United Imaging) | Pure Python |

## API

### `tmapslide.OpenSlide(filename)`

| Member                | Description                                        |
| --------------------- | -------------------------------------------------- |
| `dimensions`          | `(width, height)` at level 0                       |
| `level_count`         | number of pyramid levels                           |
| `level_dimensions`    | `(w, h)` per level                                 |
| `level_downsamples`   | downsample factor per level                        |
| `properties`          | read-only metadata mapping (`openslide.vendor=unic`, `tmap.*`) |
| `associated_images`   | lazy mapping, typically `macro` / `label`          |
| `read_region(loc, level, size)` | `PIL.Image` (RGBA) of the region         |
| `get_thumbnail(size)`  | thumbnail from the lowest resolution level        |
| `get_best_level_for_downsample(ds)` | best level for a downsample factor   |
| `close()` / context manager | release resources                            |

### `tmapslide.open_slide(filename)`

Alias of `OpenSlide(filename)`.

## Format notes (reverse-engineered)

TMAP is an undocumented proprietary format. This reader is built from
binary analysis of real scanner output, cross-validated against
[ASlide](https://github.com/MrPeterJin/ASlide). In short: both variants
store plain JPEG tiles with a small binary header and index tables; there
is no encryption.

- TMAP06 stores 3 pyramid levels (40x / 10x / 2.5x); TMAP07 stores up to
  10 levels (40x down to 0.078x, halving each level).
- TMAP06 level-2 previews come from pre-rendered `ShrinkTile` entries and
  are JPEG-compressed at that scale (slightly softer than downsampling
  level 0 yourself).
- `iter_tiles()` exposes the stored tile grid directly, useful for
  tile-based ML pipelines.

## Testing

Tests run against real TMAP samples when the `scce_external_center` data
directory (or `TAPSLIDE_TEST_DATA`) is present next to the repo, and are
skipped otherwise.

```bash
pip install -e .[dev]
pytest
```

## License

MIT — see [LICENSE](LICENSE).

## Acknowledgments

- [kfbslide](https://github.com/yifanfeng97/kfbslide) — the KFB reader this
  project is modelled after.
- [OpenSlide](https://openslide.org/) — the API this library mimics.
- [ASlide](https://github.com/MrPeterJin/ASlide) — its independent
  reverse-engineering of the TMAP06 layer/block structures (from decompiled
  vendor SDK) was used to cross-validate this implementation. tmapslide is
  an independent MIT-licensed implementation and ships no ASlide code.
