Skip to content
 
 

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flexcolor — the Hasselblad Flextight negative pipeline, unpacked

A parser + light processing library for the Hasselblad/Imacon FlexColor film-scanning software (the driver behind the Flextight X1/X5, the 343/848/949 sensors and the iXpress backs). The scanner code ships the per-film recipes as plain plist XML, and the per-sensor calibration as plist color profiles — this repo parses both, recovers their structure, and can apply a film profile's tone curves to a linear scan.

python -m flexcolor profiles path/to/FlexColor/curves
python -m flexcolor profile  Kodak_Portra_160_NC.xml
python -m flexcolor lut      LUTTable39MPC.xml
python -m flexcolor apply    Kodak_Portra_160_NC.xml in.tif -o out.tif

Why this is interesting

The Flextight scanners have a beloved, distinctive "Flextight look" people reproduce with Lightroom presets. Those presets guess. The software itself ships the real thing:

  • Per-film image-setting plists — one per film stock (Kodak Portra 160 NC/VC, Gold, Ektachrome-profiled, Fuji Superia/NPS/NPH, Ilford, Konica, Agfa, Mitsubishi, Polaroid, …). Each carries FilmType (1 = color, 2 = B&W), Mode, and 7 Gradations tone curves (piecewise points that encode the film's character), plus endpoints, color matrix, ICC profile refs.
  • Per-sensor LUTTable*.xml color profiles — 3×3 color matrices (mf/mfd/mt flash/TS variants), white points, clip points, and four 18,690-float LUT tables (the sensor calibration response).
  • The engineFlexColor.dll (10.5 MB, CxImage-based OLE server) that consumes these, with the .3fr raw format (SGILog/LogLuv compressed TIFF).

This is the same playbook as the sibling project noritsu-tool: recover the format and the math from the shipped binaries rather than approximate it from a preset.

Install

pip install numpy pillow

The recovered format (see docs/FLEXCOLOR_FORMAT.md for the full spec)

Per-film profile (Apple plist XML, ImageSetting → ImageCorrection):

key meaning
FilmType 1 = color negative, 2 = B&W
Mode 0/2 presets
Gradations 7 tone curves; each Points list of (X, Y, DY)
EndPoints black/white clip (list of 2)
ColorCorr 36-value color correction
Gamma, Contrast, Saturation, Brightness global sliders
ApplyCC/Curves/Histogram stage toggles
InputProfile/RGBProfile/CMYKProfile embedded ICC refs

Per-sensor LUTTable profile (ColorProfile, Version 2.0):

key meaning
mf/mfd/mt 3×3 color matrices (flash / flash-daylight / tungsten)
vf/vt white points
tf/tt temps
CbS/CbE/CrS/CrE hard clip points
LUTTableFlashStd/TSStd/FlashRepro/TSRepro 18,690-float calibration LUTs

Where the data comes from

From the public FlexColor 4.8.9.1 installer (fc4891win.zip, Hasselblad's archive CDN). Extraction chain: WinZip SFX → nested installer → embedded MSI + MSCF cabinet → 231 files (engine DLL + ~100 film plists + LUT tables + ICC + firmware). See docs/FLEXCOLOR_JOURNEY.md for the full account and docs/FLEXCOLOR_FORMAT.md for the byte/spec detail.

The proprietary files (DLLs, film plists, ICCs) are not redistributed here; point the tools at your own FlexColor install.

Status / honesty

  • ✅ Format recovery: per-film plists + LUTTable profiles fully parsed.
  • ✅ Curve application: piecewise tone curves reconstructable per film.
  • .3fr/.fff decode: LogLuv32 (PackBits-style RLE), LogLuv24 (uvcode index), and uncompressed 16-bit RGB variants -> XYZ -> linear sRGB, with a normalized negative converter for external inversion tools.
  • 🔶 Engine math partially recovered by decompilation: per-channel 16-bit LUT apply, min-span/point normalization, pow-based neg-gamma LUT builder (CGammaNegCurve), and CPointCurve interpolation (linear per segment for <=2 points; de Boor B-spline basis for >=3 points, medium confidence). Exact rendering still needs the B-spline orientation + a real sample to validate.
  • 🔲 Full engine-equivalent render (needs the exact curve/grad math; the matrices/LUTs + LogLuv decode give a strong starting point).
  • The profiles differ meaningfully by film (e.g. Portra 160 NC carries a real 4-point S-curve; Tri-X, Superia and Gold default to linear) — confirming these encode real per-film character, not generic presets.

Related

  • docs/FLEXCOLOR_FORMAT.md — the recovered format spec.
  • docs/FLEXCOLOR_JOURNEY.md — the chronological unpacking account.
  • docs/FLEXCOLOR_BLOG.md — the written-up story.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages