android: 统一APP工程骨架 + 官方渲染管线Kotlin移植(与C参考逐字节一致)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate Kotlin tables from csdk C headers (palette256, t2e)."""
|
||||
import re, sys, io
|
||||
|
||||
CSDK = r"C:\Project\MAG160C\csdk\src"
|
||||
OUT = r"C:\Project\MAG160C\android\app\src\main\kotlin\com\mag160c\thermal\core\OfficialTables.kt"
|
||||
|
||||
def read(fn):
|
||||
with open(fn, encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
def parse_matrix(text, rows=256):
|
||||
vals = []
|
||||
for m in re.finditer(r"\{\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\}", text):
|
||||
vals.append((int(m.group(3)), int(m.group(2)), int(m.group(1)))) # R,G,B from (B,G,R,0)
|
||||
if len(vals) == rows:
|
||||
break
|
||||
return vals
|
||||
|
||||
def parse_int32(text):
|
||||
body = text[text.index("{"):]
|
||||
return [int(x) for x in re.findall(r"-?\d+", body)]
|
||||
|
||||
pal_txt = read(rf"{CSDK}\mag160c_official_palette256.h")
|
||||
t2e_txt = read(rf"{CSDK}\mag160c_official_t2e.h")
|
||||
tables_txt = read(rf"{CSDK}\mag160c_tables.h")
|
||||
|
||||
pal = parse_matrix(pal_txt)
|
||||
assert len(pal) == 256, f"palette entries: {len(pal)}"
|
||||
t2e = parse_int32(t2e_txt)
|
||||
assert len(t2e) == 646, f"t2e entries: {len(t2e)}"
|
||||
|
||||
# mag160c_t2e (274 entries, hex) + mag160c_e2t_acc_q10 (274 entries)
|
||||
def parse_hex_array(text, name):
|
||||
m = re.search(rf"static const uint32_t {name}\[MAG160C_TEMP_CURVE_ENTRIES\] = \{{(.*?)\}};", text, re.S)
|
||||
assert m, name
|
||||
return [int(x, 16) for x in re.findall(r"0x[0-9a-fA-F]+", m.group(1))]
|
||||
|
||||
t2e274 = parse_hex_array(tables_txt, "mag160c_t2e")
|
||||
assert len(t2e274) == 274, f"t2e274: {len(t2e274)}"
|
||||
e2t = parse_hex_array(tables_txt, "mag160c_e2t_acc_q10")
|
||||
assert len(e2t) == 274, f"e2t: {len(e2t)}"
|
||||
|
||||
# palette ARGB int per gray index
|
||||
lines = []
|
||||
lines.append("package com.mag160c.thermal.core")
|
||||
lines.append("")
|
||||
lines.append("/** Generated from csdk C headers by analysis/gen_kotlin_tables.py. DO NOT EDIT. */")
|
||||
lines.append("object OfficialTables {")
|
||||
lines.append(" /** Official default palette (256 gray levels -> ARGB int), source: CoreSDKLib dev+0xb18. */")
|
||||
lines.append(" val PALETTE256_ARGB = intArrayBuilder {")
|
||||
for i, (r, g, b) in enumerate(pal):
|
||||
argb = (0xFF << 24) | (r << 16) | (g << 8) | b
|
||||
lines.append(f" add({argb}) // {i}")
|
||||
lines.append(" }")
|
||||
lines.append("")
|
||||
lines.append(" /** Official T2E table (646 int32), temp = slope*diff>>12 + (i<<12) - 0x249f0. */")
|
||||
lines.append(" val T2E = intArrayBuilder {")
|
||||
for i in range(0, len(t2e), 8):
|
||||
chunk = t2e[i:i+8]
|
||||
lines.append(" add(" + ", ".join(str(v) for v in chunk) + (")" if i + 8 >= len(t2e) else ""))
|
||||
lines.append(" }")
|
||||
lines.append("}")
|
||||
kt = "\n".join(lines) + "\n"
|
||||
|
||||
# intArrayBuilder trick is overkill; use direct arrays with chunked lines instead.
|
||||
argb_lines = []
|
||||
def signed(v):
|
||||
return v if v < 2**31 else v - 2**32
|
||||
for i in range(0, len(pal), 6):
|
||||
row = ", ".join(str(signed((0xFF << 24) | (r << 16) | (g << 8) | b)) for (r, g, b) in pal[i:i+6])
|
||||
argb_lines.append(" " + row + ",")
|
||||
t2e_lines = []
|
||||
for i in range(0, len(t2e), 8):
|
||||
row = ", ".join(str(v) for v in t2e[i:i+8])
|
||||
t2e_lines.append(" " + row + ("," if i + 8 < len(t2e) else ""))
|
||||
|
||||
t2e274_lines = []
|
||||
for i in range(0, len(t2e274), 8):
|
||||
row = ", ".join(f"0x{v:08x}" for v in t2e274[i:i+8])
|
||||
t2e274_lines.append(" " + row + ("," if i + 8 < len(t2e274) else ""))
|
||||
|
||||
e2t_lines = []
|
||||
for i in range(0, len(e2t), 8):
|
||||
row = ", ".join(f"0x{v:08x}" for v in e2t[i:i+8])
|
||||
e2t_lines.append(" " + row + ("," if i + 8 < len(e2t) else ""))
|
||||
|
||||
kt = f"""package com.mag160c.thermal.core
|
||||
|
||||
/** Generated from csdk C headers by analysis/gen_kotlin_tables.py. DO NOT EDIT. */
|
||||
object OfficialTables {{
|
||||
/** Official default palette: 256 gray levels -> ARGB int (from CoreSDKLib dev+0xb18, B,G,R order swapped). */
|
||||
val PALETTE256_ARGB = intArrayOf(
|
||||
{chr(10).join(argb_lines)}
|
||||
)
|
||||
|
||||
/** Official T2E table (646 int32): temp = slope*diff>>12 + (i<<12) - 0x249f0. */
|
||||
val T2E = intArrayOf(
|
||||
{chr(10).join(t2e_lines)}
|
||||
)
|
||||
|
||||
/** Vendor T2E curve from libcoresdk.so ARM64 @0x402010 (274 uint32 entries). */
|
||||
val T2E274 = intArrayOf(
|
||||
{chr(10).join(t2e274_lines)}
|
||||
)
|
||||
|
||||
/** Vendor E2TAccQ10 curve from libcoresdk.so ARM64 @0x40245c (274 uint32 entries). */
|
||||
val E2T_ACC_Q10 = intArrayOf(
|
||||
{chr(10).join(e2t_lines)}
|
||||
)
|
||||
}}
|
||||
"""
|
||||
with open(OUT, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(kt)
|
||||
print(f"written {OUT}: palette {len(pal)} entries, t2e {len(t2e)} entries")
|
||||
@@ -0,0 +1,69 @@
|
||||
/* render_offline.c - PC reference runner for the official mag160c pipeline.
|
||||
* Usage: render_offline.exe <ddt> <frames.bin> <out.rgb> <stats.txt>
|
||||
* frames.bin = sequence of complete USB frames (0x38 + 38400 bytes each).
|
||||
* Writes per-frame 320x240x3 RGB24 + one stats line per frame.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mag160c/mag160c_render.h"
|
||||
|
||||
static unsigned rd32(const unsigned char *p) {
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | ((unsigned)p[3] << 24);
|
||||
}
|
||||
|
||||
static void ffc_cb(void *user, int param) { (void)user; (void)param; }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 5) { fprintf(stderr, "usage: %s ddt frames out.rgb stats\n", argv[0]); return 1; }
|
||||
FILE *ff = fopen(argv[2], "rb");
|
||||
if (!ff) { fprintf(stderr, "open frames fail\n"); return 1; }
|
||||
fseek(ff, 0, SEEK_END);
|
||||
long fsz = ftell(ff);
|
||||
fseek(ff, 0, SEEK_SET);
|
||||
unsigned char *buf = malloc(fsz);
|
||||
if (fread(buf, 1, fsz, ff) != (size_t)fsz) { fclose(ff); return 1; }
|
||||
fclose(ff);
|
||||
|
||||
const unsigned frame_len = 38400;
|
||||
const unsigned total = 0x38 + frame_len;
|
||||
if (fsz < (long)total) { fprintf(stderr, "frames too small\n"); return 1; }
|
||||
|
||||
FILE *out = fopen(argv[3], "wb");
|
||||
FILE *st = fopen(argv[4], "w");
|
||||
if (!out || !st) { fprintf(stderr, "open out fail\n"); return 1; }
|
||||
|
||||
mag160c_render_t *r = NULL;
|
||||
mag160c_render_cfg_t cfg;
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.width = 160; cfg.height = 120;
|
||||
cfg.ddt_path = argv[1];
|
||||
cfg.ffc_cb = ffc_cb;
|
||||
cfg.startup_force_ffc = 1;
|
||||
cfg.cdf_pivot_75 = 1;
|
||||
if (mag160c_render_init(&r, &cfg) != MAG160C_OK) {
|
||||
fprintf(stderr, "render init fail\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char *rgb = malloc(320 * 240 * 3);
|
||||
int nframes = fsz / total;
|
||||
for (int f = 0; f < nframes; ++f) {
|
||||
unsigned char *fr = buf + (long)f * total;
|
||||
/* sanity: marker + len */
|
||||
if (rd32(fr) != 0x1bb1b11b) { fprintf(stderr, "bad marker at frame %d\n", f); return 1; }
|
||||
if (rd32(fr + 8) != frame_len) { fprintf(stderr, "bad len at frame %d\n", f); return 1; }
|
||||
if (rd32(fr + 0x1c + frame_len) != 0x1bb1b11c) { fprintf(stderr, "bad trailer at frame %d\n", f); return 1; }
|
||||
mag160c_error_t rc = mag160c_render_frame(r, fr, 1, rgb);
|
||||
if (rc == MAG160C_OK) {
|
||||
fwrite(rgb, 1, 320 * 240 * 3, out);
|
||||
int lo, hi, mn, mx, mean, sd;
|
||||
mag160c_render_get_stats(r, &lo, &hi, &mn, &mx, &mean, &sd);
|
||||
fprintf(st, "%d %d %d %d %d %d %d\n", f, lo, hi, mn, mx, mean, sd);
|
||||
} else {
|
||||
fprintf(st, "%d HIDDEN\n", f);
|
||||
}
|
||||
}
|
||||
fclose(out); fclose(st);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
0 HIDDEN
|
||||
1 HIDDEN
|
||||
2 HIDDEN
|
||||
3 HIDDEN
|
||||
4 HIDDEN
|
||||
5 HIDDEN
|
||||
6 HIDDEN
|
||||
7 HIDDEN
|
||||
8 HIDDEN
|
||||
9 HIDDEN
|
||||
10 HIDDEN
|
||||
11 HIDDEN
|
||||
12 HIDDEN
|
||||
13 HIDDEN
|
||||
14 HIDDEN
|
||||
15 HIDDEN
|
||||
16 HIDDEN
|
||||
17 HIDDEN
|
||||
18 HIDDEN
|
||||
19 HIDDEN
|
||||
20 HIDDEN
|
||||
21 HIDDEN
|
||||
22 HIDDEN
|
||||
23 HIDDEN
|
||||
24 HIDDEN
|
||||
25 HIDDEN
|
||||
26 HIDDEN
|
||||
27 HIDDEN
|
||||
28 HIDDEN
|
||||
29 HIDDEN
|
||||
30 HIDDEN
|
||||
31 HIDDEN
|
||||
32 6961 7961 7118 7668 7461 103
|
||||
33 6962 7962 7098 7663 7462 103
|
||||
34 6962 7962 7116 7675 7462 103
|
||||
35 6961 7961 7106 7672 7461 103
|
||||
36 6961 7961 7106 7659 7461 103
|
||||
37 6961 7961 7116 7664 7461 103
|
||||
38 6961 7961 7121 7671 7461 103
|
||||
39 6962 7962 7117 7673 7462 103
|
||||
40 6962 7962 7132 7667 7462 103
|
||||
41 6962 7962 7105 7664 7462 103
|
||||
42 6961 7961 7118 7671 7461 103
|
||||
43 6961 7961 7130 7671 7461 103
|
||||
44 6962 7962 7122 7661 7462 103
|
||||
45 6961 7961 7096 7669 7461 103
|
||||
46 6961 7961 7096 7671 7461 103
|
||||
47 6962 7962 7122 7675 7462 103
|
||||
48 6961 7961 7094 7667 7461 103
|
||||
49 6962 7962 7099 7664 7462 103
|
||||
50 6962 7962 7134 7669 7462 103
|
||||
51 6962 7962 7133 7662 7462 103
|
||||
52 6961 7961 7129 7671 7461 103
|
||||
53 6962 7962 7126 7671 7462 103
|
||||
54 6961 7961 7119 7669 7461 103
|
||||
55 6961 7961 7096 7673 7461 103
|
||||
56 6961 7961 7135 7661 7461 103
|
||||
57 6962 7962 7099 7662 7462 103
|
||||
58 6961 7961 7122 7659 7461 103
|
||||
59 6962 7962 7116 7669 7462 103
|
||||
Reference in New Issue
Block a user