1 /*****************************************************************************
2 * croppadd.c: Crop/Padd image filter
3 *****************************************************************************
4 * Copyright (C) 2008 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea @t videolan dot org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
34 #include "vlc_filter.h"
36 /****************************************************************************
38 ****************************************************************************/
39 static int OpenFilter ( vlc_object_t
* );
40 static void CloseFilter( vlc_object_t
* );
42 static picture_t
*Filter( filter_t
*, picture_t
* );
44 /*****************************************************************************
46 *****************************************************************************/
48 set_description( N_("Video scaling filter") );
49 set_capability( "video filter2", 0 );
50 set_callbacks( OpenFilter
, CloseFilter
);
53 /*****************************************************************************
54 * OpenFilter: probe the filter and return score
55 *****************************************************************************/
56 static int OpenFilter( vlc_object_t
*p_this
)
58 filter_t
*p_filter
= (filter_t
*)p_this
;
60 if( p_filter
->fmt_in
.video
.i_chroma
!= p_filter
->fmt_out
.video
.i_chroma
)
65 p_filter
->pf_video_filter
= Filter
;
67 msg_Dbg( p_filter
, "%ix%i + %ix%i -> %ix%i + %ix%i",
68 p_filter
->fmt_in
.video
.i_visible_width
,
69 p_filter
->fmt_in
.video
.i_visible_height
,
70 p_filter
->fmt_in
.video
.i_x_offset
,
71 p_filter
->fmt_in
.video
.i_y_offset
,
72 p_filter
->fmt_out
.video
.i_visible_width
,
73 p_filter
->fmt_out
.video
.i_visible_height
,
74 p_filter
->fmt_out
.video
.i_x_offset
,
75 p_filter
->fmt_out
.video
.i_y_offset
);
80 /*****************************************************************************
81 * CloseFilter: clean up the filter
82 *****************************************************************************/
83 static void CloseFilter( vlc_object_t
*p_this
)
88 /****************************************************************************
89 * Filter: the whole thing
90 ****************************************************************************/
91 static picture_t
*Filter( filter_t
*p_filter
, picture_t
*p_pic
)
95 int i_width
, i_height
, i_xcrop
, i_ycrop
,
96 i_outwidth
, i_outheight
, i_xpadd
, i_ypadd
;
98 const int p_padd_color
[] = { 0x00, 0x80, 0x80, 0xff };
100 if( !p_pic
) return NULL
;
102 /* Request output picture */
103 p_outpic
= p_filter
->pf_vout_buffer_new( p_filter
);
106 msg_Warn( p_filter
, "can't get output picture" );
107 if( p_pic
->pf_release
)
108 p_pic
->pf_release( p_pic
);
112 for( i_plane
= 0; i_plane
< p_pic
->i_planes
; i_plane
++ )
113 /* p_pic and p_outpic have the same chroma/number of planes but that's
116 plane_t
*p_plane
= p_pic
->p
+i_plane
;
117 plane_t
*p_outplane
= p_outpic
->p
+i_plane
;
118 uint8_t *p_in
= p_plane
->p_pixels
;
119 uint8_t *p_out
= p_outplane
->p_pixels
;
120 int i_pixel_pitch
= p_plane
->i_pixel_pitch
;
121 int i_padd_color
= i_plane
> 3 ? p_padd_color
[0]
122 : p_padd_color
[i_plane
];
124 /* These assignments assume that the first plane always has
125 * a width and height equal to the picture's */
126 i_width
= ( p_filter
->fmt_in
.video
.i_visible_width
127 * p_plane
->i_visible_pitch
)
128 / p_pic
->p
->i_visible_pitch
;
129 i_height
= ( p_filter
->fmt_in
.video
.i_visible_height
130 * p_plane
->i_visible_lines
)
131 / p_pic
->p
->i_visible_lines
;
132 i_xcrop
= ( p_filter
->fmt_in
.video
.i_x_offset
133 * p_plane
->i_visible_pitch
)
134 / p_pic
->p
->i_visible_pitch
;
135 i_ycrop
= ( p_filter
->fmt_in
.video
.i_y_offset
136 * p_plane
->i_visible_lines
)
137 / p_pic
->p
->i_visible_lines
;
138 i_outwidth
= ( p_filter
->fmt_out
.video
.i_visible_width
139 * p_outplane
->i_visible_pitch
)
140 / p_outpic
->p
->i_visible_pitch
;
141 i_outheight
= ( p_filter
->fmt_out
.video
.i_visible_height
142 * p_outplane
->i_visible_lines
)
143 / p_outpic
->p
->i_visible_lines
;
144 i_xpadd
= ( p_filter
->fmt_out
.video
.i_x_offset
145 * p_outplane
->i_visible_pitch
)
146 / p_outpic
->p
->i_visible_pitch
;
147 i_ypadd
= ( p_filter
->fmt_out
.video
.i_y_offset
148 * p_outplane
->i_visible_lines
)
149 / p_outpic
->p
->i_visible_lines
;
152 p_in
+= i_ycrop
* p_plane
->i_pitch
;
154 /* Padd on the top */
155 vlc_memset( p_out
, i_padd_color
, i_ypadd
* p_outplane
->i_pitch
);
156 p_out
+= i_ypadd
* p_outplane
->i_pitch
;
159 for( i_line
= 0; i_line
< i_height
; i_line
++ )
161 uint8_t *p_in_next
= p_in
+ p_plane
->i_pitch
;
162 uint8_t *p_out_next
= p_out
+ p_outplane
->i_pitch
;
164 /* Crop on the left */
165 p_in
+= i_xcrop
* i_pixel_pitch
;
167 /* Padd on the left */
168 vlc_memset( p_out
, i_padd_color
, i_xpadd
* i_pixel_pitch
);
169 p_out
+= i_xpadd
* i_pixel_pitch
;
171 /* Copy the image and crop on the right */
172 vlc_memcpy( p_out
, p_in
, i_width
* i_pixel_pitch
);
173 p_out
+= i_width
* i_pixel_pitch
;
174 p_in
+= i_width
* i_pixel_pitch
;
176 /* Padd on the right */
177 vlc_memset( p_out
, i_padd_color
,
178 ( i_outwidth
- i_width
) * i_pixel_pitch
);
180 /* Got to begining of the next line */
185 /* Padd on the bottom */
186 vlc_memset( p_out
, i_padd_color
,
187 ( i_outheight
- i_ypadd
- i_height
) * p_outplane
->i_pitch
);
190 p_outpic
->date
= p_pic
->date
;
191 p_outpic
->b_force
= p_pic
->b_force
;
192 p_outpic
->i_nb_fields
= p_pic
->i_nb_fields
;
193 p_outpic
->b_progressive
= p_pic
->b_progressive
;
194 p_outpic
->b_top_field_first
= p_pic
->b_top_field_first
;
196 p_pic
->pf_release( p_pic
);