Mercurial > mplayer.hg
comparison libmpcodecs/vf_eq2.c @ 7517:9d433771b6d0
-vf eq2, LUT-based brightness/contrast/gamma correction (Y-only)
by Hampa Hug <hhug@student.ethz.ch>
author | arpi |
---|---|
date | Fri, 27 Sep 2002 21:08:36 +0000 |
parents | |
children | b667328dc62e |
comparison
equal
deleted
inserted
replaced
7516:657041b7236b | 7517:9d433771b6d0 |
---|---|
1 /* | |
2 * vf_eq2.c | |
3 * | |
4 * Extended software equalizer (brightness, contrast, gamma) | |
5 * | |
6 * Hampa Hug <hhug@student.ethz.ch> | |
7 * | |
8 */ | |
9 | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <math.h> | |
14 | |
15 #include "../config.h" | |
16 #include "../mp_msg.h" | |
17 | |
18 #include "img_format.h" | |
19 #include "mp_image.h" | |
20 #include "vf.h" | |
21 | |
22 | |
23 typedef struct vf_priv_s { | |
24 unsigned char *buf; | |
25 int buf_w; | |
26 int buf_h; | |
27 | |
28 double contrast; | |
29 double bright; | |
30 double gamma; | |
31 | |
32 unsigned char lut[256]; | |
33 } vf_eq2_t; | |
34 | |
35 | |
36 static | |
37 void create_lut (vf_eq2_t *eq2) | |
38 { | |
39 unsigned i; | |
40 double c, b, g; | |
41 double v; | |
42 | |
43 c = eq2->contrast; | |
44 b = eq2->bright; | |
45 g = eq2->gamma; | |
46 | |
47 if ((g < 0.001) || (g > 1000.0)) { | |
48 g = 1.0; | |
49 } | |
50 | |
51 fprintf (stderr, "vf_eq2: c=%.2f b=%.2f g=%.4f\n", c, b, g); | |
52 | |
53 g = 1.0 / g; | |
54 | |
55 for (i = 0; i < 256; i++) { | |
56 v = (double) i / 255.0; | |
57 v = c * (v - 0.5) + 0.5 + b; | |
58 | |
59 if (v <= 0.0) { | |
60 eq2->lut[i] = 0; | |
61 } | |
62 else { | |
63 v = pow (v, g); | |
64 | |
65 if (v >= 1.0) { | |
66 eq2->lut[i] = 255; | |
67 } | |
68 else { | |
69 eq2->lut[i] = (unsigned char) (256.0 * v); | |
70 } | |
71 } | |
72 } | |
73 } | |
74 | |
75 /* could inline this */ | |
76 static | |
77 void process (unsigned char *dst, int dstride, unsigned char *src, int sstride, | |
78 int w, int h, unsigned char lut[256]) | |
79 { | |
80 int i, j; | |
81 | |
82 for (j = 0; j < h; j++) { | |
83 for (i = 0; i < w; i++) { | |
84 *(dst++) = lut[*(src++)]; | |
85 } | |
86 | |
87 src += sstride - w; | |
88 dst += dstride - w; | |
89 } | |
90 } | |
91 | |
92 static | |
93 int put_image (vf_instance_t *vf, mp_image_t *src) | |
94 { | |
95 mp_image_t *dst; | |
96 vf_eq2_t *eq2; | |
97 | |
98 eq2 = vf->priv; | |
99 | |
100 if ((eq2->buf == NULL) || (eq2->buf_w != src->stride[0]) || (eq2->buf_h != src->h)) { | |
101 eq2->buf = (unsigned char *) realloc (eq2->buf, src->stride[0] * src->h); | |
102 eq2->buf_w = src->stride[0]; | |
103 eq2->buf_h = src->h; | |
104 } | |
105 | |
106 dst = vf_get_image (vf->next, src->imgfmt, MP_IMGTYPE_EXPORT, 0, src->w, src->h); | |
107 | |
108 dst->stride[0] = src->stride[0]; | |
109 dst->stride[1] = src->stride[1]; | |
110 dst->stride[2] = src->stride[2]; | |
111 dst->planes[0] = vf->priv->buf; | |
112 dst->planes[1] = src->planes[1]; | |
113 dst->planes[2] = src->planes[2]; | |
114 | |
115 process ( | |
116 dst->planes[0], dst->stride[0], src->planes[0], src->stride[0], | |
117 src->w, src->h, eq2->lut | |
118 ); | |
119 | |
120 return vf_next_put_image (vf, dst); | |
121 } | |
122 | |
123 static | |
124 int control (vf_instance_t *vf, int request, void *data) | |
125 { | |
126 vf_equalizer_t *eq; | |
127 | |
128 switch (request) { | |
129 case VFCTRL_SET_EQUALIZER: | |
130 eq = (vf_equalizer_t *) data; | |
131 | |
132 if (strcmp (eq->item, "gamma") == 0) { | |
133 vf->priv->gamma = exp (log (8.0) * eq->value / 100.0); | |
134 create_lut (vf->priv); | |
135 return CONTROL_TRUE; | |
136 } | |
137 else if (strcmp (eq->item, "contrast") == 0) { | |
138 vf->priv->contrast = (1.0 / 100.0) * (eq->value + 100); | |
139 create_lut (vf->priv); | |
140 return CONTROL_TRUE; | |
141 } | |
142 else if (strcmp (eq->item, "brightness") == 0) { | |
143 vf->priv->bright = (1.0 / 100.0) * eq->value; | |
144 create_lut (vf->priv); | |
145 return CONTROL_TRUE; | |
146 } | |
147 break; | |
148 | |
149 case VFCTRL_GET_EQUALIZER: | |
150 eq = (vf_equalizer_t *) data; | |
151 if (strcmp (eq->item, "gamma") == 0) { | |
152 eq->value = (int) (100.0 * log (vf->priv->gamma) / log (8.0)); | |
153 return CONTROL_TRUE; | |
154 } | |
155 else if (strcmp (eq->item, "contrast") == 0) { | |
156 eq->value = (int) (100.0 * vf->priv->contrast) - 100; | |
157 return CONTROL_TRUE; | |
158 } | |
159 else if (strcmp (eq->item, "brightness") == 0) { | |
160 eq->value = (int) (100.0 * vf->priv->bright); | |
161 return CONTROL_TRUE; | |
162 } | |
163 break; | |
164 } | |
165 | |
166 return vf_next_control (vf, request, data); | |
167 } | |
168 | |
169 static | |
170 int query_format (vf_instance_t *vf, unsigned fmt) | |
171 { | |
172 switch (fmt) { | |
173 case IMGFMT_YVU9: | |
174 case IMGFMT_IF09: | |
175 case IMGFMT_YV12: | |
176 case IMGFMT_I420: | |
177 case IMGFMT_IYUV: | |
178 case IMGFMT_CLPL: | |
179 case IMGFMT_Y800: | |
180 case IMGFMT_Y8: | |
181 case IMGFMT_NV12: | |
182 case IMGFMT_444P: | |
183 case IMGFMT_422P: | |
184 case IMGFMT_411P: | |
185 return vf_next_query_format (vf, fmt); | |
186 } | |
187 | |
188 return 0; | |
189 } | |
190 | |
191 static | |
192 void uninit (vf_instance_t *vf) | |
193 { | |
194 if (vf->priv != NULL) { | |
195 free (vf->priv->buf); | |
196 free (vf->priv); | |
197 } | |
198 } | |
199 | |
200 static | |
201 int open (vf_instance_t *vf, char *args) | |
202 { | |
203 vf_eq2_t *eq2; | |
204 | |
205 vf->control = control; | |
206 vf->query_format = query_format; | |
207 vf->put_image = put_image; | |
208 vf->uninit = uninit; | |
209 | |
210 vf->priv = (vf_eq2_t *) malloc (sizeof (vf_eq2_t)); | |
211 eq2 = vf->priv; | |
212 | |
213 eq2->buf = NULL; | |
214 eq2->buf_w = 0; | |
215 eq2->buf_h = 0; | |
216 | |
217 eq2->gamma = 1.0; | |
218 eq2->contrast = 1.0; | |
219 eq2->bright = 0.0; | |
220 | |
221 if (args != NULL) { | |
222 sscanf (args, "%lf:%lf:%lf", &eq2->gamma, &eq2->contrast, &eq2->bright); | |
223 } | |
224 | |
225 create_lut (eq2); | |
226 | |
227 return 1; | |
228 } | |
229 | |
230 vf_info_t vf_info_eq2 = { | |
231 "extended software equalizer", | |
232 "eq2", | |
233 "Hampa Hug", | |
234 "", | |
235 &open | |
236 }; |