00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029
00030 #include SDL_IMAGE_INCLUDE_FILE
00031
00032
00033
00034
00035 struct decoder_sys_t
00036 {
00037 const char *psz_sdl_type;
00038 };
00039
00040
00041
00042
00043 static int OpenDecoder ( vlc_object_t * );
00044 static void CloseDecoder ( vlc_object_t * );
00045
00046 static picture_t *DecodeBlock ( decoder_t *, block_t ** );
00047
00048
00049
00050
00051 vlc_module_begin();
00052 set_category( CAT_INPUT );
00053 set_subcategory( SUBCAT_INPUT_VCODEC );
00054 set_description( _("SDL_image video decoder") );
00055 set_capability( "decoder", 900 );
00056 set_callbacks( OpenDecoder, CloseDecoder );
00057 add_shortcut( "sdl_image" );
00058 vlc_module_end();
00059
00060 static const struct supported_fmt_t
00061 {
00062 vlc_fourcc_t i_fourcc;
00063 char *psz_sdl_type;
00064 } p_supported_fmt[] =
00065 {
00066 { VLC_FOURCC('t','g','a',' '), "TGA" },
00067 { VLC_FOURCC('b','m','p',' '), "BMP" },
00068 { VLC_FOURCC('p','n','m',' '), "PNM" },
00069 { VLC_FOURCC('x','p','m',' '), "XPM" },
00070 { VLC_FOURCC('x','c','f',' '), "XCF" },
00071 { VLC_FOURCC('p','c','x',' '), "PCX" },
00072 { VLC_FOURCC('g','i','f',' '), "GIF" },
00073 { VLC_FOURCC('j','p','e','g'), "JPG" },
00074 { VLC_FOURCC('t','i','f','f'), "TIF" },
00075 { VLC_FOURCC('l','b','m',' '), "LBM" },
00076 { VLC_FOURCC('p','n','g',' '), "PNG" }
00077 };
00078
00079
00080
00081
00082 static int OpenDecoder( vlc_object_t *p_this )
00083 {
00084 decoder_t *p_dec = (decoder_t *)p_this;
00085 decoder_sys_t *p_sys;
00086 int i;
00087
00088
00089 for ( i = 0;
00090 i < (int)(sizeof(p_supported_fmt)/sizeof(struct supported_fmt_t));
00091 i++ )
00092 {
00093 if ( p_supported_fmt[i].i_fourcc == p_dec->fmt_in.i_codec )
00094 break;
00095 }
00096 if ( i == (int)(sizeof(p_supported_fmt)/sizeof(struct supported_fmt_t)) )
00097 {
00098 return VLC_EGENERIC;
00099 }
00100
00101
00102 if( ( p_dec->p_sys = p_sys =
00103 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00104 {
00105 msg_Err( p_dec, "out of memory" );
00106 return VLC_EGENERIC;
00107 }
00108 p_sys->psz_sdl_type = p_supported_fmt[i].psz_sdl_type;
00109
00110
00111 p_dec->fmt_out.i_cat = VIDEO_ES;
00112 p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','3','2');
00113
00114
00115 p_dec->pf_decode_video = DecodeBlock;
00116
00117 return VLC_SUCCESS;
00118 }
00119
00120
00121
00122
00123
00124
00125 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00126 {
00127 decoder_sys_t *p_sys = p_dec->p_sys;
00128 block_t *p_block;
00129 picture_t *p_pic = NULL;
00130 SDL_Surface *p_surface;
00131 SDL_RWops *p_rw;
00132
00133 if( pp_block == NULL || *pp_block == NULL ) return NULL;
00134 p_block = *pp_block;
00135
00136 p_rw = SDL_RWFromConstMem( p_block->p_buffer, p_block->i_buffer );
00137
00138
00139 p_surface = IMG_LoadTyped_RW( p_rw, 1, p_sys->psz_sdl_type );
00140 if ( p_surface == NULL )
00141 {
00142 msg_Warn( p_dec, "SDL_image couldn't load the image (%s)",
00143 IMG_GetError() );
00144 goto error;
00145 }
00146
00147 switch ( p_surface->format->BitsPerPixel )
00148 {
00149 case 16:
00150 p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','1','6');
00151 break;
00152 case 8:
00153 case 24:
00154 p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','2','4');
00155 break;
00156 case 32:
00157 p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','3','2');
00158 break;
00159 default:
00160 msg_Warn( p_dec, "unknown bits/pixel format (%d)",
00161 p_surface->format->BitsPerPixel );
00162 goto error;
00163 }
00164 p_dec->fmt_out.video.i_width = p_surface->w;
00165 p_dec->fmt_out.video.i_height = p_surface->h;
00166 p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_surface->w
00167 / p_surface->h;
00168
00169
00170 p_pic = p_dec->pf_vout_buffer_new( p_dec );
00171 if ( p_pic == NULL ) goto error;
00172
00173 if ( p_surface->format->BitsPerPixel == 8 )
00174 {
00175 int i, j;
00176 uint8_t *r = p_pic->p[0].p_pixels;
00177 uint8_t *g = p_pic->p[0].p_pixels + 1;
00178 uint8_t *b = p_pic->p[0].p_pixels + 2;
00179 SDL_Palette *p_palette = p_surface->format->palette;
00180
00181 for ( i = 0; i < p_surface->h; i++ )
00182 {
00183 for ( j = 0; j < p_surface->w; j++ )
00184 {
00185 uint8_t i_index = ((uint8_t *)p_surface->pixels)[j];
00186 SDL_Color *p_color = &p_palette->colors[i_index];
00187 r[j] = p_color->r;
00188 g[j] = p_color->g;
00189 b[j] = p_color->b;
00190 }
00191 }
00192 r += p_pic->p[0].i_pitch;
00193 g += p_pic->p[0].i_pitch;
00194 b += p_pic->p[0].i_pitch;
00195 }
00196 else
00197 {
00198 int i;
00199 uint8_t *p_src = p_surface->pixels;
00200 uint8_t *p_dst = p_pic->p[0].p_pixels;
00201 int i_pitch = p_pic->p[0].i_pitch < p_surface->pitch ?
00202 p_pic->p[0].i_pitch : p_surface->pitch;
00203
00204 for ( i = 0; i < p_surface->h; i++ )
00205 {
00206 p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_pitch );
00207 p_src += p_surface->pitch;
00208 p_dst += p_pic->p[0].i_pitch;
00209 }
00210 }
00211
00212 SDL_FreeSurface( p_surface );
00213 block_Release( p_block ); *pp_block = NULL;
00214 return p_pic;
00215
00216 error:
00217 if ( p_surface != NULL ) SDL_FreeSurface( p_surface );
00218 block_Release( p_block ); *pp_block = NULL;
00219 return NULL;
00220 }
00221
00222
00223
00224
00225 static void CloseDecoder( vlc_object_t *p_this )
00226 {
00227 decoder_t *p_dec = (decoder_t *)p_this;
00228 decoder_sys_t *p_sys = p_dec->p_sys;
00229
00230 free( p_sys );
00231 }