/* * mag160c_render.h - platform-independent official rendering pipeline. * * Mirrors the official CoreSDKLib.dll frame path (verified pixel-exact): * raw frame -> shutter extract -> FFC state machine -> endpoint select * + Q12 table interp -> ref (4x type-1 mean) -> NUC lookup -> blind * compensation -> stats/window -> LUT1024 rebuild -> gray -> 2x * upscale -> palette -> RGB24 output. * * No OS/display dependencies: feed it USB frames, get 320x240 RGB24. * FFC commands are emitted through a callback so the caller owns the * transport (libusb on Linux, bulk transfers on Windows, ...). */ #ifndef MAG160C_RENDER_H #define MAG160C_RENDER_H #include #include #include "mag160c.h" #ifdef __cplusplus extern "C" { #endif /* Default output geometry (official: 2x of the 160x120 sensor). */ #define MAG160C_RENDER_OUT_W 320 #define MAG160C_RENDER_OUT_H 240 /* FFC command callback: param 0 = FFC(0), 1 = FFC(1). */ typedef void (*mag160c_render_ffc_cb_t)(void *user, int param); typedef struct mag160c_render_t mag160c_render_t; typedef struct mag160c_render_cfg_t { uint16_t width; /* sensor width, 160 */ uint16_t height; /* sensor height, 120 */ const char *ddt_path; /* official DDT calibration file */ int ffc_period; /* frames between FFC pairs, official 1800 */ int ffc_drift; /* shutter drift threshold, official 250 */ int startup_force_ffc; /* official frame-75 forced FFC, 1 = on */ int warm_frames; /* frames dropped after start, official 20 */ int cdf_pivot_75; /* 0x8c: CDF pivot at 75% cumulative, 1 = on */ mag160c_render_ffc_cb_t ffc_cb; void *ffc_user; } mag160c_render_cfg_t; MAG160C_API mag160c_error_t mag160c_render_init(mag160c_render_t **out, const mag160c_render_cfg_t *cfg); /* Process one raw frame. * frame : USB frame buffer. If has_hdr, the 28-byte header is at * frame[0] (marker 0x1bb1b11b, counter, len, type, ...) and * the shutter word is extracted from the tail; otherwise * frame is the bare 38400-byte pixel buffer and shutter * must be supplied via mag160c_render_set_shutter(). * out_rgb : 320x240x3 RGB24 (palette-colored). * Returns MAG160C_OK when out_rgb was written, MAG160C_ERR_NOT_READY * while the startup/FFC window is running (image frozen by caller). */ MAG160C_API mag160c_error_t mag160c_render_frame(mag160c_render_t *r, const uint8_t *frame, int has_hdr, uint8_t *out_rgb); /* Bare-pixel mode: set the current shutter (device temperature proxy) * before calling mag160c_render_frame(). */ MAG160C_API void mag160c_render_set_shutter(mag160c_render_t *r, int shutter); /* Per-frame diagnostics for UI overlays. */ MAG160C_API void mag160c_render_get_stats(mag160c_render_t *r, int *win_lo, int *win_hi, int *fmin, int *fmax, int *mean, int *stddev); MAG160C_API int mag160c_render_get_shutter(mag160c_render_t *r); MAG160C_API int mag160c_render_get_endpoint(mag160c_render_t *r); MAG160C_API int mag160c_render_get_frame_index(mag160c_render_t *r); MAG160C_API int mag160c_render_has_reference(mag160c_render_t *r); /* Temperature probe on the current NUC output (millidegrees C). */ MAG160C_API mag160c_error_t mag160c_render_probe_temp(mag160c_render_t *r, uint32_t x, uint32_t y, int32_t *out_temp_mc); MAG160C_API void mag160c_render_destroy(mag160c_render_t *r); #ifdef __cplusplus } #endif #endif /* MAG160C_RENDER_H */