Skip to main content

muraw logo

muraw

License

Python library for reading, writing, and rendering Adobe DNG (Digital Negative) raw image files. Provides both a comprehensive Python API and command-line tools for DNG manipulation, rendering, metadata handling, and multi-threaded batch processing. Performance-critical operations are implemented in C/C++ extensions, but this initial (May 1, 2026) release prioritizes rendering correctness over speed optimization.

Key Features

  • DNG Read/Write: Full support for reading, writing, and modifying Adobe DNG (Digital Negative) files.
  • RAW Rendering Pipeline: Complete implementation of DNG rendering pipeline (linearization, demosaicing, opcodes, color correction, tone curves). On macOS can opt between built-in renderer and Core Image renderer.
  • Multiple Demosaicing Algorithms: BILINEAR, VNG, RCD (optional), EA, EA_FAST, OPENCV_EA
  • XMP Support: Renderer supports Temperature, Tint, Exposure, Curves, and radial distortion from XMP metadata.
  • Metadata Handling: User-friendly TIFF/EXIF/XMP tag handling with automatic type conversion
  • Compression: Uncompressed, JPEG, JPEG XL support with multi-core parallel compression for tiled formats
  • CLI Tools: Comprehensive command-line interface for DNG operations.
  • Batch Processing: Multi-threaded batch conversion and video encoding.

Installation

From PyPI

The last published package name is still muimg. This tree installs as muraw. Use the GitHub or local-dev instructions until muraw is published.

pip install muraw

Or in pyproject.toml:

[project]
dependencies = [
    "muraw",
]

Optional Dependencies

Video Encoding & Google Photos: For video encoding and Google Photos integration:

pip install "muraw[all]"

Core Image (macOS): For macOS users, installing the Core Image dependency enables a second rendering engine that will be available at runtime alongside the built-in renderer:

pip install "muraw[coreimage]"

Combined: To install all optional features:

pip install "muraw[all,coreimage]"

Or in pyproject.toml:

[project]
dependencies = [
    "muraw[all,coreimage]",
]

From GitHub

To install the latest development version directly from GitHub:

[project]
dependencies = [
    "muraw @ git+https://github.com/mu-files/mu-image.git#subdirectory=muraw",
]

For Local Development

Clone the repository and install the package in editable mode:

git clone https://github.com/mu-files/mu-image.git
cd mu-image/muraw
pip install -e .

Note: muraw includes C/C++ extensions that are compiled during install. macOS and Linux have built-in C compilers and require no additional setup. Windows users installing from source need Microsoft C++ Build Tools. Pre-built Windows wheels are available when installing from PyPI.

API Overview

Core Classes

DngFile: Subclass of TiffFile for reading DNG files. Provides access to IFDs (Image File Directories), metadata, and raw image data.

DngPage: Subclass of TiffPage representing a single IFD within a DNG file. Can be a raw CFA page, LinearRaw RGB page, or preview/thumbnail. Provides methods to extract raw data at various pipeline stages and render to display-referred RGB.

MetadataTags: Container for TIFF/EXIF/DNG tags with type-safe tag handling.

Reading DNGs

Opening and navigating: DngFile(path) opens a DNG file. Use ifd0 property to access IFD0, get_main_page() to get the primary raw image, or get_flattened_pages() to access all IFDs including SubIFDs.

Extracting raw data: DngPage.get_cfa() extracts CFA (Color Filter Array) data at various pipeline stages (raw, linearized, post-opcodes). DngPage.get_linear_raw() extracts LinearRaw RGB data.

Rendering to RGB: DngPage.render() applies the full DNG rendering pipeline (demosaicing, opcodes, color correction, tone curves, etc.) to produce display-referred RGB. The scale parameter allows for fast preview renders at reduced resolution. decode_dng() is a convenience function that handles file opening and rendering in one call.

Metadata access: DngPage.get_tag(name) retrieves TIFF/DNG tags with automatic type conversion (e.g., get_tag("ColorMatrix1") returns a 3×3 NumPy array).

Writing DNGs

PageEncoding: Dataclass that groups compression type and codec-specific arguments. Used to specify how image data should be compressed when -writing DNGs from an array or -transcoding a DNG page. For JXL compression, compression_args=None defaults to lossless (distance=0.0, effort=4). Example: PageEncoding(compression=COMPRESSION.JPEGXL_DNG, compression_args={'distance': 0.5, 'effort': 7}).

