#include "result_json.h" #include static const char* task_name(yolo_task_type_t task) { switch (task) { case YOLO_TASK_SEG: return "seg"; case YOLO_TASK_CLS: return "cls"; case YOLO_TASK_OBB: return "obb"; case YOLO_TASK_POSE: return "pose"; default: return "detect"; } } static void write_escaped(FILE* file, const char* text) { for (const unsigned char* cursor = (const unsigned char*)text; cursor && *cursor; ++cursor) { if (*cursor == '"' || *cursor == '\\') fputc('\\', file); if (*cursor >= 0x20) fputc(*cursor, file); } } int write_result_json(const char* path, const char* model_config, const yolo_result_list_t* report) { if (!path || !model_config || !report) return -1; FILE* file = fopen(path, "wb"); if (!file) return -2; fprintf(file, "{\n \"schemaVersion\": \"1\",\n \"modelConfig\": \""); write_escaped(file, model_config); fprintf(file, "\",\n \"task\": \"%s\",\n", task_name(report->task)); fprintf(file, " \"performance\": {\"preprocessMs\": %.3f, \"inferenceMs\": %.3f, \"postprocessMs\": %.3f, \"totalMs\": %.3f},\n", report->performance.preprocess_ms, report->performance.inference_ms, report->performance.postprocess_ms, report->performance.total_ms); fprintf(file, " \"results\": ["); for (int index = 0; index < report->count; ++index) { const yolo_result_t* result = &report->results[index]; fprintf(file, "%s\n {\"task\": \"%s\", \"classId\": %d, \"label\": \"", index ? "," : "", task_name(result->task), result->class_id); write_escaped(file, result->label); fprintf(file, "\", \"score\": %.6f", result->score); if (result->task != YOLO_TASK_CLS) { fprintf(file, ", \"bbox\": {\"x\": %.3f, \"y\": %.3f, \"width\": %.3f, \"height\": %.3f", result->bbox.x, result->bbox.y, result->bbox.width, result->bbox.height); if (result->bbox.has_angle) fprintf(file, ", \"angle\": %.6f", result->bbox.angle); fputc('}', file); } fputc('}', file); } fprintf(file, "%s ]\n}\n", report->count ? "\n" : ""); fclose(file); return 0; }