20% faster hqdn3d on x86_64
[mplayer/glamo.git] / libmpcodecs / vf_rectangle.c
blob3431d5b90f3447fc09d3ba986b8fe944794d9e0c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "mp_image.h"
5 #include "mp_msg.h"
6 #include "vf.h"
8 #include "libvo/fastmemcpy.h"
9 #include "libavutil/common.h"
11 struct vf_priv_s {
12 int x, y, w, h;
15 static int
16 config(struct vf_instance_s* vf,
17 int width, int height, int d_width, int d_height,
18 unsigned int flags, unsigned int outfmt)
20 if (vf->priv->w < 0 || width < vf->priv->w)
21 vf->priv->w = width;
22 if (vf->priv->h < 0 || height < vf->priv->h)
23 vf->priv->h = height;
24 if (vf->priv->x < 0)
25 vf->priv->x = (width - vf->priv->w) / 2;
26 if (vf->priv->y < 0)
27 vf->priv->y = (height - vf->priv->h) / 2;
28 if (vf->priv->w + vf->priv->x > width
29 || vf->priv->h + vf->priv->y > height) {
30 mp_msg(MSGT_VFILTER,MSGL_WARN,"rectangle: bad position/width/height - rectangle area is out of the original!\n");
31 return 0;
33 return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
36 static int
37 control(struct vf_instance_s* vf, int request, void *data)
39 const int *const tmp = data;
40 switch(request){
41 case VFCTRL_CHANGE_RECTANGLE:
42 switch (tmp[0]){
43 case 0:
44 vf->priv->w += tmp[1];
45 return 1;
46 break;
47 case 1:
48 vf->priv->h += tmp[1];
49 return 1;
50 break;
51 case 2:
52 vf->priv->x += tmp[1];
53 return 1;
54 break;
55 case 3:
56 vf->priv->y += tmp[1];
57 return 1;
58 break;
59 default:
60 mp_msg(MSGT_VFILTER,MSGL_FATAL,"Unknown param %d \n", tmp[0]);
61 return 0;
64 return vf_next_control(vf, request, data);
65 return 0;
67 static int
68 put_image(struct vf_instance_s* vf, mp_image_t* mpi, double pts){
69 mp_image_t* dmpi;
70 unsigned int bpp = mpi->bpp / 8;
71 int x, y, w, h;
72 dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP,
73 MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
74 mpi->w, mpi->h);
76 memcpy_pic(dmpi->planes[0],mpi->planes[0],mpi->w*bpp, mpi->h,
77 dmpi->stride[0],mpi->stride[0]);
78 if(mpi->flags&MP_IMGFLAG_PLANAR && mpi->flags&MP_IMGFLAG_YUV){
79 memcpy_pic(dmpi->planes[1],mpi->planes[1],
80 mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
81 dmpi->stride[1],mpi->stride[1]);
82 memcpy_pic(dmpi->planes[2],mpi->planes[2],
83 mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
84 dmpi->stride[2],mpi->stride[2]);
87 /* Draw the rectangle */
89 mp_msg(MSGT_VFILTER,MSGL_INFO, "rectangle: -vf rectangle=%d:%d:%d:%d \n", vf->priv->w, vf->priv->h, vf->priv->x, vf->priv->y);
91 x = FFMIN(vf->priv->x, dmpi->width);
92 x = FFMAX(x, 0);
94 w = vf->priv->x + vf->priv->w - 1 - x;
95 w = FFMIN(w, dmpi->width - x);
96 w = FFMAX(w, 0);
98 y = FFMIN(vf->priv->y, dmpi->height);
99 y = FFMAX(y, 0);
101 h = vf->priv->y + vf->priv->h - 1 - y;
102 h = FFMIN(h, dmpi->height - y);
103 h = FFMAX(h, 0);
105 if (0 <= vf->priv->y && vf->priv->y <= dmpi->height) {
106 unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
107 unsigned int count = w * bpp;
108 while (count--)
109 p[count] = 0xff - p[count];
111 if (h != 1 && vf->priv->y + vf->priv->h - 1 <= mpi->height) {
112 unsigned char *p = dmpi->planes[0] + (vf->priv->y + vf->priv->h - 1) * dmpi->stride[0] + x * bpp;
113 unsigned int count = w * bpp;
114 while (count--)
115 p[count] = 0xff - p[count];
117 if (0 <= vf->priv->x && vf->priv->x <= dmpi->width) {
118 unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
119 unsigned int count = h;
120 while (count--) {
121 unsigned int i = bpp;
122 while (i--)
123 p[i] = 0xff - p[i];
124 p += dmpi->stride[0];
127 if (w != 1 && vf->priv->x + vf->priv->w - 1 <= mpi->width) {
128 unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + (vf->priv->x + vf->priv->w - 1) * bpp;
129 unsigned int count = h;
130 while (count--) {
131 unsigned int i = bpp;
132 while (i--)
133 p[i] = 0xff - p[i];
134 p += dmpi->stride[0];
137 return vf_next_put_image(vf, dmpi, pts);
140 static int
141 open(vf_instance_t* vf, char* args) {
142 vf->config = config;
143 vf->control = control;
144 vf->put_image = put_image;
145 vf->priv = malloc(sizeof(struct vf_priv_s));
146 vf->priv->x = -1;
147 vf->priv->y = -1;
148 vf->priv->w = -1;
149 vf->priv->h = -1;
150 if (args)
151 sscanf(args, "%d:%d:%d:%d",
152 &vf->priv->w, &vf->priv->h, &vf->priv->x, &vf->priv->y);
153 return 1;
156 const vf_info_t vf_info_rectangle = {
157 "draw rectangle",
158 "rectangle",
159 "Kim Minh Kaplan",
161 open,
162 NULL