70 lines
2.6 KiB
C
70 lines
2.6 KiB
C
/* 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;
|
|
}
|