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 *****************************************************************************/
33 #include "vlc_filter.h"
35 /****************************************************************************
37 ****************************************************************************/
38 static int OpenFilter ( vlc_object_t * );
39 static void CloseFilter( vlc_object_t * );
41 static picture_t *Filter( filter_t *, picture_t * );
43 /*****************************************************************************
45 *****************************************************************************/
47 set_description( _("Video scaling filter") );
48 set_capability( "video filter2", 0 );
49 set_callbacks( OpenFilter, CloseFilter );
52 /*****************************************************************************
53 * OpenFilter: probe the filter and return score
54 *****************************************************************************/
55 static int OpenFilter( vlc_object_t *p_this )
57 filter_t *p_filter = (filter_t*)p_this;
59 if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma )
64 p_filter->pf_video_filter = Filter;
66 msg_Dbg( p_filter, "%ix%i + %ix%i -> %ix%i + %ix%i",
67 p_filter->fmt_in.video.i_visible_width,
68 p_filter->fmt_in.video.i_visible_height,
69 p_filter->fmt_in.video.i_x_offset,
70 p_filter->fmt_in.video.i_y_offset,
71 p_filter->fmt_out.video.i_visible_width,
72 p_filter->fmt_out.video.i_visible_height,
73 p_filter->fmt_out.video.i_x_offset,
74 p_filter->fmt_out.video.i_y_offset );
79 /*****************************************************************************
80 * CloseFilter: clean up the filter
81 *****************************************************************************/
82 static void CloseFilter( vlc_object_t *p_this )
87 /****************************************************************************
88 * Filter: the whole thing
89 ****************************************************************************/
90 static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
94 int i_width, i_height, i_xcrop, i_ycrop,
95 i_outwidth, i_outheight, i_xpadd, i_ypadd;
97 const int p_padd_color[] = { 0x00, 0x80, 0x80, 0xff };
99 if( !p_pic ) return NULL;
101 /* Request output picture */
102 p_outpic = p_filter->pf_vout_buffer_new( p_filter );
105 msg_Warn( p_filter, "can't get output picture" );
106 if( p_pic->pf_release )
107 p_pic->pf_release( p_pic );
111 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
112 /* p_pic and p_outpic have the same chroma/number of planes but that's
115 plane_t *p_plane = p_pic->p+i_plane;
116 plane_t *p_outplane = p_outpic->p+i_plane;
117 uint8_t *p_in = p_plane->p_pixels;
118 uint8_t *p_out = p_outplane->p_pixels;
119 int i_pixel_pitch = p_plane->i_pixel_pitch;
120 int i_padd_color = i_plane > 3 ? p_padd_color[0]
121 : p_padd_color[i_plane];
123 /* These assignments assume that the first plane always has
124 * a width and height equal to the picture's */
125 i_width = ( p_filter->fmt_in.video.i_visible_width
126 * p_plane->i_visible_pitch )
127 / p_pic->p->i_visible_pitch;
128 i_height = ( p_filter->fmt_in.video.i_visible_height
129 * p_plane->i_visible_lines )
130 / p_pic->p->i_visible_lines;
131 i_xcrop = ( p_filter->fmt_in.video.i_x_offset
132 * p_plane->i_visible_pitch)
133 / p_pic->p->i_visible_pitch;
134 i_ycrop = ( p_filter->fmt_in.video.i_y_offset
135 * p_plane->i_visible_lines)
136 / p_pic->p->i_visible_lines;
137 i_outwidth = ( p_filter->fmt_out.video.i_visible_width
138 * p_outplane->i_visible_pitch )
139 / p_outpic->p->i_visible_pitch;
140 i_outheight = ( p_filter->fmt_out.video.i_visible_height
141 * p_outplane->i_visible_lines )
142 / p_outpic->p->i_visible_lines;
143 i_xpadd = ( p_filter->fmt_out.video.i_x_offset
144 * p_outplane->i_visible_pitch )
145 / p_outpic->p->i_visible_pitch;
146 i_ypadd = ( p_filter->fmt_out.video.i_y_offset
147 * p_outplane->i_visible_lines )
148 / p_outpic->p->i_visible_lines;
151 p_in += i_ycrop * p_plane->i_pitch;
153 /* Padd on the top */
154 vlc_memset( p_out, i_padd_color, i_ypadd * p_outplane->i_pitch );
155 p_out += i_ypadd * p_outplane->i_pitch;
158 for( i_line = 0; i_line < i_height; i_line++ )
160 uint8_t *p_in_next = p_in + p_plane->i_pitch;
161 uint8_t *p_out_next = p_out + p_outplane->i_pitch;
163 /* Crop on the left */
164 p_in += i_xcrop * i_pixel_pitch;
166 /* Padd on the left */
167 vlc_memset( p_out, i_padd_color, i_xpadd * i_pixel_pitch );
168 p_out += i_xpadd * i_pixel_pitch;
170 /* Copy the image and crop on the right */
171 vlc_memcpy( p_out, p_in, i_width * i_pixel_pitch );
172 p_out += i_width * i_pixel_pitch;
173 p_in += i_width * i_pixel_pitch;
175 /* Padd on the right */
176 vlc_memset( p_out, i_padd_color,
177 ( i_outwidth - i_width ) * i_pixel_pitch );
179 /* Got to begining of the next line */
184 /* Padd on the bottom */
185 vlc_memset( p_out, i_padd_color,
186 ( i_outheight - i_ypadd - i_height ) * p_outplane->i_pitch );
189 p_outpic->date = p_pic->date;
190 p_outpic->b_force = p_pic->b_force;
191 p_outpic->i_nb_fields = p_pic->i_nb_fields;
192 p_outpic->b_progressive = p_pic->b_progressive;
193 p_outpic->b_top_field_first = p_pic->b_top_field_first;
195 p_pic->pf_release( p_pic );