write_dng(): The most general function to create a DNG file. Takes an IFD0 spec and optional list of SubIFD specs (each can be IfdPageSpec or IfdDataSpec). Each spec describes the page data and how to encode it.

write_dng_from_page(): Create a DNG from an existing DngPage or IfdPageSpec. Supports transformations (scaling, demosaicing), compression transcoding (e.g., uncompressed to JXL via transcode_encoding=PageEncoding(...)), preview/pyramid generation, and tag manipulation.

write_dng_from_array(): Create a DNG from an IfdDataSpec containing a NumPy raw pixel data array and metadata. Supports preview and pyramid generation with optional compression via encoding=PageEncoding(...).

Batch Processing

Pipeline control: ProcessingPipeline class provides fine-grained control over batch processing with customizable producer/consumer/writer stages that decouple file I/O operations from pixel processing (e.g., decouple reading DngFile from disk and rendering it).

Image sequences: ImageSequencePipeline is a ProcessingPipeline for processing sequences of image files and saving the results (.tiff/.jpg) to an output folder.

Video encoding: VideoEncodePipeline is a ProcessingPipeline for encoding image sequences to video files with configurable codecs, resolution, and frame rates, and saving the result to a video file (.mp4). Requires pip install muraw[all].

Parallelism: Control parallelism with --num-workers flag in CLI or num_workers parameter in API. Default is 4 workers. Adjust based on CPU cores and memory availability.

Metadata

Tag management: MetadataTags.add_tag() adds TIFF/EXIF tags with automatic type handling. DngPage.get_page_tags() returns a MetadataTags object with metadata for that page.

Type registry: TIFF_TAG_TYPE_REGISTRY provides metadata about all supported TIFF/DNG tags, including data types, valid IFDs, and enum mappings.

CLI Commands

The muraw command provides comprehensive DNG operations:

Image Format Conversion

# Convert any image format to another
muraw convert-image input.tif output.jpg

DNG Metadata

Display and filter DNG metadata:

# Show all metadata for all IFDs
muraw dng metadata input.dng

# Show specific IFD
muraw dng metadata input.dng --ifd 0

# Filter tags by pattern
muraw dng metadata input.dng --tag "Color.*" --tag "Exposure"

# Exclude tags
muraw dng metadata input.dng --exclude-tag "XMP"

# Summary only
muraw dng metadata input.dng --summary

DNG Raw Stage Extraction

Extract raw data at specific pipeline stages:

# Extract unprocessed raw data
muraw dng raw-stage input.dng output.tif raw

# Extract after OpcodeList2
muraw dng raw-stage input.dng output.tif linearized-plus-ops

# Extract demosaiced camera RGB
muraw dng raw-stage input.dng output.tif camera-rgb --demosaic VNG

# Extract from specific IFD
muraw dng raw-stage input.dng output.tif linearized --ifd subifd2

DNG Copy and Transform

Create a new DNG from source DNG with optional transformations:

# Create a new DNG file with the main page transcoded to JXL
muraw dng copy input.dng output.dng --jxl-distance 0.5

# Scale and demosaic
muraw dng copy input.dng output.dng --scale 0.5 --demosaic

# Generate preview (1/4 scale)
muraw dng copy input.dng output.dng --preview --preview-reduce 4

# Generate preview (1/2 scale)
muraw dng copy input.dng output.dng --preview --preview-reduce 2

# Strip tags
muraw dng copy input.dng output.dng --strip-tag OpcodeList2,OpcodeList3

# Add/override tags
muraw dng copy input.dng output.dng --tag "Artist=John Doe" --tag "Copyright=2026"

# Generate raw "preview" pyramid levels
muraw dng copy input.dng output.dng --pyramid-levels 3

DNG Rendering

Convert DNG to display image with adjustments:

# Basic conversion
muraw dng convert input.dng output.jpg

# With white balance and exposure
muraw dng convert input.dng output.tif --temperature 5500 --tint 10 --exposure 0.5

# 16-bit output
muraw dng convert input.dng output.tif --bit-depth 16

# Use Core Image on macOS
muraw dng convert input.dng output.jpg --use-coreimage

# Convert specific IFD
muraw dng convert input.dng output.jpg --ifd subifd1

Batch DNG Conversion

Process multiple DNGs in parallel:

# Convert folder of DNGs to TIFF
muraw dng batch-convert /path/to/dngs/ /path/to/output/ --format tif

