croppadd.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * croppadd.c: Crop/Padd image filter
  3.  *****************************************************************************
  4.  * Copyright (C) 2008 the VideoLAN team
  5.  * $Id: 887e6e5a62201f967888d4537164dd0420191615 $
  6.  *
  7.  * Authors: Antoine Cellerier <dionoea @t videolan dot org>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <limits.h> /* INT_MAX */
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_vout.h>
  33. #include "vlc_filter.h"
  34. #include "filter_picture.h"
  35. /****************************************************************************
  36.  * Local prototypes
  37.  ****************************************************************************/
  38. static int  OpenFilter ( vlc_object_t * );
  39. static void CloseFilter( vlc_object_t * );
  40. static picture_t *Filter( filter_t *, picture_t * );
  41. #define CROPTOP_TEXT N_( "Pixels to crop from top" )
  42. #define CROPTOP_LONGTEXT N_( 
  43.     "Number of pixels to crop from the top of the image." )
  44. #define CROPBOTTOM_TEXT N_( "Pixels to crop from bottom" )
  45. #define CROPBOTTOM_LONGTEXT N_( 
  46.     "Number of pixels to crop from the bottom of the image." )
  47. #define CROPLEFT_TEXT N_( "Pixels to crop from left" )
  48. #define CROPLEFT_LONGTEXT N_( 
  49.     "Number of pixels to crop from the left of the image." )
  50. #define CROPRIGHT_TEXT N_( "Pixels to crop from right" )
  51. #define CROPRIGHT_LONGTEXT N_( 
  52.     "Number of pixels to crop from the right of the image." )
  53. #define PADDTOP_TEXT N_( "Pixels to padd to top" )
  54. #define PADDTOP_LONGTEXT N_( 
  55.     "Number of pixels to padd to the top of the image after cropping." )
  56. #define PADDBOTTOM_TEXT N_( "Pixels to padd to bottom" )
  57. #define PADDBOTTOM_LONGTEXT N_( 
  58.     "Number of pixels to padd to the bottom of the image after cropping." )
  59. #define PADDLEFT_TEXT N_( "Pixels to padd to left" )
  60. #define PADDLEFT_LONGTEXT N_( 
  61.     "Number of pixels to padd to the left of the image after cropping." )
  62. #define PADDRIGHT_TEXT N_( "Pixels to padd to right" )
  63. #define PADDRIGHT_LONGTEXT N_( 
  64.     "Number of pixels to padd to the right of the image after cropping." )
  65. #define CFG_PREFIX "croppadd-"
  66. /*****************************************************************************
  67.  * Module descriptor
  68.  *****************************************************************************/
  69. vlc_module_begin ()
  70.     set_shortname( N_("Cropadd") )
  71.     set_description( N_("Video scaling filter") )
  72.     set_capability( "video filter2", 0 )
  73.     set_callbacks( OpenFilter, CloseFilter )
  74.     set_category( CAT_VIDEO )
  75.     set_subcategory( SUBCAT_VIDEO_VFILTER2 );
  76.     set_section( N_("Crop"), NULL )
  77.         add_integer_with_range( CFG_PREFIX "croptop", 0, 0, INT_MAX, NULL,
  78.                                 CROPTOP_TEXT, CROPTOP_LONGTEXT, false )
  79.         add_integer_with_range( CFG_PREFIX "cropbottom", 0, 0, INT_MAX, NULL,
  80.                                 CROPBOTTOM_TEXT, CROPBOTTOM_LONGTEXT, false )
  81.         add_integer_with_range( CFG_PREFIX "cropleft", 0, 0, INT_MAX, NULL,
  82.                                 CROPLEFT_TEXT, CROPLEFT_LONGTEXT, false )
  83.         add_integer_with_range( CFG_PREFIX "cropright", 0, 0, INT_MAX, NULL,
  84.                                 CROPRIGHT_TEXT, CROPRIGHT_LONGTEXT, false )
  85.     set_section( N_("Padd"), NULL )
  86.         add_integer_with_range( CFG_PREFIX "paddtop", 0, 0, INT_MAX, NULL,
  87.                                 PADDTOP_TEXT, PADDTOP_LONGTEXT, false )
  88.         add_integer_with_range( CFG_PREFIX "paddbottom", 0, 0, INT_MAX, NULL,
  89.                                 PADDBOTTOM_TEXT, PADDBOTTOM_LONGTEXT, false )
  90.         add_integer_with_range( CFG_PREFIX "paddleft", 0, 0, INT_MAX, NULL,
  91.                                 PADDLEFT_TEXT, PADDLEFT_LONGTEXT, false )
  92.         add_integer_with_range( CFG_PREFIX "paddright", 0, 0, INT_MAX, NULL,
  93.                                 PADDRIGHT_TEXT, PADDRIGHT_LONGTEXT, false )
  94. vlc_module_end ()
  95. static const char *const ppsz_filter_options[] = {
  96.     "croptop", "cropbottom", "cropleft", "cropright",
  97.     "paddtop", "paddbottom", "paddleft", "paddright",
  98.     NULL
  99. };
  100. struct filter_sys_t
  101. {
  102.     int i_croptop;
  103.     int i_cropbottom;
  104.     int i_cropleft;
  105.     int i_cropright;
  106.     int i_paddtop;
  107.     int i_paddbottom;
  108.     int i_paddleft;
  109.     int i_paddright;
  110. };
  111. /*****************************************************************************
  112.  * OpenFilter: probe the filter and return score
  113.  *****************************************************************************/
  114. static int OpenFilter( vlc_object_t *p_this )
  115. {
  116.     filter_t *p_filter = (filter_t*)p_this;
  117.     filter_sys_t *p_sys;
  118.     if( !p_filter->b_allow_fmt_out_change )
  119.     {
  120.         msg_Err( p_filter, "Picture format change isn't allowed" );
  121.         return VLC_EGENERIC;
  122.     }
  123.     if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma )
  124.     {
  125.         msg_Err( p_filter, "Input and output chromas don't match" );
  126.         /* In fact we don't really care about this since we're allowed
  127.          * to change the output format ... FIXME? */
  128.         return VLC_EGENERIC;
  129.     }
  130.     p_filter->p_sys = (filter_sys_t *)malloc( sizeof( filter_sys_t ) );
  131.     if( !p_filter->p_sys ) return VLC_ENOMEM;
  132.     config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
  133.                        p_filter->p_cfg );
  134.     p_sys = p_filter->p_sys;
  135. #define GET_OPTION( name ) 
  136.     p_sys->i_ ## name = var_CreateGetInteger( p_filter, CFG_PREFIX #name ); 
  137.     if( p_sys->i_ ## name & 1 ) 
  138.         msg_Warn( p_filter, "Using even values for `" #name "' is recommended" );
  139.     GET_OPTION( croptop )
  140.     GET_OPTION( cropbottom )
  141.     GET_OPTION( cropleft )
  142.     GET_OPTION( cropright )
  143.     GET_OPTION( paddtop )
  144.     GET_OPTION( paddbottom )
  145.     GET_OPTION( paddleft )
  146.     GET_OPTION( paddright )
  147.     p_filter->fmt_out.video.i_height =
  148.     p_filter->fmt_out.video.i_visible_height =
  149.         p_filter->fmt_in.video.i_visible_height
  150.         - p_sys->i_croptop - p_sys->i_cropbottom
  151.         + p_sys->i_paddtop + p_sys->i_paddbottom;
  152.     p_filter->fmt_out.video.i_width =
  153.     p_filter->fmt_out.video.i_visible_width =
  154.         p_filter->fmt_in.video.i_visible_width
  155.         - p_sys->i_cropleft - p_sys->i_cropright
  156.         + p_sys->i_paddleft + p_sys->i_paddright;
  157.     p_filter->pf_video_filter = Filter;
  158.     msg_Dbg( p_filter, "Crop: Top: %d, Bottom: %d, Left: %d, Right: %d",
  159.              p_sys->i_croptop, p_sys->i_cropbottom, p_sys->i_cropleft,
  160.              p_sys->i_cropright );
  161.     msg_Dbg( p_filter, "Padd: Top: %d, Bottom: %d, Left: %d, Right: %d",
  162.              p_sys->i_paddtop, p_sys->i_paddbottom, p_sys->i_paddleft,
  163.              p_sys->i_paddright );
  164.     msg_Dbg( p_filter, "%dx%d -> %dx%d",
  165.              p_filter->fmt_in.video.i_width,
  166.              p_filter->fmt_in.video.i_height,
  167.              p_filter->fmt_out.video.i_width,
  168.              p_filter->fmt_out.video.i_height );
  169.     return VLC_SUCCESS;
  170. }
  171. /*****************************************************************************
  172.  * CloseFilter: clean up the filter
  173.  *****************************************************************************/
  174. static void CloseFilter( vlc_object_t *p_this )
  175. {
  176.     filter_t *p_filter = (filter_t *)p_this;
  177.     free( p_filter->p_sys );
  178. }
  179. /****************************************************************************
  180.  * Filter: the whole thing
  181.  ****************************************************************************/
  182. static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
  183. {
  184.     filter_sys_t *p_sys = p_filter->p_sys;
  185.     picture_t *p_outpic;
  186.     int i_plane;
  187.     int i_width, i_height, i_xcrop, i_ycrop,
  188.         i_outwidth, i_outheight, i_xpadd, i_ypadd;
  189.     const int p_padd_color[] = { 0x00, 0x80, 0x80, 0xff };
  190.     if( !p_pic ) return NULL;
  191.     /* Request output picture */
  192.     p_outpic = filter_NewPicture( p_filter );
  193.     if( !p_outpic )
  194.     {
  195.         picture_Release( p_pic );
  196.         return NULL;
  197.     }
  198.     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  199.     /* p_pic and p_outpic have the same chroma/number of planes but that's
  200.      * about it. */
  201.     {
  202.         plane_t *p_plane = p_pic->p+i_plane;
  203.         plane_t *p_outplane = p_outpic->p+i_plane;
  204.         uint8_t *p_in = p_plane->p_pixels;
  205.         uint8_t *p_out = p_outplane->p_pixels;
  206.         int i_pixel_pitch = p_plane->i_pixel_pitch;
  207.         int i_padd_color = i_plane > 3 ? p_padd_color[0]
  208.                                        : p_padd_color[i_plane];
  209.         /* These assignments assume that the first plane always has
  210.          * a width and height equal to the picture's */
  211.         i_width =     ( ( p_filter->fmt_in.video.i_visible_width
  212.                           - p_sys->i_cropleft - p_sys->i_cropright )
  213.                         * p_plane->i_visible_pitch )
  214.                       / p_pic->p->i_visible_pitch;
  215.         i_height =    ( ( p_filter->fmt_in.video.i_visible_height
  216.                           - p_sys->i_croptop - p_sys->i_cropbottom )
  217.                         * p_plane->i_visible_lines )
  218.                       / p_pic->p->i_visible_lines;
  219.         i_xcrop =     ( p_sys->i_cropleft * p_plane->i_visible_pitch)
  220.                       / p_pic->p->i_visible_pitch;
  221.         i_ycrop =     ( p_sys->i_croptop * p_plane->i_visible_lines)
  222.                       / p_pic->p->i_visible_lines;
  223.         i_outwidth =  ( p_filter->fmt_out.video.i_visible_width
  224.                         * p_outplane->i_visible_pitch )
  225.                       / p_outpic->p->i_visible_pitch;
  226.         i_outheight = ( p_filter->fmt_out.video.i_visible_height
  227.                         * p_outplane->i_visible_lines )
  228.                       / p_outpic->p->i_visible_lines;
  229.         i_xpadd =     ( p_sys->i_paddleft * p_outplane->i_visible_pitch )
  230.                       / p_outpic->p->i_visible_pitch;
  231.         i_ypadd =     ( p_sys->i_paddtop * p_outplane->i_visible_lines )
  232.                        / p_outpic->p->i_visible_lines;
  233.         /* Crop the top */
  234.         p_in += i_ycrop * p_plane->i_pitch;
  235.         /* Padd on the top */
  236.         vlc_memset( p_out, i_padd_color, i_ypadd * p_outplane->i_pitch );
  237.         p_out += i_ypadd * p_outplane->i_pitch;
  238.         int i_line;
  239.         for( i_line = 0; i_line < i_height; i_line++ )
  240.         {
  241.             uint8_t *p_in_next = p_in + p_plane->i_pitch;
  242.             uint8_t *p_out_next = p_out + p_outplane->i_pitch;
  243.             /* Crop on the left */
  244.             p_in += i_xcrop * i_pixel_pitch;
  245.             /* Padd on the left */
  246.             vlc_memset( p_out, i_padd_color, i_xpadd * i_pixel_pitch );
  247.             p_out += i_xpadd * i_pixel_pitch;
  248.             /* Copy the image and crop on the right */
  249.             vlc_memcpy( p_out, p_in, i_width * i_pixel_pitch );
  250.             p_out += i_width * i_pixel_pitch;
  251.             p_in += i_width * i_pixel_pitch;
  252.             /* Padd on the right */
  253.             vlc_memset( p_out, i_padd_color,
  254.                         ( i_outwidth - i_xpadd - i_width ) * i_pixel_pitch );
  255.             /* Got to begining of the next line */
  256.             p_in = p_in_next;
  257.             p_out = p_out_next;
  258.         }
  259.         /* Padd on the bottom */
  260.         vlc_memset( p_out, i_padd_color,
  261.                  ( i_outheight - i_ypadd - i_height ) * p_outplane->i_pitch );
  262.     }
  263.     return CopyInfoAndRelease( p_outpic, p_pic );
  264. }