Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

sdl_image.c

00001 /*****************************************************************************
00002  * sdl_image.c: sdl decoder module making use of libsdl_image.
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  * $Id: sdl_image.c 11896 2005-07-29 15:14:00Z massiot $
00006  *
00007  * Authors: Christophe Massiot <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029 
00030 #include SDL_IMAGE_INCLUDE_FILE
00031 
00032 /*****************************************************************************
00033  * decoder_sys_t : sdl decoder descriptor
00034  *****************************************************************************/
00035 struct decoder_sys_t
00036 {
00037     const char *psz_sdl_type;
00038 };
00039 
00040 /*****************************************************************************
00041  * Local prototypes
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  * Module descriptor
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  * OpenDecoder: probe the decoder and return score
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     /* Find codec. */
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     /* Allocate the memory needed to store the decoder's structure */
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     /* Set output properties - this is a decoy and isn't used anywhere */
00111     p_dec->fmt_out.i_cat = VIDEO_ES;
00112     p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','3','2');
00113 
00114     /* Set callbacks */
00115     p_dec->pf_decode_video = DecodeBlock;
00116 
00117     return VLC_SUCCESS;
00118 }
00119 
00120 /****************************************************************************
00121  * DecodeBlock: the whole thing
00122  ****************************************************************************
00123  * This function must be fed with a complete compressed frame.
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     /* Decode picture. */
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     /* Get a new picture. */
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  * CloseDecoder: sdl decoder destruction
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 }

Generated on Tue Dec 20 10:14:29 2005 for vlc-0.8.4a by  doxygen 1.4.2