# Control parallelism (set to 8 here, default is 4 workers)
muraw dng batch-convert /path/to/dngs/ /path/to/output/ --format tif --num-workers 8

# Use fixed rendering parameters for each image
muraw dng batch-convert /path/to/dngs/ /path/to/output/ \
  --format jxl --temperature 5500 --exposure 0.5

# From CSV with per-file settings
# CSV format: filename,Temperature,Tint,Exposure2012,orientation
muraw dng batch-convert settings.csv /path/to/output/ --format tif

# Scaled output (uses the efficient scaling rendering path)
muraw dng batch-convert /path/to/dngs/ /path/to/output/ --scale 0.5

Batch DNG to Video

Requires: pip install muraw[all] (for video encoding support)

Create video from DNG sequence:

# Basic video creation
muraw dng batch-to-video /path/to/dngs/ output.mp4

# With rendering and encoding options
muraw dng batch-to-video /path/to/dngs/ output.mp4 \
  --resolution 1920x1080 --codec hevc --crf 20 --bit-depth 10 \
  --temperature 5500 --exposure 0.5 --frame-rate 30

# Timelapse (1 frame every 2 seconds)
muraw dng batch-to-video /path/to/dngs/ timelapse.mp4 --frame-rate 0.5

# With filename overlay
muraw dng batch-to-video /path/to/dngs/ output.mp4 --overlay-txt

# From CSV with per-file settings
muraw dng batch-to-video settings.csv output.mp4 --resolution 1920x1080

Google Photos Integration

Requires: pip install muraw[all] (for Google Photos support)

Upload images to Google Photos:

# Authenticate
muraw google-photos auth --credentials credentials.json

# Upload image
muraw google-photos upload image.jpg --album "My Album"

# List albums
muraw google-photos list-albums

Examples

make_test_dng.py

Creates size-constrained test DNG files by iteratively scaling down the image resolution until it fits within a target size. All test files were generated using this code.

python examples/make_test_dng.py input.dng output.dng --target-size 1048576
python examples/make_test_dng.py input.dng output.dng --target-size 1048576 --generate-preview

Features:

  • Iterative scaling by powers of 2 until target size is met
  • Demosaics to LINEAR_RAW in order to scale image
  • Optional JXL compression

Tests

The test suite covers DNG reading, writing, rendering, metadata handling, and CLI operations.

Running Tests

Requires: pip install muraw[all] (pytest is included in the [all] extra)

cd /path/to/mu-image/muraw
venv/bin/pytest tests/

Run specific test file:

venv/bin/pytest tests/test_dng_render.py -v

Run with detailed logging:

venv/bin/pytest tests/test_cli.py -v -s --log-cli-level=INFO

Test Categories

Note: Many tests validate results against Adobe's dng_validate tool from the DNG SDK. To use this validation:

  1. Download DNG SDK from: https://helpx.adobe.com/camera-raw/digital-negative.html
  2. Build the dng_validate tool (see SDK documentation)
  3. Place the binary at the path specified in tests/conftest.py or update DNG_VALIDATE_PATH

Tests always use muraw's built-in validator.

Note: Test image files (~80 MB) are stored in a separate repository (mu-files/mu-image-testdata) and are automatically downloaded on the first test run.

DNG Rendering (test_dng_render.py): Tests the full rendering pipeline, including linearization, demosaicing, color correction, tone curves, and output color space conversion for a variety of real camera DNG files (scaled to download-friendly resolution) and compares results against dng_validate.

Metadata Handling (test_metadata_*.py): Tests TIFF tag reading/writing, endianness handling, XMP parsing, and Core Graphics metadata extraction on macOS.

Write Operations (test_write_dng*.py): Tests DNG creation from arrays, page copying, compression options, and tag manipulation.

Roundtrip Tests (test_*_roundtrip.py): Tests that read-modify-write operations preserve data correctly (color temperature, SubIFD structure).

CLI Commands (test_cli.py): Tests command-line interface functionality.

Preview and Pyramid (test_preview_rendering.py, test_pyramid_subifd.py): Tests thumbnail/preview generation and pyramid-level creation.

Demosaicing (test_demosaic.py): Tests various demosaicing algorithms.

Known Issues

Not Implemented

The following DNG features are not yet implemented:

  • Triple-illuminant: Support for 3 calibration illuminants (ColorMatrix3, CalibrationIlluminant3)
  • RGBTables: DNG version 1.6+ per-channel 1D LUTs
  • ReductionMatrix: Support for cameras with >3 color channels
  • SemanticMasks: DNG v1.6+ depth maps and segmentation masks
  • HDR/Overrange: ProfileDynamicRange and extended dynamic range support

See docs/dng_render_pipeline.md for detailed implementation status of each pipeline stage.

Performance Notes

Demosaicing Algorithms: muraw includes several demosaicing algorithms with different quality/speed tradeoffs:

  • BILINEAR: Good quality, fast (default for most operations)
  • VNG: High quality, slower
  • EA: Hamilton–Adams (default for convert / camera RGB)
  • EA_FAST: Single-pass axis-pick green + bilinear chroma; faster, lower quality
  • OPENCV_EA: OpenCV edge-aware demosaic (comparison / visualization only)
  • RCD (optional, GPL-licensed): High quality, slower

The RCD (Ratio Corrected Demosaicing) algorithm is disabled by default because it's licensed under GPL v3, which is separate from muraw's BSD-3-Clause license. To enable RCD:

  1. Rename c-src/demosaic/rcd.txt to c-src/demosaic/rcd.c
  2. Rebuild: pip install -e .

By enabling RCD, you accept the GPL v3 license terms for that component. The RCD source is based on Luis Sanz Rodríguez's implementation.

Core Image Rendering: On macOS, Core Image provides native DNG rendering. Use --use-coreimage flag in CLI or use_coreimage_if_available=True in API.

Technical Documentation

For detailed technical documentation on the DNG rendering pipeline, including tag reference, pipeline stages, and implementation status, see:

docs/dng_render_pipeline.md

This document provides:

  • Complete pipeline flowchart from raw sensor data to display RGB
  • Tag reference organized by pipeline stage
  • Implementation status for each stage
  • Detailed explanations of color matrix calculations, tone curves, and opcode processing

License

This software is released under the BSD 3-Clause License. See LICENSE for full terms.

Third-Party Components

  • Adobe DNG SDK: Adobe DNG SDK License (permissive, royalty-free)
  • VNG Demosaicing: LGPL v2.1 / CDDL v1.0
  • RCD Demosaicing (optional): GPL v3

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

muraw-0.1.20260905.1732.tar.gz (2.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

muraw-0.1.20260905.1732-cp313-cp313-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.13Windows x86-64

muraw-0.1.20260905.1732-cp312-cp312-win_amd64.whl (2.1 MB view details)

Uploaded CPython 3.12Windows x86-64

File details

Details for the file muraw-0.1.20260905.1732.tar.gz.

File metadata

  • Download URL: muraw-0.1.20260905.1732.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for muraw-0.1.20260905.1732.tar.gz
Algorithm Hash digest
SHA256 ad4c6146a39b2c4f93b3a332ac8a1f61101a670132d366c494cc06c22ba8cdc5
MD5 9c54771562b24ae8a55102616ac5eacc
BLAKE2b-256 9b93f36d76b38ffa09d067538652e9b005bc96436e970bd72ae94eeacac57565

See more details on using hashes here.

Provenance

The following attestation bundles were made for muraw-0.1.20260905.1732.tar.gz:

Publisher: publish.yml on mu-files/mu-image

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file muraw-0.1.20260905.1732-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for muraw-0.1.20260905.1732-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 102398020a9895879a71ac77ff0684019fb6890f25fb3a0be9c991129f7235af
MD5 a41c37d95781e1ffaf33ece86e1f0637
BLAKE2b-256 233d159faf42128ded8e149f06bb266719f311fef64ea3ef66987aed2be1bcc1

See more details on using hashes here.

Provenance

The following attestation bundles were made for muraw-0.1.20260905.1732-cp313-cp313-win_amd64.whl:

Publisher: publish.yml on mu-files/mu-image

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file muraw-0.1.20260905.1732-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for muraw-0.1.20260905.1732-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8f2df271038c8a0fc7ff965f7a0c411910bfa3cceace923ac129472d84c0ceb6
MD5 44c0c44c7415df85a91d6a37691f6b85
BLAKE2b-256 2e14e3921c966daa7ca61bc1f4f17cb6a666270ea56f2a39eb629f4c0a7c471b

See more details on using hashes here.

Provenance

The following attestation bundles were made for muraw-0.1.20260905.1732-cp312-cp312-win_amd64.whl:

Publisher: publish.yml on mu-files/mu-image

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.20260905.1732 This release

3 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page