1 /*****************************************************************************
2 * sdl_image.c: sdl decoder module making use of libsdl_image.
3 *****************************************************************************
4 * Copyright (C) 2005 VLC authors and VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * 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 int 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( "video 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_codec
= VLC_CODEC_RGB32
;
118 p_dec
->pf_decode
= DecodeBlock
;
123 /****************************************************************************
124 * DecodeBlock: the whole thing
125 ****************************************************************************
126 * This function must be fed with a complete compressed frame.
127 ****************************************************************************/
128 static int DecodeBlock( decoder_t
*p_dec
, block_t
*p_block
)
130 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
131 picture_t
*p_pic
= NULL
;
132 SDL_Surface
*p_surface
;
135 if( p_block
== NULL
) /* No Drain */
136 return VLCDEC_SUCCESS
;
138 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
140 block_Release( p_block
);
141 return VLCDEC_SUCCESS
;
144 p_rw
= SDL_RWFromConstMem( p_block
->p_buffer
, p_block
->i_buffer
);
146 /* Decode picture. */
147 p_surface
= IMG_LoadTyped_RW( p_rw
, 1, (char*)p_sys
->psz_sdl_type
);
148 if ( p_surface
== NULL
)
150 msg_Warn( p_dec
, "SDL_image couldn't load the image (%s)",
155 switch ( p_surface
->format
->BitsPerPixel
)
158 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB16
;
162 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB24
;
165 p_dec
->fmt_out
.i_codec
= VLC_CODEC_RGB32
;
168 msg_Warn( p_dec
, "unknown bits/pixel format (%d)",
169 p_surface
->format
->BitsPerPixel
);
172 p_dec
->fmt_out
.video
.i_width
= p_surface
->w
;
173 p_dec
->fmt_out
.video
.i_height
= p_surface
->h
;
174 p_dec
->fmt_out
.video
.i_sar_num
= 1;
175 p_dec
->fmt_out
.video
.i_sar_den
= 1;
177 /* Get a new picture. */
178 if( decoder_UpdateVideoFormat( p_dec
) )
180 p_pic
= decoder_NewPicture( p_dec
);
181 if ( p_pic
== NULL
) goto error
;
183 switch ( p_surface
->format
->BitsPerPixel
)
187 for ( int i
= 0; i
< p_surface
->h
; i
++ )
189 uint8_t *p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
190 uint8_t *p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
191 for ( int j
= 0; j
< p_surface
->w
; j
++ )
194 SDL_GetRGB( *(p_src
++), p_surface
->format
,
205 uint8_t *p_src
= p_surface
->pixels
;
206 uint8_t *p_dst
= p_pic
->p
[0].p_pixels
;
207 int i_pitch
= p_pic
->p
[0].i_pitch
< p_surface
->pitch
?
208 p_pic
->p
[0].i_pitch
: p_surface
->pitch
;
210 for ( int i
= 0; i
< p_surface
->h
; i
++ )
212 memcpy( p_dst
, p_src
, i_pitch
);
213 p_src
+= p_surface
->pitch
;
214 p_dst
+= p_pic
->p
[0].i_pitch
;
220 for ( int i
= 0; i
< p_surface
->h
; i
++ )
222 uint8_t *p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
223 uint8_t *p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
224 for ( int j
= 0; j
< p_surface
->w
; j
++ )
227 SDL_GetRGB( *(uint32_t*)p_src
, p_surface
->format
,
239 for ( int i
= 0; i
< p_surface
->h
; i
++ )
241 uint8_t *p_src
= (uint8_t*)p_surface
->pixels
+ i
* p_surface
->pitch
;
242 uint8_t *p_dst
= p_pic
->p
[0].p_pixels
+ i
* p_pic
->p
[0].i_pitch
;
243 for ( int j
= 0; j
< p_surface
->w
; j
++ )
246 SDL_GetRGBA( *(uint32_t*)p_src
, p_surface
->format
,
259 p_pic
->date
= (p_block
->i_pts
!= VLC_TICK_INVALID
) ?
260 p_block
->i_pts
: p_block
->i_dts
;
262 decoder_QueueVideo( p_dec
, p_pic
);
265 if ( p_surface
!= NULL
) SDL_FreeSurface( p_surface
);
266 block_Release( p_block
);
267 return VLCDEC_SUCCESS
;
270 /*****************************************************************************
271 * CloseDecoder: sdl decoder destruction
272 *****************************************************************************/
273 static void CloseDecoder( vlc_object_t
*p_this
)
275 decoder_t
*p_dec
= (decoder_t
*)p_this
;
276 decoder_sys_t
*p_sys
= p_dec
->p_sys
;