Kill in-repo libass and ffms and clean up some old cruft in the configure script
Originally committed to SVN as r5480.
This commit is contained in:
parent
da3e7e4d88
commit
eea30df7db
66 changed files with 27 additions and 19409 deletions
|
@ -33,12 +33,6 @@ covered by another license in the file itself.
|
|||
The following directories and file are covered by their respective licenses as
|
||||
follows:
|
||||
|
||||
libass/
|
||||
- ISC license. See libass/COPYING.
|
||||
|
||||
libffms/
|
||||
- MIT license.
|
||||
|
||||
src/boost/
|
||||
- Boost Software License Version 1.0 see src/boost/LICENSE_1_0.txt.
|
||||
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
include Makefile.inc
|
||||
|
||||
ifeq (yes, $(WITH_LIBASS))
|
||||
SUBDIRS += libass
|
||||
endif
|
||||
|
||||
ifeq (yes, $(HAVE_PROVIDER_FFMPEGSOURCE))
|
||||
SUBDIRS += libffms
|
||||
endif
|
||||
|
||||
SUBDIRS += \
|
||||
universalchardet \
|
||||
libaegisub \
|
||||
|
|
|
@ -4,18 +4,15 @@
|
|||
HAVE_ALSA = @with_alsa@
|
||||
HAVE_AUTO4_LUA = @with_auto4_lua@
|
||||
HAVE_AUTOMATION = @with_automation@
|
||||
HAVE_FFMPEG = @agi_cv_with_ffmpeg@
|
||||
HAVE_HUNSPELL = @with_hunspell@
|
||||
HAVE_OPENAL = @with_openal@
|
||||
HAVE_OPENMP = @with_openmp@
|
||||
HAVE_OSS = @with_oss@
|
||||
HAVE_PORTAUDIO = @with_portaudio@
|
||||
HAVE_PROVIDER_FFMPEGSOURCE = @with_provider_ffmpegsource@
|
||||
HAVE_FFMS = @with_ffms@
|
||||
HAVE_PULSEAUDIO = @with_pulseaudio@
|
||||
WITH_EXTERNAL_LIBASS = @with_external_libass@
|
||||
WITH_LIBASS = @with_libass@
|
||||
HAVE_LIBASS = @with_libass@
|
||||
FOUND_AUDIO_PLAYER = @found_audio_player@
|
||||
FOUND_VIDEO_PROVIDER = @found_video_provider@
|
||||
|
||||
|
||||
###################
|
||||
|
@ -93,18 +90,12 @@ CPPFLAGS_WX = @WX_CPPFLAGS@
|
|||
CFLAGS_FONTCONFIG = @FONTCONFIG_CFLAGS@
|
||||
CFLAGS_FREETYPE = @FREETYPE_CFLAGS@
|
||||
CFLAGS_GL = @GL_CFLAGS@
|
||||
CFLAGS_FFMPEGSOURCE = -I../libffms/include
|
||||
CFLAGS_FFMS = @FFMS_CFLAGS@
|
||||
CFLAGS_HUNSPELL = @HUNSPELL_CFLAGS@
|
||||
CFLAGS_ICONV = @ICONV_CFLAGS@
|
||||
CFLAGS_LIBASS = -I../libass
|
||||
#CFLAGS_LIBASS = @LIBASS_CFLAGS@
|
||||
CFLAGS_LIBAVCODEC = @LIBAVCODEC_CFLAGS@
|
||||
CFLAGS_LIBAVFORMAT = @LIBAVFORMAT_CFLAGS@
|
||||
CFLAGS_LIBAVUTIL = @LIBAVUTIL_CFLAGS@
|
||||
CFLAGS_LIBASS = @LIBASS_CFLAGS@
|
||||
CFLAGS_LIBCURL = @LIBCURL_CFLAGS@
|
||||
CFLAGS_LIBPOSTPROC = @LIBPOSTPROC_CFLAGS@
|
||||
CFLAGS_LIBPULSE = @LIBPULSE_CFLAGS@
|
||||
CFLAGS_LIBSWSCALE = @LIBSWSCALE_CFLAGS@
|
||||
CFLAGS_LUA = @LUA_CFLAGS@
|
||||
CFLAGS_OPENAL = @OPENAL_CFLAGS@
|
||||
CFLAGS_PORTAUDIO = @PORTAUDIO_CFLAGS@
|
||||
|
@ -116,18 +107,12 @@ LDFLAGS_ALSA = @ALSA_LDFLAGS@
|
|||
LDFLAGS_FONTCONFIG = @FONTCONFIG_LIBS@
|
||||
LDFLAGS_FREETYPE = @FREETYPE_LIBS@
|
||||
LDFLAGS_GL = @GL_LIBS@
|
||||
LDFLAGS_FFMPEGSOURCE = ../libffms/libffmpegsource_aegisub.a
|
||||
LDFLAGS_FFMS = @FFMS_LIBS@
|
||||
LDFLAGS_HUNSPELL = @HUNSPELL_LIBS@
|
||||
LDFLAGS_ICONV = @ICONV_LDFLAGS@
|
||||
LDFLAGS_LIBASS = ../libass/libass_aegisub.a
|
||||
#LDFLAGS_LIBASS = @LIBASS_LIBS@
|
||||
LDFLAGS_LIBAVCODEC = @LIBAVCODEC_LIBS@
|
||||
LDFLAGS_LIBAVFORMAT = @LIBAVFORMAT_LIBS@
|
||||
LDFLAGS_LIBAVUTIL = @LIBAVUTIL_LIBS@
|
||||
LDFLAGS_LIBASS = @LIBASS_LIBS@
|
||||
LDFLAGS_LIBCURL = @LIBCURL_LIBS@
|
||||
LDFLAGS_LIBPOSTPROC = @LIBPOSTPROC_LIBS@
|
||||
LDFLAGS_LIBPULSE = @LIBPULSE_LIBS@
|
||||
LDFLAGS_LIBSWSCALE = @LIBSWSCALE_LIBS@
|
||||
LDFLAGS_LUA = @LUA_LDFLAGS@
|
||||
LDFLAGS_OPENAL = @OPENAL_LIBS@
|
||||
LDFLAGS_PTHREAD = @PTHREAD_LIBS@
|
||||
|
|
|
@ -121,7 +121,7 @@ $(SUBDIRS):
|
|||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
# Set relations to ensure dependencies are built before their targets during parallel builds.
|
||||
src: universalchardet libass libffms tools libaegisub
|
||||
src: universalchardet tools libaegisub
|
||||
tests: libaegisub
|
||||
reporter: src
|
||||
command: libresrc
|
||||
|
|
|
@ -16,12 +16,6 @@ m4_define([aegisub_version_data], [aegisub_version_major.aegisub_version_minor])
|
|||
###################
|
||||
# Required packages
|
||||
###################
|
||||
m4_define([libavcodec_required_version], [52.27.0]) # (r18642)
|
||||
m4_define([libavformat_required_version], [52.32.0]) # (r18642)
|
||||
m4_define([libavutil_required_version], [50.3.0]) # (r18642)
|
||||
m4_define([libpostproc_required_version], [51.2.0]) # (r18642)
|
||||
m4_define([libswscale_required_version], [0.7.1]) # (r18642)
|
||||
|
||||
m4_define([lua_auto4_required_version], [5.1])
|
||||
m4_define([portaudio_required_version], [19])
|
||||
m4_define([pulseaudio_required_version], [0.5])
|
||||
|
@ -31,6 +25,7 @@ m4_define([freetype_required_version], [9.7.0])
|
|||
m4_define([pkgconfig_required_version], [0.20])
|
||||
m4_define([wx_required_version], [2.9.0])
|
||||
m4_define([libass_required_version], [0.9.7])
|
||||
m4_define([ffms_required_version], [2.1.15])
|
||||
|
||||
|
||||
#######
|
||||
|
@ -681,154 +676,24 @@ AC_SUBST(with_oss)
|
|||
#########################
|
||||
# Video / Audio Providers
|
||||
#########################
|
||||
AC_ARG_WITH(ffms,[ --without-ffms build without ffms2 A/V provider. (default: auto)], ffms_disabled="(disabled)")
|
||||
|
||||
AC_ARG_WITH(ffmpeg, [ --without-ffmpeg build without FFMPEG support.
|
||||
Disables FFMPEG and FFmpegSource A/V providers.
|
||||
(default: auto)], [ffmpeg_disabled="(disabled)"; with_ffmpeg="no"])
|
||||
|
||||
if test "$with_ffmpeg" != "no"; then
|
||||
PKG_CHECK_MODULES(LIBAVCODEC, libavcodec >= libavcodec_required_version, [], [with_ffmpeg="no"])
|
||||
PKG_CHECK_MODULES(LIBAVFORMAT, libavformat >= libavformat_required_version, [], [with_ffmpeg="no"])
|
||||
PKG_CHECK_MODULES(LIBSWSCALE, libswscale >= libswscale_required_version, [], [with_ffmpeg="no"])
|
||||
PKG_CHECK_MODULES(LIBAVUTIL, libavutil >= libavutil_required_version, [], [with_ffmpeg="no"])
|
||||
if test "$with_ffms" != "no"; then
|
||||
PKG_CHECK_MODULES(FFMS, ffms2 >= ffms_required_version, [with_ffms="yes"], [with_ffms="no"])
|
||||
fi
|
||||
|
||||
if test "$with_ffmpeg" != "no" && test "$enable_old_ffmpeg" != "yes"; then
|
||||
AC_AGI_COMPILE([FFMPEG], [ffmpeg], [$LIBSWSCALE_CFLAGS $LIBAVCODEC_CFLAGS $LIBAVFORMAT_CFLAGS $LIBAVUTIL_CFLAGS], [$LIBSWSCALE_LIBS $LIBAVCODEC_LIBS $LIBAVFORMAT_LIBS $LIBAVUTIL_LIBS],[
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
AVFormatContext *fc = NULL;
|
||||
AVCodec *c = NULL;
|
||||
SwsContext *swsc = NULL;
|
||||
|
||||
av_register_all();
|
||||
fc = avformat_alloc_context();
|
||||
if (fc == NULL) {
|
||||
printf("avformat failure\n");
|
||||
return 1;
|
||||
}
|
||||
av_free(fc);
|
||||
|
||||
avcodec_init();
|
||||
avcodec_register_all();
|
||||
c = avcodec_find_decoder(CODEC_ID_PCM_S16LE);
|
||||
if (c == NULL) {
|
||||
printf("avcodec failure\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
swsc = sws_getContext(704, 480, PIX_FMT_RGB32, 704, 480, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
|
||||
if (swsc == NULL) {
|
||||
printf("swscale failure\n");
|
||||
return 1;
|
||||
}
|
||||
sws_freeContext(swsc);
|
||||
|
||||
return 0;
|
||||
} ])
|
||||
fi
|
||||
|
||||
if test "$agi_cv_with_ffmpeg" = "no" && test "$with_ffmpeg" != "no"; then
|
||||
AC_MSG_WARN([FFMPEG detected, but it doesn't work...])
|
||||
with_ffmpeg="no"
|
||||
fi
|
||||
|
||||
if test "$agi_cv_with_ffmpeg" = "yes" && test "$with_ffmpeg" != "no"; then
|
||||
with_ffmpeg="yes"
|
||||
fi
|
||||
|
||||
if test "$agi_cv_with_ffmpeg" = "no" || test "$with_ffmpeg" = "no"; then
|
||||
ffmpegsource_provider_disabled="(disabled, requires FFMPEG)"
|
||||
ffmpeg_provider_disabled="(disabled, requires FFMPEG)"
|
||||
with_ffmpeg="no"
|
||||
fi
|
||||
|
||||
AC_SUBST(agi_cv_with_ffmpeg)
|
||||
AC_SUBST(LIBAVFORMAT_LIBS)
|
||||
AC_SUBST(LIBAVFORMAT_CFLAGS)
|
||||
AC_SUBST(LIBAVCODEC_LIBS)
|
||||
AC_SUBST(LIBAVCODEC_CFLAGS)
|
||||
AC_SUBST(LIBSWSCALE_LIBS)
|
||||
AC_SUBST(LIBSWSCALE_CFLAGS)
|
||||
AC_SUBST(LIBAVUTIL_LIBS)
|
||||
AC_SUBST(LIBAVUTIL_CFLAGS)
|
||||
|
||||
AC_ARG_WITH(provider-ffmpegsource, [ --without-provider-ffmpegsource
|
||||
build without FFmpegSource A/V provider.
|
||||
(default: auto)], ffmpegsource_provider_disabled="(disabled)", with_provider_ffmpegsource="yes")
|
||||
|
||||
if test "$agi_cv_with_ffmpeg" = "yes" && test "$with_provider_ffmpegsource" = "yes"; then
|
||||
PKG_CHECK_MODULES(LIBPOSTPROC, libpostproc >= libpostproc_required_version, [], [with_libpostproc="no"])
|
||||
|
||||
AC_AGI_COMPILE([postproc], [postproc], [$LIBPOSTPROC_CFLAGS], [$LIBPOSTPROC_LIBS],[
|
||||
extern "C" {
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#include <libpostproc/postprocess.h>
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
pp_context_t *PPContext = pp_get_context(704,480, 0);
|
||||
|
||||
if (!PPContext) return 1;
|
||||
pp_free_context(PPContext);
|
||||
return 0;
|
||||
} ])
|
||||
|
||||
if test "$agi_cv_with_postproc" = "yes"; then
|
||||
found_video_provider="yes"
|
||||
AC_DEFINE(WITH_FFMPEGSOURCE, 1, [Enable FFmpegSource2 Video Provider])
|
||||
else
|
||||
with_provider_ffmpegsource="no"
|
||||
fi
|
||||
else
|
||||
with_provider_ffmpegsource="no"
|
||||
fi
|
||||
|
||||
AC_SUBST(with_provider_ffmpegsource)
|
||||
AC_SUBST(LIBPOSTPROC_LIBS)
|
||||
AC_SUBST(LIBPOSTPROC_CFLAGS)
|
||||
|
||||
AC_SUBST(with_ffms)
|
||||
|
||||
###################
|
||||
# Subtitle Provider
|
||||
###################
|
||||
AC_ARG_WITH(libass,[ --without-libass build without libass support (default: auto)], libass_disabled="(disabled)")
|
||||
|
||||
AC_ARG_ENABLE(libass, [ --disable-libass disable libass support (default=enabled)], libass_disabled="(disabled)")
|
||||
AC_ARG_WITH(external-libass, [ --with-external-libass link to external libass (default=use internal)])
|
||||
|
||||
if test "$enable_libass" != "no"; then
|
||||
if test "$with_external_libass" != "yes"; then
|
||||
with_external_libass="no"
|
||||
|
||||
if test "$agi_cv_with_iconv" = "yes"; then
|
||||
LIBASS_LIBS="-L../libass -lass_aegisub"
|
||||
LIBASS_CFLAGS="-I../libass"
|
||||
with_libass="yes"
|
||||
else
|
||||
AC_MSG_WARN([libiconv is required for libass support.])
|
||||
with_libass="no"
|
||||
fi
|
||||
else
|
||||
PKG_CHECK_MODULES(LIBASS, libass >= libass_required_version, [with_libass="yes"], [with_libass="no"])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$with_libass" = "yes" || test "$enable_libass" != "no"; then
|
||||
AC_DEFINE(WITH_LIBASS, 1, [Enable libass Subtitle Provider])
|
||||
else
|
||||
with_libass="no"
|
||||
if test "$with_libass" != "no"; then
|
||||
PKG_CHECK_MODULES(LIBASS, libass >= libass_required_version, [with_libass="yes"], [with_libass="no"])
|
||||
fi
|
||||
|
||||
AC_SUBST(with_libass)
|
||||
AC_SUBST(with_external_libass)
|
||||
AC_SUBST(LIBASS_LIBS)
|
||||
AC_SUBST(LIBASS_CFLAGS)
|
||||
|
||||
|
||||
###########
|
||||
|
@ -841,10 +706,7 @@ if test "$with_hunspell" != "no"; then
|
|||
AC_AGI_COMPILE([Hunspell], [hunspell], [$HUNSPELL_CFLAGS], [$HUNSPELL_LIBS],[
|
||||
#include <hunspell.hxx>
|
||||
int main(void) {
|
||||
Hunspell *hunspell;
|
||||
hunspell = new Hunspell(".", ".");
|
||||
if (!hunspell) return 1;
|
||||
return 0;
|
||||
return !(new Hunspell(".", "."));
|
||||
} ])
|
||||
fi
|
||||
|
||||
|
@ -1163,44 +1025,10 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
|||
# it above.
|
||||
####################################################################
|
||||
|
||||
AC_ARG_WITH(provider-video, [ --with-provider-video=(ffmpegsource)
|
||||
Default Video Provider. (default: ffmpegsource)])
|
||||
AC_ARG_WITH(provider-audio, [ --with-provider-audio=(ffmpegsource)
|
||||
Default Audio Provider. (default: ffmpegsource)])
|
||||
AC_ARG_WITH(player-audio, [ --with-player-audio=(alsa|openal|portaudio|pulseaudio)
|
||||
Default Audio Player (default: Linux/ALSA,
|
||||
Darwin/OpenAL, 1:*/OSS, 2:*/PortAudio.])
|
||||
|
||||
# Default Video Provider.
|
||||
if ! test -z "$with_provider_video"; then
|
||||
default_provider_video="$with_provider_video"
|
||||
else
|
||||
if test "$with_provider_ffmpegsource" = "yes"; then
|
||||
default_provider_video="ffmpegsource"
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_PROVIDER_VIDEO], ["$default_provider_video"], [Default Video Provider.])
|
||||
|
||||
# Default Audio Provider.
|
||||
if ! test -z "$with_provider_audio"; then
|
||||
default_provider_audio="$with_provider_audio"
|
||||
else
|
||||
if test "$with_provider_ffmpegsource" = "yes"; then
|
||||
default_provider_audio="ffmpegsource"
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_PROVIDER_AUDIO], ["$default_provider_audio"], [Default Video Provider.])
|
||||
|
||||
# Default Subtitle Provider.
|
||||
if ! test -z "$with_provider_subtitle"; then
|
||||
default_provider_subtitle="$with_provider_subtitle"
|
||||
else
|
||||
if test "$with_libass" = "yes"; then
|
||||
default_provider_subtitle="libass"
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_PROVIDER_SUBTITLE], ["$default_provider_subtitle"], [Default Subtitle Provider.])
|
||||
|
||||
# Default audio player.
|
||||
if ! test -z "$with_player_audio"; then
|
||||
default_player_audio="$with_player_audio"
|
||||
|
@ -1221,31 +1049,15 @@ AC_DEFINE_UNQUOTED([DEFAULT_PLAYER_AUDIO], ["$default_player_audio"], [Default a
|
|||
|
||||
|
||||
# Set some friendly strings if some of the above aren't detected.
|
||||
if test -z "$default_provider_video"; then
|
||||
default_provider_video="NONE (requires ffmpeg)"
|
||||
fi
|
||||
|
||||
if test -z "$default_provider_audio"; then
|
||||
default_provider_audio="NONE (requires ffmpeg)"
|
||||
fi
|
||||
|
||||
if test -z "$default_provider_subtitle"; then
|
||||
default_provider_subtitle="NONE"
|
||||
fi
|
||||
|
||||
if test -z "$default_player_audio"; then
|
||||
default_player_audio="NONE"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
###############
|
||||
# Misc settings
|
||||
###############
|
||||
AC_SUBST(found_audio_player)
|
||||
AC_SUBST(found_audio_provider)
|
||||
AC_SUBST(found_video_provider)
|
||||
|
||||
# Files that need substitution.
|
||||
AC_CONFIG_FILES([
|
||||
|
@ -1273,7 +1085,7 @@ if test -z "$found_audio_player"; then
|
|||
])
|
||||
fi
|
||||
|
||||
if test -z "$found_video_provider"; then
|
||||
if test "$with_ffms" != "yes"; then
|
||||
AC_MSG_NOTICE([
|
||||
|
||||
***********************************************************************
|
||||
|
@ -1284,8 +1096,8 @@ if test -z "$found_video_provider"; then
|
|||
* virtual video clip with subtitles overlaid.
|
||||
* Currently we only support one video/audio provider on non-Windows
|
||||
* systems:
|
||||
* - FFmpeg (libavcodec + libavformat)
|
||||
* * http://ffmpeg.mplayerhq.hu/
|
||||
* - FFMS2
|
||||
* * http://code.google.com/p/ffmpegsource/
|
||||
***********************************************************************
|
||||
])
|
||||
fi
|
||||
|
@ -1300,9 +1112,6 @@ Configure settings
|
|||
LDFLAGS $LDFLAGS
|
||||
|
||||
Default Settings
|
||||
Video Provider: $default_provider_video
|
||||
Audio Provider: $default_provider_audio
|
||||
Subtitle Provider: $default_provider_subtitle
|
||||
Audio Player: $default_player_audio
|
||||
|
||||
Scripting Engines
|
||||
|
@ -1315,16 +1124,11 @@ Audio Players
|
|||
PortAudio: $with_portaudio $portaudio_disabled
|
||||
PulseAudio: $with_pulseaudio $pulseaudio_disabled
|
||||
|
||||
A/V Support
|
||||
FFMPEG: $with_ffmpeg $ffmpeg_disabled
|
||||
(required for video providers)
|
||||
|
||||
A/V Providers
|
||||
FFmpegSource: $with_provider_ffmpegsource $ffmpegsource_provider_disabled
|
||||
FFMS2: $with_ffms $ffms_disabled
|
||||
|
||||
Subtitle Providers:
|
||||
libASS $with_libass $libass_disabled $libass_default
|
||||
(both require iconv and fontconfig)
|
||||
libass $with_libass $libass_disabled
|
||||
|
||||
Misc Packages
|
||||
Hunspell: $with_hunspell $with_hunspell_version $hunspell_disabled
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@ -1,24 +0,0 @@
|
|||
include ../Makefile.inc
|
||||
|
||||
CXXFLAGS += -DCONFIG_ICONV -DCONFIG_FONTCONFIG $(CFLAGS_FREETYPE) $(CFLAGS_ICONV) $(CFLAGS_FONTCONFIG)
|
||||
|
||||
LIB = libass_aegisub.a
|
||||
|
||||
SRC = \
|
||||
ass.c \
|
||||
ass_bitmap.c \
|
||||
ass_cache.c \
|
||||
ass_drawing.c \
|
||||
ass_font.c \
|
||||
ass_fontconfig.c \
|
||||
ass_library.c \
|
||||
ass_parse.c \
|
||||
ass_render.c \
|
||||
ass_render_api.c \
|
||||
ass_strtod.c \
|
||||
ass_utils.c
|
||||
|
||||
HEADER = *.h
|
||||
|
||||
include ../Makefile.target
|
||||
-include *.d
|
1238
aegisub/libass/ass.c
1238
aegisub/libass/ass.c
File diff suppressed because it is too large
Load diff
|
@ -1,383 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
|
||||
*
|
||||
* This file is part of libass.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBASS_ASS_H
|
||||
#define LIBASS_ASS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "ass_types.h"
|
||||
|
||||
#define LIBASS_VERSION 0x00911000
|
||||
|
||||
/*
|
||||
* A linked list of images produced by an ass renderer.
|
||||
*
|
||||
* These images have to be rendered in-order for the correct screen
|
||||
* composition. The libass renderer clips these bitmaps to the frame size.
|
||||
* w/h can be zero, in this case the bitmap should not be rendered at all.
|
||||
* The last bitmap row is not guaranteed to be padded up to stride size,
|
||||
* e.g. in the worst case a bitmap has the size stride * (h - 1) + w.
|
||||
*/
|
||||
typedef struct ass_image {
|
||||
int w, h; // Bitmap width/height
|
||||
int stride; // Bitmap stride
|
||||
unsigned char *bitmap; // 1bpp stride*h alpha buffer
|
||||
// Note: the last row may not be padded to
|
||||
// bitmap stride!
|
||||
uint32_t color; // Bitmap color and alpha, RGBA
|
||||
int dst_x, dst_y; // Bitmap placement inside the video frame
|
||||
|
||||
struct ass_image *next; // Next image, or NULL
|
||||
} ASS_Image;
|
||||
|
||||
/*
|
||||
* Hinting type. (see ass_set_hinting below)
|
||||
*
|
||||
* FreeType's native hinter is still buggy sometimes and it is recommended
|
||||
* to use the light autohinter, ASS_HINTING_LIGHT, instead. For best
|
||||
* compatibility with problematic fonts, disable hinting.
|
||||
*/
|
||||
typedef enum {
|
||||
ASS_HINTING_NONE = 0,
|
||||
ASS_HINTING_LIGHT,
|
||||
ASS_HINTING_NORMAL,
|
||||
ASS_HINTING_NATIVE
|
||||
} ASS_Hinting;
|
||||
|
||||
/**
|
||||
* \brief Initialize the library.
|
||||
* \return library handle or NULL if failed
|
||||
*/
|
||||
ASS_Library *ass_library_init(void);
|
||||
|
||||
/**
|
||||
* \brief Finalize the library
|
||||
* \param priv library handle
|
||||
*/
|
||||
void ass_library_done(ASS_Library *priv);
|
||||
|
||||
/**
|
||||
* \brief Set additional fonts directory.
|
||||
* Optional directory that will be scanned for fonts recursively. The fonts
|
||||
* found are used for font lookup.
|
||||
* NOTE: A valid font directory is not needed to support embedded fonts.
|
||||
*
|
||||
* \param priv library handle
|
||||
* \param fonts_dir directory with additional fonts
|
||||
*/
|
||||
void ass_set_fonts_dir(ASS_Library *priv, const char *fonts_dir);
|
||||
|
||||
/**
|
||||
* \brief Whether fonts should be extracted from track data.
|
||||
* \param priv library handle
|
||||
* \param extract whether to extract fonts
|
||||
*/
|
||||
void ass_set_extract_fonts(ASS_Library *priv, int extract);
|
||||
|
||||
/**
|
||||
* \brief Register style overrides with a library instance.
|
||||
* The overrides should have the form [Style.]Param=Value, e.g.
|
||||
* SomeStyle.Font=Arial
|
||||
* ScaledBorderAndShadow=yes
|
||||
*
|
||||
* \param priv library handle
|
||||
* \param list NULL-terminated list of strings
|
||||
*/
|
||||
void ass_set_style_overrides(ASS_Library *priv, char **list);
|
||||
|
||||
/**
|
||||
* \brief Explicitly process style overrides for a track.
|
||||
* \param track track handle
|
||||
*/
|
||||
void ass_process_force_style(ASS_Track *track);
|
||||
|
||||
/**
|
||||
* \brief Register a callback for debug/info messages.
|
||||
* If a callback is registered, it is called for every message emitted by
|
||||
* libass. The callback receives a format string and a list of arguments,
|
||||
* to be used for the printf family of functions. Additionally, a log level
|
||||
* from 0 (FATAL errors) to 7 (verbose DEBUG) is passed. Usually, level 5
|
||||
* should be used by applications.
|
||||
* If no callback is set, all messages level < 5 are printed to stderr,
|
||||
* prefixed with [ass].
|
||||
*
|
||||
* \param priv library handle
|
||||
* \param msg_cb pointer to callback function
|
||||
* \param data additional data, will be passed to callback
|
||||
*/
|
||||
void ass_set_message_cb(ASS_Library *priv, void (*msg_cb)
|
||||
(int level, const char *fmt, va_list args, void *data),
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* \brief Initialize the renderer.
|
||||
* \param priv library handle
|
||||
* \return renderer handle or NULL if failed
|
||||
*/
|
||||
ASS_Renderer *ass_renderer_init(ASS_Library *);
|
||||
|
||||
/**
|
||||
* \brief Finalize the renderer.
|
||||
* \param priv renderer handle
|
||||
*/
|
||||
void ass_renderer_done(ASS_Renderer *priv);
|
||||
|
||||
/**
|
||||
* \brief Set the frame size in pixels, including margins.
|
||||
* \param priv renderer handle
|
||||
* \param w width
|
||||
* \param h height
|
||||
*/
|
||||
void ass_set_frame_size(ASS_Renderer *priv, int w, int h);
|
||||
|
||||
/**
|
||||
* \brief Set frame margins. These values may be negative if pan-and-scan
|
||||
* is used.
|
||||
* \param priv renderer handle
|
||||
* \param t top margin
|
||||
* \param b bottom margin
|
||||
* \param l left margin
|
||||
* \param r right margin
|
||||
*/
|
||||
void ass_set_margins(ASS_Renderer *priv, int t, int b, int l, int r);
|
||||
|
||||
/**
|
||||
* \brief Whether margins should be used for placing regular events.
|
||||
* \param priv renderer handle
|
||||
* \param use whether to use the margins
|
||||
*/
|
||||
void ass_set_use_margins(ASS_Renderer *priv, int use);
|
||||
|
||||
/**
|
||||
* \brief Set aspect ratio parameters.
|
||||
* \param priv renderer handle
|
||||
* \param dar display aspect ratio (DAR), prescaled for output PAR
|
||||
* \param sar storage aspect ratio (SAR)
|
||||
*/
|
||||
void ass_set_aspect_ratio(ASS_Renderer *priv, double dar, double sar);
|
||||
|
||||
/**
|
||||
* \brief Set a fixed font scaling factor.
|
||||
* \param priv renderer handle
|
||||
* \param font_scale scaling factor, default is 1.0
|
||||
*/
|
||||
void ass_set_font_scale(ASS_Renderer *priv, double font_scale);
|
||||
|
||||
/**
|
||||
* \brief Set font hinting method.
|
||||
* \param priv renderer handle
|
||||
* \param ht hinting method
|
||||
*/
|
||||
void ass_set_hinting(ASS_Renderer *priv, ASS_Hinting ht);
|
||||
|
||||
/**
|
||||
* \brief Set line spacing. Will not be scaled with frame size.
|
||||
* \param priv renderer handle
|
||||
* \param line_spacing line spacing in pixels
|
||||
*/
|
||||
void ass_set_line_spacing(ASS_Renderer *priv, double line_spacing);
|
||||
|
||||
/**
|
||||
* \brief Set font lookup defaults.
|
||||
* \param default_font path to default font to use. Must be supplied if
|
||||
* fontconfig is disabled or unavailable.
|
||||
* \param default_family fallback font family for fontconfig, or NULL
|
||||
* \param fc whether to use fontconfig
|
||||
* \param config path to fontconfig configuration file, or NULL. Only relevant
|
||||
* if fontconfig is used.
|
||||
* \param update whether fontconfig cache should be built/updated now. Only
|
||||
* relevant if fontconfig is used.
|
||||
*
|
||||
* NOTE: font lookup must be configured before an ASS_Renderer can be used.
|
||||
*/
|
||||
void ass_set_fonts(ASS_Renderer *priv, const char *default_font,
|
||||
const char *default_family, int fc, const char *config,
|
||||
int update);
|
||||
|
||||
/**
|
||||
* \brief Update/build font cache. This needs to be called if it was
|
||||
* disabled when ass_set_fonts was set.
|
||||
*
|
||||
* \param priv renderer handle
|
||||
* \return success
|
||||
*/
|
||||
int ass_fonts_update(ASS_Renderer *priv);
|
||||
|
||||
/**
|
||||
* \brief Set hard cache limits. Do not set, or set to zero, for reasonable
|
||||
* defaults.
|
||||
*
|
||||
* \param priv renderer handle
|
||||
* \param glyph_max maximum number of cached glyphs
|
||||
* \param bitmap_max_size maximum bitmap cache size (in MB)
|
||||
*/
|
||||
void ass_set_cache_limits(ASS_Renderer *priv, int glyph_max,
|
||||
int bitmap_max_size);
|
||||
|
||||
/**
|
||||
* \brief Render a frame, producing a list of ASS_Image.
|
||||
* \param priv renderer handle
|
||||
* \param track subtitle track
|
||||
* \param now video timestamp in milliseconds
|
||||
* \param detect_change will be set to 1 if a change occured compared
|
||||
* to the last invocation
|
||||
*/
|
||||
ASS_Image *ass_render_frame(ASS_Renderer *priv, ASS_Track *track,
|
||||
long long now, int *detect_change);
|
||||
|
||||
|
||||
/*
|
||||
* The following functions operate on track objects and do not need
|
||||
* an ass_renderer
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Allocate a new empty track object.
|
||||
* \param library handle
|
||||
* \return pointer to empty track
|
||||
*/
|
||||
ASS_Track *ass_new_track(ASS_Library *);
|
||||
|
||||
/**
|
||||
* \brief Deallocate track and all its child objects (styles and events).
|
||||
* \param track track to deallocate
|
||||
*/
|
||||
void ass_free_track(ASS_Track *track);
|
||||
|
||||
/**
|
||||
* \brief Allocate new style.
|
||||
* \param track track
|
||||
* \return newly allocated style id
|
||||
*/
|
||||
int ass_alloc_style(ASS_Track *track);
|
||||
|
||||
/**
|
||||
* \brief Allocate new event.
|
||||
* \param track track
|
||||
* \return newly allocated event id
|
||||
*/
|
||||
int ass_alloc_event(ASS_Track *track);
|
||||
|
||||
/**
|
||||
* \brief Delete a style.
|
||||
* \param track track
|
||||
* \param sid style id
|
||||
* Deallocates style data. Does not modify track->n_styles.
|
||||
*/
|
||||
void ass_free_style(ASS_Track *track, int sid);
|
||||
|
||||
/**
|
||||
* \brief Delete an event.
|
||||
* \param track track
|
||||
* \param eid event id
|
||||
* Deallocates event data. Does not modify track->n_events.
|
||||
*/
|
||||
void ass_free_event(ASS_Track *track, int eid);
|
||||
|
||||
/**
|
||||
* \brief Parse a chunk of subtitle stream data.
|
||||
* \param track track
|
||||
* \param data string to parse
|
||||
* \param size length of data
|
||||
*/
|
||||
void ass_process_data(ASS_Track *track, char *data, int size);
|
||||
|
||||
/**
|
||||
* \brief Parse Codec Private section of the subtitle stream, in Matroska
|
||||
* format. See the Matroska specification for details.
|
||||
* \param track target track
|
||||
* \param data string to parse
|
||||
* \param size length of data
|
||||
*/
|
||||
void ass_process_codec_private(ASS_Track *track, char *data, int size);
|
||||
|
||||
/**
|
||||
* \brief Parse a chunk of subtitle stream data. A chunk contains exactly one
|
||||
* event in Matroska format. See the Matroska specification for details.
|
||||
* \param track track
|
||||
* \param data string to parse
|
||||
* \param size length of data
|
||||
* \param timecode starting time of the event (milliseconds)
|
||||
* \param duration duration of the event (milliseconds)
|
||||
*/
|
||||
void ass_process_chunk(ASS_Track *track, char *data, int size,
|
||||
long long timecode, long long duration);
|
||||
|
||||
/**
|
||||
* \brief Flush buffered events.
|
||||
* \param track track
|
||||
*/
|
||||
void ass_flush_events(ASS_Track *track);
|
||||
|
||||
/**
|
||||
* \brief Read subtitles from file.
|
||||
* \param library library handle
|
||||
* \param fname file name
|
||||
* \param codepage encoding (iconv format)
|
||||
* \return newly allocated track
|
||||
*/
|
||||
ASS_Track *ass_read_file(ASS_Library *library, char *fname,
|
||||
char *codepage);
|
||||
|
||||
/**
|
||||
* \brief Read subtitles from memory.
|
||||
* \param library library handle
|
||||
* \param buf pointer to subtitles text
|
||||
* \param bufsize size of buffer
|
||||
* \param codepage encoding (iconv format)
|
||||
* \return newly allocated track
|
||||
*/
|
||||
ASS_Track *ass_read_memory(ASS_Library *library, char *buf,
|
||||
size_t bufsize, char *codepage);
|
||||
/**
|
||||
* \brief Read styles from file into already initialized track.
|
||||
* \param fname file name
|
||||
* \param codepage encoding (iconv format)
|
||||
* \return 0 on success
|
||||
*/
|
||||
int ass_read_styles(ASS_Track *track, char *fname, char *codepage);
|
||||
|
||||
/**
|
||||
* \brief Add a memory font.
|
||||
* \param library library handle
|
||||
* \param name attachment name
|
||||
* \param data binary font data
|
||||
* \param data_size data size
|
||||
*/
|
||||
void ass_add_font(ASS_Library *library, char *name, char *data,
|
||||
int data_size);
|
||||
|
||||
/**
|
||||
* \brief Remove all fonts stored in an ass_library object.
|
||||
* \param library library handle
|
||||
*/
|
||||
void ass_clear_fonts(ASS_Library *library);
|
||||
|
||||
/**
|
||||
* \brief Calculates timeshift from now to the start of some other subtitle
|
||||
* event, depending on movement parameter.
|
||||
* \param track subtitle track
|
||||
* \param now current time in milliseconds
|
||||
* \param movement how many events to skip from the one currently displayed
|
||||
* +2 means "the one after the next", -1 means "previous"
|
||||
* \return timeshift in milliseconds
|
||||
*/
|
||||
long long ass_step_sub(ASS_Track *track, long long now, int movement);
|
||||
|
||||
#endif /* LIBASS_ASS_H */
|
|
@ -1,531 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
|
||||
*
|
||||
* This file is part of libass.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_GLYPH_H
|
||||
|
||||
#include "ass_utils.h"
|
||||
#include "ass_bitmap.h"
|
||||
|
||||
struct ass_synth_priv {
|
||||
int tmp_w, tmp_h;
|
||||
unsigned short *tmp;
|
||||
|
||||
int g_r;
|
||||
int g_w;
|
||||
|
||||
unsigned *g;
|
||||
unsigned *gt2;
|
||||
|
||||
double radius;
|
||||
};
|
||||
|
||||
static const unsigned int maxcolor = 255;
|
||||
static const unsigned base = 256;
|
||||
|
||||
static int generate_tables(ASS_SynthPriv *priv, double radius)
|
||||
{
|
||||
double A = log(1.0 / base) / (radius * radius * 2);
|
||||
int mx, i;
|
||||
double volume_diff, volume_factor = 0;
|
||||
unsigned volume;
|
||||
|
||||
if (priv->radius == radius)
|
||||
return 0;
|
||||
else
|
||||
priv->radius = radius;
|
||||
|
||||
priv->g_r = ceil(radius);
|
||||
priv->g_w = 2 * priv->g_r + 1;
|
||||
|
||||
if (priv->g_r) {
|
||||
priv->g = realloc(priv->g, priv->g_w * sizeof(unsigned));
|
||||
priv->gt2 = realloc(priv->gt2, 256 * priv->g_w * sizeof(unsigned));
|
||||
if (priv->g == NULL || priv->gt2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->g_r) {
|
||||
// gaussian curve with volume = 256
|
||||
for (volume_diff = 10000000; volume_diff > 0.0000001;
|
||||
volume_diff *= 0.5) {
|
||||
volume_factor += volume_diff;
|
||||
volume = 0;
|
||||
for (i = 0; i < priv->g_w; ++i) {
|
||||
priv->g[i] =
|
||||
(unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) *
|
||||
volume_factor + .5);
|
||||
volume += priv->g[i];
|
||||
}
|
||||
if (volume > 256)
|
||||
volume_factor -= volume_diff;
|
||||
}
|
||||
volume = 0;
|
||||
for (i = 0; i < priv->g_w; ++i) {
|
||||
priv->g[i] =
|
||||
(unsigned) (exp(A * (i - priv->g_r) * (i - priv->g_r)) *
|
||||
volume_factor + .5);
|
||||
volume += priv->g[i];
|
||||
}
|
||||
|
||||
// gauss table:
|
||||
for (mx = 0; mx < priv->g_w; mx++) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
priv->gt2[mx + i * priv->g_w] = i * priv->g[mx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void resize_tmp(ASS_SynthPriv *priv, int w, int h)
|
||||
{
|
||||
if (priv->tmp_w >= w && priv->tmp_h >= h)
|
||||
return;
|
||||
if (priv->tmp_w == 0)
|
||||
priv->tmp_w = 64;
|
||||
if (priv->tmp_h == 0)
|
||||
priv->tmp_h = 64;
|
||||
while (priv->tmp_w < w)
|
||||
priv->tmp_w *= 2;
|
||||
while (priv->tmp_h < h)
|
||||
priv->tmp_h *= 2;
|
||||
free(priv->tmp);
|
||||
priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(short));
|
||||
}
|
||||
|
||||
ASS_SynthPriv *ass_synth_init(double radius)
|
||||
{
|
||||
ASS_SynthPriv *priv = calloc(1, sizeof(ASS_SynthPriv));
|
||||
generate_tables(priv, radius);
|
||||
return priv;
|
||||
}
|
||||
|
||||
void ass_synth_done(ASS_SynthPriv *priv)
|
||||
{
|
||||
free(priv->tmp);
|
||||
free(priv->g);
|
||||
free(priv->gt2);
|
||||
free(priv);
|
||||
}
|
||||
|
||||
static Bitmap *alloc_bitmap(int w, int h)
|
||||
{
|
||||
Bitmap *bm;
|
||||
bm = malloc(sizeof(Bitmap));
|
||||
bm->buffer = calloc(w, h);
|
||||
bm->w = w;
|
||||
bm->h = h;
|
||||
bm->left = bm->top = 0;
|
||||
return bm;
|
||||
}
|
||||
|
||||
void ass_free_bitmap(Bitmap *bm)
|
||||
{
|
||||
if (bm)
|
||||
free(bm->buffer);
|
||||
free(bm);
|
||||
}
|
||||
|
||||
static Bitmap *copy_bitmap(const Bitmap *src)
|
||||
{
|
||||
Bitmap *dst = alloc_bitmap(src->w, src->h);
|
||||
dst->left = src->left;
|
||||
dst->top = src->top;
|
||||
memcpy(dst->buffer, src->buffer, src->w * src->h);
|
||||
return dst;
|
||||
}
|
||||
|
||||
int check_glyph_area(ASS_Library *library, FT_Glyph glyph)
|
||||
{
|
||||
FT_BBox bbox;
|
||||
long long dx, dy;
|
||||
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
|
||||
dx = bbox.xMax - bbox.xMin;
|
||||
dy = bbox.yMax - bbox.yMin;
|
||||
if (dx * dy > 8000000) {
|
||||
ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
|
||||
(int) dx, (int) dy);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Bitmap *glyph_to_bitmap_internal(ASS_Library *library,
|
||||
FT_Glyph glyph, int bord)
|
||||
{
|
||||
FT_BitmapGlyph bg;
|
||||
FT_Bitmap *bit;
|
||||
Bitmap *bm;
|
||||
int w, h;
|
||||
unsigned char *src;
|
||||
unsigned char *dst;
|
||||
int i;
|
||||
int error;
|
||||
|
||||
if (check_glyph_area(library, glyph))
|
||||
return 0;
|
||||
error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
|
||||
if (error) {
|
||||
ass_msg(library, MSGL_WARN, "FT_Glyph_To_Bitmap error %d",
|
||||
error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bg = (FT_BitmapGlyph) glyph;
|
||||
bit = &(bg->bitmap);
|
||||
if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) {
|
||||
ass_msg(library, MSGL_WARN, "Unsupported pixel mode: %d",
|
||||
(int) (bit->pixel_mode));
|
||||
FT_Done_Glyph(glyph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
w = bit->width;
|
||||
h = bit->rows;
|
||||
bm = alloc_bitmap(w + 2 * bord, h + 2 * bord);
|
||||
bm->left = bg->left - bord;
|
||||
bm->top = -bg->top - bord;
|
||||
|
||||
src = bit->buffer;
|
||||
dst = bm->buffer + bord + bm->w * bord;
|
||||
for (i = 0; i < h; ++i) {
|
||||
memcpy(dst, src, w);
|
||||
src += bit->pitch;
|
||||
dst += bm->w;
|
||||
}
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
return bm;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fix outline bitmap
|
||||
*
|
||||
* The glyph bitmap is subtracted from outline bitmap. This way looks much
|
||||
* better in some cases.
|
||||
*/
|
||||
static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
|
||||
{
|
||||
int x, y;
|
||||
const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left;
|
||||
const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top;
|
||||
const int r =
|
||||
bm_o->left + bm_o->w <
|
||||
bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w;
|
||||
const int b =
|
||||
bm_o->top + bm_o->h <
|
||||
bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h;
|
||||
|
||||
unsigned char *g =
|
||||
bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left);
|
||||
unsigned char *o =
|
||||
bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left);
|
||||
|
||||
for (y = 0; y < b - t; ++y) {
|
||||
for (x = 0; x < r - l; ++x) {
|
||||
unsigned char c_g, c_o;
|
||||
c_g = g[x];
|
||||
c_o = o[x];
|
||||
o[x] = (c_o > c_g) ? c_o - (c_g / 2) : 0;
|
||||
}
|
||||
g += bm_g->w;
|
||||
o += bm_o->w;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Shift a bitmap by the fraction of a pixel in x and y direction
|
||||
* expressed in 26.6 fixed point
|
||||
*/
|
||||
static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
|
||||
int shift_y)
|
||||
{
|
||||
int x, y, b;
|
||||
|
||||
// Shift in x direction
|
||||
if (shift_x > 0) {
|
||||
for (y = 0; y < h; y++) {
|
||||
for (x = w - 1; x > 0; x--) {
|
||||
b = (buf[x + y * w - 1] * shift_x) >> 6;
|
||||
buf[x + y * w - 1] -= b;
|
||||
buf[x + y * w] += b;
|
||||
}
|
||||
}
|
||||
} else if (shift_x < 0) {
|
||||
shift_x = -shift_x;
|
||||
for (y = 0; y < h; y++) {
|
||||
for (x = 0; x < w - 1; x++) {
|
||||
b = (buf[x + y * w + 1] * shift_x) >> 6;
|
||||
buf[x + y * w + 1] -= b;
|
||||
buf[x + y * w] += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shift in y direction
|
||||
if (shift_y > 0) {
|
||||
for (x = 0; x < w; x++) {
|
||||
for (y = h - 1; y > 0; y--) {
|
||||
b = (buf[x + (y - 1) * w] * shift_y) >> 6;
|
||||
buf[x + (y - 1) * w] -= b;
|
||||
buf[x + y * w] += b;
|
||||
}
|
||||
}
|
||||
} else if (shift_y < 0) {
|
||||
shift_y = -shift_y;
|
||||
for (x = 0; x < w; x++) {
|
||||
for (y = 0; y < h - 1; y++) {
|
||||
b = (buf[x + (y + 1) * w] * shift_y) >> 6;
|
||||
buf[x + (y + 1) * w] -= b;
|
||||
buf[x + y * w] += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gaussian blur. An fast pure C implementation from MPlayer.
|
||||
*/
|
||||
static void ass_gauss_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 < height; y++) {
|
||||
memset(t - 1, 0, (width + 1) * sizeof(short));
|
||||
|
||||
for (x = 0; x < r; x++) {
|
||||
const int src = s[x];
|
||||
if (src) {
|
||||
register unsigned short *dstp = t + x - r;
|
||||
int mx;
|
||||
unsigned *m3 = (unsigned *) (m2 + src * mwidth);
|
||||
for (mx = r - x; mx < mwidth; mx++) {
|
||||
dstp[mx] += m3[mx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; x < width - r; x++) {
|
||||
const int src = s[x];
|
||||
if (src) {
|
||||
register unsigned short *dstp = t + x - r;
|
||||
int mx;
|
||||
unsigned *m3 = (unsigned *) (m2 + src * mwidth);
|
||||
for (mx = 0; mx < mwidth; mx++) {
|
||||
dstp[mx] += m3[mx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; x < width; x++) {
|
||||
const int src = s[x];
|
||||
if (src) {
|
||||
register unsigned short *dstp = t + x - r;
|
||||
int mx;
|
||||
const int x2 = r + width - x;
|
||||
unsigned *m3 = (unsigned *) (m2 + src * mwidth);
|
||||
for (mx = 0; mx < x2; mx++) {
|
||||
dstp[mx] += m3[mx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s += stride;
|
||||
t += width + 1;
|
||||
}
|
||||
|
||||
t = tmp2;
|
||||
for (x = 0; x < width; x++) {
|
||||
for (y = 0; y < r; y++) {
|
||||
unsigned short *srcp = t + y * (width + 1) + 1;
|
||||
int src = *srcp;
|
||||
if (src) {
|
||||
register unsigned short *dstp = srcp - 1 + width + 1;
|
||||
const int src2 = (src + 128) >> 8;
|
||||
unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
|
||||
|
||||
int mx;
|
||||
*srcp = 128;
|
||||
for (mx = r - 1; mx < mwidth; mx++) {
|
||||
*dstp += m3[mx];
|
||||
dstp += width + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; y < height - r; y++) {
|
||||
unsigned short *srcp = t + y * (width + 1) + 1;
|
||||
int src = *srcp;
|
||||
if (src) {
|
||||
register unsigned short *dstp = srcp - 1 - r * (width + 1);
|
||||
const int src2 = (src + 128) >> 8;
|
||||
unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
|
||||
|
||||
int mx;
|
||||
*srcp = 128;
|
||||
for (mx = 0; mx < mwidth; mx++) {
|
||||
*dstp += m3[mx];
|
||||
dstp += width + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; y < height; y++) {
|
||||
unsigned short *srcp = t + y * (width + 1) + 1;
|
||||
int src = *srcp;
|
||||
if (src) {
|
||||
const int y2 = r + height - y;
|
||||
register unsigned short *dstp = srcp - 1 - r * (width + 1);
|
||||
const int src2 = (src + 128) >> 8;
|
||||
unsigned *m3 = (unsigned *) (m2 + src2 * mwidth);
|
||||
|
||||
int mx;
|
||||
*srcp = 128;
|
||||
for (mx = 0; mx < y2; mx++) {
|
||||
*dstp += m3[mx];
|
||||
dstp += width + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
t++;
|
||||
}
|
||||
|
||||
t = tmp2;
|
||||
s = buffer;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
s[x] = t[x] >> 8;
|
||||
}
|
||||
s += stride;
|
||||
t += width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel
|
||||
* This blur is the same as the one employed by vsfilter.
|
||||
*/
|
||||
static void be_blur(unsigned char *buf, int w, int h)
|
||||
{
|
||||
unsigned int x, y;
|
||||
unsigned int old_sum, new_sum;
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
old_sum = 2 * buf[y * w];
|
||||
for (x = 0; x < w - 1; x++) {
|
||||
new_sum = buf[y * w + x] + buf[y * w + x + 1];
|
||||
buf[y * w + x] = (old_sum + new_sum) >> 2;
|
||||
old_sum = new_sum;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < w; x++) {
|
||||
old_sum = 2 * buf[x];
|
||||
for (y = 0; y < h - 1; y++) {
|
||||
new_sum = buf[y * w + x] + buf[(y + 1) * w + x];
|
||||
buf[y * w + x] = (old_sum + new_sum) >> 2;
|
||||
old_sum = new_sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
|
||||
FT_Glyph glyph, FT_Glyph outline_glyph,
|
||||
Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
|
||||
int be, double blur_radius, FT_Vector shadow_offset,
|
||||
int border_style)
|
||||
{
|
||||
int bbord;
|
||||
int gbord;
|
||||
int bord;
|
||||
blur_radius *= 2;
|
||||
bbord = be > 0 ? sqrt(2 * be) : 0;
|
||||
gbord = blur_radius > 0.0 ? blur_radius + 1 : 0;
|
||||
bord = FFMAX(bbord, gbord);
|
||||
if (bord == 0 && (shadow_offset.x || shadow_offset.y))
|
||||
bord = 1;
|
||||
|
||||
assert(bm_g && bm_o && bm_s);
|
||||
|
||||
*bm_g = *bm_o = *bm_s = 0;
|
||||
|
||||
if (glyph)
|
||||
*bm_g = glyph_to_bitmap_internal(library, glyph, bord);
|
||||
if (!*bm_g)
|
||||
return 1;
|
||||
|
||||
if (outline_glyph) {
|
||||
*bm_o = glyph_to_bitmap_internal(library, outline_glyph, bord);
|
||||
if (!*bm_o) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply box blur (multiple passes, if requested)
|
||||
while (be--) {
|
||||
if (*bm_o)
|
||||
be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h);
|
||||
else
|
||||
be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h);
|
||||
}
|
||||
|
||||
// Apply gaussian blur
|
||||
if (blur_radius > 0.0) {
|
||||
if (*bm_o)
|
||||
resize_tmp(priv_blur, (*bm_o)->w, (*bm_o)->h);
|
||||
else
|
||||
resize_tmp(priv_blur, (*bm_g)->w, (*bm_g)->h);
|
||||
generate_tables(priv_blur, blur_radius);
|
||||
if (*bm_o)
|
||||
ass_gauss_blur((*bm_o)->buffer, priv_blur->tmp,
|
||||
(*bm_o)->w, (*bm_o)->h, (*bm_o)->w,
|
||||
(int *) priv_blur->gt2, priv_blur->g_r,
|
||||
priv_blur->g_w);
|
||||
else
|
||||
ass_gauss_blur((*bm_g)->buffer, priv_blur->tmp,
|
||||
(*bm_g)->w, (*bm_g)->h, (*bm_g)->w,
|
||||
(int *) priv_blur->gt2, priv_blur->g_r,
|
||||
priv_blur->g_w);
|
||||
}
|
||||
|
||||
// Create shadow and fix outline as needed
|
||||
if (*bm_o && border_style != 3) {
|
||||
*bm_s = copy_bitmap(*bm_o);
|
||||
fix_outline(*bm_g, *bm_o);
|
||||
} else if (*bm_o) {
|
||||
*bm_s = copy_bitmap(*bm_o);
|
||||
} else
|
||||
*bm_s = copy_bitmap(*bm_g);
|
||||
|
||||
assert(bm_s);
|
||||
|
||||
shift_bitmap((*bm_s)->buffer, (*bm_s)->w,(*bm_s)->h,
|
||||
shadow_offset.x, shadow_offset.y);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
|
||||
*
|
||||
* This file is part of libass.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBASS_BITMAP_H
|
||||
#define LIBASS_BITMAP_H
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_GLYPH_H
|
||||
|
||||
#include "ass.h"
|
||||
|
||||
typedef struct ass_synth_priv ASS_SynthPriv;
|
||||
|
||||
ASS_SynthPriv *ass_synth_init(double);
|
||||
void ass_synth_done(ASS_SynthPriv *priv);
|
||||
|
||||
typedef struct {
|
||||
int left, top;
|
||||
int w, h; // width, height
|
||||
unsigned char *buffer; // w x h buffer
|
||||
} Bitmap;
|
||||
|
||||
/**
|
||||
* \brief perform glyph rendering
|
||||
* \param glyph original glyph
|
||||
* \param outline_glyph "border" glyph, produced from original by FreeType's glyph stroker
|
||||
* \param bm_g out: pointer to the bitmap of original glyph is returned here
|
||||
* \param bm_o out: pointer to the bitmap of outline (border) glyph is returned here
|
||||
* \param bm_g out: pointer to the bitmap of glyph shadow is returned here
|
||||
* \param be 1 = produces blurred bitmaps, 0 = normal bitmaps
|
||||
*/
|
||||
int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
|
||||
FT_Glyph glyph, FT_Glyph outline_glyph,
|
||||
Bitmap ** |