TGA images (-mf on:type=tga) support

patch by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7363 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
arpi 2002-09-10 20:59:52 +00:00
parent 870d1cb130
commit 5b3e3be175
5 changed files with 289 additions and 3 deletions

View File

@ -60,6 +60,14 @@ videocodec mpng
driver mpng
out BGR32,BGR24
videocodec mtga
info "TGA images decoder"
status working
comment "Only 24bpp and 32bpp RGB TGA files supported"
fourcc mtga,MTGA
driver mtga
out BGR32 ;,BGR24
videocodec fli
info "Autodesk FLI/FLC Animation"
status working

View File

@ -5,7 +5,7 @@ LIBNAME = libmpcodecs.a
LIBNAME2 = libmpencoders.a
AUDIO_SRCS=dec_audio.c ad.c ad_liba52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3lib.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c
VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_realvid.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_mpegpes.c vd_svq1.c vd_xvid.c vd_libdv.c vd_lcl.c
VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_realvid.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_mpegpes.c vd_svq1.c vd_xvid.c vd_libdv.c vd_lcl.c vd_mtga.c
VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_pp.c vf_scale.c vf_format.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_halfpack.c
ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c
NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/cyuv.c native/fli.c native/minilzo.c native/msvidc.c native/nuppelvideo.c native/qtrle.c native/qtrpza.c native/qtsmc.c native/roqav.c native/xa_gsm.c native/svq1.c

View File

