1 /*****************************************************************************
2 * puzzle_lib.c : Useful functions used by puzzle game filter
3 *****************************************************************************
4 * Copyright (C) 2005-2009 VLC authors and VideoLAN
5 * Copyright (C) 2013 Vianney Boyer
8 * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
9 * Vianney Boyer <vlcvboyer -at- gmail -dot- com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_filter.h>
40 #include "filter_picture.h"
42 #include "puzzle_lib.h"
44 const char *ppsz_shuffle_button[SHUFFLE_LINES] =
46 "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
47 "oooooooooooooo oooooooooooooooooooooooooooo oooooooo oooooo ooooooooooooooo",
48 "oooooooooooooo ooooooooooooooooooooooooooo ooooooooo oooooooo ooooooooooooooo",
49 "oooooooooooooo ooooooooooooooooooooooooooo ooooooooo oooooooo ooooooooooooooo",
50 "oo ooooooo o ooooooo oooo oooooo oooooo oooooo oooooooo ooo",
51 "o oooo oooooo ooo oooooo oooo ooooooo ooooooooo oooooooo ooooooo oo oo",
52 "o ooooooooooo oooo oooooo oooo ooooooo ooooooooo oooooooo oooooo oooo o",
53 "o ooooooo oooo oooooo oooo ooooooo ooooooooo oooooooo oooooo o",
54 "oo oooooo oooo oooooo oooo ooooooo ooooooooo oooooooo oooooo ooooooo",
55 "oooooo oooooo oooo oooooo oooo ooooooo ooooooooo oooooooo oooooo ooooooo",
56 "o oooo oooooo oooo oooooo ooo ooooooo ooooooooo oooooooo ooooooo oooo o",
57 "oo ooooooo oooo ooooooo o ooooooo ooooooooo oooooooo oooooooo oo",
58 "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
61 const char *ppsz_rot_arrow_sign[ARROW_LINES] =
78 const char *ppsz_mir_arrow_sign[ARROW_LINES] =
95 /*****************************************************************************
96 * fill target image (clean memory)
97 *****************************************************************************/
98 void puzzle_preset_desk_background( picture_t *p_pic_out, uint8_t Y, uint8_t U, uint8_t V)
102 for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
103 if (i_plane == Y_PLANE)
105 else if (i_plane == U_PLANE)
107 else if (i_plane == V_PLANE)
110 const int32_t i_dst_pitch = p_pic_out->p[i_plane].i_pitch;
111 const int32_t i_dst_lines = p_pic_out->p[i_plane].i_lines;
113 uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
115 for (int32_t y = 0; y < i_dst_lines; y++)
116 memset(&p_dst[y * i_dst_pitch], i_c, i_dst_pitch);
120 /*****************************************************************************
121 * draw the borders around the visible desk
122 *****************************************************************************/
123 void puzzle_draw_borders( filter_t *p_filter, picture_t *p_pic_in, picture_t *p_pic_out)
125 filter_sys_t *p_sys = p_filter->p_sys;
127 for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
128 const int32_t i_in_pitch = p_sys->ps_pict_planes[i_plane].i_pitch;
129 const int32_t i_out_pitch = p_sys->ps_desk_planes[i_plane].i_pitch;
130 const int32_t i_lines = p_sys->ps_desk_planes[i_plane].i_lines;
131 const int32_t i_visible_pitch = p_sys->ps_desk_planes[i_plane].i_visible_pitch;
132 const int32_t i_border_pitch = p_sys->ps_desk_planes[i_plane].i_border_width * p_sys->ps_desk_planes[i_plane].i_pixel_pitch;
133 const int32_t i_border_lines = p_sys->ps_desk_planes[i_plane].i_border_lines;
135 uint8_t *p_src = p_pic_in->p[i_plane].p_pixels;
136 uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
138 for (int32_t y = 0 ; y < i_border_lines; y++)
139 memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], i_visible_pitch);
141 for (int32_t y = i_lines - i_border_lines ; y < i_lines; y++)
142 memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], i_visible_pitch);
144 for (int32_t y = i_border_lines ; y < i_lines - i_border_lines; y++) {
145 memcpy( &p_dst[y * i_out_pitch], &p_src[y * i_in_pitch], i_border_pitch);
146 memcpy( &p_dst[y * i_out_pitch + i_visible_pitch - i_border_pitch], &p_src[y * i_in_pitch + i_visible_pitch - i_border_pitch], i_border_pitch);
151 /*****************************************************************************
152 * draw preview in a corner of the desk
153 *****************************************************************************/
154 void puzzle_draw_preview( filter_t *p_filter, picture_t *p_pic_in, picture_t *p_pic_out)
156 filter_sys_t *p_sys = p_filter->p_sys;
158 for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
159 int32_t i_preview_offset = 0;
160 int32_t i_preview_width = p_sys->ps_desk_planes[i_plane].i_width * p_sys->s_current_param.i_preview_size / 100;
161 int32_t i_preview_lines = p_pic_out->p[i_plane].i_visible_lines * p_sys->s_current_param.i_preview_size / 100;
162 int32_t i_pixel_pitch = p_pic_out->p[i_plane].i_pixel_pitch;
164 const int32_t i_src_pitch = p_pic_in->p[i_plane].i_pitch;
165 const int32_t i_dst_pitch = p_pic_out->p[i_plane].i_pitch;
167 uint8_t *p_src = p_pic_in->p[i_plane].p_pixels;
168 uint8_t *p_dst = p_pic_out->p[i_plane].p_pixels;
170 switch ( p_sys->i_preview_pos ) {
172 i_preview_offset = 0;
176 (p_sys->ps_desk_planes[i_plane].i_width - 1 - i_preview_width) * i_pixel_pitch;
180 (p_sys->ps_desk_planes[i_plane].i_width - 1 - i_preview_width) * i_pixel_pitch
181 + ((int32_t) ( p_sys->ps_desk_planes[i_plane].i_lines - 1 - i_preview_lines )) * i_dst_pitch;
184 i_preview_offset = ((int32_t) ( p_sys->ps_desk_planes[i_plane].i_lines - 1 - i_preview_lines )) * i_dst_pitch;
187 i_preview_offset = 0;
191 for ( int32_t y = 0; y < i_preview_lines; y++ )
192 for ( int32_t x = 0; x < i_preview_width; x++ )
193 memcpy( &p_dst[ y * i_dst_pitch + x * i_pixel_pitch + i_preview_offset ],
194 &p_src[ ( y * 100 / p_sys->s_current_param.i_preview_size ) * i_src_pitch
195 + ( x * 100 / p_sys->s_current_param.i_preview_size ) * i_pixel_pitch ],
200 /*****************************************************************************
201 * draw sign/icon/symbol in the output picture
202 *****************************************************************************/
203 void puzzle_draw_sign(picture_t *p_pic_out, int32_t i_x, int32_t i_y, int32_t i_width, int32_t i_lines, const char **ppsz_sign, bool b_reverse)
205 plane_t *p_out = &p_pic_out->p[Y_PLANE];
206 int32_t i_pixel_pitch = p_pic_out->p[Y_PLANE].i_pixel_pitch;
210 i_Y = ( p_out->p_pixels[ i_y * p_out->i_pitch + i_x ] >= 0x7F ) ? 0x00 : 0xFF;
212 for( int32_t y = 0; y < i_lines ; y++ )
213 for( int32_t x = 0; x < i_width; x++ ) {
214 int32_t i_dst_x = ( x + i_x ) * i_pixel_pitch;
215 int32_t i_dst_y = y + i_y;
216 if ( ppsz_sign[y][b_reverse?i_width-1-x:x] == 'o' ) {
217 if ((i_dst_x < p_out->i_visible_pitch) && (i_dst_y < p_out->i_visible_lines) && (i_dst_x >= 0 ) && (i_dst_y >= 0))
218 memset( &p_out->p_pixels[ i_dst_y * p_out->i_pitch + i_dst_x ], i_Y, p_out->i_pixel_pitch );
220 else if ( ppsz_sign[y][b_reverse?i_width-1-x:x] == '.' ) {
221 if ((i_dst_x < p_out->i_visible_pitch) && (i_dst_y < p_out->i_visible_lines) && (i_dst_x >= 0 ) && (i_dst_y >= 0))
222 p_out->p_pixels[ i_dst_y * p_out->i_pitch + i_dst_x ] = p_out->p_pixels[ i_dst_y * p_out->i_pitch + i_dst_x ] / 2 + i_Y / 2;
227 /*****************************************************************************
228 * draw outline rectangle in output picture
229 *****************************************************************************/
230 void puzzle_draw_rectangle(picture_t *p_pic_out, int32_t i_x, int32_t i_y, int32_t i_w, int32_t i_h, uint8_t i_Y, uint8_t i_U, uint8_t i_V )
234 for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
235 plane_t *p_oyp = &p_pic_out->p[i_plane];
236 int32_t i_pixel_pitch = p_pic_out->p[i_plane].i_pixel_pitch;
238 if (i_plane == Y_PLANE)
240 else if (i_plane == U_PLANE)
242 else if (i_plane == V_PLANE)
245 int32_t i_x_min = ( i_x * p_oyp->i_visible_pitch / p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
246 int32_t i_x_max = ( (i_x + i_w) * p_oyp->i_visible_pitch / p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
247 int32_t i_y_min = i_y * p_oyp->i_visible_lines / p_pic_out->p[0].i_visible_lines;
248 int32_t i_y_max = (i_y + i_h) * p_oyp->i_visible_lines / p_pic_out->p[0].i_visible_lines;
251 memset( &p_oyp->p_pixels[i_y_min * p_oyp->i_pitch + i_x_min], i_c, i_x_max - i_x_min);
254 for( int32_t i_dy = 1; i_dy < i_y_max - i_y_min - 1; i_dy++ ) {
255 memset( &p_oyp->p_pixels[ (i_y_min + i_dy) * p_oyp->i_pitch + i_x_min ], i_c, p_oyp->i_pixel_pitch );
256 memset( &p_oyp->p_pixels[(i_y_min + i_dy) * p_oyp->i_pitch + i_x_max - 1], i_c, p_oyp->i_pixel_pitch );
260 memset( &p_oyp->p_pixels[(i_y_max - 1) * p_oyp->i_pitch + i_x_min], i_c, i_x_max - i_x_min);
264 /*****************************************************************************
265 * draw bold rectangle in output picture
266 *****************************************************************************/
267 void puzzle_fill_rectangle(picture_t *p_pic_out, int32_t i_x, int32_t i_y, int32_t i_w, int32_t i_h, uint8_t i_Y, uint8_t i_U, uint8_t i_V )
271 for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ ) {
272 plane_t *p_oyp = &p_pic_out->p[i_plane];
273 int32_t i_pixel_pitch = p_pic_out->p[i_plane].i_pixel_pitch;
275 if (i_plane == Y_PLANE)
277 else if (i_plane == U_PLANE)
279 else if (i_plane == V_PLANE)
282 int32_t i_x_min = ( i_x * p_oyp->i_visible_pitch / p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
283 int32_t i_x_max = ( (i_x + i_w) * p_oyp->i_visible_pitch / p_pic_out->p[0].i_visible_pitch ) * i_pixel_pitch;
284 int32_t i_y_min = i_y * p_oyp->i_visible_lines / p_pic_out->p[0].i_visible_lines;
285 int32_t i_y_max = (i_y + i_h) * p_oyp->i_visible_lines / p_pic_out->p[0].i_visible_lines;
287 for( int32_t i_dy = 0; i_dy < i_y_max - i_y_min; i_dy++ )
288 memset( &p_oyp->p_pixels[(i_y_min + i_dy) * p_oyp->i_pitch + i_x_min], i_c, i_x_max - i_x_min);