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

152 lines
6.0 KiB
C

/* Official CoreSDKLib.dll harness: drive the vendor pipeline on the real
* device and dump (a) the official rendered BMP, (b) temperature data,
* (c) the Gray2Temperature LUT. This is the authoritative reference for
* what the official app displays.
*
* Build: gcc official_harness.c -o official_harness.exe -ldl (loads dll
* manually so we can use the vendor's own libusb0.dll from its folder).
*/
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/* --- MAG API prototypes (from CoreSDKLib.dll exports, verified RVAs) ---
* Initialize 0x22c0 (chan, ...) EnumCameras 0x2590 (chan)
* NewChannel 0x1ee0 (chan) LinkCamera 0x2650 (chan, pid, ...)
* StartProcessImage 0x2cd0 (chan, ...) GetTemperatureData 0x3fc0 (chan,...)
*/
typedef int (*MAG_Initialize_t)(int, int);
typedef void (*MAG_Free_t)(void);
typedef int (*MAG_IsInitialized_t)(int);
typedef int (*MAG_EnumCameras_t)(int);
typedef int (*MAG_NewChannel_t)(int);
typedef int (*MAG_LinkCamera_t)(int, int, int);
typedef void (*MAG_DisLinkCamera_t)(int);
typedef int (*MAG_StartProcessImage_t)(int, void *, int, int);
typedef int (*MAG_StopProcessImage_t)(int);
typedef int (*MAG_IsProcessingImage_t)(int);
typedef int (*MAG_GetOutputBMPdataRGB24_t)(int, unsigned char *, int, int);
typedef int (*MAG_GetOutputBMPdata_t)(int, unsigned char *, int);
typedef int (*MAG_GetTemperatureData_t)(int, int *, int, int);
typedef int (*MAG_GetCamInfo_t)(int, void *);
typedef int (*MAG_TriggerFFC_t)(int, int);
typedef int (*MAG_SetFixPara_t)(int, void *, int);
typedef int (*MAG_GetApproximateGray2TemperatureLUT_t)(int, float *);
static HMODULE g_core;
static MAG_Initialize_t fn_Initialize;
static MAG_Free_t fn_Free;
static MAG_IsInitialized_t fn_IsInitialized;
static MAG_EnumCameras_t fn_EnumCameras;
static MAG_NewChannel_t fn_NewChannel;
static MAG_LinkCamera_t fn_LinkCamera;
static MAG_DisLinkCamera_t fn_DisLinkCamera;
static MAG_StartProcessImage_t fn_StartProcessImage;
static MAG_StopProcessImage_t fn_StopProcessImage;
static MAG_IsProcessingImage_t fn_IsProcessingImage;
static MAG_GetOutputBMPdataRGB24_t fn_GetOutputBMPdataRGB24;
static MAG_GetOutputBMPdata_t fn_GetOutputBMPdata;
static MAG_GetTemperatureData_t fn_GetTemperatureData;
static MAG_GetCamInfo_t fn_GetCamInfo;
static MAG_TriggerFFC_t fn_TriggerFFC;
static MAG_SetFixPara_t fn_SetFixPara;
static MAG_GetApproximateGray2TemperatureLUT_t fn_GetApproximateGray2TemperatureLUT;
#define LOAD(name) fn_##name = (MAG_##name##_t)GetProcAddress(g_core, "MAG_" #name); \
if (!fn_##name) { printf("missing export MAG_" #name "\n"); return 2; }
int main(int argc, char **argv) {
const char *dllpath = argc > 1 ? argv[1]
: "C:\\Project\\MAG160C\\IR_Camera_SDK-1.0.1\\windows\\windows\\app\\CoreSDKLib.dll";
SetDllDirectoryA("C:\\Project\\MAG160C\\IR_Camera_SDK-1.0.1\\windows\\windows\\app");
g_core = LoadLibraryA(dllpath);
if (!g_core) { printf("LoadLibrary failed: %lu\n", GetLastError()); return 1; }
LOAD(Initialize); LOAD(Free); LOAD(IsInitialized); LOAD(EnumCameras);
LOAD(NewChannel); LOAD(LinkCamera); LOAD(DisLinkCamera); LOAD(StartProcessImage);
LOAD(StopProcessImage); LOAD(IsProcessingImage); LOAD(GetOutputBMPdataRGB24);
LOAD(GetOutputBMPdata); LOAD(GetTemperatureData); LOAD(GetCamInfo);
LOAD(TriggerFFC); LOAD(SetFixPara); LOAD(GetApproximateGray2TemperatureLUT);
printf("CoreSDKLib loaded, isInit=%d\n", fn_IsInitialized(0));
int rc = fn_Initialize(0, 0);
printf("MAG_Initialize(0,0) rc=%d\n", rc);
/* official Windows sequence: NewChannel(0) first, then EnumCameras */
int chan = fn_NewChannel(0);
printf("MAG_NewChannel(0) -> channel=%d\n", chan);
rc = fn_EnumCameras(chan);
printf("MAG_EnumCameras(chan) rc=%d\n", rc);
rc = fn_LinkCamera(chan, 0x101, 0);
printf("MAG_LinkCamera(chan,pid,0) rc=%d\n", rc);
/* camera info */
unsigned char info[0x100] = {0};
rc = fn_GetCamInfo(chan, info);
printf("MAG_GetCamInfo rc=%d\n", rc);
rc = fn_StartProcessImage(chan, NULL, 0x10, 0);
printf("MAG_StartProcessImage rc=%d\n", rc);
Sleep(3000);
fn_TriggerFFC(chan, 1);
Sleep(2000);
printf("after FFC(1): isProcessing=%d\n", fn_IsProcessingImage(chan));
/* temperature LUT (256 floats) */
float lut[256];
rc = fn_GetApproximateGray2TemperatureLUT(chan, lut);
printf("Gray2TempLUT rc=%d lut[0]=%.3f lut[64]=%.3f lut[128]=%.3f lut[255]=%.3f\n",
rc, lut[0], lut[64], lut[128], lut[255]);
if (rc == 0) {
FILE *f = fopen("official_g2t_lut.txt", "w");
for (int i = 0; i < 256; ++i) fprintf(f, "%d %.4f\n", i, lut[i]);
fclose(f);
printf("saved official_g2t_lut.txt\n");
}
/* official BMP */
unsigned char bmp[160 * 120 * 3 + 64];
rc = fn_GetOutputBMPdataRGB24(chan, bmp, 160 * 120 * 3, 1);
printf("GetOutputBMPdataRGB24 rc=%d first px RGB=%d,%d,%d\n",
rc, bmp[0], bmp[1], bmp[2]);
if (rc) {
/* save as BMP file */
unsigned sz = 54 + 160 * 120 * 3;
unsigned char hdr[54] = {0};
hdr[0] = 'B'; hdr[1] = 'M';
hdr[2] = sz; hdr[3] = sz >> 8; hdr[4] = sz >> 16; hdr[5] = sz >> 24;
hdr[10] = 54; hdr[14] = 40;
hdr[18] = 160; hdr[22] = 120; hdr[26] = 1; hdr[28] = 24;
FILE *f = fopen("official_render.bmp", "wb");
fwrite(hdr, 1, 54, f);
fwrite(bmp, 1, 160 * 120 * 3, f);
fclose(f);
printf("saved official_render.bmp\n");
}
/* temperature data (19200 ints) */
static int tempdata[19200];
rc = fn_GetTemperatureData(chan, tempdata, 1, 1);
printf("GetTemperatureData rc=%d t[0]=%d t[9600]=%d\n", rc, tempdata[0], tempdata[9600]);
if (rc) {
FILE *f = fopen("official_tempdata.bin", "wb");
fwrite(tempdata, 4, 19200, f);
fclose(f);
printf("saved official_tempdata.bin\n");
}
printf("(inner temp export not present in this dll)\\n");
fn_StopProcessImage(chan);
fn_DisLinkCamera(chan);
fn_Free();
printf("done\n");
return 0;
}