113 lines
4.7 KiB
C
Raw Normal View History

2026-08-04 14:23:07 +08:00
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int load_bmp_rgb(const char* path, unsigned char** pixels, int* width, int* height);
void free_bmp_rgb(unsigned char* pixels);
#ifdef __cplusplus
}
#endif
#ifndef SDK_MODEL_ROI_H
#define SDK_MODEL_ROI_H
#include "yolo_runtime.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
/* TXT belongs to the application contract. Runtime receives only the final ROI.
Return 0 for absent configuration, 1 for valid ROI, -1 for invalid input. */
static int load_model_roi(const char* config, int width, int height, yolo_roi_v1_t* roi) {
char path[4096];
const char* slash = strrchr(config, '/');
const char* backslash = strrchr(config, '\\');
if (backslash && (!slash || backslash > slash)) slash = backslash;
const size_t prefix = slash ? (size_t)(slash - config + 1) : 0;
if (prefix + sizeof("roi_info.txt") > sizeof(path)) return -1;
memcpy(path, config, prefix);
strcpy(path + prefix, "roi_info.txt");
FILE* file = fopen(path, "rb");
if (!file) return errno == ENOENT ? 0 : -1;
const char* keys[] = {"source_width", "source_height", "roi_width", "roi_height", "x", "y", "x1", "y1", "x2", "y2", "w", "h", "l", "t"};
int values[14] = {0}, seen[14] = {0}, valid = 1, first = 1;
char line[512];
while (valid && fgets(line, sizeof(line), file)) {
char* key = line;
if (first && strlen(key) >= 3 && (unsigned char)key[0] == 0xef && (unsigned char)key[1] == 0xbb && (unsigned char)key[2] == 0xbf) key += 3;
first = 0;
while (isspace((unsigned char)*key)) ++key;
if (!*key) continue;
char* equal = strpbrk(key, "=:");
if (!equal) { valid = 0; break; }
char* key_end = equal;
while (key_end > key && isspace((unsigned char)key_end[-1])) --key_end;
*key_end = 0;
int index;
for (index = 0; index < 14 && strcmp(key, keys[index]); ++index) {}
if (index == 14 || seen[index]) { valid = 0; break; }
errno = 0;
char* end;
long value = strtol(equal + 1, &end, 10);
if (end == equal + 1 || errno || value < INT_MIN || value > INT_MAX) { valid = 0; break; }
while (isspace((unsigned char)*end)) ++end;
if (*end == '\\') { ++end; while (isspace((unsigned char)*end)) ++end; }
if (*end) { valid = 0; break; }
values[index] = (int)value; seen[index] = 1;
}
if (ferror(file)) valid = 0;
fclose(file);
if (!valid) return -1;
if (seen[10] || seen[11] || seen[12] || seen[13]) {
for (int i = 0; i < 10; ++i) if (seen[i]) return -1;
if (!seen[10] || !seen[11] || !seen[12] || !seen[13] ||
width <= 0 || height <= 0 || values[10] <= 0 || values[11] <= 0 ||
values[12] < 0 || values[13] < 0 ||
(long long)values[12] + values[10] > width ||
(long long)values[13] + values[11] > height) return -1;
*roi = yolo_roi_from_whlt(values[10], values[11], values[12], values[13]);
return 1;
}
if (!seen[0] || !seen[1] || (!seen[4] && !seen[6]) || (!seen[5] && !seen[7]) ||
(!seen[2] && !seen[8]) || (!seen[3] && !seen[9])) return -1;
const int x = seen[4] ? values[4] : values[6], y = seen[5] ? values[5] : values[7];
const long long w = seen[2] ? values[2] : (long long)values[8] - x;
const long long h = seen[3] ? values[3] : (long long)values[9] - y;
if (values[0] != width || values[1] != height || width <= 0 || height <= 0 ||
x < 0 || y < 0 || w <= 0 || h <= 0 || (long long)x + w > width || (long long)y + h > height ||
(seen[6] && values[6] != x) || (seen[7] && values[7] != y) ||
(seen[8] && values[8] != (long long)x + w) || (seen[9] && values[9] != (long long)y + h)) return -1;
*roi = yolo_roi_from_whlt((int)w, (int)h, x, y);
return 1;
}
/* Parse arguments only: 0=absent, 1=LT, 2=WHLT, -1=invalid.
ROI construction and field assignment are shown directly in each main file. */
static int parse_example_roi_args(int argc, char** argv, int values[4]) {
int found = 0;
for (int i = 1; i < argc; ++i) {
const int lt = strcmp(argv[i], "--roi-lt") == 0;
const int whlt = strcmp(argv[i], "--roi-whlt") == 0;
if (!lt && !whlt) continue;
const int count = lt ? 2 : 4;
if (found || i + count >= argc) return -1;
for (int j = 0; j < count; ++j) {
char* end;
errno = 0;
const long value = strtol(argv[i + j + 1], &end, 10);
if (end == argv[i + j + 1] || *end || errno || value < INT_MIN || value > INT_MAX)
return -1;
values[j] = (int)value;
}
found = lt ? 1 : 2;
i += count;
}
return found;
}
#endif