summaryrefslogtreecommitdiffstats
path: root/libass/ass_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libass/ass_utils.c')
-rw-r--r--libass/ass_utils.c236
1 files changed, 154 insertions, 82 deletions
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 9a89e8afae..59fdbdfb94 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -1,5 +1,3 @@
-// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
-// vim:ts=8:sw=8:noet:ai:
/*
* Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
@@ -23,113 +21,187 @@
#include "config.h"
#include <stdlib.h>
+#include <stdio.h>
#include <inttypes.h>
#include <ft2build.h>
#include FT_GLYPH_H
-#include "mputils.h"
+#include "ass_library.h"
+#include "ass.h"
#include "ass_utils.h"
-int mystrtoi(char** p, int* res)
+int mystrtoi(char **p, int *res)
{
- // NOTE: base argument is ignored, but not used in libass anyway
- double temp_res;
- char* start = *p;
- temp_res = strtod(*p, p);
- *res = (int) (temp_res + 0.5);
- if (*p != start) return 1;
- else return 0;
+ double temp_res;
+ char *start = *p;
+ temp_res = ass_strtod(*p, p);
+ *res = (int) (temp_res + (temp_res > 0 ? 0.5 : -0.5));
+ if (*p != start)
+ return 1;
+ else
+ return 0;
}
-int mystrtoll(char** p, long long* res)
+int mystrtoll(char **p, long long *res)
{
- double temp_res;
- char* start = *p;
- temp_res = strtod(*p, p);
- *res = (long long) (temp_res + 0.5);
- if (*p != start) return 1;
- else return 0;
+ double temp_res;
+ char *start = *p;
+ temp_res = ass_strtod(*p, p);
+ *res = (int) (temp_res + (temp_res > 0 ? 0.5 : -0.5));
+ if (*p != start)
+ return 1;
+ else
+ return 0;
}
-int mystrtou32(char** p, int base, uint32_t* res)
+int mystrtou32(char **p, int base, uint32_t *res)
{
- char* start = *p;
- *res = strtoll(*p, p, base);
- if (*p != start) return 1;
- else return 0;
+ char *start = *p;
+ *res = strtoll(*p, p, base);
+ if (*p != start)
+ return 1;
+ else
+ return 0;
}
-int mystrtod(char** p, double* res)
+int mystrtod(char **p, double *res)
{
- char* start = *p;
- *res = strtod(*p, p);
- if (*p != start) return 1;
- else return 0;
+ char *start = *p;
+ *res = ass_strtod(*p, p);
+ if (*p != start)
+ return 1;
+ else
+ return 0;
}
-int strtocolor(char** q, uint32_t* res)
+int strtocolor(ASS_Library *library, char **q, uint32_t *res, int hex)
{
- uint32_t color = 0;
- int result;
- char* p = *q;
-
- if (*p == '&') ++p;
- else mp_msg(MSGT_ASS, MSGL_DBG2, "suspicious color format: \"%s\"\n", p);
-
- if (*p == 'H' || *p == 'h') {
- ++p;
- result = mystrtou32(&p, 16, &color);
- } else {
- result = mystrtou32(&p, 0, &color);
- }
-
- {
- unsigned char* tmp = (unsigned char*)(&color);
- unsigned char b;
- b = tmp[0]; tmp[0] = tmp[3]; tmp[3] = b;
- b = tmp[1]; tmp[1] = tmp[2]; tmp[2] = b;
- }
- if (*p == '&') ++p;
- *q = p;
-
- *res = color;
- return result;
+ uint32_t color = 0;
+ int result;
+ char *p = *q;
+ int base = hex ? 16 : 10;
+
+ if (*p == '&')
+ ++p;
+ else
+ ass_msg(library, MSGL_DBG2, "suspicious color format: \"%s\"\n", p);
+
+ if (*p == 'H' || *p == 'h') {
+ ++p;
+ result = mystrtou32(&p, 16, &color);
+ } else {
+ result = mystrtou32(&p, base, &color);
+ }
+
+ {
+ unsigned char *tmp = (unsigned char *) (&color);
+ unsigned char b;
+ b = tmp[0];
+ tmp[0] = tmp[3];
+ tmp[3] = b;
+ b = tmp[1];
+ tmp[1] = tmp[2];
+ tmp[2] = b;
+ }
+ if (*p == '&')
+ ++p;
+ *q = p;
+
+ *res = color;
+ return result;
}
// Return a boolean value for a string
-char parse_bool(char* str) {
- while (*str == ' ' || *str == '\t')
- str++;
- if (!strncasecmp(str, "yes", 3))
- return 1;
- else if (strtol(str, NULL, 10) > 0)
- return 1;
- return 0;
+char parse_bool(char *str)
+{
+ while (*str == ' ' || *str == '\t')
+ str++;
+ if (!strncasecmp(str, "yes", 3))
+ return 1;
+ else if (strtol(str, NULL, 10) > 0)
+ return 1;
+ return 0;
}
-#if 0
-static void sprint_tag(uint32_t tag, char* dst)
+void ass_msg(ASS_Library *priv, int lvl, char *fmt, ...)
{
- dst[0] = (tag >> 24) & 0xFF;
- dst[1] = (tag >> 16) & 0xFF;
- dst[2] = (tag >> 8) & 0xFF;
- dst[3] = tag & 0xFF;
- dst[4] = 0;
+ va_list va;
+ va_start(va, fmt);
+ priv->msg_callback(lvl, fmt, va, priv->msg_callback_data);
+ va_end(va);
}
-void dump_glyph(FT_Glyph g)
+unsigned ass_utf8_get_char(char **str)
{
- char tag[5];
- int i;
- FT_OutlineGlyph og = (FT_OutlineGlyph)g;
- FT_Outline* o = &(og->outline);
- sprint_tag(g->format, tag);
- printf("glyph: %p \n", g);
- printf("format: %s \n", tag);
- printf("outline: %p \n", o);
- printf("contours: %d, points: %d, points ptr: %p \n", o->n_contours, o->n_points, o->points);
- for (i = 0; i < o->n_points; ++i) {
- printf(" point %f, %f \n", d6_to_double(o->points[i].x), d6_to_double(o->points[i].y));
- }
+ uint8_t *strp = (uint8_t *) * str;
+ unsigned c = *strp++;
+ unsigned mask = 0x80;
+ int len = -1;
+ while (c & mask) {
+ mask >>= 1;
+ len++;
+ }
+ if (len <= 0 || len > 4)
+ goto no_utf8;
+ c &= mask - 1;
+ while ((*strp & 0xc0) == 0x80) {
+ if (len-- <= 0)
+ goto no_utf8;
+ c = (c << 6) | (*strp++ & 0x3f);
+ }
+ if (len)
+ goto no_utf8;
+ *str = (char *) strp;
+ return c;
+
+ no_utf8:
+ strp = (uint8_t *) * str;
+ c = *strp++;
+ *str = (char *) strp;
+ return c;
+}
+
+#ifdef CONFIG_ENCA
+void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
+ int buflen, char *preferred_language,
+ char *fallback)
+{
+ const char **languages;
+ size_t langcnt;
+ EncaAnalyser analyser;
+ EncaEncoding encoding;
+ char *detected_sub_cp = NULL;
+ int i;
+
+ languages = enca_get_languages(&langcnt);
+ ass_msg(library, MSGL_V, "ENCA supported languages");
+ for (i = 0; i < langcnt; i++) {
+ ass_msg(library, MSGL_V, "lang %s", languages[i]);
+ }
+
+ for (i = 0; i < langcnt; i++) {
+ const char *tmp;
+
+ if (strcasecmp(languages[i], preferred_language) != 0)
+ continue;
+ analyser = enca_analyser_alloc(languages[i]);
+ encoding = enca_analyse_const(analyser, buffer, buflen);
+ tmp = enca_charset_name(encoding.charset, ENCA_NAME_STYLE_ICONV);
+ if (tmp && encoding.charset != ENCA_CS_UNKNOWN) {
+ detected_sub_cp = strdup(tmp);
+ ass_msg(library, MSGL_INFO, "ENCA detected charset: %s", tmp);
+ }
+ enca_analyser_free(analyser);
+ }
+
+ free(languages);
+
+ if (!detected_sub_cp) {
+ detected_sub_cp = strdup(fallback);
+ ass_msg(library, MSGL_INFO,
+ "ENCA detection failed: fallback to %s", fallback);
+ }
+
+ return detected_sub_cp;
}
#endif