#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 #include #include #include #include #include /* 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