@@ -38,48 +38,75 @@ static int librsvg_decode_frame(AVCodecContext *avctx, AVFrame *frame,
38
38
{
39
39
int ret ;
40
40
LibRSVGContext * s = avctx -> priv_data ;
41
-
42
- RsvgHandle * handle ;
43
- RsvgDimensionData unscaled_dimensions , dimensions ;
44
- cairo_surface_t * image ;
41
+ RsvgHandle * handle = NULL ;
42
+ RsvgDimensionData dimensions ;
43
+ #if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
44
+ RsvgRectangle viewport = { 0 };
45
+ #else
46
+ RsvgDimensionData unscaled_dimensions ;
47
+ #endif
48
+ cairo_surface_t * image = NULL ;
45
49
cairo_t * crender = NULL ;
46
50
GError * error = NULL ;
51
+ gboolean gret ;
47
52
48
53
* got_frame = 0 ;
49
54
50
55
handle = rsvg_handle_new_from_data (pkt -> data , pkt -> size , & error );
51
56
if (error ) {
52
- av_log (avctx , AV_LOG_ERROR , "Error parsing svg! \n" );
53
- g_error_free ( error ) ;
54
- return AVERROR_INVALIDDATA ;
57
+ av_log (avctx , AV_LOG_ERROR , "Error parsing svg: %s \n" , error -> message );
58
+ ret = AVERROR_INVALIDDATA ;
59
+ goto end ;
55
60
}
56
61
62
+ #if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
63
+ gret = rsvg_handle_get_intrinsic_size_in_pixels (handle , & viewport .width , & viewport .height );
64
+ if (!gret ) {
65
+ viewport .width = s -> width ? s -> width : 100 ;
66
+ viewport .height = s -> height ? s -> height : 100 ;
67
+ }
68
+ dimensions .width = (int )viewport .width ;
69
+ dimensions .height = (int )viewport .height ;
70
+ #else
57
71
rsvg_handle_get_dimensions (handle , & dimensions );
58
72
rsvg_handle_get_dimensions (handle , & unscaled_dimensions );
73
+ #endif
59
74
dimensions .width = s -> width ? s -> width : dimensions .width ;
60
75
dimensions .height = s -> height ? s -> height : dimensions .height ;
61
76
if (s -> keep_ar && (s -> width || s -> height )) {
77
+ #if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
78
+ double default_ar = viewport .width / viewport .height ;
79
+ #else
62
80
double default_ar = unscaled_dimensions .width /(double )unscaled_dimensions .height ;
81
+ #endif
63
82
if (!s -> width )
64
83
dimensions .width = lrintf (dimensions .height * default_ar );
65
84
else
66
85
dimensions .height = lrintf (dimensions .width / default_ar );
67
86
}
68
87
69
- if ((ret = ff_set_dimensions (avctx , dimensions .width , dimensions .height )))
70
- return ret ;
88
+ ret = ff_set_dimensions (avctx , dimensions .width , dimensions .height );
89
+ if (ret < 0 )
90
+ goto end ;
91
+
71
92
avctx -> pix_fmt = AV_PIX_FMT_RGB32 ;
93
+ viewport .width = dimensions .width ;
94
+ viewport .height = dimensions .height ;
95
+
96
+ ret = ff_get_buffer (avctx , frame , 0 );
97
+ if (ret < 0 )
98
+ goto end ;
72
99
73
- if ((ret = ff_get_buffer (avctx , frame , 0 )))
74
- return ret ;
75
100
frame -> pict_type = AV_PICTURE_TYPE_I ;
76
101
frame -> flags |= AV_FRAME_FLAG_KEY ;
77
102
78
103
image = cairo_image_surface_create_for_data (frame -> data [0 ], CAIRO_FORMAT_ARGB32 ,
79
104
frame -> width , frame -> height ,
80
105
frame -> linesize [0 ]);
81
- if (cairo_surface_status (image ) != CAIRO_STATUS_SUCCESS )
82
- return AVERROR_INVALIDDATA ;
106
+ if (cairo_surface_status (image ) != CAIRO_STATUS_SUCCESS ) {
107
+ ret = AVERROR_EXTERNAL ;
108
+ goto end ;
109
+ }
83
110
84
111
crender = cairo_create (image );
85
112
@@ -88,18 +115,34 @@ static int librsvg_decode_frame(AVCodecContext *avctx, AVFrame *frame,
88
115
cairo_paint (crender );
89
116
cairo_restore (crender );
90
117
118
+ #if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
119
+ gret = rsvg_handle_render_document (handle , crender , & viewport , & error );
120
+ #else
91
121
cairo_scale (crender , dimensions .width / (double )unscaled_dimensions .width ,
92
122
dimensions .height / (double )unscaled_dimensions .height );
123
+ gret = rsvg_handle_render_cairo (handle , crender );
124
+ #endif
93
125
94
- rsvg_handle_render_cairo ( handle , crender );
95
-
96
- cairo_destroy ( crender ) ;
97
- cairo_surface_destroy ( image ) ;
98
- g_object_unref ( handle );
126
+ if (! gret ) {
127
+ av_log ( avctx , AV_LOG_ERROR , "Error rendering svg: %s\n" , error ? error -> message : "unknown error" );
128
+ ret = AVERROR_EXTERNAL ;
129
+ goto end ;
130
+ }
99
131
100
132
* got_frame = 1 ;
133
+ ret = 0 ;
101
134
102
- return 0 ;
135
+ end :
136
+ if (error )
137
+ g_error_free (error );
138
+ if (handle )
139
+ g_object_unref (handle );
140
+ if (crender )
141
+ cairo_destroy (crender );
142
+ if (image )
143
+ cairo_surface_destroy (image );
144
+
145
+ return ret ;
103
146
}
104
147
105
148
#define OFFSET (x ) offsetof(LibRSVGContext, x)
0 commit comments