Files
ZXCLI 0bfb926892 完成官方管线全量逆向与 demo3 v5 复刻,清理仓库
- 逆向:Ghidra/IDA 全量反编译 CoreSDKLib.dll/ThermalSDK.dll/libthermalSDK.so/
  libcoresdk.so(ARM64)/libmagcore.so,导出 analysis/ida/export/
- 解码官方渲染管线:DDT 校准表加载->快门端点选择->Q12 插值->ref(4x type1 帧
  均值)->NUC 查表->盲元补偿->窗口->LUT1024 重建->2x 升采样->调色板
- 逐像素验证:NUC+盲元 0/19200、插值 0 误差、2x 0/76800、窗口一致
- demo3 v5:完整复刻官方管线(含 DDT 解析、FFC 状态机、快门温度驱动),
  修复 load_ddt 表错位导致的零像素问题
- 鬼影根因分析写入 analysis/reverse_20260813_full.md
- 心跳/恢复机制:analysis/session_state.md + tools/resume_rev.ps1
- 新增 tsdk_pair3 增强采集工具;历史工具归档 csdk/tools/legacy/;
  根目录抓帧残留删除,历史文档归档 analysis/history/
- csdk/README.md 完整使用文档;.gitignore/.gitattributes 补 LFS 规则
2026-08-13 23:16:12 +08:00

75 lines
2.8 KiB
C

/* Based on tsdk_debug (works): capture frames + read temps. */
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
typedef void (CALLBACK *INewIRFrame)(const unsigned char *, int, int, int);
typedef void (CALLBACK *INewDistance)(float);
typedef void (CALLBACK *IDistanceError)();
typedef bool (CALLBACK *fn_Start_t)(void);
typedef void (CALLBACK *fn_Stop_t)(void);
typedef void (CALLBACK *fn_SetNewIRFrameDelegate_t)(INewIRFrame);
typedef void (CALLBACK *fn_SetNewDistanceDelegate_t)(INewDistance);
typedef void (CALLBACK *fn_SetDistanceError_t)(IDistanceError);
typedef void (CALLBACK *fn_ReadTemperatureAtPoint_t)(int, int, unsigned char *);
static int g_saved;
static unsigned char g_last[320 * 240 * 3];
static void CALLBACK onIR(const unsigned char *buf, int w, int h, int ch) {
if (buf) {
memcpy(g_last, buf, (size_t)w * h * ch);
if (g_saved < 8) {
char path[128];
snprintf(path, sizeof(path), "official_ir_%02d.rgb", g_saved);
FILE *f = fopen(path, "wb");
if (f) { fwrite(buf, 1, (size_t)w * h * ch, f); fclose(f); }
g_saved++;
}
}
}
static void CALLBACK onDist(float d) { (void)d; }
static void CALLBACK onDistErr() {}
int main(void) {
SetDllDirectoryA("C:\\Project\\MAG160C\\IR_Camera_SDK-1.0.1\\windows\\windows\\app");
HMODULE h = LoadLibraryA("ThermalSDK.dll");
printf("load: %p err=%lu\n", (void*)h, GetLastError());
if (!h) return 1;
fn_Start_t T_Start = (fn_Start_t)GetProcAddress(h, "Start");
fn_Stop_t T_Stop = (fn_Stop_t)GetProcAddress(h, "Stop");
fn_SetNewIRFrameDelegate_t T_Set = (fn_SetNewIRFrameDelegate_t)GetProcAddress(h, "SetNewIRFrameDelegate");
fn_SetNewDistanceDelegate_t T_Dist = (fn_SetNewDistanceDelegate_t)GetProcAddress(h, "SetNewDistanceDelegate");
fn_SetDistanceError_t T_Err = (fn_SetDistanceError_t)GetProcAddress(h, "SetDistanceError");
fn_ReadTemperatureAtPoint_t T_Temp = (fn_ReadTemperatureAtPoint_t)GetProcAddress(h, "ReadTemperatureAtPoint");
printf("Start=%p Temp=%p\n", (void*)T_Start, (void*)T_Temp);
T_Dist(onDist);
T_Err(onDistErr);
T_Set(onIR);
printf("Start()...\n"); fflush(stdout);
BOOL ok = T_Start();
printf("Start=%d\n", ok); fflush(stdout);
DWORD t0 = GetTickCount();
int n = 0;
while (GetTickCount() - t0 < 10000) {
Sleep(250);
if (n < 5) {
int x = 80 + (n % 2) * 40, y = 60 + (n / 2) * 30;
unsigned char res[64] = {0};
T_Temp(x, y, res);
printf("temp(%d,%d): ", x, y);
for (int i = 0; i < 24; ++i) printf("%02x ", res[i]);
printf("\n");
fflush(stdout);
n++;
}
}
printf("saved %d frames\n", g_saved);
T_Stop();
printf("done\n");
return 0;
}