Files
MAG160C/csdk/include/mag160c/mag160c_render.h
T
ZXCLI 5c22bfe78c 新增平台无关渲染模块 mag160c_render + Linux 参考程序 + 移植评估文档
- csdk/include/mag160c/mag160c_render.h + csdk/src/mag160c_render.c:
  官方渲染管线(快门提取/FFC 状态机/ref 采集/表重建/NUC/盲元/窗口/
  LUT(0x8c)/gray/2x/调色板)封装为无平台依赖 API,FFC 命令经回调发出
- csdk/tools/mag160c_linux_demo.c:Linux 风格参考程序(libusb + render
  API + 显示后端抽象 fbdev/DRM/LVGL),Windows 可编译验证(BMP 输出)
- 修复帧组装:第二段 bulk 读 38428B(像素+尾),尾部含快门字
  实测 shutter=31492 sel=2 stats 正常
- docs/linux_port_plan.md:芯片选型(推荐 T113-S3 QFP128 非 BGA ~20元)、
  动画库(LVGL+rlottie 参考 LiThermal)、显示方案、接口抽象设计
- csdk/README 增加 Linux 移植章节
2026-08-14 17:08:38 +08:00

89 lines
3.6 KiB
C

/*
* 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 <stdint.h>
#include <stddef.h>
#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 */