#include "set_plot.h" #include static double clamp(double v, double lo, double hi) { return fmin(hi, fmax(lo, v)); } static int finite_values(const double *v, size_t n) { size_t i; for (i = 0; i < n; ++i) if (!isfinite(v[i])) return 0; return 1; } uint32_t set_plot_abi_version(void) { return 1U; } size_t set_plot_eval(uint32_t op, const double *v, size_t n, double *out, size_t cap) { static const size_t sizes[] = {10, 3, 4, 4, 6, 2, 3, 2}; double span, fraction; if (op > SET_PLOT_DB_DELTA || !v || !out || n != sizes[op] || cap < (op == SET_PLOT_TRANSFORM ? 4U : 1U)) return 0; if (op == SET_PLOT_TRANSFORM) { double w, h, fx, fy; if (!finite_values(v, 4) || v[2] < 1.0/128 || v[2] > 1 || v[3] < 1.0/128 || v[3] > 1 || v[0] < 0 || v[1] < 0 || v[0] + v[2] > 1.000000000001 || v[1] + v[3] > 1.000000000001) return 0; out[0] = v[0]; out[1] = v[1]; out[2] = v[2]; out[3] = v[3]; if (!finite_values(v + 4, 6) || v[4] <= 0 || v[5] <= 0) return 4; w = clamp(v[2] / v[4], 1.0/128, 1); h = clamp(v[3] / v[5], 1.0/128, 1); fx = clamp(v[8], 0, 1); fy = clamp(v[9], 0, 1); out[0] = clamp(v[0] + (v[2] - w) * fx - v[6] * w, 0, 1 - w); out[1] = clamp(v[1] + (v[3] - h) * fy - v[7] * h, 0, 1 - h); out[2] = w; out[3] = h; return 4; } if (!finite_values(v, n)) return 0; switch (op) { case SET_PLOT_AXIS: if (v[2] < 0) return 0; out[0] = fmax(fabs(v[0]), fabs(v[1])) <= v[2] ? 0 : (fabs(v[1]) > fabs(v[0]) ? 2 : 1); break; case SET_PLOT_FRACTION: case SET_PLOT_VALUE: span = v[2] - v[1]; if (!isfinite(span) || span <= 0 || (v[3] != 0 && v[3] != 1)) return 0; if (op == SET_PLOT_FRACTION) { fraction = (v[0] - v[1]) / span; out[0] = v[3] ? 1 - fraction : fraction; } else { fraction = v[3] ? 1 - v[0] : v[0]; out[0] = v[1] + fraction * span; } break; case SET_PLOT_DRAG: span = v[4] - v[3]; if (!isfinite(span) || span <= 0 || v[2] <= 0 || (v[5] != 0 && v[5] != 1)) return 0; out[0] = clamp(v[0] + (v[5] ? -1 : 1) * (v[1] / v[2]) * span, v[3], v[4]); break; case SET_PLOT_TICK_STEP: { double raw, magnitude, scaled; if (v[0] <= 0 || v[1] <= 0) return 0; raw = v[0] / fmax(2, floor(v[1] / 100)); magnitude = pow(10, floor(log10(raw))); if (magnitude <= 0 || !isfinite(magnitude)) return 0; scaled = raw / magnitude; out[0] = (scaled <= 1 ? 1 : scaled <= 2 ? 2 : scaled <= 5 ? 5 : 10) * magnitude; break; } case SET_PLOT_DELTA: out[0] = (v[1] - v[0]) * v[2]; break; case SET_PLOT_DB_DELTA: if (v[0] == 0 || v[1] == 0) return 0; out[0] = 20 * log10(fabs(v[1] / v[0])); break; default: return 0; } return isfinite(out[0]) ? 1 : 0; }