Skip to content

feat: add true 8-bit and 16-bit TIFF export - #1466

Open
dimafa wants to merge 3 commits into
CyberTimon:mainfrom
dimafa:codex/true-16-bit-tiff
Open

feat: add true 8-bit and 16-bit TIFF export#1466
dimafa wants to merge 3 commits into
CyberTimon:mainfrom
dimafa:codex/true-16-bit-tiff

Conversation

@dimafa

@dimafa dimafa commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Description

Add a TIFF-only 8-bit/16-bit export control and preserve high-precision renderer data through GPU readback so 16-bit TIFF exports contain high-precision RGB16 samples instead of promoted RGB8 values.

The existing TIFF encoder always requested RGB16, but the production renderer returned ImageRgba8. Converting that result to RGB16 only multiplied 8-bit samples by 257, producing a nominally 16-bit TIFF without additional image precision.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • UI/UX improvement

Changes Made

  • Added a TIFF-only bit-depth selector with localized 8-bit and 16-bit choices; 16-bit is the default.
  • Persisted TIFF depth in export presets while defaulting legacy presets and missing Rust settings to 16-bit.
  • Added --tiff-bit-depth 8|16 to headless export with strict validation and a 16-bit default.
  • Added an rgba16float tiled GPU output/readback path used only for 16-bit TIFF export.
  • Kept the existing sRGB transfer behavior in the shared shader and disabled only the RGB8 quantization dither for high-precision output.
  • Added genuine RGB8 and RGB16 TIFF encoding without an 8-bit intermediate in the 16-bit path.
  • Audited resize and watermark post-processing so 16-bit images stay high precision.
  • Added focused tests for CLI parsing, serde compatibility, TIFF encoding, resize precision, and shader behavior.

Screenshots/Videos

16-bit-tiff

Testing

  • I have tested these changes locally and confirmed that they work as expected without issues

Test Configuration:

  • OS: macOS 26.4
  • Hardware: Apple M5 Pro, 24 GB RAM

Native and headless validation:

  • Verified the TIFF-only selector, 16-bit default, 8-bit selection, size estimate, and hidden state for JPEG in the native Tauri application.
  • Exported the same 6000 × 4000 ARW as direct RGB8 and RGB16 TIFFs using the same adjustments.
  • RGB8 output: unsigned 8/8/8-bit RGB, 72,000,786 bytes.
  • RGB16 output: unsigned 16/16/16-bit RGB, 144,001,354 bytes.
  • RGB16 unique values: R 5,914; G 5,821; B 5,716.
  • RGB16 values not divisible by 257: R 98.68%; G 99.45%; B 99.13%.
  • Down-quantized RGB16 matched direct RGB8 within one 8-bit step for 100% of samples.
  • Repeated RGB8 and RGB16 renders were byte-identical; an omitted CLI depth matched explicit 16-bit output.
  • Invalid --tiff-bit-depth 12 was rejected with process exit code 2.

Checklist

  • My code follows the project's code style
  • I haven't added unnecessary AI-generated code comments

Additional Notes

  • Related to Export PNG / TIFF 16 bits #120 and FEATURE: More Export formats and color spaces #1398. PNG remains outside this PR's scope, while FEATURE: More Export formats and color spaces #1398 also requests additional formats and color spaces; both issues therefore remain only partially addressed.
  • PR feat(gpu): add bounded high-precision export rendering #1395 adds overlapping internal high-precision GPU groundwork for future JPEG XL work, but intentionally does not wire it into export. This PR is independently based on current main and implements the TIFF product path end to end.
  • Shader output at the readback boundary is already sRGB-encoded (sRGB/Rec. 709 primaries), so the high-precision path preserves those code values and does not apply a second transfer function.
  • TIFF exports remain uncompressed and do not embed an ICC profile, matching current behavior.
  • The lazy high-precision tile is about 40.5 MiB versus 20.25 MiB for the RGB8 tile. A 6000 × 4000 RGBA16 CPU readback is about 183 MiB versus 91.6 MiB for RGBA8.

AI Disclaimer:

  • This PR is AI-generated but guided by a human

@dimafa
dimafa marked this pull request as ready for review August 3, 2026 23:20
@dimafa
dimafa requested a review from CyberTimon as a code owner August 3, 2026 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant