]> git.sesse.net Git - vlc/blob - modules/video_filter/adjust_sat_hue.c
decoder: fix data race in input_DecoderChangePause()
[vlc] / modules / video_filter / adjust_sat_hue.c
1 /*****************************************************************************
2  * adjust_sat_hue.c : Hue/Saturation executive part of adjust plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2011 VideoLAN
5  *
6  * Authors: Simon Latapie <garf@via.ecp.fr>
7  *          Antoine Cellerier <dionoea -at- videolan d0t org>
8  *          Martin Briza <gamajun@seznam.cz> (SSE)
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #   include "config.h"
27 #endif
28
29 #include <vlc_filter.h>
30 #include "filter_picture.h"
31 #include "adjust_sat_hue.h"
32
33 #define PLANAR_WRITE_UV_CLIP() \
34     i_u = *p_in++ ; i_v = *p_in_v++ ; \
35     *p_out++ = clip_uint8_vlc( (( ((i_u * i_cos + i_v * i_sin - i_x) >> 8) \
36                            * i_sat) >> 8) + 128); \
37     *p_out_v++ = clip_uint8_vlc( (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
38                            * i_sat) >> 8) + 128)
39
40 #define PLANAR_WRITE_UV() \
41     i_u = *p_in++ ; i_v = *p_in_v++ ; \
42     *p_out++ = (( ((i_u * i_cos + i_v * i_sin - i_x) >> 8) \
43                        * i_sat) >> 8) + 128; \
44     *p_out_v++ = (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
45                        * i_sat) >> 8) + 128
46
47 #define PACKED_WRITE_UV_CLIP() \
48     i_u = *p_in; p_in += 4; i_v = *p_in_v; p_in_v += 4; \
49     *p_out = clip_uint8_vlc( (( ((i_u * i_cos + i_v * i_sin - i_x) >> 8) \
50                            * i_sat) >> 8) + 128); \
51     p_out += 4; \
52     *p_out_v = clip_uint8_vlc( (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
53                            * i_sat) >> 8) + 128); \
54     p_out_v += 4
55
56 #define PACKED_WRITE_UV() \
57     i_u = *p_in; p_in += 4; i_v = *p_in_v; p_in_v += 4; \
58     *p_out = (( ((i_u * i_cos + i_v * i_sin - i_x) >> 8) \
59                        * i_sat) >> 8) + 128; \
60     p_out += 4; \
61     *p_out_v = (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
62                        * i_sat) >> 8) + 128; \
63     p_out_v += 4
64
65 #define ADJUST_2_TIMES(x) x; x
66 #define ADJUST_4_TIMES(x) x; x; x; x
67 #define ADJUST_8_TIMES(x) x; x; x; x; x; x; x; x
68
69 /*****************************************************************************
70  * Hue and saturation adjusting routines
71  *****************************************************************************/
72
73 int planar_sat_hue_clip_C( picture_t * p_pic, picture_t * p_outpic, int i_sin, int i_cos,
74                          int i_sat, int i_x, int i_y )
75 {
76     uint8_t *p_in, *p_in_v, *p_in_end, *p_line_end;
77     uint8_t *p_out, *p_out_v;
78
79     p_in = p_pic->p[U_PLANE].p_pixels;
80     p_in_v = p_pic->p[V_PLANE].p_pixels;
81     p_in_end = p_in + p_pic->p[U_PLANE].i_visible_lines
82                       * p_pic->p[U_PLANE].i_pitch - 8;
83
84     p_out = p_outpic->p[U_PLANE].p_pixels;
85     p_out_v = p_outpic->p[V_PLANE].p_pixels;
86
87     uint8_t i_u, i_v;
88
89     for( ; p_in < p_in_end ; )
90     {
91         p_line_end = p_in + p_pic->p[U_PLANE].i_visible_pitch - 8;
92
93         for( ; p_in < p_line_end ; )
94         {
95             /* Do 8 pixels at a time */
96             ADJUST_8_TIMES( PLANAR_WRITE_UV_CLIP() );
97         }
98
99         p_line_end += 8;
100
101         for( ; p_in < p_line_end ; )
102         {
103             PLANAR_WRITE_UV_CLIP();
104         }
105
106         p_in += p_pic->p[U_PLANE].i_pitch
107                 - p_pic->p[U_PLANE].i_visible_pitch;
108         p_in_v += p_pic->p[V_PLANE].i_pitch
109                 - p_pic->p[V_PLANE].i_visible_pitch;
110         p_out += p_outpic->p[U_PLANE].i_pitch
111                 - p_outpic->p[U_PLANE].i_visible_pitch;
112         p_out_v += p_outpic->p[V_PLANE].i_pitch
113                     - p_outpic->p[V_PLANE].i_visible_pitch;
114     }
115
116     return VLC_SUCCESS;
117 }
118
119 int planar_sat_hue_C( picture_t * p_pic, picture_t * p_outpic, int i_sin, int i_cos,
120                          int i_sat, int i_x, int i_y )
121 {
122     uint8_t *p_in, *p_in_v, *p_in_end, *p_line_end;
123     uint8_t *p_out, *p_out_v;
124
125     p_in = p_pic->p[U_PLANE].p_pixels;
126     p_in_v = p_pic->p[V_PLANE].p_pixels;
127     p_in_end = p_in + p_pic->p[U_PLANE].i_visible_lines
128                       * p_pic->p[U_PLANE].i_pitch - 8;
129
130     p_out = p_outpic->p[U_PLANE].p_pixels;
131     p_out_v = p_outpic->p[V_PLANE].p_pixels;
132
133     uint8_t i_u, i_v;
134
135     for( ; p_in < p_in_end ; )
136     {
137         p_line_end = p_in + p_pic->p[U_PLANE].i_visible_pitch - 8;
138
139         for( ; p_in < p_line_end ; )
140         {
141             /* Do 8 pixels at a time */
142             ADJUST_8_TIMES( PLANAR_WRITE_UV() );
143         }
144
145         p_line_end += 8;
146
147         for( ; p_in < p_line_end ; )
148         {
149             PLANAR_WRITE_UV();
150         }
151
152         p_in += p_pic->p[U_PLANE].i_pitch
153                 - p_pic->p[U_PLANE].i_visible_pitch;
154         p_in_v += p_pic->p[V_PLANE].i_pitch
155                 - p_pic->p[V_PLANE].i_visible_pitch;
156         p_out += p_outpic->p[U_PLANE].i_pitch
157                 - p_outpic->p[U_PLANE].i_visible_pitch;
158         p_out_v += p_outpic->p[V_PLANE].i_pitch
159                     - p_outpic->p[V_PLANE].i_visible_pitch;
160     }
161
162     return VLC_SUCCESS;
163 }
164
165 int packed_sat_hue_clip_C( picture_t * p_pic, picture_t * p_outpic, int i_sin, int i_cos,
166                          int i_sat, int i_x, int i_y )
167 {
168     uint8_t *p_in, *p_in_v, *p_in_end, *p_line_end;
169     uint8_t *p_out, *p_out_v;
170
171     int i_y_offset, i_u_offset, i_v_offset;
172     int i_visible_lines, i_pitch, i_visible_pitch;
173
174
175     if ( GetPackedYuvOffsets( p_pic->format.i_chroma, &i_y_offset,
176                               &i_u_offset, &i_v_offset ) != VLC_SUCCESS )
177         return VLC_EGENERIC;
178
179     i_visible_lines = p_pic->p->i_visible_lines;
180     i_pitch = p_pic->p->i_pitch;
181     i_visible_pitch = p_pic->p->i_visible_pitch;
182
183     p_in = p_pic->p->p_pixels + i_u_offset;
184     p_in_v = p_pic->p->p_pixels + i_v_offset;
185     p_in_end = p_in + i_visible_lines * i_pitch - 8 * 4;
186
187     p_out = p_outpic->p->p_pixels + i_u_offset;
188     p_out_v = p_outpic->p->p_pixels + i_v_offset;
189
190     uint8_t i_u, i_v;
191
192     for( ; p_in < p_in_end ; )
193     {
194         p_line_end = p_in + i_visible_pitch - 8 * 4;
195
196         for( ; p_in < p_line_end ; )
197         {
198             /* Do 8 pixels at a time */
199             ADJUST_8_TIMES( PACKED_WRITE_UV_CLIP() );
200         }
201
202         p_line_end += 8 * 4;
203
204         for( ; p_in < p_line_end ; )
205         {
206             PACKED_WRITE_UV_CLIP();
207         }
208
209         p_in += i_pitch - i_visible_pitch;
210         p_in_v += i_pitch - i_visible_pitch;
211         p_out += i_pitch - i_visible_pitch;
212         p_out_v += i_pitch - i_visible_pitch;
213     }
214
215     return VLC_SUCCESS;
216 }
217
218 int packed_sat_hue_C( picture_t * p_pic, picture_t * p_outpic, int i_sin,
219                       int i_cos, int i_sat, int i_x, int i_y )
220 {
221     uint8_t *p_in, *p_in_v, *p_in_end, *p_line_end;
222     uint8_t *p_out, *p_out_v;
223
224     int i_y_offset, i_u_offset, i_v_offset;
225     int i_visible_lines, i_pitch, i_visible_pitch;
226
227
228     if ( GetPackedYuvOffsets( p_pic->format.i_chroma, &i_y_offset,
229                               &i_u_offset, &i_v_offset ) != VLC_SUCCESS )
230         return VLC_EGENERIC;
231
232     i_visible_lines = p_pic->p->i_visible_lines;
233     i_pitch = p_pic->p->i_pitch;
234     i_visible_pitch = p_pic->p->i_visible_pitch;
235
236     p_in = p_pic->p->p_pixels + i_u_offset;
237     p_in_v = p_pic->p->p_pixels + i_v_offset;
238     p_in_end = p_in + i_visible_lines * i_pitch - 8 * 4;
239
240     p_out = p_outpic->p->p_pixels + i_u_offset;
241     p_out_v = p_outpic->p->p_pixels + i_v_offset;
242
243     uint8_t i_u, i_v;
244
245     for( ; p_in < p_in_end ; )
246     {
247         p_line_end = p_in + i_visible_pitch - 8 * 4;
248
249         for( ; p_in < p_line_end ; )
250         {
251             /* Do 8 pixels at a time */
252             ADJUST_8_TIMES( PACKED_WRITE_UV() );
253         }
254
255         p_line_end += 8 * 4;
256
257         for( ; p_in < p_line_end ; )
258         {
259             PACKED_WRITE_UV();
260         }
261
262         p_in += i_pitch - i_visible_pitch;
263         p_in_v += i_pitch - i_visible_pitch;
264         p_out += i_pitch - i_visible_pitch;
265         p_out_v += i_pitch - i_visible_pitch;
266     }
267
268     return VLC_SUCCESS;
269 }