Commit 61696fdb authored by Christophe Massiot's avatar Christophe Massiot

* modules/codec/sdl_image.c: New decoder taking advantage of libSDL_image

   to import various image formats.
 * src/misc/image.c: Fixed a segfault when loading an unknown image type.
parent f5122a54
......@@ -2900,16 +2900,19 @@ then
AC_PATH_PROG(SDL12_CONFIG, sdl12-config, no, ${SDL_PATH})
SDL_CONFIG="${SDL12_CONFIG}"
SDL_HEADER="SDL12/SDL.h"
SDL_IMAGE="SDL12/SDL_image.h"
if test "${SDL_CONFIG}" = "no"
then
AC_PATH_PROG(SDL11_CONFIG, sdl11-config, no, ${SDL_PATH})
SDL_CONFIG=${SDL11_CONFIG}
SDL_HEADER="SDL11/SDL.h"
SDL_IMAGE="SDL11/SDL_image.h"
fi
if test "${SDL_CONFIG}" = "no"
then
AC_PATH_PROG(SDL_CONFIG, sdl-config, no, ${SDL_PATH})
SDL_HEADER="SDL/SDL.h"
SDL_IMAGE="SDL/SDL_image.h"
fi
# check for cross-compiling
SDL_PREFIX=
......@@ -2924,8 +2927,8 @@ then
if test "${SDL_CONFIG}" != "no"
then
VLC_ADD_PLUGINS([vout_sdl aout_sdl])
VLC_ADD_CFLAGS([vout_sdl aout_sdl],[`${SDL_CONFIG} ${SDL_PREFIX} --cflags | sed 's,SDL,,'`])
VLC_ADD_LDFLAGS([vout_sdl aout_sdl],[`${SDL_CONFIG} ${SDL_PREFIX} --libs | sed 's,-rdynamic,,'`])
VLC_ADD_CFLAGS([vout_sdl aout_sdl sdl_image],[`${SDL_CONFIG} ${SDL_PREFIX} --cflags | sed 's,SDL,,'`])
VLC_ADD_LDFLAGS([vout_sdl aout_sdl sdl_image],[`${SDL_CONFIG} ${SDL_PREFIX} --libs | sed 's,-rdynamic,,'`])
CPPFLAGS="${CPPFLAGS_save} ${CFLAGS_vout_sdl}"
AC_CHECK_HEADERS(${SDL_HEADER}, AC_DEFINE_UNQUOTED(SDL_INCLUDE_FILE,
<${SDL_HEADER}>, Indicate whether we should use SDL/SDL.h or SDL11/SDL.h),
......@@ -2935,6 +2938,15 @@ then
Please install it and try again. Alternatively you can also configure with
--disable-sdl.])
])])
AC_CHECK_HEADERS(${SDL_IMAGE}, [AC_DEFINE_UNQUOTED(SDL_IMAGE_INCLUDE_FILE,
<${SDL_IMAGE}>, Indicate the path of SDL_image.h)
VLC_ADD_PLUGINS([sdl_image])
VLC_ADD_LDFLAGS([sdl_image], [-lSDL_image])],
[ AC_CHECK_HEADERS(SDL_image.h, AC_DEFINE(SDL_IMAGE_INCLUDE_FILE, <SDL_image.h>,
As a last resort we also test for SDL_image.h presence),
[ AC_MSG_WARN([The development package for SDL_image is not installed.
You should install it alongside your SDL package.])
])])
CPPFLAGS="${CPPFLAGS_save}"
if expr 1.1.5 \> `${SDL_CONFIG} --version` >/dev/null
then
......
......@@ -26,3 +26,4 @@ SOURCES_png = png.c
SOURCES_svcdsub = svcdsub.c
SOURCES_cvdsub = cvdsub.c
SOURCES_fake = fake.c
SOURCES_sdl_image = sdl_image.c
/*****************************************************************************
* sdl_image.c: sdl decoder module making use of libsdl_image.
*****************************************************************************
* Copyright (C) 2005 the VideoLAN team
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include SDL_IMAGE_INCLUDE_FILE
/*****************************************************************************
* decoder_sys_t : sdl decoder descriptor
*****************************************************************************/
struct decoder_sys_t
{
const char *psz_sdl_type;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static void CloseDecoder ( vlc_object_t * );
static picture_t *DecodeBlock ( decoder_t *, block_t ** );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_VCODEC );
set_description( _("SDL_image video decoder") );
set_capability( "decoder", 900 );
set_callbacks( OpenDecoder, CloseDecoder );
add_shortcut( "sdl_image" );
vlc_module_end();
static const struct supported_fmt_t
{
vlc_fourcc_t i_fourcc;
char *psz_sdl_type;
} p_supported_fmt[] =
{
{ VLC_FOURCC('t','g','a',' '), "TGA" },
{ VLC_FOURCC('b','m','p',' '), "BMP" },
{ VLC_FOURCC('p','n','m',' '), "PNM" },
{ VLC_FOURCC('x','p','m',' '), "XPM" },
{ VLC_FOURCC('x','c','f',' '), "XCF" },
{ VLC_FOURCC('p','c','x',' '), "PCX" },
{ VLC_FOURCC('g','i','f',' '), "GIF" },
{ VLC_FOURCC('j','p','e','g'), "JPG" },
{ VLC_FOURCC('t','i','f','f'), "TIF" },
{ VLC_FOURCC('l','b','m',' '), "LBM" },
{ VLC_FOURCC('p','n','g',' '), "PNG" }
};
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys;
int i;
/* Find codec. */
for ( i = 0;
i < (int)(sizeof(p_supported_fmt)/sizeof(struct supported_fmt_t));
i++ )
{
if ( p_supported_fmt[i].i_fourcc == p_dec->fmt_in.i_codec )
break;
}
if ( i == (int)(sizeof(p_supported_fmt)/sizeof(struct supported_fmt_t)) )
{
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the decoder's structure */
if( ( p_dec->p_sys = p_sys =
(decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
{
msg_Err( p_dec, "out of memory" );
return VLC_EGENERIC;
}
p_sys->psz_sdl_type = p_supported_fmt[i].psz_sdl_type;
/* Set output properties - this is a decoy and isn't used anywhere */
p_dec->fmt_out.i_cat = VIDEO_ES;
p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','3','2');
/* Set callbacks */
p_dec->pf_decode_video = DecodeBlock;
return VLC_SUCCESS;
}
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************
* This function must be fed with a complete compressed frame.
****************************************************************************/
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
picture_t *p_pic = NULL;
SDL_Surface *p_surface;
SDL_RWops *p_rw;
if( pp_block == NULL || *pp_block == NULL ) return NULL;
p_block = *pp_block;
p_rw = SDL_RWFromConstMem( p_block->p_buffer, p_block->i_buffer );
/* Decode picture. */
p_surface = IMG_LoadTyped_RW( p_rw, 1, p_sys->psz_sdl_type );
if ( p_surface == NULL )
{
msg_Warn( p_dec, "SDL_image couldn't load the image (%s)",
IMG_GetError() );
goto error;
}
switch ( p_surface->format->BitsPerPixel )
{
case 16:
p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','1','6');
break;
case 8:
case 24:
p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','2','4');
break;
case 32:
p_dec->fmt_out.i_codec = VLC_FOURCC('R','V','3','2');
break;
default:
msg_Warn( p_dec, "unknown bits/pixel format (%d)",
p_surface->format->BitsPerPixel );
goto error;
}
p_dec->fmt_out.video.i_width = p_surface->w;
p_dec->fmt_out.video.i_height = p_surface->h;
p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_surface->w
/ p_surface->h;
/* Get a new picture. */
p_pic = p_dec->pf_vout_buffer_new( p_dec );
if ( p_pic == NULL ) goto error;
if ( p_surface->format->BitsPerPixel == 8 )
{
int i, j;
uint8_t *r = p_pic->p[0].p_pixels;
uint8_t *g = p_pic->p[0].p_pixels + 1;
uint8_t *b = p_pic->p[0].p_pixels + 2;
SDL_Palette *p_palette = p_surface->format->palette;
for ( i = 0; i < p_surface->h; i++ )
{
for ( j = 0; j < p_surface->w; j++ )
{
uint8_t i_index = ((uint8_t *)p_surface->pixels)[j];
SDL_Color *p_color = &p_palette->colors[i_index];
r[j] = p_color->r;
g[j] = p_color->g;
b[j] = p_color->b;
}
}
r += p_pic->p[0].i_pitch;
g += p_pic->p[0].i_pitch;
b += p_pic->p[0].i_pitch;
}
else
{
int i;
uint8_t *p_src = p_surface->pixels;
uint8_t *p_dst = p_pic->p[0].p_pixels;
int i_pitch = p_pic->p[0].i_pitch < p_surface->pitch ?
p_pic->p[0].i_pitch : p_surface->pitch;
for ( i = 0; i < p_surface->h; i++ )
{
p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_pitch );
p_src += p_surface->pitch;
p_dst += p_pic->p[0].i_pitch;
}
}
SDL_FreeSurface( p_surface );
block_Release( p_block ); *pp_block = NULL;
return p_pic;
error:
if ( p_surface != NULL ) SDL_FreeSurface( p_surface );
block_Release( p_block ); *pp_block = NULL;
return NULL;
}
/*****************************************************************************
* CloseDecoder: sdl decoder destruction
*****************************************************************************/
static void CloseDecoder( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
free( p_sys );
}
......@@ -103,7 +103,7 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
video_format_t *p_fmt_in,
video_format_t *p_fmt_out )
{
picture_t *p_pic;
picture_t *p_pic = NULL, *p_tmp;
/* Check if we can reuse the current decoder */
if( p_image->p_dec &&
......@@ -122,11 +122,17 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
p_block->i_pts = p_block->i_dts = mdate();
p_pic = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block );
p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block );
while( (p_tmp = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block ))
!= NULL )
{
if ( p_pic != NULL )
p_pic->pf_release( p_pic );
p_pic = p_tmp;
}
if( !p_pic )
if( p_pic == NULL )
{
msg_Dbg( p_image->p_parent, "no image decoded" );
msg_Warn( p_image->p_parent, "no image decoded" );
return 0;
}
......@@ -446,6 +452,16 @@ static struct
{ VLC_FOURCC('p','g','m','y'), "pgmyuv" },
{ VLC_FOURCC('p','b','m',' '), "pbm" },
{ VLC_FOURCC('p','a','m',' '), "pam" },
{ VLC_FOURCC('t','g','a',' '), "tga" },
{ VLC_FOURCC('b','m','p',' '), "bmp" },
{ VLC_FOURCC('p','n','m',' '), "pnm" },
{ VLC_FOURCC('x','p','m',' '), "xpm" },
{ VLC_FOURCC('x','c','f',' '), "xcf" },
{ VLC_FOURCC('p','c','x',' '), "pcx" },
{ VLC_FOURCC('g','i','f',' '), "gif" },
{ VLC_FOURCC('t','i','f','f'), "tif" },
{ VLC_FOURCC('t','i','f','f'), "tiff" },
{ VLC_FOURCC('l','b','m',' '), "lbm" },
{ 0, NULL }
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment