Iris-Codec


NameIris-Codec JSON
Version 2025.3.1 PyPI version JSON
download
home_pageNone
SummaryPortable and blazingly fast whole slide image compression and serialization library for the Iris File Extension
upload_time2025-08-18 19:38:41
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
license----------------------------------------------------------------------------- Iris Codec Community License ----------------------------------------------------------------------------- MIT License Copyright (c) 2025 Iris Digital Pathology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords iris pathology digital pathology whole slide image digital slide
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Iris Codec Python API
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/iris-codec.svg?style=for-the-badge&logo=anaconda)](https://anaconda.org/conda-forge/iris-codec) 
[![PyPI Version](https://img.shields.io/pypi/v/Iris-Codec?color=blue&style=for-the-badge&logo=pypi)](https://pypi.org/project/Iris-Codec/)
[![Python CI](https://img.shields.io/github/actions/workflow/status/IrisDigitalPathology/Iris-Codec/distribute-pypi.yml?style=for-the-badge&logo=python&label=Python%20CI)](https://github.com/IrisDigitalPathology/Iris-Codec/actions/workflows/python-CI.yml)

Copyright © 2025 Iris Developers; MIT Software License

The Iris Codec Community module is a part of the Iris Digital Pathology project. This module allows for:

- Reading and writing of Iris whole slide image (WSI) digital slide files (.iris)
- Decoding Iris Codec-type compressed tile image data.

This module was designed to allow for extremely fast slide access using a simple API. We want to simplify access to these files for you.

Iris Codec for Python is available via the Anaconda and PyPi package managers. We prefer the Anaconda enviornment as it includes dynamic libraries. In a true package manager sense, if you choose to develop C/C++ applications with Python bindings Anaconda will allow you to dynamically link the C++ Iris-Codec in addition to Python modules.

## Installation

### Conda-Forge (Recommended)
[![Static Badge](https://img.shields.io/badge/Feedstock-Iris_Codec-g?style=for-the-badge)](https://github.com/conda-forge/Iris-Codec-feedstock) 
[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/iris-codec.svg?style=for-the-badge)](https://anaconda.org/conda-forge/iris-codec) 
[![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/iris-codec.svg?color=blue&style=for-the-badge)](https://anaconda.org/conda-forge/iris-codec)

We prefer the Anaconda environment as it includes optimized dynamic libraries and better dependency management for scientific computing environments, particularly for OpenSlide integration on Linux and macOS.

**Quick Installation:**
```shell
conda install -c conda-forge iris-codec
```

**Or with mamba (faster):**
```shell
mamba install iris-codec
```

**Environment Setup:**
```shell
# Configure conda-forge channel permanently
conda config --add channels conda-forge
conda config --set channel_priority strict

# Then install
conda install iris-codec
```

### PyPI
[![PyPI - Status](https://img.shields.io/pypi/status/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Iris-Codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)
[![PyPI - Downloads](https://img.shields.io/pepy/dt/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)
[![Supported Platforms](https://img.shields.io/badge/platforms-Many%20Linux%20%7C%20macOS%20%7C%20Windows-blue?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)

**Basic Installation:**
```shell
pip install iris-codec
```

**With Encoder Support:**
```shell
# For slide encoding capabilities (requires OpenSlide)
pip install iris-codec openslide-bin
```

> [!NOTE]
> **Windows Limitation**: The Conda-Forge encoder does not support OpenSlide on Windows as OpenSlide lacks official Windows support in Conda-Forge. We're developing native vendor format support to eliminate this dependency.

## Key Features

- **High-Performance Slide Reading**: Optimized C++ backend with Python bindings
- **Multiple Format Support**: Read Iris files and encode from 40+ vendor formats
- **Memory Efficient**: Tiles loaded on-demand with automatic memory management
- **Research-Friendly**: NumPy array output, PIL/Pillow integration
- **Metadata Rich**: Full access to slide properties, annotations, and associated images
- **Encoding Pipeline**: Convert vendor formats (SVS, NDPI, VSI, MRXS) to optimized Iris format
- **Privacy Controls**: Metadata stripping and anonymization for research workflows 

## Quick Start

### Basic Slide Reading

```python
from Iris import Codec

# Open and validate slide
slide_path = 'path/to/slide.iris'
result = Codec.validate_slide_path(slide_path)
if not result.success():
    raise Exception(f'Validation failed: {result.message}')

slide = Codec.open_slide(slide_path)
if not slide:
    raise Exception('Failed to open slide')

# Get slide information
result, info = slide.get_info()
if not result.success():
    raise Exception(f'Failed to read slide info: {result.message}')

print(f"Slide: {info.extent.width}x{info.extent.height}px")
print(f"Layers: {len(info.extent.layers)}")
print(f"Encoding: {info.encoding}")
```

### Slide Encoding

```python
from Iris import Encoder, Codec

# Convert vendor format to Iris
result = Encoder.encode_slide_file(
    source='input.dcm',
    outdir='./output/',
    desired_encoding=Codec.Encoding.TILE_ENCODING_JPEG,
    derivation=Encoder.EncoderDerivation.layer_2x,
    concurrency=8
)

if not result.success():
    raise Exception(f'Encoding failed: {result.message}')
print('Encoding completed successfully!')
```

## API Reference

### Core Reading Functions

Import the Iris Codec module and basic validation:

```python
from Iris import Codec

# File validation (recommended before opening)
slide_path = 'path/to/slide_file.iris'
result = Codec.validate_slide_path(slide_path)
if not result.success():
    raise Exception(f'Invalid slide file: {result.message}')
print(f"Slide '{slide_path}' passed validation")
```

### Opening Slides

Deep validation performs comprehensive checks of the internal offset chain and IFE standard compliance:

```python
# Open slide file
slide = Codec.open_slide(slide_path)
if not slide: 
    raise Exception('Failed to open slide file')
```

### Slide Information and Metadata

Get comprehensive slide information including dimensions, layers, and metadata:

```python
# Get slide abstraction
result, info = slide.get_info()
if not result.success():
    raise Exception(f'Failed to read slide information: {result.message}')

# Basic slide properties
extent = info.extent
print(f"Slide: {extent.width}x{extent.height}px")
print(f"Encoding: {info.encoding}")
print(f"Format: {info.format}")

# Layer information
print(f"Layers: {len(extent.layers)}")
for i, layer in enumerate(extent.layers):
    print(f"  Layer {i}: {layer.x_tiles}x{layer.y_tiles} tiles, {layer.scale}x scale, {layer.downsample}x downsample")

# Metadata access
metadata = info.metadata
print(f"Codec Version: {metadata.codec_version.major}.{metadata.codec_version.minor}.{metadata.codec_version.build}")
print(f"Microns Per Pixel: {metadata.microns_per_pixel}")
print(f"Magnification: {metadata.magnification}")

# Slide attributes
print("Slide attributes:")
for key in metadata.attributes:
    value = metadata.attributes[key]
    print(f"  {key}: {value}")
```

### Reading Tile Data

Read individual tiles as NumPy arrays for analysis:

```python
import numpy as np
from PIL import Image

# Read a specific tile
layer_index = 0  # Lowest resolution layer
tile_index = 0   # First tile

# Get tile as NumPy array (RGBA format)
tile_array = slide.read_slide_tile(layer_index, tile_index)
print(f"Tile shape: {tile_array.shape}")  # Should be (256, 256, 4)
print(f"Tile dtype: {tile_array.dtype}")  # Should be uint8

# Convert to PIL Image for display/processing
tile_image = Image.fromarray(tile_array)
tile_image.show()

# Access raw pixel data
red_channel = tile_array[:, :, 0]
alpha_channel = tile_array[:, :, 3]
```

### Creating Composite Images

Generate overview images by stitching tiles together:

```python
from PIL import Image

def create_layer_composite(slide, layer_index=0):
    """Create a composite image from all tiles in a layer"""
    
    # Get layer information
    result, info = slide.get_info()
    if not result.success():
        raise Exception(f'Failed to read slide info: {result.message}')
    
    layer = info.extent.layers[layer_index]
    scale = int(layer.scale)
    
    # Create composite image
    composite_width = info.extent.width // scale
    composite_height = info.extent.height // scale
    composite = Image.new('RGBA', (composite_width, composite_height))
    
    # Stitch tiles together
    tile_size = 256  # Iris tiles are always 256x256
    for y in range(layer.y_tiles):
        for x in range(layer.x_tiles):
            tile_index = y * layer.x_tiles + x
            tile_array = slide.read_slide_tile(layer_index, tile_index)
            tile_image = Image.fromarray(tile_array)
            
            # Paste tile into composite
            paste_x = x * tile_size
            paste_y = y * tile_size
            composite.paste(tile_image, (paste_x, paste_y))
    
    return composite

# Create and display low-resolution overview
overview = create_layer_composite(slide, layer_index=0)
overview.show()
```

> [!CAUTION]
> **Memory Warning**: Despite Iris's fast read speeds, creating composite images of high-resolution layers requires substantial memory and processing time. PIL.Image creates full in-memory images rather than tiled representations. Limit composite creation to layer 0 or 1 for practical performance.

### Associated Images and Thumbnails

Access embedded thumbnails and associated images:

```python
from PIL import Image

# Get slide info first
result, info = slide.get_info()
if not result.success():
    raise Exception(f'Failed to read slide information: {result.message}')

# List available associated images
print("Available associated images:")
for image_name in info.metadata.associated_images:
    print(f"  - {image_name}")

# Read and display thumbnail if available
if 'thumbnail' in info.metadata.associated_images:
    thumbnail_array = slide.read_associated_image('thumbnail')
    thumbnail_image = Image.fromarray(thumbnail_array)
    thumbnail_image.show()
    print(f"Thumbnail size: {thumbnail_image.size}")

# Read other associated images
if 'label' in info.metadata.associated_images:
    label_array = slide.read_associated_image('label')
    label_image = Image.fromarray(label_array)
    label_image.show()
```

### Advanced Reading Patterns

Efficient patterns for large-scale analysis:


## Encoding API

The Python module includes comprehensive encoding capabilities for converting vendor WSI formats to optimized Iris files.

### Basic Encoding

```python
from Iris import Encoder, Codec

# Simple encoding with default settings
result = Encoder.encode_slide_file(
    source='path/to/input.dcm',  # SVS, NDPI, VSI, MRXS, DCM, etc.
    outdir='./output/'           # Output directory
)

if not result.success():
    raise Exception(f'Encoding failed: {result.message}')
print('Encoding completed successfully!')
```

### Advanced Encoding Options

```python
from Iris import Encoder, Codec, iris_core

# Comprehensive encoding configuration
result = Encoder.encode_slide_file(
    source='input.dcm',                                    # DICOM with byte-stream preservation
    outdir='./encoded/',                                   # Output directory
    desired_encoding=Codec.Encoding.TILE_ENCODING_AVIF,   # Modern AVIF compression
    desired_byte_format=iris_core.Format.FORMAT_R8G8B8,   # RGB format
    derivation=Encoder.EncoderDerivation.layer_4x,        # 4x downsampling pyramid
    strip_metadata=True,                                   # Remove patient identifiers
    anonymize=True,                                        # Additional anonymization
    concurrency=8                                          # Use 8 threads
)

if not result.success():
    raise Exception(f'Advanced encoding failed: {result.message}')
```

### Encoding Options Reference

**Compression Formats:**
- `TILE_ENCODING_JPEG` (default): High compatibility, excellent compression
- `TILE_ENCODING_AVIF`: Modern format, superior compression at higher quality

**Pyramid Derivation:**
- `layer_2x`: Generate 2x downsampled layers (recommended for most use cases)
- `layer_4x`: Generate 4x downsampled layers (good for very large slides)
- `use_source`: Use existing pyramid structure from source file

**Byte Formats:**
- `FORMAT_R8G8B8`: Standard RGB (3 bytes per pixel)
- `FORMAT_R8G8B8A8`: RGBA with alpha channel (4 bytes per pixel)
- `FORMAT_B8G8R8`: BGR format for specific applications
- `FORMAT_B8G8R8A8`: BGRA format

**Privacy Options:**
- `strip_metadata=True`: Remove patient identifiers and PHI

### Progress Monitoring

The encoder automatically displays progress during encoding operations:

```python
# The encode_slide_file function includes built-in progress display
result = Encoder.encode_slide_file(
    source='large_slide.dcm',
    outdir='./output/',
    concurrency=8
)

# Output shows real-time progress:
# [████████████████████████████████████████] 100.0% ETA: 00:00
# Iris Encoder completed successfully
# Slide written to ./output/large_slide.iris
```

## Integration Examples

### Channel-Separated Data with PyTorch

Iris provides `read_slide_tile_channels` which returns data in `[4,256,256]` format with separate channel arrays, useful for advanced image processing:

```python
import numpy as np
import torch
from Iris import Codec

def create_channel_separated_dataset(slide_path, layer_index=0):
    """Demonstrate channel-separated tile reading with PyTorch tensors"""
    
    slide = Codec.open_slide(slide_path)
    if not slide:
        raise Exception(f'Failed to open slide: {slide_path}')
    
    result, info = slide.get_info()
    if not result.success():
        raise Exception('Failed to read slide info')
    
    layer = info.extent.layers[layer_index]
    print(f"Processing layer {layer_index}: {layer.x_tiles}x{layer.y_tiles} tiles")
    
    # Read first tile using channel-separated format
    tile_channels = slide.read_slide_tile_channels(layer_index, tile_index=0)
    print(f"Channel-separated shape: {tile_channels.shape}")  # Should be [4, 256, 256]
    
    # Convert to PyTorch tensor
    tensor = torch.from_numpy(tile_channels).float()
    
    # Access individual channels
    red_channel = tensor[0]      # Red channel [256, 256]
    green_channel = tensor[1]    # Green channel [256, 256] 
    blue_channel = tensor[2]     # Blue channel [256, 256]
    alpha_channel = tensor[3]    # Alpha channel [256, 256]
    
    print(f"Red channel shape: {red_channel.shape}")
    print(f"Alpha channel mean: {alpha_channel.mean():.2f}")
    
    # Example: Create a custom RGB combination
    # Emphasize red channel, reduce blue
    enhanced_rgb = torch.stack([
        red_channel * 1.2,      # Enhance red
        green_channel,          # Keep green
        blue_channel * 0.8      # Reduce blue
    ], dim=0)
    
    return enhanced_rgb, tensor

# Usage example
enhanced_rgb, original_tensor = create_channel_separated_dataset('slide.iris', layer_index=1)
print(f"Enhanced RGB shape: {enhanced_rgb.shape}")  # [3, 256, 256]
print(f"Original RGBA shape: {original_tensor.shape}")  # [4, 256, 256]
```

This channel-separated format is particularly useful for:
- **Custom color space transformations**
- **Advanced image augmentations** 
- **Channel-specific analysis** (e.g., studying alpha transparency patterns)
- **Memory-efficient processing** when you only need specific channels

For additional support and examples, visit the [Iris-Codec GitHub repository](https://github.com/IrisDigitalPathology/Iris-Codec).
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "Iris-Codec",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Ryan Landvater <ryanlandvater@gmail.com>",
    "keywords": "Iris, pathology, digital pathology, whole slide image, digital slide",
    "author": null,
    "author_email": "Ryan Landvater <ryanlandvater@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/01/a8/687e10f4ae3c5d609b5f07baaa44f4a4e393165557d10b1bf9e514311bb7/iris_codec-2025.3.1.tar.gz",
    "platform": null,
    "description": "# Iris Codec Python API\n[![Conda Version](https://img.shields.io/conda/vn/conda-forge/iris-codec.svg?style=for-the-badge&logo=anaconda)](https://anaconda.org/conda-forge/iris-codec) \n[![PyPI Version](https://img.shields.io/pypi/v/Iris-Codec?color=blue&style=for-the-badge&logo=pypi)](https://pypi.org/project/Iris-Codec/)\n[![Python CI](https://img.shields.io/github/actions/workflow/status/IrisDigitalPathology/Iris-Codec/distribute-pypi.yml?style=for-the-badge&logo=python&label=Python%20CI)](https://github.com/IrisDigitalPathology/Iris-Codec/actions/workflows/python-CI.yml)\n\nCopyright &copy; 2025 Iris Developers; MIT Software License\n\nThe Iris Codec Community module is a part of the Iris Digital Pathology project. This module allows for:\n\n- Reading and writing of Iris whole slide image (WSI) digital slide files (.iris)\n- Decoding Iris Codec-type compressed tile image data.\n\nThis module was designed to allow for extremely fast slide access using a simple API. We want to simplify access to these files for you.\n\nIris Codec for Python is available via the Anaconda and PyPi package managers. We prefer the Anaconda enviornment as it includes dynamic libraries. In a true package manager sense, if you choose to develop C/C++ applications with Python bindings Anaconda will allow you to dynamically link the C++ Iris-Codec in addition to Python modules.\n\n## Installation\n\n### Conda-Forge (Recommended)\n[![Static Badge](https://img.shields.io/badge/Feedstock-Iris_Codec-g?style=for-the-badge)](https://github.com/conda-forge/Iris-Codec-feedstock) \n[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/iris-codec.svg?style=for-the-badge)](https://anaconda.org/conda-forge/iris-codec) \n[![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/iris-codec.svg?color=blue&style=for-the-badge)](https://anaconda.org/conda-forge/iris-codec)\n\nWe prefer the Anaconda environment as it includes optimized dynamic libraries and better dependency management for scientific computing environments, particularly for OpenSlide integration on Linux and macOS.\n\n**Quick Installation:**\n```shell\nconda install -c conda-forge iris-codec\n```\n\n**Or with mamba (faster):**\n```shell\nmamba install iris-codec\n```\n\n**Environment Setup:**\n```shell\n# Configure conda-forge channel permanently\nconda config --add channels conda-forge\nconda config --set channel_priority strict\n\n# Then install\nconda install iris-codec\n```\n\n### PyPI\n[![PyPI - Status](https://img.shields.io/pypi/status/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Iris-Codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)\n[![PyPI - Wheel](https://img.shields.io/pypi/wheel/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)\n[![PyPI - Downloads](https://img.shields.io/pepy/dt/iris-codec?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)\n[![Supported Platforms](https://img.shields.io/badge/platforms-Many%20Linux%20%7C%20macOS%20%7C%20Windows-blue?style=for-the-badge)](https://pypi.org/project/Iris-Codec/)\n\n**Basic Installation:**\n```shell\npip install iris-codec\n```\n\n**With Encoder Support:**\n```shell\n# For slide encoding capabilities (requires OpenSlide)\npip install iris-codec openslide-bin\n```\n\n> [!NOTE]\n> **Windows Limitation**: The Conda-Forge encoder does not support OpenSlide on Windows as OpenSlide lacks official Windows support in Conda-Forge. We're developing native vendor format support to eliminate this dependency.\n\n## Key Features\n\n- **High-Performance Slide Reading**: Optimized C++ backend with Python bindings\n- **Multiple Format Support**: Read Iris files and encode from 40+ vendor formats\n- **Memory Efficient**: Tiles loaded on-demand with automatic memory management\n- **Research-Friendly**: NumPy array output, PIL/Pillow integration\n- **Metadata Rich**: Full access to slide properties, annotations, and associated images\n- **Encoding Pipeline**: Convert vendor formats (SVS, NDPI, VSI, MRXS) to optimized Iris format\n- **Privacy Controls**: Metadata stripping and anonymization for research workflows \n\n## Quick Start\n\n### Basic Slide Reading\n\n```python\nfrom Iris import Codec\n\n# Open and validate slide\nslide_path = 'path/to/slide.iris'\nresult = Codec.validate_slide_path(slide_path)\nif not result.success():\n    raise Exception(f'Validation failed: {result.message}')\n\nslide = Codec.open_slide(slide_path)\nif not slide:\n    raise Exception('Failed to open slide')\n\n# Get slide information\nresult, info = slide.get_info()\nif not result.success():\n    raise Exception(f'Failed to read slide info: {result.message}')\n\nprint(f\"Slide: {info.extent.width}x{info.extent.height}px\")\nprint(f\"Layers: {len(info.extent.layers)}\")\nprint(f\"Encoding: {info.encoding}\")\n```\n\n### Slide Encoding\n\n```python\nfrom Iris import Encoder, Codec\n\n# Convert vendor format to Iris\nresult = Encoder.encode_slide_file(\n    source='input.dcm',\n    outdir='./output/',\n    desired_encoding=Codec.Encoding.TILE_ENCODING_JPEG,\n    derivation=Encoder.EncoderDerivation.layer_2x,\n    concurrency=8\n)\n\nif not result.success():\n    raise Exception(f'Encoding failed: {result.message}')\nprint('Encoding completed successfully!')\n```\n\n## API Reference\n\n### Core Reading Functions\n\nImport the Iris Codec module and basic validation:\n\n```python\nfrom Iris import Codec\n\n# File validation (recommended before opening)\nslide_path = 'path/to/slide_file.iris'\nresult = Codec.validate_slide_path(slide_path)\nif not result.success():\n    raise Exception(f'Invalid slide file: {result.message}')\nprint(f\"Slide '{slide_path}' passed validation\")\n```\n\n### Opening Slides\n\nDeep validation performs comprehensive checks of the internal offset chain and IFE standard compliance:\n\n```python\n# Open slide file\nslide = Codec.open_slide(slide_path)\nif not slide: \n    raise Exception('Failed to open slide file')\n```\n\n### Slide Information and Metadata\n\nGet comprehensive slide information including dimensions, layers, and metadata:\n\n```python\n# Get slide abstraction\nresult, info = slide.get_info()\nif not result.success():\n    raise Exception(f'Failed to read slide information: {result.message}')\n\n# Basic slide properties\nextent = info.extent\nprint(f\"Slide: {extent.width}x{extent.height}px\")\nprint(f\"Encoding: {info.encoding}\")\nprint(f\"Format: {info.format}\")\n\n# Layer information\nprint(f\"Layers: {len(extent.layers)}\")\nfor i, layer in enumerate(extent.layers):\n    print(f\"  Layer {i}: {layer.x_tiles}x{layer.y_tiles} tiles, {layer.scale}x scale, {layer.downsample}x downsample\")\n\n# Metadata access\nmetadata = info.metadata\nprint(f\"Codec Version: {metadata.codec_version.major}.{metadata.codec_version.minor}.{metadata.codec_version.build}\")\nprint(f\"Microns Per Pixel: {metadata.microns_per_pixel}\")\nprint(f\"Magnification: {metadata.magnification}\")\n\n# Slide attributes\nprint(\"Slide attributes:\")\nfor key in metadata.attributes:\n    value = metadata.attributes[key]\n    print(f\"  {key}: {value}\")\n```\n\n### Reading Tile Data\n\nRead individual tiles as NumPy arrays for analysis:\n\n```python\nimport numpy as np\nfrom PIL import Image\n\n# Read a specific tile\nlayer_index = 0  # Lowest resolution layer\ntile_index = 0   # First tile\n\n# Get tile as NumPy array (RGBA format)\ntile_array = slide.read_slide_tile(layer_index, tile_index)\nprint(f\"Tile shape: {tile_array.shape}\")  # Should be (256, 256, 4)\nprint(f\"Tile dtype: {tile_array.dtype}\")  # Should be uint8\n\n# Convert to PIL Image for display/processing\ntile_image = Image.fromarray(tile_array)\ntile_image.show()\n\n# Access raw pixel data\nred_channel = tile_array[:, :, 0]\nalpha_channel = tile_array[:, :, 3]\n```\n\n### Creating Composite Images\n\nGenerate overview images by stitching tiles together:\n\n```python\nfrom PIL import Image\n\ndef create_layer_composite(slide, layer_index=0):\n    \"\"\"Create a composite image from all tiles in a layer\"\"\"\n    \n    # Get layer information\n    result, info = slide.get_info()\n    if not result.success():\n        raise Exception(f'Failed to read slide info: {result.message}')\n    \n    layer = info.extent.layers[layer_index]\n    scale = int(layer.scale)\n    \n    # Create composite image\n    composite_width = info.extent.width // scale\n    composite_height = info.extent.height // scale\n    composite = Image.new('RGBA', (composite_width, composite_height))\n    \n    # Stitch tiles together\n    tile_size = 256  # Iris tiles are always 256x256\n    for y in range(layer.y_tiles):\n        for x in range(layer.x_tiles):\n            tile_index = y * layer.x_tiles + x\n            tile_array = slide.read_slide_tile(layer_index, tile_index)\n            tile_image = Image.fromarray(tile_array)\n            \n            # Paste tile into composite\n            paste_x = x * tile_size\n            paste_y = y * tile_size\n            composite.paste(tile_image, (paste_x, paste_y))\n    \n    return composite\n\n# Create and display low-resolution overview\noverview = create_layer_composite(slide, layer_index=0)\noverview.show()\n```\n\n> [!CAUTION]\n> **Memory Warning**: Despite Iris's fast read speeds, creating composite images of high-resolution layers requires substantial memory and processing time. PIL.Image creates full in-memory images rather than tiled representations. Limit composite creation to layer 0 or 1 for practical performance.\n\n### Associated Images and Thumbnails\n\nAccess embedded thumbnails and associated images:\n\n```python\nfrom PIL import Image\n\n# Get slide info first\nresult, info = slide.get_info()\nif not result.success():\n    raise Exception(f'Failed to read slide information: {result.message}')\n\n# List available associated images\nprint(\"Available associated images:\")\nfor image_name in info.metadata.associated_images:\n    print(f\"  - {image_name}\")\n\n# Read and display thumbnail if available\nif 'thumbnail' in info.metadata.associated_images:\n    thumbnail_array = slide.read_associated_image('thumbnail')\n    thumbnail_image = Image.fromarray(thumbnail_array)\n    thumbnail_image.show()\n    print(f\"Thumbnail size: {thumbnail_image.size}\")\n\n# Read other associated images\nif 'label' in info.metadata.associated_images:\n    label_array = slide.read_associated_image('label')\n    label_image = Image.fromarray(label_array)\n    label_image.show()\n```\n\n### Advanced Reading Patterns\n\nEfficient patterns for large-scale analysis:\n\n\n## Encoding API\n\nThe Python module includes comprehensive encoding capabilities for converting vendor WSI formats to optimized Iris files.\n\n### Basic Encoding\n\n```python\nfrom Iris import Encoder, Codec\n\n# Simple encoding with default settings\nresult = Encoder.encode_slide_file(\n    source='path/to/input.dcm',  # SVS, NDPI, VSI, MRXS, DCM, etc.\n    outdir='./output/'           # Output directory\n)\n\nif not result.success():\n    raise Exception(f'Encoding failed: {result.message}')\nprint('Encoding completed successfully!')\n```\n\n### Advanced Encoding Options\n\n```python\nfrom Iris import Encoder, Codec, iris_core\n\n# Comprehensive encoding configuration\nresult = Encoder.encode_slide_file(\n    source='input.dcm',                                    # DICOM with byte-stream preservation\n    outdir='./encoded/',                                   # Output directory\n    desired_encoding=Codec.Encoding.TILE_ENCODING_AVIF,   # Modern AVIF compression\n    desired_byte_format=iris_core.Format.FORMAT_R8G8B8,   # RGB format\n    derivation=Encoder.EncoderDerivation.layer_4x,        # 4x downsampling pyramid\n    strip_metadata=True,                                   # Remove patient identifiers\n    anonymize=True,                                        # Additional anonymization\n    concurrency=8                                          # Use 8 threads\n)\n\nif not result.success():\n    raise Exception(f'Advanced encoding failed: {result.message}')\n```\n\n### Encoding Options Reference\n\n**Compression Formats:**\n- `TILE_ENCODING_JPEG` (default): High compatibility, excellent compression\n- `TILE_ENCODING_AVIF`: Modern format, superior compression at higher quality\n\n**Pyramid Derivation:**\n- `layer_2x`: Generate 2x downsampled layers (recommended for most use cases)\n- `layer_4x`: Generate 4x downsampled layers (good for very large slides)\n- `use_source`: Use existing pyramid structure from source file\n\n**Byte Formats:**\n- `FORMAT_R8G8B8`: Standard RGB (3 bytes per pixel)\n- `FORMAT_R8G8B8A8`: RGBA with alpha channel (4 bytes per pixel)\n- `FORMAT_B8G8R8`: BGR format for specific applications\n- `FORMAT_B8G8R8A8`: BGRA format\n\n**Privacy Options:**\n- `strip_metadata=True`: Remove patient identifiers and PHI\n\n### Progress Monitoring\n\nThe encoder automatically displays progress during encoding operations:\n\n```python\n# The encode_slide_file function includes built-in progress display\nresult = Encoder.encode_slide_file(\n    source='large_slide.dcm',\n    outdir='./output/',\n    concurrency=8\n)\n\n# Output shows real-time progress:\n# [\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588] 100.0% ETA: 00:00\n# Iris Encoder completed successfully\n# Slide written to ./output/large_slide.iris\n```\n\n## Integration Examples\n\n### Channel-Separated Data with PyTorch\n\nIris provides `read_slide_tile_channels` which returns data in `[4,256,256]` format with separate channel arrays, useful for advanced image processing:\n\n```python\nimport numpy as np\nimport torch\nfrom Iris import Codec\n\ndef create_channel_separated_dataset(slide_path, layer_index=0):\n    \"\"\"Demonstrate channel-separated tile reading with PyTorch tensors\"\"\"\n    \n    slide = Codec.open_slide(slide_path)\n    if not slide:\n        raise Exception(f'Failed to open slide: {slide_path}')\n    \n    result, info = slide.get_info()\n    if not result.success():\n        raise Exception('Failed to read slide info')\n    \n    layer = info.extent.layers[layer_index]\n    print(f\"Processing layer {layer_index}: {layer.x_tiles}x{layer.y_tiles} tiles\")\n    \n    # Read first tile using channel-separated format\n    tile_channels = slide.read_slide_tile_channels(layer_index, tile_index=0)\n    print(f\"Channel-separated shape: {tile_channels.shape}\")  # Should be [4, 256, 256]\n    \n    # Convert to PyTorch tensor\n    tensor = torch.from_numpy(tile_channels).float()\n    \n    # Access individual channels\n    red_channel = tensor[0]      # Red channel [256, 256]\n    green_channel = tensor[1]    # Green channel [256, 256] \n    blue_channel = tensor[2]     # Blue channel [256, 256]\n    alpha_channel = tensor[3]    # Alpha channel [256, 256]\n    \n    print(f\"Red channel shape: {red_channel.shape}\")\n    print(f\"Alpha channel mean: {alpha_channel.mean():.2f}\")\n    \n    # Example: Create a custom RGB combination\n    # Emphasize red channel, reduce blue\n    enhanced_rgb = torch.stack([\n        red_channel * 1.2,      # Enhance red\n        green_channel,          # Keep green\n        blue_channel * 0.8      # Reduce blue\n    ], dim=0)\n    \n    return enhanced_rgb, tensor\n\n# Usage example\nenhanced_rgb, original_tensor = create_channel_separated_dataset('slide.iris', layer_index=1)\nprint(f\"Enhanced RGB shape: {enhanced_rgb.shape}\")  # [3, 256, 256]\nprint(f\"Original RGBA shape: {original_tensor.shape}\")  # [4, 256, 256]\n```\n\nThis channel-separated format is particularly useful for:\n- **Custom color space transformations**\n- **Advanced image augmentations** \n- **Channel-specific analysis** (e.g., studying alpha transparency patterns)\n- **Memory-efficient processing** when you only need specific channels\n\nFor additional support and examples, visit the [Iris-Codec GitHub repository](https://github.com/IrisDigitalPathology/Iris-Codec).",
    "bugtrack_url": null,
    "license": "-----------------------------------------------------------------------------\n         Iris Codec Community License\n         -----------------------------------------------------------------------------\n         \n         MIT License\n         \n         Copyright (c) 2025 Iris Digital Pathology\n         \n         Permission is hereby granted, free of charge, to any person obtaining a copy\n         of this software and associated documentation files (the \"Software\"), to deal\n         in the Software without restriction, including without limitation the rights\n         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n         copies of the Software, and to permit persons to whom the Software is\n         furnished to do so, subject to the following conditions:\n         \n         The above copyright notice and this permission notice shall be included in all\n         copies or substantial portions of the Software.\n         \n         THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n         SOFTWARE.",
    "summary": "Portable and blazingly fast whole slide image compression and serialization library for the Iris File Extension",
    "version": "2025.3.1",
    "project_urls": {
        "Bug Reports": "https://github.com/IrisDigitalPathology/Iris-Codec/issues",
        "Homepage": "https://github.com/IrisDigitalPathology/Iris-Codec",
        "Source": "https://github.com/IrisDigitalPathology/Iris-Codec"
    },
    "split_keywords": [
        "iris",
        " pathology",
        " digital pathology",
        " whole slide image",
        " digital slide"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2bca3f4f8c228413ef2c2da99749906907a14f4114e46ab93df82ebe45f3cae1",
                "md5": "8720def5251c7ff963cdf0232699b91a",
                "sha256": "23613658fe6e303f8092f296282b3abf4f22219aac7433e3aa5fedc3857380e7"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "8720def5251c7ff963cdf0232699b91a",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 7953913,
            "upload_time": "2025-08-18T19:38:03",
            "upload_time_iso_8601": "2025-08-18T19:38:03.994919Z",
            "url": "https://files.pythonhosted.org/packages/2b/ca/3f4f8c228413ef2c2da99749906907a14f4114e46ab93df82ebe45f3cae1/iris_codec-2025.3.1-cp311-cp311-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d71926dcf376df80261f1d1a7a4a48cc90154d03353fa62624e7f51f458cc763",
                "md5": "f475227219ba6b669f8cea7bc298e4e7",
                "sha256": "0534f61e869715d840dbd4bf371e9410da2aae82977a38836a35cd8da194140e"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-macosx_15_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "f475227219ba6b669f8cea7bc298e4e7",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 6535749,
            "upload_time": "2025-08-18T19:38:05",
            "upload_time_iso_8601": "2025-08-18T19:38:05.938954Z",
            "url": "https://files.pythonhosted.org/packages/d7/19/26dcf376df80261f1d1a7a4a48cc90154d03353fa62624e7f51f458cc763/iris_codec-2025.3.1-cp311-cp311-macosx_15_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1ee7f30b1f10465cbeca8d003d17e867ca9d912fad200f0cf676a66f7e4f97ed",
                "md5": "539a7bbb9c533e9fc744160845286c1b",
                "sha256": "82d7c9e5ed26a4695bebf5211d4caa70bca5f414690c10130f444b92b1d6a30b"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "539a7bbb9c533e9fc744160845286c1b",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 8571106,
            "upload_time": "2025-08-18T19:38:07",
            "upload_time_iso_8601": "2025-08-18T19:38:07.925904Z",
            "url": "https://files.pythonhosted.org/packages/1e/e7/f30b1f10465cbeca8d003d17e867ca9d912fad200f0cf676a66f7e4f97ed/iris_codec-2025.3.1-cp311-cp311-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a35b7f335d84412434efe253e8dae6ff0cf774493714dbaea3a420c0f9194481",
                "md5": "288acad47a9945c1b1d237d570038e58",
                "sha256": "480989682a1564a58985cc8041e6b9ee426376dd1eb439e8b47553d94d72d729"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "288acad47a9945c1b1d237d570038e58",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 8786489,
            "upload_time": "2025-08-18T19:38:09",
            "upload_time_iso_8601": "2025-08-18T19:38:09.876680Z",
            "url": "https://files.pythonhosted.org/packages/a3/5b/7f335d84412434efe253e8dae6ff0cf774493714dbaea3a420c0f9194481/iris_codec-2025.3.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9c6adcc561fb04d300ca350c4e5ecef95e2c4b90145f0394c40f0ad570467960",
                "md5": "3e2b362dd9c8020f2342ce5e7657d4b3",
                "sha256": "bd0084e0445265055153a8df5f3ca9cc016f7ad959340b53b55e2b7265d2350a"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-musllinux_1_2_aarch64.whl",
            "has_sig": false,
            "md5_digest": "3e2b362dd9c8020f2342ce5e7657d4b3",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 9937172,
            "upload_time": "2025-08-18T19:38:12",
            "upload_time_iso_8601": "2025-08-18T19:38:12.485027Z",
            "url": "https://files.pythonhosted.org/packages/9c/6a/dcc561fb04d300ca350c4e5ecef95e2c4b90145f0394c40f0ad570467960/iris_codec-2025.3.1-cp311-cp311-musllinux_1_2_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "07d846b0da37f03ea2b076cc5ad6c9bb73296bef9e93651dd2b715fa0c60e0aa",
                "md5": "db86f344404b850a8b3be954b11e7e7a",
                "sha256": "1686484dbbc1368a19c5364bbd1789f2e24e8c261043bc60c00234165b45d59b"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "db86f344404b850a8b3be954b11e7e7a",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.11",
            "size": 10335634,
            "upload_time": "2025-08-18T19:38:14",
            "upload_time_iso_8601": "2025-08-18T19:38:14.821854Z",
            "url": "https://files.pythonhosted.org/packages/07/d8/46b0da37f03ea2b076cc5ad6c9bb73296bef9e93651dd2b715fa0c60e0aa/iris_codec-2025.3.1-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "dacffaaf5ac17c8b5f6327688b20183ade6c6086cb58befd0a19d194246573c9",
                "md5": "b53a6d5d24c46d7e0ada40b9e9d4bfb1",
                "sha256": "4722b5fcdedef458cd9162787583f34fe526cf874b7c1ed2e93c2d8e07450234"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "b53a6d5d24c46d7e0ada40b9e9d4bfb1",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 7955479,
            "upload_time": "2025-08-18T19:38:16",
            "upload_time_iso_8601": "2025-08-18T19:38:16.881595Z",
            "url": "https://files.pythonhosted.org/packages/da/cf/faaf5ac17c8b5f6327688b20183ade6c6086cb58befd0a19d194246573c9/iris_codec-2025.3.1-cp312-cp312-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3e1652af3e8d44309b40dda043ea8afb1747f3333407a34a0c713d4d166faaa0",
                "md5": "91d0419bd525d6a022f4a5d3b2f46084",
                "sha256": "0c719592ec595f386f772d555790c3f7532fa308a0ade8934843d27d0d10b84a"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-macosx_15_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "91d0419bd525d6a022f4a5d3b2f46084",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 6536359,
            "upload_time": "2025-08-18T19:38:18",
            "upload_time_iso_8601": "2025-08-18T19:38:18.842907Z",
            "url": "https://files.pythonhosted.org/packages/3e/16/52af3e8d44309b40dda043ea8afb1747f3333407a34a0c713d4d166faaa0/iris_codec-2025.3.1-cp312-cp312-macosx_15_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "35ad8dec205667a18b2fab18453feeb019d6826fc4ce9fdcf44869449e3d49df",
                "md5": "d8c9e80cc0af4b49c1b7179190677bd3",
                "sha256": "53e83108d165c09673ccf9de24151dc0292698c05809b7dd393db4110178bbf7"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "d8c9e80cc0af4b49c1b7179190677bd3",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 8571350,
            "upload_time": "2025-08-18T19:38:20",
            "upload_time_iso_8601": "2025-08-18T19:38:20.945490Z",
            "url": "https://files.pythonhosted.org/packages/35/ad/8dec205667a18b2fab18453feeb019d6826fc4ce9fdcf44869449e3d49df/iris_codec-2025.3.1-cp312-cp312-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3c83d4af4fb1545de55883caa77467ca4bc43f18eb1dfdc628f87d1e75d74a8e",
                "md5": "69e2609a40aea270ea305a95cd880d6f",
                "sha256": "8af8ba9eb4c8676831ac7675dd60a570e67b60af771a8d11b686ade72663a325"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "69e2609a40aea270ea305a95cd880d6f",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 8789211,
            "upload_time": "2025-08-18T19:38:23",
            "upload_time_iso_8601": "2025-08-18T19:38:23.351272Z",
            "url": "https://files.pythonhosted.org/packages/3c/83/d4af4fb1545de55883caa77467ca4bc43f18eb1dfdc628f87d1e75d74a8e/iris_codec-2025.3.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "216c3b34f479e90508a8791badd270c7629ef7237cf752f84a11c801a2a881fc",
                "md5": "08d8dd040440d146f494a18c1dabe8c3",
                "sha256": "7a8378dcec4d076bba18dd032859e986194a85f69b70e507f0683d92ec345bdd"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-musllinux_1_2_aarch64.whl",
            "has_sig": false,
            "md5_digest": "08d8dd040440d146f494a18c1dabe8c3",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 9937145,
            "upload_time": "2025-08-18T19:38:25",
            "upload_time_iso_8601": "2025-08-18T19:38:25.261956Z",
            "url": "https://files.pythonhosted.org/packages/21/6c/3b34f479e90508a8791badd270c7629ef7237cf752f84a11c801a2a881fc/iris_codec-2025.3.1-cp312-cp312-musllinux_1_2_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6fdec482109d3894400ce7061e078c36f42f96413389d62d9197c777533e755f",
                "md5": "8638b823fcdebad584bab819df8e2cbb",
                "sha256": "4f890c3fe872354241721cd39b21cbfb7eec60a96081ed122ce8c2412b4ff4f3"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8638b823fcdebad584bab819df8e2cbb",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.11",
            "size": 10339159,
            "upload_time": "2025-08-18T19:38:27",
            "upload_time_iso_8601": "2025-08-18T19:38:27.582727Z",
            "url": "https://files.pythonhosted.org/packages/6f/de/c482109d3894400ce7061e078c36f42f96413389d62d9197c777533e755f/iris_codec-2025.3.1-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "96d34d5c8d97c32adca513d0cf549cee98e60b1d484ab06fe787f7b0597a86c9",
                "md5": "7093274bf63fed8d3bdecdc5314eff2c",
                "sha256": "42202fc68c9ce86ead7bce6857efadc902286a6e97e946a4d4e72001cd98f8ee"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7093274bf63fed8d3bdecdc5314eff2c",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 7955462,
            "upload_time": "2025-08-18T19:38:30",
            "upload_time_iso_8601": "2025-08-18T19:38:30.016425Z",
            "url": "https://files.pythonhosted.org/packages/96/d3/4d5c8d97c32adca513d0cf549cee98e60b1d484ab06fe787f7b0597a86c9/iris_codec-2025.3.1-cp313-cp313-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9bfa8373746a97dbaa973aed103f7283d2d136a6f93b70e1214020e6c29bbca3",
                "md5": "565c45ee5299b4b84ca9b5c8d68064e8",
                "sha256": "f7ee21d277682df79ff70cfd75b3bcecd860f2e7e27f9ac74e00885704d1859d"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-macosx_15_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "565c45ee5299b4b84ca9b5c8d68064e8",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 6536565,
            "upload_time": "2025-08-18T19:38:31",
            "upload_time_iso_8601": "2025-08-18T19:38:31.574538Z",
            "url": "https://files.pythonhosted.org/packages/9b/fa/8373746a97dbaa973aed103f7283d2d136a6f93b70e1214020e6c29bbca3/iris_codec-2025.3.1-cp313-cp313-macosx_15_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "111a6e524f95d51e42cdb94e1b89f26b2369ca5f3e6e7d110a8f3f9d7015fe90",
                "md5": "5ff8623eb63e63f6385219af9ac66ec2",
                "sha256": "7c665a0be201487b091a139f426e63ba0adcdc14e5c3888821bb16c91c25dae6"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "5ff8623eb63e63f6385219af9ac66ec2",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 8571254,
            "upload_time": "2025-08-18T19:38:33",
            "upload_time_iso_8601": "2025-08-18T19:38:33.085110Z",
            "url": "https://files.pythonhosted.org/packages/11/1a/6e524f95d51e42cdb94e1b89f26b2369ca5f3e6e7d110a8f3f9d7015fe90/iris_codec-2025.3.1-cp313-cp313-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a35cecec98d12f82a7b87b26b98f755f8afeaf43a517613a0539fbef47388dd5",
                "md5": "580daffa42db1e00f962c7174e8536d1",
                "sha256": "451d0982f9fb4f8a8e56577621761a18f200d467944e37a8a812f80e933b599e"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "580daffa42db1e00f962c7174e8536d1",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 8789389,
            "upload_time": "2025-08-18T19:38:35",
            "upload_time_iso_8601": "2025-08-18T19:38:35.345804Z",
            "url": "https://files.pythonhosted.org/packages/a3/5c/ecec98d12f82a7b87b26b98f755f8afeaf43a517613a0539fbef47388dd5/iris_codec-2025.3.1-cp313-cp313-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f0b76fa96949b052a7dba450f9df859727ec0f995576999b2b3a6e15ccd52162",
                "md5": "7ed9e73d3c84ed744a557d211fcf4fe0",
                "sha256": "104de251c4b6d45796444eb641022d29b3d5b9bf84bee1d412c8d3162f356739"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-musllinux_1_2_aarch64.whl",
            "has_sig": false,
            "md5_digest": "7ed9e73d3c84ed744a557d211fcf4fe0",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 9938021,
            "upload_time": "2025-08-18T19:38:37",
            "upload_time_iso_8601": "2025-08-18T19:38:37.387272Z",
            "url": "https://files.pythonhosted.org/packages/f0/b7/6fa96949b052a7dba450f9df859727ec0f995576999b2b3a6e15ccd52162/iris_codec-2025.3.1-cp313-cp313-musllinux_1_2_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4ddb3ca30982f1fd062e578b40067f9e32a548d413e4ce9bea662d6184fd4f19",
                "md5": "7dd2b5a57ac04354acdf3daeb2f0ca30",
                "sha256": "87a44acdeb965d9ad5f1431911265ffc70307650502f9afe6d4a8c0b848d8834"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1-cp313-cp313-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7dd2b5a57ac04354acdf3daeb2f0ca30",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.11",
            "size": 10339089,
            "upload_time": "2025-08-18T19:38:39",
            "upload_time_iso_8601": "2025-08-18T19:38:39.316747Z",
            "url": "https://files.pythonhosted.org/packages/4d/db/3ca30982f1fd062e578b40067f9e32a548d413e4ce9bea662d6184fd4f19/iris_codec-2025.3.1-cp313-cp313-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "01a8687e10f4ae3c5d609b5f07baaa44f4a4e393165557d10b1bf9e514311bb7",
                "md5": "244db4dd46a06e7c9956fe8edcae398c",
                "sha256": "222f470fbd5202835c70cf34655cead7f424eadd554cf0bf062f4f0db5454fae"
            },
            "downloads": -1,
            "filename": "iris_codec-2025.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "244db4dd46a06e7c9956fe8edcae398c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 104695,
            "upload_time": "2025-08-18T19:38:41",
            "upload_time_iso_8601": "2025-08-18T19:38:41.375547Z",
            "url": "https://files.pythonhosted.org/packages/01/a8/687e10f4ae3c5d609b5f07baaa44f4a4e393165557d10b1bf9e514311bb7/iris_codec-2025.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-18 19:38:41",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "IrisDigitalPathology",
    "github_project": "Iris-Codec",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "iris-codec"
}
        
Elapsed time: 2.49477s