- 逆向: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 规则
69 lines
3.0 KiB
C
69 lines
3.0 KiB
C
/* Read the LIVE official palette: after ThermalSDK Start(), the channel
|
|
* device object holds the 256-entry palette at dev+0xb00 (4 bytes each,
|
|
* BGR order). We find the device pointer via MAG_GetOutputBMPdata which
|
|
* returns the grayscale buffer at dev+0xaf0 - the palette is 0x10 before it.
|
|
*/
|
|
#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 bool (CALLBACK *fn_Start_t)(void);
|
|
typedef void (CALLBACK *fn_Stop_t)(void);
|
|
typedef void (CALLBACK *fn_SetNewIRFrameDelegate_t)(INewIRFrame);
|
|
typedef int (CALLBACK *MAG_GetOutputBMPdata_t)(int, int *, unsigned char **);
|
|
typedef int (CALLBACK *MAG_GetOutputBMPdataRGB24_t)(int, unsigned char *, int, int);
|
|
typedef int (CALLBACK *MAG_GetOutputColorBardata_t)(int, unsigned char *, int);
|
|
|
|
static volatile int g_frames;
|
|
static void CALLBACK onIR(const unsigned char *buf, int w, int h, int ch) {
|
|
(void)buf; (void)w; (void)h; (void)ch;
|
|
g_frames++;
|
|
}
|
|
|
|
int main(void) {
|
|
SetDllDirectoryA("C:\\Project\\MAG160C\\IR_Camera_SDK-1.0.1\\windows\\windows\\app");
|
|
HMODULE t = LoadLibraryA("ThermalSDK.dll");
|
|
HMODULE c = LoadLibraryA("CoreSDKLib.dll");
|
|
if (!t || !c) return 1;
|
|
fn_Start_t T_Start = (fn_Start_t)GetProcAddress(t, "Start");
|
|
fn_Stop_t T_Stop = (fn_Stop_t)GetProcAddress(t, "Stop");
|
|
fn_SetNewIRFrameDelegate_t T_Set = (fn_SetNewIRFrameDelegate_t)GetProcAddress(t, "SetNewIRFrameDelegate");
|
|
MAG_GetOutputBMPdata_t G_Gray = (MAG_GetOutputBMPdata_t)GetProcAddress(c, "MAG_GetOutputBMPdata");
|
|
MAG_GetOutputBMPdataRGB24_t G_RGB = (MAG_GetOutputBMPdataRGB24_t)GetProcAddress(c, "MAG_GetOutputBMPdataRGB24");
|
|
MAG_GetOutputColorBardata_t G_Bar = (MAG_GetOutputColorBardata_t)GetProcAddress(c, "MAG_GetOutputColorBardata");
|
|
|
|
T_Set(onIR);
|
|
BOOL ok = T_Start();
|
|
printf("Start=%d\n", ok); fflush(stdout);
|
|
Sleep(3000);
|
|
|
|
for (int chan = 0; chan < 5; ++chan) {
|
|
int w = 0;
|
|
unsigned char *graybuf = NULL;
|
|
int rc = G_Gray(chan, &w, &graybuf);
|
|
printf("chan %d gray rc=%d buf=%p\n", chan, rc, (void*)graybuf);
|
|
if (rc && graybuf) {
|
|
/* palette at graybuf - 0x10 (dev+0xaf0 - 0x10 = dev+0xae0?)
|
|
* Actually palette is dev+0xb00 = graybuf + 0x10 */
|
|
unsigned char *pal = graybuf + 0x10;
|
|
FILE *f = fopen("official_palette_live.bin", "wb");
|
|
if (f) { fwrite(pal, 1, 256 * 4, f); fclose(f); }
|
|
printf("saved official_palette_live.bin (first entries):\n");
|
|
for (int i = 0; i < 12; ++i) {
|
|
printf(" %2d: %3d %3d %3d %3d\n", i, pal[i*4], pal[i*4+1], pal[i*4+2], pal[i*4+3]);
|
|
}
|
|
/* also dump a few RGB24 render pixels to correlate */
|
|
unsigned char rgb[160*120*3];
|
|
int rc2 = G_RGB(chan, rgb, 160*120*3, 1);
|
|
printf("RGB24 rc=%d\n", rc2);
|
|
break;
|
|
}
|
|
}
|
|
T_Stop();
|
|
printf("done\n");
|
|
return 0;
|
|
}
|