From 1f6287474fd88642757235b7e605385341ef3735 Mon Sep 17 00:00:00 2001 From: rtognimp Date: Thu, 28 Aug 2003 21:23:40 +0000 Subject: Quicktime 8BPS decoder git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10713 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/Makefile | 2 +- libmpcodecs/vd.c | 2 + libmpcodecs/vd_qt8bps.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 libmpcodecs/vd_qt8bps.c (limited to 'libmpcodecs') diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile index 97c9d432f7..76aefea58a 100644 --- a/libmpcodecs/Makefile +++ b/libmpcodecs/Makefile @@ -10,7 +10,7 @@ AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c a AUDIO_SRCS=dec_audio.c ad.c $(AUDIO_SRCS_LIB) $(AUDIO_SRCS_NAT) $(AUDIO_SRCS_OPT) VIDEO_SRCS_LIB=vd_libmpeg2.c vd_nuv.c vd_lzo.c -VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_msrle.c vd_mpegpes.c vd_lcl.c vd_mtga.c vd_sgi.c +VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_msrle.c vd_mpegpes.c vd_lcl.c vd_mtga.c vd_sgi.c vd_qt8bps.c VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_xanim.c vd_xvid.c vd_libdv.c vd_qtvideo.c vd_theora.c VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT) diff --git a/libmpcodecs/vd.c b/libmpcodecs/vd.c index 3c59ef5ff5..7ed1d3a674 100644 --- a/libmpcodecs/vd.c +++ b/libmpcodecs/vd.c @@ -61,6 +61,7 @@ extern vd_functions_t mpcodecs_vd_libdv; extern vd_functions_t mpcodecs_vd_lcl; extern vd_functions_t mpcodecs_vd_lzo; extern vd_functions_t mpcodecs_vd_qtvideo; +extern vd_functions_t mpcodecs_vd_qt8bps; vd_functions_t* mpcodecs_vd_drivers[] = { &mpcodecs_vd_null, @@ -125,6 +126,7 @@ vd_functions_t* mpcodecs_vd_drivers[] = { #if defined(USE_QTX_CODECS) || defined(MACOSX) &mpcodecs_vd_qtvideo, #endif + &mpcodecs_vd_qt8bps, NULL }; diff --git a/libmpcodecs/vd_qt8bps.c b/libmpcodecs/vd_qt8bps.c new file mode 100644 index 0000000000..14a647acf1 --- /dev/null +++ b/libmpcodecs/vd_qt8bps.c @@ -0,0 +1,236 @@ +/* + * + * QuickTime 8BPS decoder for Mplayer + * (c) 2003 Roberto Togni + * + * Fourcc: 8BPS + * + * Supports 8bpp (paletted), 24bpp and 32bpp (4th plane ignored) + * + */ + +#include +#include + +#include "config.h" +#include "bswap.h" + +#include "mp_msg.h" + +#include "vd_internal.h" + + +static vd_info_t info = { + "8BPS Video decoder", + "qt8bps", + "Roberto Togni", + "Roberto Togni", + "native codec" +}; + +LIBVD_EXTERN(qt8bps) + + +/* + * Decoder context + */ +typedef struct { + unsigned char planes; + unsigned char planemap[4]; + unsigned char *palette; +} qt8bps_context_t; + + +/* + * Internal function prototypes + */ + + +// to set/get/query special features/parameters +static int control(sh_video_t *sh,int cmd,void* arg,...) +{ + qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context + + if (cmd == VDCTRL_QUERY_FORMAT) + switch (hc->planes) { + case 1: + if (*((int*)arg) == IMGFMT_BGR8) + return CONTROL_TRUE; + else + return CONTROL_FALSE; + break; + case 3: + case 4: + if ((*((int*)arg) == IMGFMT_BGR24) || (*((int*)arg) == IMGFMT_BGR32)) + return CONTROL_TRUE; + else + return CONTROL_FALSE; + break; + default: + return CONTROL_FALSE; + } + + return CONTROL_UNKNOWN; +} + + +/* + * + * Init 8BPS decoder + * + */ +static int init(sh_video_t *sh) +{ + int vo_ret; // Video output init ret value + qt8bps_context_t *hc; // Decoder context + BITMAPINFOHEADER *bih = sh->bih; + int i; + unsigned char *psrc, *pdest; + + if ((hc = malloc(sizeof(qt8bps_context_t))) == NULL) { + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for 8BPS decoder context.\n"); + return 0; + } + + sh->context = (void *)hc; + hc->palette = NULL; + + switch (bih->biBitCount) { + case 8: + hc->planes = 1; + hc->planemap[0] = 0; // 1st plane is palette indexes + if (bih->biSize > sizeof(BITMAPINFOHEADER)) { + psrc = (unsigned char*)bih + sizeof(BITMAPINFOHEADER); + pdest = hc->palette = (unsigned char *)malloc(256*3); + for (i = 0; i < 256; i++) { + *pdest++ = *psrc++; + *pdest++ = *psrc++; + *pdest++ = *psrc++; + psrc++; + } + } + break; + case 24: + hc->planes = 3; + hc->planemap[0] = 2; // 1st plane is red + hc->planemap[1] = 1; // 2nd plane is green + hc->planemap[2] = 0; // 3rd plane is blue + break; + case 32: + hc->planes = 4; + hc->planemap[0] = 2; // 1st plane is red + hc->planemap[1] = 1; // 2nd plane is green + hc->planemap[2] = 0; // 3rd plane is blue + hc->planemap[3] = 3; // 4th plane is alpha??? + mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[8BPS] Ignoring 4th (alpha?) plane.\n"); + break; + default: + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "[8BPS] Unsupported color depth: %u.\n", bih->biBitCount); + return 0; + } + + /* + * Initialize video output device + */ + vo_ret = mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24); + + return vo_ret; +} + + + + +/* + * + * Uninit 8BPS decoder + * + */ +static void uninit(sh_video_t *sh) +{ + qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context + + if (sh->context) { + if (hc->palette) + free (hc->palette); + free(sh->context); + } +} + + + +/* + * + * Decode a frame + * + */ +static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags) +{ + mp_image_t* mpi; + unsigned char *encoded = (unsigned char *)data; + qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context + unsigned char *outptr, *pixptr; + unsigned int height = sh->disp_h; // Real image height + unsigned int dlen, p, row; + unsigned char *lp, *dp; + unsigned char count; + unsigned int px_inc; + unsigned int planes = hc->planes; + unsigned char *planemap = hc->planemap; + + + // Skipped frame + if(len <= 0) + return NULL; + + /* Get output image buffer */ + mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE, sh->disp_w, sh->disp_h); + if (!mpi) { + mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate mpi image for 8BPS codec.\n"); + return NULL; + } + + outptr = mpi->planes[0]; // Output image pointer + px_inc = mpi->bpp/8; + + /* Set data pointer after line lengths */ + dp = encoded + hc->planes*(height << 1); + + /* Ignore alpha plane, don't know what to do with it */ + if (planes == 4) + planes--; + + for (p = 0; p < planes; p++) { + /* Lines length pointer for this plane */ + lp = encoded + p*(height << 1); + + /* Decode a plane */ + for(row = 0; row < height; row++) { + pixptr = outptr + row * mpi->stride[0] + planemap[p]; + dlen = be2me_16(*(unsigned short *)(lp+row*2)); + /* Decode a row of this plane */ + while(dlen > 0) { + if ((count = *dp++) <= 127) { + count++; + dlen -= count + 1; + while(count--) { + *pixptr = *dp++; + pixptr += px_inc; + } + } else { + count = 257 - count; + while(count--) { + *pixptr = *dp; + pixptr += px_inc; + } + dp++; + dlen -= 2; + } + } + } + } + + if (hc->palette) + mpi->planes[1] = hc->palette; + + return mpi; +} -- cgit v1.2.3