+/* Euclidean algorithm
+ * http://en.wikipedia.org/wiki/Euclidean_algorithm */
+static unsigned int
+gcd(unsigned int a, unsigned int b)
+{
+ unsigned int t;
+
+ while (b) {
+ t = b;
+ b = a % t;
+ a = t;
+ }
+
+ return a;
+}
+
+/**
+ * Guess aspect ratio from known ratios or Greatest Common Divisor.
+ *
+ * @param ret where to store the newly allocated string with ratio.
+ * @param width frame width to guess aspect ratio.
+ * @param height frame height to guess aspect ratio.
+ * @return 1 on success and @c ret->str must be @c free()d, 0 on failure.
+ */
+int
+lms_aspect_ratio_guess(struct lms_string_size *ret, int width, int height)
+{
+ static struct {
+ double ratio;
+ struct lms_string_size str;
+ } *itr, known_ratios[] = {
+ {16.0 / 9.0, LMS_STATIC_STRING_SIZE("16:9")},
+ {4.0 / 3.0, LMS_STATIC_STRING_SIZE("4:3")},
+ {3.0 / 2.0, LMS_STATIC_STRING_SIZE("3:2")},
+ {5.0 / 3.0, LMS_STATIC_STRING_SIZE("5:3")},
+ {8.0 / 5.0, LMS_STATIC_STRING_SIZE("8:5")},
+ {1.85, LMS_STATIC_STRING_SIZE("1.85:1")},
+ {1.4142, LMS_STATIC_STRING_SIZE("1.41:1")},
+ {2.39, LMS_STATIC_STRING_SIZE("2.39:1")},
+ {16.18 / 10.0, LMS_STATIC_STRING_SIZE("16.18:10")},
+ {-1.0, {NULL, 0}}
+ };
+ double ratio;
+ unsigned num, den, f;
+
+ if (width <= 0 || height <= 0) {
+ ret->len = 0;
+ ret->str = NULL;
+ return 0;
+ }
+
+ ratio = (double)width / (double)height;
+ for (itr = known_ratios; itr->ratio > 0.0; itr++) {
+ if (fabs(ratio - itr->ratio) <= 0.01)
+ return lms_string_size_dup(ret, &itr->str);
+ }
+
+ f = gcd(width, height);
+
+ num = width / f;
+ den = height / f;
+ ret->len = asprintf(&ret->str, "%u:%u", num, den);
+ if (ret->len == (unsigned int)-1) {
+ ret->len = 0;
+ ret->str = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+