Docs

ptp

Camera control over USB PTP, in Go, with no vendor SDK.

ptp  

Camera control over USB PTP, in Go. No vendor SDK runs in the process.

Source: github.com/mikefsq/ptp .

import (
    "github.com/mikefsq/ptp"
    "github.com/mikefsq/ptp/fuji"
)

cam, err := fuji.Open("")        // empty serial: the only attached body
defer cam.Close()                // hands the camera back to its owner

cam.SetManualFocus()
cam.SetShutter(time.Second / 1000)
cam.Capture(120 * time.Second)

Layout  

Package Covers
ptp Framing, sessions, objects, property descriptors, events.
ptp/usb The per-OS USB transports.
ptp/fuji Fujifilm X and GFX.
ptp/sony Sony Alpha.
ptp/canon, ptp/nikon Not implemented.

Capability interfaces in camera.go give the vendors one shape: Capturer, ExposureControl, Downloader, BufferReporter, FocusControl, LiveViewer, and RawDecoder.

Status  

ptp/fuji is validated on an X-T5: capture, download, live view, histogram, exposures from 5 µs to 64 s, bracketed bursts at 0.76 s per frame, clock sync, and clean teardown. 250 of the body’s 263 properties are named, and all 263 are reachable with validation against a live descriptor.

ptp/usb on darwin is validated on an X-T5 and a NEX-6. It recovers a wedged body in software by clearing both bulk endpoints and issuing the still-image class Device Reset, so a camera left waiting for the rest of an abandoned data phase no longer needs unplugging.

ptp/sony has RAW decoding validated on A7R V and A7R VI frames. The control layer is implemented, covering the SDIO handshake, the property blob, the button-driven shutter, exposure encodings, bursts, card readiness, live view, clock sync, the image-format surface, and value naming. Its transport and object layers are validated on a NEX-6, but every SDIO path is unverified: a NEX-6 has no SDIO operations, so nothing that supports them has been driven yet.

RAW decoding  

Both vendors decode their own RAW to an undemosaiced ptp.CFA: the full sensor readout, with the mosaic described rather than applied. Calibration is only valid while every value still sits at the photosite that produced it, so demosaicing is left to whatever consumes the frame.

Uncompressed Compressed
Fujifilm RAF done lossless done; lossy not implemented
Sony ARW done ARW2 lossy and lossless JPEG both done

Every path is verified pixel-for-pixel against libraw on real frames, including a 40.9 Mpx X-T5 frame, a 64.7 Mpx ILCE-7RM5 frame, and 73.4 Mpx ILCE-7RM6 frames.

The two vendors chose very differently. Fujifilm invented a codec, an adaptive Golomb-Rice scheme over gradient contexts, which is unpublished and was reverse engineered for this module. Sony reused lossless JPEG (ITU-T T.81 Annex H), the same codec behind Canon CR2 and Adobe DNG, so that decoder is written from the spec.

Single-threaded, both decoders sit at parity with libraw, which is the honest framing given that libraw is C++ and this is Go. The difference is that this work divides: Fujifilm into independent column blocks, Sony into independent 512×512 tiles. Four cores, the count on the Raspberry Pi this is aimed at, scale 3.4× to 3.9× over the same decoder’s single-core time on both vendors.

On this page