changeset 7362:8ae490fbf89d

TGA images (-mf on:type=tga) support patch by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
author arpi
date Tue, 10 Sep 2002 20:59:52 +0000
parents c3865710b53d
children 8acd8cb8fd52
files etc/codecs.conf libmpcodecs/Makefile libmpcodecs/vd.c libmpcodecs/vd_mtga.c libmpdemux/demux_mf.c
diffstat 5 files changed, 289 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/etc/codecs.conf	Tue Sep 10 20:42:45 2002 +0000
+++ b/etc/codecs.conf	Tue Sep 10 20:59:52 2002 +0000
@@ -60,6 +60,14 @@
   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
--- a/libmpcodecs/Makefile	Tue Sep 10 20:42:45 2002 +0000
+++ b/libmpcodecs/Makefile	Tue Sep 10 20:59:52 2002 +0000
@@ -5,7 +5,7 @@
 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
--- a/libmpcodecs/vd.c	Tue Sep 10 20:42:45 2002 +0000
+++ b/libmpcodecs/vd.c	Tue Sep 10 20:59:52 2002 +0000
@@ -46,6 +46,7 @@
 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 @@
 #ifdef HAVE_JPEG
 	&mpcodecs_vd_ijpg,
 #endif
+	&mpcodecs_vd_mtga,
         &mpcodecs_vd_libmpeg2,
         &mpcodecs_vd_huffyuv,
         &mpcodecs_vd_mpegpes,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpcodecs/vd_mtga.c	Tue Sep 10 20:59:52 2002 +0000
@@ -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;
+}
+
--- a/libmpdemux/demux_mf.c	Tue Sep 10 20:42:45 2002 +0000
+++ b/libmpdemux/demux_mf.c	Tue Sep 10 20:59:52 2002 +0000
@@ -95,9 +95,11 @@
 
   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;