@ -46,6 +46,7 @@ extern vd_functions_t mpcodecs_vd_cyuv;
extern vd_functions_t mpcodecs_vd_nuv;
extern vd_functions_t mpcodecs_vd_mpng;
extern vd_functions_t mpcodecs_vd_ijpg;
extern vd_functions_t mpcodecs_vd_mtga;
extern vd_functions_t mpcodecs_vd_libmpeg2;
extern vd_functions_t mpcodecs_vd_huffyuv;
extern vd_functions_t mpcodecs_vd_mpegpes;
@ -93,6 +94,7 @@ vd_functions_t* mpcodecs_vd_drivers[] = {
#ifdef HAVE_JPEG
&mpcodecs_vd_ijpg,
#endif
&mpcodecs_vd_mtga,
&mpcodecs_vd_libmpeg2,
&mpcodecs_vd_huffyuv,
&mpcodecs_vd_mpegpes,

274
libmpcodecs/vd_mtga.c Normal file
View File

@ -0,0 +1,274 @@
/* author: Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
* based on: XreaL's x_r_img_tga.* (http://www.sourceforge.net/projects/xreal/)
* libtarga.*
* xli's tga.*
*/
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "mp_msg.h"
#include "bswap.h"
#include "postproc/rgb2rgb.h"
#include "libvo/fastmemcpy.h"
#include "vd_internal.h"
static vd_info_t info =
{
"TGA Images decoder",
"mtga",
"Tilman Sauerbeck",
"Tilman Sauerbeck",
"only 24bpp and 32bpp RGB targa files support so far"
};
LIBVD_EXTERN(mtga)
typedef enum
{
TGA_NO_DATA,
TGA_UNCOMP_PALETTED,
TGA_UNCOMP_TRUECOLOR,
TGA_UNCOMP_GRAYSCALE,
TGA_RLE_PALETTED = 9,
TGA_RLE_TRUECOLOR,
TGA_RLE_GRAYSCALE
} TGAImageType;
typedef struct
{
unsigned char id_len;
unsigned short img_type;
unsigned short width;
unsigned short height;
unsigned char bpp;
unsigned char origin; /* 0 = lower left, 1 = upper left */
} TGAInfo;
typedef struct
{
/* red, green, blue, alpha */
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} ColorChannels;
static unsigned int out_fmt = 0;
static int last_w = -1;
static int last_h = -1;
static int last_c = -1;
/* to set/get/query special features/parameters */
static int control(sh_video_t *sh, int cmd, void *arg, ...)
{
return CONTROL_UNKNOWN;
}
/* init driver */
static int init(sh_video_t *sh)
{
last_w = -1;
return 1;
}
/* uninit driver */
static void uninit(sh_video_t *sh)
{
}
/* decode a runlength-encoded tga */
static void decode_rle_tga(TGAInfo info, unsigned char *data, mp_image_t **mpi)
{
ColorChannels chans = {0, 0, 0, 0};
unsigned char repetitions, packet_header, *final;
unsigned short row, col, i;
short modifier;
/* if img.origin is 0, we decode from bottom to top. if it's 1, we decode from top to bottom */
row = (info.origin) ? 0 : info.height - 1;
modifier = (info.origin) ? 1 : -1;
for (;;)
{
final = (*mpi)->planes[0] + (*mpi)->stride[0] * row;
for (col = 0; col < info.width;)
{
packet_header = *data++;
repetitions = 1 + (packet_header & 0x7f);
if (packet_header & 0x80)
{
chans.b = *data++;
chans.g = *data++;
chans.r = *data++;
chans.a = (info.bpp == 32) ? *data++ : 255;
for (i = 0; i < repetitions; i++)
{
*final++ = chans.r;
*final++ = chans.g;
*final++ = chans.b;
*final++ = chans.a;
col++;
}
}
else /* raw packet */
{
for (i = 0; i < repetitions; i++)
{
chans.b = *data++;
chans.g = *data++;
chans.r = *data++;
*final++ = chans.r;
*final++ = chans.g;
*final++ = chans.b;
*final++ = chans.a = (info.bpp == 32) ? *data++ : 255;
col++;
}
}
}
row = row + modifier;
if ((!info.origin && !row) || (info.origin && row >= info.height))
break;
}
return;
}
static void decode_uncompressed_tga(TGAInfo info, unsigned char *data, mp_image_t **mpi)
{
ColorChannels chans;
unsigned short row, col;
unsigned char *final;
short modifier;
/* if img.origin is 0, we decode from bottom to top. if it's 1, we decode from top to bottom */
row = (info.origin) ? 0 : info.height - 1;
modifier = (info.origin) ? 1 : -1;
for (;;)
{
final = (*mpi)->planes[0] + (*mpi)->stride[0] * row;
for (col = 0; col < info.width; col++)
{
chans.b = *data++;
chans.g = *data++;
chans.r = *data++;
*final++ = chans.r;
*final++ = chans.g;
*final++ = chans.b;
*final++ = info.bpp == 32 ? *data++ : 255;
}
row = row + modifier;
if ((!info.origin && !row) || (info.origin && row >= info.height))
break;
}
return;
}
static short read_tga_header(unsigned char *buf, TGAInfo *info)
{
(*info).id_len = buf[0];
(*info).img_type = buf[2];
/* targa data is always stored in little endian byte order */
(*info).width = le2me_16(*(unsigned short *) &buf[12]);
(*info).height = le2me_16(*(unsigned short *) &buf[14]);
(*info).bpp = buf[16];
(*info).origin = (buf[17] & 0x20) >> 5;
/* FIXME check for valid targa data */
return 0;
}
/* decode a frame */
static mp_image_t *decode(sh_video_t *sh, void *raw, int len, int flags)
{
TGAInfo info;
unsigned char *data = raw;
mp_image_t *mpi;
if (len <= 0)
return NULL; /* skip frame */
read_tga_header(data, &info); /* read information about the file */
if (info.bpp == 24)
out_fmt = IMGFMT_RGB24;
else if (info.bpp == 32)
out_fmt = IMGFMT_RGB32;
else
{
mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type!\n");
return NULL;
}
if (info.img_type != TGA_UNCOMP_TRUECOLOR && info.img_type != TGA_RLE_TRUECOLOR) /* not a true color image */
{
mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type: %i!\n", info.img_type);
return NULL;
}
/* set data to the beginning of the image data */
data = data + 18 + info.id_len;
/* (re)init libvo if image parameters changed (width/height/colorspace) */
if (last_w != info.width || last_h != info.height || last_c != out_fmt)
{
last_w = info.width;
last_h = info.height;
last_c = out_fmt;
if (!out_fmt || !mpcodecs_config_vo(sh, info.width, info.height, out_fmt))
return NULL;
}
if (!(mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, info.width, info.height)))
return NULL;
/* finally decode the image */
if (info.img_type == TGA_UNCOMP_TRUECOLOR)
decode_uncompressed_tga(info, data, &mpi);
else if (info.img_type == TGA_RLE_TRUECOLOR)
decode_rle_tga(info, data, &mpi);
else
mpi = NULL;
return mpi;
}

View File

@ -95,9 +95,11 @@ demuxer_t* demux_open_mf(demuxer_t* demuxer){
if ( !strcasecmp( mf_type,"jpg" ) ||
!(strcasecmp(mf_type, "jpeg"))) sh_video->format = mmioFOURCC('I', 'J', 'P', 'G');
else
else
if ( !strcasecmp( mf_type,"png" )) sh_video->format = mmioFOURCC('M', 'P', 'N', 'G' );
else { mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknow input file type.\n" ); free( dmf ); return NULL; }
else
if ( !strcasecmp( mf_type,"tga" )) sh_video->format = mmioFOURCC('M', 'T', 'G', 'A' );
else { mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknow input file type.\n" ); free( dmf ); return NULL; }
sh_video->disp_w = mf_w;
sh_video->disp_h = mf_h;