From cfaca0053dbfda1c2a091fa92037427bb3600e9e Mon Sep 17 00:00:00 2001 From: melanson Date: Wed, 20 Mar 2002 05:15:53 +0000 Subject: [PATCH] added a BMP file demuxer...yeah, that's right, a static image BMP file demuxer; what, is that so weird?...:) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5215 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpdemux/Makefile | 2 +- libmpdemux/demux_bmp.c | 111 +++++++++++++++++++++++++++++++++++++++++ libmpdemux/demuxer.c | 18 +++++++ libmpdemux/demuxer.h | 3 +- 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 libmpdemux/demux_bmp.c diff --git a/libmpdemux/Makefile b/libmpdemux/Makefile index b85d0dcad4..345af8da03 100644 --- a/libmpdemux/Makefile +++ b/libmpdemux/Makefile @@ -3,7 +3,7 @@ LIBNAME = libmpdemux.a include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c opt-reg.c mpdemux.c demux_ogg.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c opt-reg.c mpdemux.c demux_ogg.c demux_bmp.c ifeq ($(STREAMING),yes) SRCS += asf_streaming.c url.c http.c network.c rtp.c endif diff --git a/libmpdemux/demux_bmp.c b/libmpdemux/demux_bmp.c new file mode 100644 index 0000000000..df28daee37 --- /dev/null +++ b/libmpdemux/demux_bmp.c @@ -0,0 +1,111 @@ +/* + BMP file parser for the MPlayer program + by Mike Melanson +*/ + +#include +#include +#include + +#include "config.h" +#include "mp_msg.h" +#include "help_mp.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" + +typedef struct { + int image_size; + int image_offset; +} bmp_image_t; + +// Check if a file is a BMP file depending on whether starts with 'BM' +int bmp_check_file(demuxer_t *demuxer) +{ + stream_reset(demuxer->stream); + stream_seek(demuxer->stream, 0); + + if (stream_read_word(demuxer->stream) == (('B' << 8) | 'M')) + return 1; + else + return 0; +} + +// return value: +// 0 = EOF or no stream found +// 1 = successfully read a packet +int demux_bmp_fill_buffer(demuxer_t *demuxer) +{ + bmp_image_t *bmp_image = (bmp_image_t *)demuxer->priv; + + stream_reset(demuxer->stream); + stream_seek(demuxer->stream, bmp_image->image_offset); + ds_read_packet(demuxer->video, demuxer->stream, bmp_image->image_size, + 0, bmp_image->image_offset, 1); + + return 1; +} + +demuxer_t* demux_open_bmp(demuxer_t* demuxer) +{ + sh_video_t *sh_video = NULL; + unsigned int filesize; + unsigned int data_offset; + bmp_image_t *bmp_image; + + // go back to the beginning + stream_reset(demuxer->stream); + stream_seek(demuxer->stream, 2); + filesize = stream_read_dword_le(demuxer->stream); + stream_skip(demuxer->stream, 4); + data_offset = stream_read_word_le(demuxer->stream); + stream_skip(demuxer->stream, 2); + + // create a new video stream header + sh_video = new_sh_video(demuxer, 0); + + // make sure the demuxer knows about the new video stream header + demuxer->video->sh = sh_video; + + // make sure that the video demuxer stream header knows about its + // parent video demuxer stream + sh_video->ds = demuxer->video; + + // load the BITMAPINFOHEADER + // allocate size and take the palette table into account + sh_video->bih = (BITMAPINFOHEADER *)malloc(data_offset - 12); + sh_video->bih->biSize = stream_read_dword_le(demuxer->stream); + sh_video->bih->biWidth = stream_read_dword_le(demuxer->stream); + sh_video->bih->biHeight = stream_read_dword_le(demuxer->stream); + sh_video->bih->biPlanes = stream_read_word_le(demuxer->stream); + sh_video->bih->biBitCount = stream_read_word_le(demuxer->stream); + sh_video->bih->biCompression = stream_read_dword_le(demuxer->stream); + sh_video->bih->biSizeImage = stream_read_dword_le(demuxer->stream); + sh_video->bih->biXPelsPerMeter = stream_read_dword_le(demuxer->stream); + sh_video->bih->biYPelsPerMeter = stream_read_dword_le(demuxer->stream); + sh_video->bih->biClrUsed = stream_read_dword_le(demuxer->stream); + sh_video->bih->biClrImportant = stream_read_dword_le(demuxer->stream); + // fetch the palette + stream_read(demuxer->stream, (unsigned char *)(sh_video->bih) + 40, + sh_video->bih->biClrUsed * 4); + + // load the data + bmp_image = (bmp_image_t *)malloc(sizeof(bmp_image_t)); + bmp_image->image_size = filesize - data_offset; + bmp_image->image_offset = data_offset; + + // custom fourcc for internal MPlayer use + sh_video->format = sh_video->bih->biCompression; + + sh_video->disp_w = sh_video->bih->biWidth; + sh_video->disp_h = sh_video->bih->biHeight; + + // get the speed + sh_video->fps = 2; + sh_video->frametime = 1 / sh_video->fps; + + demuxer->priv = bmp_image; + + return demuxer; +} diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index 8f45423dae..06edf250f7 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -196,6 +196,7 @@ void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,off_t int demux_mf_fill_buffer( demuxer_t *demux); int demux_roq_fill_buffer(demuxer_t *demux); int demux_film_fill_buffer(demuxer_t *demux); +int demux_bmp_fill_buffer(demuxer_t *demux); int demux_fli_fill_buffer(demuxer_t *demux); int demux_mpg_es_fill_buffer(demuxer_t *demux); int demux_mpg_fill_buffer(demuxer_t *demux); @@ -227,6 +228,7 @@ int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ case DEMUXER_TYPE_MF: return demux_mf_fill_buffer(demux); case DEMUXER_TYPE_ROQ: return demux_roq_fill_buffer(demux); case DEMUXER_TYPE_FILM: return demux_film_fill_buffer(demux); + case DEMUXER_TYPE_BMP: return demux_bmp_fill_buffer(demux); case DEMUXER_TYPE_FLI: return demux_fli_fill_buffer(demux); case DEMUXER_TYPE_MPEG_ES: return demux_mpg_es_fill_buffer(demux); case DEMUXER_TYPE_MPEG_PS: return demux_mpg_fill_buffer(demux); @@ -422,6 +424,7 @@ int mov_read_header(demuxer_t* demuxer); int demux_open_fli(demuxer_t* demuxer); int demux_open_mf(demuxer_t* demuxer); int demux_open_film(demuxer_t* demuxer); +int demux_open_bmp(demuxer_t* demuxer); int demux_open_roq(demuxer_t* demuxer); extern int vivo_check_file(demuxer_t *demuxer); @@ -598,6 +601,17 @@ if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_ROQ){ demuxer = NULL; } } +//=============== Try to open as BMP file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_BMP){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_BMP,audio_id,video_id,dvdsub_id); + if(bmp_check_file(demuxer)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,"BMP file\n"); + file_format=DEMUXER_TYPE_BMP; + } else { + free_demuxer(demuxer); + demuxer = NULL; + } +} //=============== Try to open as Ogg file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_OGG){ demuxer=new_demuxer(stream,DEMUXER_TYPE_OGG,audio_id,video_id,dvdsub_id); @@ -724,6 +738,10 @@ switch(file_format){ if (!demux_open_film(demuxer)) return NULL; break; } + case DEMUXER_TYPE_BMP: { + if (!demux_open_bmp(demuxer)) return NULL; + break; + } case DEMUXER_TYPE_ROQ: { if (!demux_open_roq(demuxer)) return NULL; break; diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 0bb93ca2f6..528ce4644b 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -23,9 +23,10 @@ #define DEMUXER_TYPE_MF 16 #define DEMUXER_TYPE_AUDIO 17 #define DEMUXER_TYPE_OGG 18 +#define DEMUXER_TYPE_BMP 19 // This should always match the higest demuxer type number. // Unless you want to disallow users to force the demuxer to some types -#define DEMUXER_TYPE_MAX 18 +#define DEMUXER_TYPE_MAX 19 #define DEMUXER_TYPE_DEMUXERS (1<<16) // A virtual demuxer type for the network code