blocky/liblocky/liblocky.h
2022-06-22 11:49:01 +09:00

172 lines
3.6 KiB
C

#pragma once
#include <stdbool.h>
#include <stdint.h>
#define blky_clamp(x, a, b) ((x) < (a)? (a): (x) > (b)? (b): (x))
#define blky_abs(x) ((x) < 0? -(x): (x))
/* ---- Sensor ----
* calculates correl from samples sequencially */
typedef struct blky_sensor_t {
double sum, avg, var;
uint64_t time;
double cov;
double correl;
double prev_correl;
# define BLKY_SENSOR_MAX_DUR 64
float values[BLKY_SENSOR_MAX_DUR];
} blky_sensor_t;
void
blky_sensor_feed(
blky_sensor_t*, const float* v, uint64_t n);
void
blky_sensor_drop(
blky_sensor_t*, uint64_t until);
/* ---- Block ----
* calculates probability representing how likely the block is a feature,
* by dealing with multiple sensors */
double /* 0~1 probability */
blky_block_estimate(
const blky_sensor_t* sensors, uint64_t n,
double max_var, double min_avg);
/* ---- Extractor ----
* extracts all features from a sequence of multiple frames */
typedef struct blky_extractor_t {
// must be filled before init()
uint32_t block_num_x;
uint32_t block_num_y;
uint32_t sensor_num_block_x;
uint32_t sensor_num_block_y;
uint32_t samples_per_pix;
uint32_t pix_stride;
uint32_t utime;
double correl_max_var;
double correl_min_avg;
// immutable internal params
uint32_t block_num;
uint32_t sensor_num_block;
uint32_t sensor_num_whole;
double block_w;
double block_h;
double sensor_interval_x;
double sensor_interval_y;
// mutable internal state
uint64_t time;
// heap objects
uint8_t* mem;
blky_sensor_t* sensors;
double* probs;
} blky_extractor_t;
typedef struct blky_extractor_feat_t {
uint32_t block;
uint64_t begin;
double prob;
} blky_extractor_feat_t;
void
blky_extractor_init(
blky_extractor_t* ex);
void
blky_extractor_deinit(
blky_extractor_t* ex);
bool
blky_extractor_feed(
blky_extractor_t* ex,
const uint8_t* img, uint32_t w, uint32_t h, const double verts[8]);
/* ---- pathfinder ---- */
typedef struct blky_pathfinder_step_t {
struct blky_pathfinder_step_t* next;
uint32_t indices[1];
} blky_pathfinder_step_t;
typedef struct blky_pathfinder_t {
// must be filled before init()
uint32_t block_num;
uint32_t step_branch;
uint64_t seed;
uint8_t hopping_algo;
# define BLKY_PATHFINDER_HOPPING_ALGO_XORSHFIT 0
// internal state
blky_pathfinder_step_t* step_first;
blky_pathfinder_step_t* step_last;
uint64_t steps;
uint64_t step_bytes;
double* probs;
double* probs_prev;
} blky_pathfinder_t;
void
blky_pathfinder_init(
blky_pathfinder_t* pf);
void
blky_pathfinder_deinit(
blky_pathfinder_t* pf);
void
blky_pathfinder_feed(
blky_pathfinder_t* pf,
const double* probs);
/* ---- Image utility ---- */
void blky_image_convert_to_normalized_coord(
const double verts[8], double* x, double* y);
uint64_t blky_image_offset(
uint32_t w, uint32_t h, const double verts[8], double x, double y);
/* ---- numeric utility ---- */
static inline uint64_t blky_numeric_xorrshift64_rev(uint64_t x, uint8_t n) {
for (int16_t i = 64-n; i >= 0; --i) {
x ^= (1 << i) & (x >> n);
}
return x;
}
static inline uint64_t blky_numeric_xorlshift64_rev(uint64_t x, uint8_t n) {
for (uint8_t i = n; i < 64; ++i) {
x ^= (1 << i) & (x << n);
}
return x;
}
static inline uint64_t blky_numeric_xorshift64(uint64_t x) {
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return x;
}
static inline uint64_t blky_numeric_xorshift64_rev(uint64_t x) {
x = blky_numeric_xorlshift64_rev(x, 13);
x = blky_numeric_xorrshift64_rev(x, 7);
x = blky_numeric_xorlshift64_rev(x, 17);
return x;
}