On 8 May 2017 at 05:46, Rostislav Pehlivanov <atomnu...@gmail.com> wrote:
> Enables rendering of SVG images. This is possible since SVG images > still contain and specify the dimensions in pixels to which they've > been drawn to and thus enable browsers to display them without any > external data. Users can still override and generate images with > arbitrary resolutions. > > Signed-off-by: Rostislav Pehlivanov <atomnu...@gmail.com> > --- > configure | 4 ++ > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/librsvgdec.c | 127 ++++++++++++++++++++++++++++++ > ++++++++++++++++++ > 4 files changed, 133 insertions(+) > create mode 100644 libavcodec/librsvgdec.c > > diff --git a/configure b/configure > index 2e1786a6fc..4f20d177a5 100755 > --- a/configure > +++ b/configure > @@ -245,6 +245,7 @@ External library support: > --enable-libopenmpt enable decoding tracked files via libopenmpt > [no] > --enable-libopus enable Opus de/encoding via libopus [no] > --enable-libpulse enable Pulseaudio input via libpulse [no] > + --enable-librsvg enable SVG rasterization via librsvg [no] > --enable-librubberband enable rubberband needed for rubberband filter > [no] > --enable-librtmp enable RTMP[E] support via librtmp [no] > --enable-libschroedinger enable Dirac de/encoding via libschroedinger > [no] > @@ -1557,6 +1558,7 @@ EXTERNAL_LIBRARY_LIST=" > libopenmpt > libopus > libpulse > + librsvg > librtmp > libschroedinger > libshine > @@ -2867,6 +2869,7 @@ libopenmpt_demuxer_deps="libopenmpt" > libopus_decoder_deps="libopus" > libopus_encoder_deps="libopus" > libopus_encoder_select="audio_frame_queue" > +librsvg_decoder_deps="librsvg" > libschroedinger_decoder_deps="libschroedinger" > libschroedinger_encoder_deps="libschroedinger" > libshine_encoder_deps="libshine" > @@ -5819,6 +5822,7 @@ enabled libopus && { > } > } > enabled libpulse && require_pkg_config libpulse > pulse/pulseaudio.h pa_context_new > +enabled librsvg && require_pkg_config librsvg-2.0 > librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo > enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h > RTMP_Socket > enabled librubberband && require_pkg_config "rubberband >= 1.8.1" > rubberband/rubberband-c.h rubberband_new > enabled libschroedinger && require_pkg_config schroedinger-1.0 > schroedinger/schro.h schro_init > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index b5c8cc1f98..5829063ee8 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -550,6 +550,7 @@ OBJS-$(CONFIG_SUBVIEWER1_DECODER) += textdec.o > ass.o > OBJS-$(CONFIG_SUBVIEWER_DECODER) += subviewerdec.o ass.o > OBJS-$(CONFIG_SUNRAST_DECODER) += sunrast.o > OBJS-$(CONFIG_SUNRAST_ENCODER) += sunrastenc.o > +OBJS-$(CONFIG_LIBRSVG_DECODER) += librsvgdec.o > OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o svq13.o > h263data.o > OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o h263data.o \ > h263.o ituh263enc.o > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index 7fcc26f2c1..425a32c924 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -319,6 +319,7 @@ static void register_all(void) > REGISTER_DECODER(SPEEDHQ, speedhq); > REGISTER_DECODER(SRGC, srgc); > REGISTER_ENCDEC (SUNRAST, sunrast); > + REGISTER_DECODER(LIBRSVG, librsvg); > REGISTER_ENCDEC (SVQ1, svq1); > REGISTER_DECODER(SVQ3, svq3); > REGISTER_ENCDEC (TARGA, targa); > diff --git a/libavcodec/librsvgdec.c b/libavcodec/librsvgdec.c > new file mode 100644 > index 0000000000..29b771c5a3 > --- /dev/null > +++ b/libavcodec/librsvgdec.c > @@ -0,0 +1,127 @@ > +/* > + * Librsvg rasterization wrapper > + * Copyright (c) 2017 Rostislav Pehlivanov <atomnu...@gmail.com> > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > 02110-1301 USA > + */ > + > +#include "avcodec.h" > +#include "internal.h" > +#include "libavutil/opt.h" > +#include "librsvg-2.0/librsvg/rsvg.h" > + > +typedef struct LibRSVGContext { > + AVClass *class; > + > + int width; > + int height; > + int keep_ar; > +} LibRSVGContext; > + > +static int librsvg_decode_frame(AVCodecContext *avctx, void *data, int > *got_frame, AVPacket *pkt) > +{ > + int ret; > + LibRSVGContext *s = avctx->priv_data; > + AVFrame *frame = data; > + > + RsvgHandle *handle; > + RsvgDimensionData unscaled_dimensions, dimensions; > + cairo_surface_t *image; > + cairo_t *crender = NULL; > + GError *error = NULL; > + > + *got_frame = 0; > + > + handle = rsvg_handle_new_from_data(pkt->data, pkt->size, &error); > + if (error) { > + av_log(avctx, AV_LOG_ERROR, "Error parsing svg!\n"); > + g_error_free(error); > + return AVERROR_INVALIDDATA; > + } > + > + rsvg_handle_get_dimensions(handle, &dimensions); > + rsvg_handle_get_dimensions(handle, &unscaled_dimensions); > + dimensions.width = s->width ? s->width : dimensions.width; > + dimensions.height = s->height ? s->height : dimensions.height; > + if (s->keep_ar && (s->width || s->height)) { > + double default_ar = unscaled_dimensions.width/( > double)unscaled_dimensions.height; > + if (!s->width) > + dimensions.width = lrintf(dimensions.height * default_ar); > + else > + dimensions.height = lrintf(dimensions.width / default_ar); > + } > + > + if ((ret = ff_set_dimensions(avctx, dimensions.width, > dimensions.height))) > + return ret; > + avctx->pix_fmt = AV_PIX_FMT_BGRA; > + > + if ((ret = ff_get_buffer(avctx, frame, 0))) > + return ret; > + frame->pict_type = AV_PICTURE_TYPE_I; > + frame->key_frame = 1; > + > + image = cairo_image_surface_create_for_data(frame->data[0], > CAIRO_FORMAT_ARGB32, > + frame->width, > frame->height, > + frame->linesize[0]); > + if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) > + return AVERROR_INVALIDDATA; > + > + crender = cairo_create(image); > + > + cairo_set_source_rgba(crender, 0.0, 0.0, 0.0, 1.0f); > + cairo_paint_with_alpha(crender, 0.0f); > + > + cairo_scale(crender, dimensions.width / (double)unscaled_dimensions. > width, > + dimensions.height / (double)unscaled_dimensions.height); > + > + rsvg_handle_render_cairo(handle, crender); > + > + cairo_destroy(crender); > + cairo_surface_destroy(image); > + g_object_unref(handle); > + > + *got_frame = 1; > + > + return 0; > +} > + > +#define OFFSET(x) offsetof(LibRSVGContext, x) > +#define DEC (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) > +static const AVOption options[] = { > + { "width", "Width to render to (0 for default)", OFFSET(width), > AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, DEC }, > + { "height", "Height to render to (0 for default)", OFFSET(height), > AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, DEC }, > + { "keep_ar", "Keep aspect ratio with custom width/height", > OFFSET(keep_ar), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, DEC }, > + { NULL }, > +}; > + > +static const AVClass librsvg_decoder_class = { > + .class_name = "Librsvg", > + .item_name = av_default_item_name, > + .option = options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > +AVCodec ff_librsvg_decoder = { > + .name = "librsvg", > + .long_name = NULL_IF_CONFIG_SMALL("Librsvg rasterizer"), > + .priv_class = &librsvg_decoder_class, > + .type = AVMEDIA_TYPE_VIDEO, > + .id = AV_CODEC_ID_SVG, > + .decode = librsvg_decode_frame, > + .priv_data_size = sizeof(LibRSVGContext), > + .capabilities = AV_CODEC_CAP_LOSSLESS | AV_CODEC_CAP_DR1, > +}; > -- > 2.13.0.rc1.294.g07d810a77f > > Pushed _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel