Hacking the Reflecta DigitDia Evolution (Novatek NT96660) Slide Scanner

melw

Tinkerer
Jun 23, 2026
41
64
18
Hello all!

After the Kodak Reels tinkering I got back to my other digitizing device: a Reflecta DigitDia Evolution magazine slide scanner. It works fine, but I've never been fully happy with the image quality: visible JPEG artifacts and a soft "watercolor" look. It turns out to be the same Novatek family as the Kodak Reels, so I started digging. Sharing what I have so far.

1. Hardware
  • Main board AFS61N_MAIN_V1.0 (2021.09.19)
  • SoC Novatek NT96660BG-H (MIPS, same family as the Kodak Reels' NT96658)
  • Flash Winbond 25Q64JVSIQ: 8 MB SPI NOR, the wide 208-mil SOIC-8 package
  • RAM: NANYA DDR3, 2 Gbit
  • Unpopulated GND / TX / RX UART pads (flat SMD pads, not tried yet), plus empty speaker/mic footprints (the board looks like a cut-down camera design)
  • Three slide-position sensor connectors (POSITION_A/B/C), stepper motor, LED light board
  • Sensor: 16 MP. The "16M" menu setting is the native 4920×3280. "24M" (6000×4000) is upscaled from it.
2. Dumping the flash (no soldering)

I read the 8 MB chip in-circuit with an SOIC-8 test clip + a Raspberry Pi 2 + flashrom (scanner unplugged; the Pi's 3.3 V powers the chip):
  • Wiring (flash pin → Pi header pin): 1 CS → 24, 2 DO → 21, 3 WP → not connected, 4 GND → 25, 5 DI → 19, 6 CLK → 23, 7 HOLD → 17 (3.3 V), 8 VCC → 1 (3.3 V)
  • flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=500 -c W25Q64JV-.Q -r dump.bin.
3. Firmware layout (firmware version 2.0)
  • 0x000000: bootloader (its body is compressed at 0xB1C and runs at 0x8FF09000)
  • 0x008000: main firmware, BCL1 FullComp: 3.4 MB → 22.6 MB, load address 0x80000000 (uITRON + eCos)
  • A second, older-looking compressed block further up, with a bad checksum. I think it's leftover data, but I haven't confirmed that.
  • Compression is the LZ77 from the "Basic Compression Library" (BCL1, algorithm 9). The checksums work with Tobi@s' ntkcalc. bfc4ntk -c refuses this 22.6 MB image (size limit), so I had to write my own compressor.
  • Loader rules: back-references <= 99 999 bytes, no overlapping copies, and the file size must be a multiple of 4, or the loader hangs.
4. Run-from-SD test mode

The loader recognises several files on the card. Its board-init code renames the generic Novatek names, so on this scanner they are:
  • FWFS601T.BIN: load the firmware from the card into RAM and run it. Remove the file and power-cycle, and you're back to stock firmware. This makes testing almost risk-free.
  • FWFS601A.BIN = flash the firmware, LDFS601A.BIN = flash the bootloader — don't put these on a card unless you know exactly what you're doing!
  • The loader reads FAT32, no exFAT.
5. JPEG quality findings
  • Stock photos are Q95, 4:2:2. The bigger visual issue is strong noise reduction, which makes even small block steps visible. Chroma blocking is the worst artifact.
  • Still capture (ImgCap_EncBS 0x80344874): if the finished JPEG doesn't fit its buffer, the firmware re-encodes 5 points lower (95 → 90 → …). The buffer is whatever is left in the capture memory pool: about 6 MB at 24M and ~4.5 MB at 16M. Detailed slides drop to Q90.
  • Encoder: standard IJG quality formula (0x801C1D40); Q100 = all-ones tables. The capture parameter table is at 0x815938C0 (quality is entry 0, plus the rate-control targets 4/5/6 MiB, which are unused by default).
Looking for other DigitDia Evolution owners! It would help a lot to know your firmware version (the EXIF "Software" field of any scan) and board revision. Later, once things are stable, I'd love some testers. I'm not sharing firmware binaries at this point, but I plan to share the patch recipe and tools.

Thanks to everyone who has been tinkering with the Kodak Reels devices — the knowledge from there transferred surprisingly well!

Attaching a few pictures of the board and from the flash dumping process.
 

Attachments

  • 20260929_140214.jpg
    20260929_140214.jpg
    772.7 KB · Views: 56
  • 20261007_202423.jpg
    20261007_202423.jpg
    958.6 KB · Views: 57
  • 20261007_201800.jpg
    20261007_201800.jpg
    982.5 KB · Views: 58
  • Like
Reactions: Kai Robinson

melw

Tinkerer
Jun 23, 2026
41
64
18
6. JPEG quality: Q95 → Q100
  • Correction to my first post: the JPEG buffer is not "what is left in the memory pool". The stock app sets it as a fixed budget of 0.25 bytes per pixel (+ header) at 0x801E4588. That's 6.4 MB at 24M and 4.4 MB at 16M. Detailed slides that don't fit drop to Q90.
  • The capture memory pool is ~180 MB, and over 100 MB of it is unused. The small buffer is a setting, not a memory limit.
  • Patches: start at Q100 and step down 1 instead of 5 (0x803449BC, 0x80344B10), and raise the buffer budget to ~0.97 bytes/pixel (shift constants at 0x801E4604/46E8/46F8).
  • Firmware has three hidden quality levels (0.30 / 0.25 / 0.20 bytes/px). The scanner uses the middle one.
7. Sharpening and noise reduction - first findings
  • Sensor is a Sony IMX206. The firmware has Novatek's full IQ framework: IFE (raw NR), IFE2 (Y/UV NR), IPE (edge enhancement), IME (chroma NR, film grain), DRE.
  • Sharpness is a 0–100 value (50 = default) that scales the edge enhancement linearly. 0 switches it off.
  • The first NR stage (IFE bilateral filter) has an enable bit (0x803317A4, ori 0x3e; bit 0x04 = filter).
 

melw

Tinkerer
Jun 23, 2026
41
64
18
Another update. I found the controls for both noise reduction and sharpening. The scans now come out at Q100, with much less smoothing and no sharpening halos, at the same scan speed. Everything runs from the SD card (FWFS601T.BIN); nothing has been flashed.

8. Corrections to my previous posts
  • IFE enable bit 0x04 is colour gain / white balance, not the noise filter. The firmware's own NR-off branch clears bits 0x22 instead.
  • The UI sharpness value (0–100, IPL setting 0x43210002) doesn't reach still capture.
9. Noise reduction
  • The "watercolor" look is the IFE range (bilateral) filter. Forcing the firmware's NR-off branch in IFE_IQparam (0x8033183C, beqz → b) removes the plastic look, but dark slides show coloured sensor noise.
  • The strength lives in RangeA/B thresholds[6] + LUTs[17] at 0x8179D350 / D380 / D3B0 / D438. They are filled per ISO by 0x803368A0 through an interpolation helper (0x8030CB7C).
  • A small wrapper on those four interpolation calls scales the result by K/256. Measured texture: full 1.64, 3/4 2.42, 1/2 2.59, off 2.96. The stock values are tiny integers, so the first step down has the biggest effect.
  • My pick: 3/4 strength. It keeps the film grain and still stops the coloured speckle in dark slides.
10. Sharpening
  • The IPE edge gains live at 0x8179D5A8 / D5AC (stock 80). They are interpolated in 0x803368A0 (0x803371DC, 0x80337214). Setting them to 0 removes the halos completely.
  • My pick: half gain (40). The white outlines on high-contrast edges are gone, fine detail stays crisp.
11. Result: stock vs patched (same 20 slides)
  • JPEG: Q95 → Q100, 3.4 → 11.6 MB per scan (16M)
  • Blockiness (luma / chroma): 1.36 / 2.48 → 1.01 / 1.10 (1.0 = none)
  • Measured texture/detail: 1.27 → 2.05 (+61 %)
  • Scan time: Same in all versions
  • Visually: never worse, often clearly better. Slides that are soft to begin with look about the same.
  • The whole patch is 183 bytes different from stock firmware 2.0.
Attaching a 1:1 crop: stock vs patched, same slide.
 

Attachments

  • forum3_stock_vs_patched.png
    forum3_stock_vs_patched.png
    266.8 KB · Views: 6
  • Like
Reactions: fishgee