1 /*****************************************************************************
2 * sdl_image.c: sdl decoder module making use of libsdl_image.
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_codec.h>
36 #include <SDL_image.h>
38 /*****************************************************************************
39 * decoder_sys_t : sdl decoder descriptor
40 *****************************************************************************/
43 const char *psz_sdl_type
;
46 /*****************************************************************************
48 *****************************************************************************/
49 static int OpenDecoder ( vlc_object_t
* );
50 static void CloseDecoder ( vlc_object_t
* );
52 static picture_t
*DecodeBlock ( decoder_t
*, block_t
** );
54 /*****************************************************************************
56 *****************************************************************************/
58 set_category( CAT_INPUT
)
59 set_subcategory( SUBCAT_INPUT_VCODEC
)
60 set_shortname( N_("SDL Image decoder"))
61 set_description( N_("SDL_image video decoder") )
62 set_capability( "decoder", 60 )
63 set_callbacks( OpenDecoder
, CloseDecoder
)
64 add_shortcut( "sdl_image" )
67 static const struct supported_fmt_t
69 vlc_fourcc_t i_fourcc
;
70 const char *psz_sdl_type
;
73 { VLC_CODEC_TARGA
, "TGA" },
74 { VLC_CODEC_BMP
, "BMP" },
75 { VLC_CODEC_PNM
, "PNM" },
76 { VLC_FOURCC('x','p','m',' '), "XPM" },
77 { VLC_FOURCC('x','c','f',' '), "XCF" },
78 { VLC_CODEC_PCX
, "PCX" },
79 { VLC_CODEC_GIF
, "GIF" },
80 { VLC_CODEC_JPEG
, "JPG" },
81 { VLC_CODEC_TIFF
, "TIF" },
82 { VLC_FOURCC('l','b','m',' '), "LBM" },
83 { VLC_CODEC_PNG
, "PNG" }
86 /*****************************************************************************
87 * OpenDecoder: probe the decoder and return score
88 *****************************************************************************/
89 static int OpenDecoder( vlc_object_t
*p_this
)
91 decoder_t
*p_dec
= (decoder_t
*)p_this
;
97 i
< (int)(sizeof(p_supported_fmt
)/sizeof(struct supported_fmt_t
));
100 if ( p_supported_fmt
[i
].i_fourcc
== p_dec
->fmt_in
.i_codec
)
103 if ( i
== (int)(sizeof(p_supported_fmt
)/sizeof(struct supported_fmt_t
)) )
108 /* Allocate the memory needed to store the decoder's structure */
109 if( ( p_dec
->p_sys
= p_sys
=
110 (decoder_sys_t
*)malloc(sizeof(decoder_sys_t
)) ) == NULL
)
112 p_sys
->psz_sdl_type
= p_supported_fmt
[i
].psz_sdl_type
;
114 /* Set output properties - this is a decoy and isn't used anywhere */
115 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
116 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB32
;
119 p_dec
->pf_decode_video
= DecodeBlock
;
124 /****************************************************************************
125 * DecodeBlock: the whole thing
126 ****************************************************************************
127 * This function must be fed with a complete compressed frame.
128 ****************************************************************************/
129 static picture_t
*DecodeBlock( decoder_t
*p_dec
, block_t
**pp_block
)
131 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
133 picture_t
*p_pic
= NULL
;
134 SDL_Surface
*p_surface
;
137 if( pp_block
== NULL
|| *pp_block
== NULL
) return NULL
;
140 if( p_block
->i_flags
& BLOCK_FLAG_DISCONTINUITY
)
142 block_Release( p_block
); *pp_block
= NULL
;
146 p_rw
= SDL_RWFromConstMem( p_block
->p_buffer
, p_block
->i_buffer
);
148 /* Decode picture. */
149 p_surface
= IMG_LoadTyped_RW( p_rw
, 1, (char*)p_sys
->psz_sdl_type
);
150 if ( p_surface
== NULL
)
152 msg_Warn( p_dec
, "SDL_image couldn't load the image (%s)",
157 switch ( p_surface
->format
->BitsPerPixel
)
160 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB16
;
164 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB24
;
167 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB32
;
170 msg_Warn( p_dec
, "unknown bits/pixel format (%d)",
171 p_surface
->format
->BitsPerPixel
);
174 p_dec
->fmt_out
.video
.i_width
= p_surface
->w
;
175 p_dec
->fmt_out
.video
.i_height
= p_surface
->h
;
176 p_dec
->fmt_out
.video
.i_sar_num
= 1;
177 p_dec
->fmt_out
.video
.i_sar_den
= 1;
179 /* Get a new picture. */
180 p_pic
= decoder_NewPicture( p_dec
);
181 if ( p_pic
== NULL
) goto error
;
183 switch ( p_surface
->format
->BitsPerPixel
)
188 uint8_t *p_src
, *p_dst
;
190 for ( i
= 0; i
< p_surface
->h
; i
++ )
192 p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
193 p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
194 for ( j
= 0; j
< p_surface
->w
; j
++ )
196 SDL_GetRGB( *(p_src
++), p_surface
->format
,
208 uint8_t *p_src
= p_surface
->pixels
;
209 uint8_t *p_dst
= p_pic
->p
[0].p_pixels
;
210 int i_pitch
= p_pic
->p
[0].i_pitch
< p_surface
->pitch
?
211 p_pic
->p
[0].i_pitch
: p_surface
->pitch
;
213 for ( i
= 0; i
< p_surface
->h
; i
++ )
215 vlc_memcpy( p_dst
, p_src
, i_pitch
);
216 p_src
+= p_surface
->pitch
;
217 p_dst
+= p_pic
->p
[0].i_pitch
;
224 uint8_t *p_src
, *p_dst
;
226 for ( i
= 0; i
< p_surface
->h
; i
++ )
228 p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
229 p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
230 for ( j
= 0; j
< p_surface
->w
; j
++ )
232 SDL_GetRGB( *(uint32_t*)p_src
, p_surface
->format
,
245 uint8_t *p_src
, *p_dst
;
247 for ( i
= 0; i
< p_surface
->h
; i
++ )
249 p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
250 p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
251 for ( j
= 0; j
< p_surface
->w
; j
++ )
253 SDL_GetRGBA( *(uint32_t*)p_src
, p_surface
->format
,
266 p_pic
->date
= (p_block
->i_pts
> VLC_TS_INVALID
) ?
267 p_block
->i_pts
: p_block
->i_dts
;
269 SDL_FreeSurface( p_surface
);
270 block_Release( p_block
); *pp_block
= NULL
;
274 if ( p_surface
!= NULL
) SDL_FreeSurface( p_surface
);
275 block_Release( p_block
); *pp_block
= NULL
;
279 /*****************************************************************************
280 * CloseDecoder: sdl decoder destruction
281 *****************************************************************************/
282 static void CloseDecoder( vlc_object_t
*p_this
)
284 decoder_t
*p_dec
= (decoder_t
*)p_this
;
285 decoder_sys_t
*p_sys
= p_dec
->p_sys
;