1 /*****************************************************************************
2 * adjust_sat_hue.c : Hue/Saturation executive part of adjust plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2011 VideoLAN
6 * Authors: Simon Latapie <garf@via.ecp.fr>
7 * Antoine Cellerier <dionoea -at- videolan d0t org>
8 * Martin Briza <gamajun@seznam.cz> (SSE)
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.
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.
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 *****************************************************************************/
29 #include <vlc_filter.h>
30 #include "filter_picture.h"
31 #include "adjust_sat_hue.h"
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) \
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) \
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); \
52 *p_out_v = clip_uint8_vlc( (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
53 * i_sat) >> 8) + 128); \
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; \
61 *p_out_v = (( ((i_v * i_cos - i_u * i_sin - i_y) >> 8) \
62 * i_sat) >> 8) + 128; \
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
69 /*****************************************************************************
70 * Hue and saturation adjusting routines
71 *****************************************************************************/
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
)
76 uint8_t *p_in
, *p_in_v
, *p_in_end
, *p_line_end
;
77 uint8_t *p_out
, *p_out_v
;
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;
84 p_out
= p_outpic
->p
[U_PLANE
].p_pixels
;
85 p_out_v
= p_outpic
->p
[V_PLANE
].p_pixels
;
89 for( ; p_in
< p_in_end
; )
91 p_line_end
= p_in
+ p_pic
->p
[U_PLANE
].i_visible_pitch
- 8;
93 for( ; p_in
< p_line_end
; )
95 /* Do 8 pixels at a time */
96 ADJUST_8_TIMES( PLANAR_WRITE_UV_CLIP() );
101 for( ; p_in
< p_line_end
; )
103 PLANAR_WRITE_UV_CLIP();
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
;
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
)
122 uint8_t *p_in
, *p_in_v
, *p_in_end
, *p_line_end
;
123 uint8_t *p_out
, *p_out_v
;
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;
130 p_out
= p_outpic
->p
[U_PLANE
].p_pixels
;
131 p_out_v
= p_outpic
->p
[V_PLANE
].p_pixels
;
135 for( ; p_in
< p_in_end
; )
137 p_line_end
= p_in
+ p_pic
->p
[U_PLANE
].i_visible_pitch
- 8;
139 for( ; p_in
< p_line_end
; )
141 /* Do 8 pixels at a time */
142 ADJUST_8_TIMES( PLANAR_WRITE_UV() );
147 for( ; p_in
< p_line_end
; )
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
;
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
)
168 uint8_t *p_in
, *p_in_v
, *p_in_end
, *p_line_end
;
169 uint8_t *p_out
, *p_out_v
;
171 int i_y_offset
, i_u_offset
, i_v_offset
;
172 int i_visible_lines
, i_pitch
, i_visible_pitch
;
175 if ( GetPackedYuvOffsets( p_pic
->format
.i_chroma
, &i_y_offset
,
176 &i_u_offset
, &i_v_offset
) != VLC_SUCCESS
)
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
;
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;
187 p_out
= p_outpic
->p
->p_pixels
+ i_u_offset
;
188 p_out_v
= p_outpic
->p
->p_pixels
+ i_v_offset
;
192 for( ; p_in
< p_in_end
; )
194 p_line_end
= p_in
+ i_visible_pitch
- 8 * 4;
196 for( ; p_in
< p_line_end
; )
198 /* Do 8 pixels at a time */
199 ADJUST_8_TIMES( PACKED_WRITE_UV_CLIP() );
204 for( ; p_in
< p_line_end
; )
206 PACKED_WRITE_UV_CLIP();
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
;
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
)
221 uint8_t *p_in
, *p_in_v
, *p_in_end
, *p_line_end
;
222 uint8_t *p_out
, *p_out_v
;
224 int i_y_offset
, i_u_offset
, i_v_offset
;
225 int i_visible_lines
, i_pitch
, i_visible_pitch
;
228 if ( GetPackedYuvOffsets( p_pic
->format
.i_chroma
, &i_y_offset
,
229 &i_u_offset
, &i_v_offset
) != VLC_SUCCESS
)
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
;
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;
240 p_out
= p_outpic
->p
->p_pixels
+ i_u_offset
;
241 p_out_v
= p_outpic
->p
->p_pixels
+ i_v_offset
;
245 for( ; p_in
< p_in_end
; )
247 p_line_end
= p_in
+ i_visible_pitch
- 8 * 4;
249 for( ; p_in
< p_line_end
; )
251 /* Do 8 pixels at a time */
252 ADJUST_8_TIMES( PACKED_WRITE_UV() );
257 for( ; p_in
< p_line_end
; )
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
;