From 597a3d181a15107e52ef2533dbedad365250e486 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 18 Jun 2009 13:00:37 +0200 Subject: [PATCH] Apply initial changes needed for standalone libass. --- libass/ass_mp.c | 279 ----------------------------------------------- libass/ass_mp.h | 60 ---------- libass/help_mp.h | 56 ++++++++++ libass/mputils.c | 218 ++++++++++++++++++++++++++++++++++++ libass/mputils.h | 62 ++++++----- 5 files changed, 307 insertions(+), 368 deletions(-) delete mode 100644 libass/ass_mp.c delete mode 100644 libass/ass_mp.h create mode 100644 libass/help_mp.h create mode 100644 libass/mputils.c diff --git a/libass/ass_mp.c b/libass/ass_mp.c deleted file mode 100644 index b3c78b6..0000000 --- a/libass/ass_mp.c +++ /dev/null @@ -1,279 +0,0 @@ -// -*- c-basic-offset: 8; indent-tabs-mode: t -*- -// vim:ts=8:sw=8:noet:ai: -/* - * Copyright (C) 2006 Evgeniy Stepanov - * - * This file is part of libass. - * - * libass is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * libass is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with libass; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include - -#include "mp_msg.h" -#include "get_path.h" - -#include "ass.h" -#include "ass_utils.h" -#include "ass_mp.h" -#include "ass_library.h" - -#ifdef CONFIG_FONTCONFIG -#include -#endif - -// libass-related command line options -ass_library_t* ass_library; -int ass_enabled = 0; -float ass_font_scale = 1.; -float ass_line_spacing = 0.; -int ass_top_margin = 0; -int ass_bottom_margin = 0; -#if defined(FC_VERSION) && (FC_VERSION >= 20402) -int extract_embedded_fonts = 1; -#else -int extract_embedded_fonts = 0; -#endif -char **ass_force_style_list = NULL; -int ass_use_margins = 0; -char* ass_color = NULL; -char* ass_border_color = NULL; -char* ass_styles_file = NULL; -int ass_hinting = ASS_HINTING_NATIVE + 4; // native hinting for unscaled osd - -#ifdef CONFIG_FONTCONFIG -extern int font_fontconfig; -#else -static int font_fontconfig = -1; -#endif -extern char* font_name; -extern char* sub_font_name; -extern float text_font_scale_factor; -extern int subtitle_autoscale; - -#ifdef CONFIG_ICONV -extern char* sub_cp; -#else -static char* sub_cp = 0; -#endif - -void process_force_style(ass_track_t* track); - -ass_track_t* ass_default_track(ass_library_t* library) { - ass_track_t* track = ass_new_track(library); - - track->track_type = TRACK_TYPE_ASS; - track->Timer = 100.; - track->PlayResY = 288; - track->WrapStyle = 0; - - if (ass_styles_file) - ass_read_styles(track, ass_styles_file, sub_cp); - - if (track->n_styles == 0) { - ass_style_t* style; - int sid; - double fs; - uint32_t c1, c2; - - sid = ass_alloc_style(track); - style = track->styles + sid; - style->Name = strdup("Default"); - style->FontName = (font_fontconfig >= 0 && sub_font_name) ? strdup(sub_font_name) : (font_fontconfig >= 0 && font_name) ? strdup(font_name) : strdup("Sans"); - style->treat_fontname_as_pattern = 1; - - fs = track->PlayResY * text_font_scale_factor / 100.; - // approximate autoscale coefficients - if (subtitle_autoscale == 2) - fs *= 1.3; - else if (subtitle_autoscale == 3) - fs *= 1.4; - style->FontSize = fs; - - if (ass_color) c1 = strtoll(ass_color, NULL, 16); - else c1 = 0xFFFF0000; - if (ass_border_color) c2 = strtoll(ass_border_color, NULL, 16); - else c2 = 0x00000000; - - style->PrimaryColour = c1; - style->SecondaryColour = c1; - style->OutlineColour = c2; - style->BackColour = 0x00000000; - style->BorderStyle = 1; - style->Alignment = 2; - style->Outline = 2; - style->MarginL = 10; - style->MarginR = 10; - style->MarginV = 5; - style->ScaleX = 1.; - style->ScaleY = 1.; - } - - process_force_style(track); - return track; -} - -static int check_duplicate_plaintext_event(ass_track_t* track) -{ - int i; - ass_event_t* evt = track->events + track->n_events - 1; - - for (i = 0; in_events - 1; ++i) // ignoring last event, it is the one we are comparing with - if (track->events[i].Start == evt->Start && - track->events[i].Duration == evt->Duration && - strcmp(track->events[i].Text, evt->Text) == 0) - return 1; - return 0; -} - -/** - * \brief Convert subtitle to ass_event_t for the given track - * \param ass_track_t track - * \param sub subtitle to convert - * \return event id - * note: assumes that subtitle is _not_ fps-based; caller must manually correct - * Start and Duration in other case. - **/ -int ass_process_subtitle(ass_track_t* track, subtitle* sub) -{ - int eid; - ass_event_t* event; - int len = 0, j; - char* p; - char* end; - - eid = ass_alloc_event(track); - event = track->events + eid; - - event->Start = sub->start * 10; - event->Duration = (sub->end - sub->start) * 10; - event->Style = 0; - - for (j = 0; j < sub->lines; ++j) - len += sub->text[j] ? strlen(sub->text[j]) : 0; - - len += 2 * sub->lines; // '\N', including the one after the last line - len += 6; // {\anX} - len += 1; // '\0' - - event->Text = malloc(len); - end = event->Text + len; - p = event->Text; - - if (sub->alignment) - p += snprintf(p, end - p, "{\\an%d}", sub->alignment); - - for (j = 0; j < sub->lines; ++j) - p += snprintf(p, end - p, "%s\\N", sub->text[j]); - - if (sub->lines > 0) p-=2; // remove last "\N" - *p = 0; - - if (check_duplicate_plaintext_event(track)) { - ass_free_event(track, eid); - track->n_events--; - return -1; - } - - mp_msg(MSGT_ASS, MSGL_V, "plaintext event at %" PRId64 ", +%" PRId64 ": %s \n", - (int64_t)event->Start, (int64_t)event->Duration, event->Text); - - return eid; -} - - -/** - * \brief Convert subdata to ass_track - * \param subdata subtitles struct from subreader - * \param fps video framerate - * \return newly allocated ass_track, filled with subtitles from subdata - */ -ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps) { - ass_track_t* track; - int i; - - track = ass_default_track(library); - track->name = subdata->filename ? strdup(subdata->filename) : 0; - - for (i = 0; i < subdata->sub_num; ++i) { - int eid = ass_process_subtitle(track, subdata->subtitles + i); - if (eid < 0) - continue; - if (!subdata->sub_uses_time) { - track->events[eid].Start *= 100. / fps; - track->events[eid].Duration *= 100. / fps; - } - } - return track; -} - -void ass_configure(ass_renderer_t* priv, int w, int h, int unscaled) { - int hinting; - ass_set_frame_size(priv, w, h); - ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0); - ass_set_use_margins(priv, ass_use_margins); - ass_set_font_scale(priv, ass_font_scale); - if (!unscaled && (ass_hinting & 4)) - hinting = 0; - else - hinting = ass_hinting & 3; - ass_set_hinting(priv, hinting); - ass_set_line_spacing(priv, ass_line_spacing); -} - -void ass_configure_fonts(ass_renderer_t* priv) { - char *dir, *path, *family; - dir = get_path("fonts"); - if (font_fontconfig < 0 && sub_font_name) path = strdup(sub_font_name); - else if (font_fontconfig < 0 && font_name) path = strdup(font_name); - else path = get_path("subfont.ttf"); - if (font_fontconfig >= 0 && sub_font_name) family = strdup(sub_font_name); - else if (font_fontconfig >= 0 && font_name) family = strdup(font_name); - else family = 0; - - if (font_fontconfig >= 0) - ass_set_fonts(priv, path, family); - else - ass_set_fonts_nofc(priv, path, family); - - free(dir); - free(path); - free(family); -} - -ass_library_t* ass_init(void) { - ass_library_t* priv; - char* path = get_path("fonts"); - priv = ass_library_init(); - ass_set_fonts_dir(priv, path); - ass_set_extract_fonts(priv, extract_embedded_fonts); - ass_set_style_overrides(priv, ass_force_style_list); - free(path); - return priv; -} - -int ass_force_reload = 0; // flag set if global ass-related settings were changed - -ass_image_t* ass_mp_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change) { - if (ass_force_reload) { - ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0); - ass_set_use_margins(priv, ass_use_margins); - ass_set_font_scale(priv, ass_font_scale); - ass_force_reload = 0; - } - return ass_render_frame(priv, track, now, detect_change); -} diff --git a/libass/ass_mp.h b/libass/ass_mp.h deleted file mode 100644 index 64b411a..0000000 --- a/libass/ass_mp.h +++ /dev/null @@ -1,60 +0,0 @@ -// -*- c-basic-offset: 8; indent-tabs-mode: t -*- -// vim:ts=8:sw=8:noet:ai: -/* - * Copyright (C) 2006 Evgeniy Stepanov - * - * This file is part of libass. - * - * libass is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * libass is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with libass; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef LIBASS_MP_H -#define LIBASS_MP_H - -#include "subreader.h" -#include "ass_types.h" -#include "ass.h" - -extern ass_library_t* ass_library; -extern int ass_enabled; -extern float ass_font_scale; -extern float ass_line_spacing; -extern int ass_top_margin; -extern int ass_bottom_margin; -extern int extract_embedded_fonts; -extern char **ass_force_style_list; -extern int ass_use_margins; -extern char* ass_color; -extern char* ass_border_color; -extern char* ass_styles_file; -extern int ass_hinting; - -ass_track_t* ass_default_track(ass_library_t* library); -int ass_process_subtitle(ass_track_t* track, subtitle* sub); -ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps); - -void ass_configure(ass_renderer_t* priv, int w, int h, int hinting); -void ass_configure_fonts(ass_renderer_t* priv); -ass_library_t* ass_init(void); - -typedef struct { - ass_image_t* imgs; - int changed; -} mp_eosd_images_t; - -extern int ass_force_reload; -ass_image_t* ass_mp_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change); - -#endif /* LIBASS_MP_H */ diff --git a/libass/help_mp.h b/libass/help_mp.h new file mode 100644 index 0000000..d926ffc --- /dev/null +++ b/libass/help_mp.h @@ -0,0 +1,56 @@ +#ifndef __LIBASS_HELP_MP_H__ +#define __LIBASS_HELP_MP_H__ +#define MSGTR_LIBASS_FT_Glyph_To_BitmapError "[ass] FT_Glyph_To_Bitmap error %d \n" +#define MSGTR_LIBASS_UnsupportedPixelMode "[ass] Unsupported pixel mode: %d\n" +#define MSGTR_LIBASS_GlyphBBoxTooLarge "[ass] Glyph bounding box too large: %dx%dpx\n" +#define MSGTR_LIBASS_NoStyleNamedXFoundUsingY "[ass] [%p] Warning: no style named '%s' found, using '%s'\n" +#define MSGTR_LIBASS_BadTimestamp "[ass] bad timestamp\n" +#define MSGTR_LIBASS_BadEncodedDataSize "[ass] bad encoded data size\n" +#define MSGTR_LIBASS_FontLineTooLong "[ass] Font line too long: %d, %s\n" +#define MSGTR_LIBASS_EventFormatHeaderMissing "[ass] Event format header missing\n" +#define MSGTR_LIBASS_ErrorOpeningIconvDescriptor "[ass] error opening iconv descriptor.\n" +#define MSGTR_LIBASS_ErrorRecodingFile "[ass] error recoding file.\n" +#define MSGTR_LIBASS_FopenFailed "[ass] ass_read_file(%s): fopen failed\n" +#define MSGTR_LIBASS_FseekFailed "[ass] ass_read_file(%s): fseek failed\n" +#define MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan10M "[ass] ass_read_file(%s): Refusing to load subtitles larger than 10M\n" +#define MSGTR_LIBASS_ReadFailed "Read failed, %d: %s\n" +#define MSGTR_LIBASS_AddedSubtitleFileMemory "[ass] Added subtitle file: (%d styles, %d events)\n" +#define MSGTR_LIBASS_AddedSubtitleFileFname "[ass] Added subtitle file: %s (%d styles, %d events)\n" +#define MSGTR_LIBASS_FailedToCreateDirectory "[ass] Failed to create directory %s\n" +#define MSGTR_LIBASS_NotADirectory "[ass] Not a directory: %s\n" +#define MSGTR_LIBASS_TooManyFonts "[ass] Too many fonts\n" +#define MSGTR_LIBASS_ErrorOpeningFont "[ass] Error opening font: %s, %d\n" +#define MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne "[ass] fontconfig: Selected font is not the requested one: '%s' != '%s'\n" +#define MSGTR_LIBASS_UsingDefaultFontFamily "[ass] fontconfig_select: Using default font family: (%s, %d, %d) -> %s, %d\n" +#define MSGTR_LIBASS_UsingDefaultFont "[ass] fontconfig_select: Using default font: (%s, %d, %d) -> %s, %d\n" +#define MSGTR_LIBASS_UsingArialFontFamily "[ass] fontconfig_select: Using 'Arial' font family: (%s, %d, %d) -> %s, %d\n" +#define MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed "[ass] FcInitLoadConfigAndFonts failed.\n" +#define MSGTR_LIBASS_UpdatingFontCache "[ass] Updating font cache.\n" +#define MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported "[ass] Beta versions of fontconfig are not supported.\n[ass] Update before reporting any bugs.\n" +#define MSGTR_LIBASS_FcStrSetAddFailed "[ass] FcStrSetAdd failed.\n" +#define MSGTR_LIBASS_FcDirScanFailed "[ass] FcDirScan failed.\n" +#define MSGTR_LIBASS_FcDirSave "[ass] FcDirSave failed.\n" +#define MSGTR_LIBASS_FcConfigAppFontAddDirFailed "[ass] FcConfigAppFontAddDir failed\n" +#define MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed "[ass] Fontconfig disabled, only default font will be used.\n" +#define MSGTR_LIBASS_FunctionCallFailed "[ass] %s failed\n" +#define MSGTR_LIBASS_NeitherPlayResXNorPlayResYDefined "[ass] Neither PlayResX nor PlayResY defined. Assuming 384x288.\n" +#define MSGTR_LIBASS_PlayResYUndefinedSettingY "[ass] PlayResY undefined, setting %d.\n" +#define MSGTR_LIBASS_PlayResXUndefinedSettingX "[ass] PlayResX undefined, setting %d.\n" +#define MSGTR_LIBASS_FT_Init_FreeTypeFailed "[ass] FT_Init_FreeType failed.\n" +#define MSGTR_LIBASS_Init "[ass] Init\n" +#define MSGTR_LIBASS_InitFailed "[ass] Init failed.\n" +#define MSGTR_LIBASS_BadCommand "[ass] Bad command: %c%c\n" +#define MSGTR_LIBASS_ErrorLoadingGlyph "[ass] Error loading glyph.\n" +#define MSGTR_LIBASS_FT_Glyph_Stroke_Error "[ass] FT_Glyph_Stroke error %d \n" +#define MSGTR_LIBASS_UnknownEffectType_InternalError "[ass] Unknown effect type (internal error)\n" +#define MSGTR_LIBASS_NoStyleFound "[ass] No style found!\n" +#define MSGTR_LIBASS_EmptyEvent "[ass] Empty event!\n" +#define MSGTR_LIBASS_MAX_GLYPHS_Reached "[ass] MAX_GLYPHS reached: event %d, start = %llu, duration = %llu\n Text = %s\n" +#define MSGTR_LIBASS_EventHeightHasChanged "[ass] Warning! Event height has changed! \n" +#define MSGTR_LIBASS_GlyphNotFoundReselectingFont "[ass] Glyph 0x%X not found, selecting one more font for (%s, %d, %d)\n" +#define MSGTR_LIBASS_GlyphNotFound "[ass] Glyph 0x%X not found in font for (%s, %d, %d)\n" +#define MSGTR_LIBASS_ErrorOpeningMemoryFont "[ass] Error opening memory font: %s\n" +#define MSGTR_LIBASS_NoCharmaps "[ass] font face with no charmaps\n" +#define MSGTR_LIBASS_NoCharmapAutodetected "[ass] no charmap autodetected, trying the first one\n" +#endif + diff --git a/libass/mputils.c b/libass/mputils.c new file mode 100644 index 0000000..9217e38 --- /dev/null +++ b/libass/mputils.c @@ -0,0 +1,218 @@ +#include "config.h" + +#include "mputils.h" + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ENCA +#include +#endif + +void my_mp_msg(int lvl, char *lvl_str, char *fmt, ...) { + va_list va; + if(lvl > MSGL_V) return; + printf("[ass] **%s**: ", lvl_str); + va_start(va, fmt); + vprintf(fmt, va); + va_end(va); +} + +unsigned utf8_get_char(char **str) { + 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; +} + +// gaussian blur +void blur( + unsigned char *buffer, + unsigned short *tmp2, + int width, + int height, + int stride, + int *m2, + int r, + int mwidth) { + + int x, y; + + unsigned char *s = buffer; + unsigned short *t = tmp2+1; + for(y=0; y>8; + unsigned *m3= m2 + src2*mwidth; + + int mx; + *srcp= 128; + for(mx=r-1; mx>8; + unsigned *m3= m2 + src2*mwidth; + + int mx; + *srcp= 128; + for(mx=0; mx>8; + unsigned *m3= m2 + src2*mwidth; + + int mx; + *srcp= 128; + for(mx=0; mx>8; + } + s+= stride; + t+= width + 1; + } +} + +#ifdef CONFIG_ENCA +void* guess_buffer_cp(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); + mp_msg(MSGT_ASS, MSGL_V, "ENCA supported languages: "); + for (i = 0; i < langcnt; i++) { + mp_msg(MSGT_ASS, MSGL_V, "%s ", languages[i]); + } + mp_msg(MSGT_ASS, MSGL_V, "\n"); + + 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); + mp_msg(MSGT_ASS, MSGL_INFO, "ENCA detected charset: %s\n", tmp); + } + enca_analyser_free(analyser); + } + + free(languages); + + if (!detected_sub_cp) { + detected_sub_cp = strdup(fallback); + mp_msg(MSGT_ASS, MSGL_INFO, "ENCA detection failed: fallback to %s\n", fallback); + } + + return detected_sub_cp; +} +#endif diff --git a/libass/mputils.h b/libass/mputils.h index cff2693..6f0e332 100644 --- a/libass/mputils.h +++ b/libass/mputils.h @@ -1,31 +1,35 @@ -/* - * Copyright (C) 2006 Evgeniy Stepanov - * - * This file is part of libass. - * - * libass is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * libass is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with libass; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef LIBASS_MPUTILS_H -#define LIBASS_MPUTILS_H - -#include "mp_msg.h" +#ifndef __MPUTILS_H__ +#define __MPUTILS_H__ + #include "help_mp.h" -#include "libvo/font_load.h" // for blur() -#include "subreader.h" // for guess_buffer_cp -#include "libvo/sub.h" // for utf8_get_char -#include "libavutil/common.h" -#endif /* LIBASS_MPUTILS_H */ +unsigned utf8_get_char(char **str); + +void my_mp_msg(int lvl, char *lvl_str, char *fmt, ...); + +#ifdef __VISUALC__ +static void mp_msg(int mod, int level, const char *fmt, ...) { + // MSVC doesn't like the # used all around for mp_msg, so it breaks va_arg +} +#else +#define mp_msg(mod, level, args...) my_mp_msg(level, #level, args) +#endif + +#define MSGT_ASS 43 + +#define MSGL_FATAL 0 +#define MSGL_ERR 1 +#define MSGL_WARN 2 +#define MSGL_INFO 4 +#define MSGL_V 6 +#define MSGL_DBG2 7 + +void blur(unsigned char *buffer, unsigned short *tmp2, int width, int height, + int stride, int *m2, int r, int mwidth); + +void* guess_buffer_cp(unsigned char* buffer, int buflen, char *preferred_language, char *fallback); + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + +#endif -- 2.40.0