Support newer GIFLIB versions This is an adapted upstream patch. This patch is incomplete so a new patch needs to be added after this one. Upstream commit: https://github.com/pigoz/mplayer-svn/commit/a0ddaef5457e222dade386901bf448c5e3ac7b89 Signed-off-by: Vicente Olivert Riera From a0ddaef5457e222dade386901bf448c5e3ac7b89 Mon Sep 17 00:00:00 2001 From: al Date: Sat, 27 Jul 2013 21:16:06 +0000 Subject: [PATCH] Support newer GIFLIB versions Work with GIFLIB version >= 4.2 Several functions have been renamed or changed in signature. GIFLIB is used by vo gif89a and demuxer gif. Note about GIFLIB Version 4.2: It does not work with vanilla GIFLIB 4.2 but it works with versions that have re-added quantize support like e.g. the package from arch linux. Note about GIFLIB Version 5: The newly added GCB functions use size_t but the necessary standard headers are not included in gif_lib.h . To workaround this: * configure: use statement_check_broken to include stdlib.h * vo gif89: include gif_lib.h after stdlib.h * demuxer gif: no workaround needed, gif_lib.h is already included after stdlib.h git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@36367 b3059339-0415-0410-9bf9-f77b7e298cf2 --- configure | 1 + libmpdemux/demux_gif.c | 44 +++++++++++++++++++++++++++++++++++--------- libvo/vo_gif89a.c | 35 ++++++++++++++++++++++++----------- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/configure b/configure index e9152a8..4cd378d 100755 --- a/configure +++ b/configure @@ -4938,6 +4938,7 @@ if test "$_gif" = auto ; then _gif=no for ld_gif in "-lungif" "-lgif" ; do statement_check gif_lib.h 'QuantizeBuffer(0, 0, 0, 0, 0, 0, 0, 0)' $ld_gif && _gif=yes && break + statement_check_broken stdlib.h gif_lib.h 'GifQuantizeBuffer(0, 0, 0, 0, 0, 0, 0, 0)' $ld_gif && _gif=yes && break done fi diff --git a/libmpdemux/demux_gif.c b/libmpdemux/demux_gif.c index 804ce8c..0a11322 100644 --- a/libmpdemux/demux_gif.c +++ b/libmpdemux/demux_gif.c @@ -45,6 +45,32 @@ typedef struct { #define GIF_SIGNATURE (('G' << 16) | ('I' << 8) | 'F') +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 +#define DGifOpen(a, b) DGifOpen(a, b, NULL) +#define DGifOpenFileHandle(a) DGifOpenFileHandle(a, NULL) +#define GifError() (gif ? gif->Error : 0) +#define GifErrorString() GifErrorString(gif->Error) +#endif + +/* >= 4.2 prior GIFLIB did not have MAJOR/MINOR defines */ +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 4 +static void print_gif_error(GifFileType *gif) +{ + int err = GifError(); + char *err_str = GifErrorString(); + + if (err_str) + mp_msg(MSGT_DEMUX, MSGL_ERR, "\n[gif] GIF-LIB error: %s.\n", err_str); + else + mp_msg(MSGT_DEMUX, MSGL_ERR, "\n[gif] GIF-LIB undefined error %d.\n", err); +} +#else +static void print_gif_error(GifFileType *gif) +{ + PrintGifError(); +} +#endif + #ifndef CONFIG_GIF_TVT_HACK // not supported by certain versions of the library static int my_read_gif(GifFileType *gif, uint8_t *buf, int len) @@ -94,14 +120,14 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) while (type != IMAGE_DESC_RECORD_TYPE) { if (DGifGetRecordType(gif, &type) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } if (type == TERMINATE_RECORD_TYPE) return 0; // eof if (type == SCREEN_DESC_RECORD_TYPE) { if (DGifGetScreenDesc(gif) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } } @@ -109,7 +135,7 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) int code; unsigned char *p = NULL; if (DGifGetExtension(gif, &code, &p) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } if (code == 0xF9) { @@ -138,7 +164,7 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) comments[length] = 0; printf("%s", comments); if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } } @@ -146,7 +172,7 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) } while (p != NULL) { if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } } @@ -154,7 +180,7 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) } if (DGifGetImageDesc(gif) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); return 0; // oops } @@ -167,7 +193,7 @@ static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) memset(dp->buffer, gif->SBackGroundColor, priv->w * priv->h); if (DGifGetLine(gif, buf, len) == GIF_ERROR) { - PrintGifError(); + print_gif_error(priv->gif); free(buf); free_demux_packet(dp); return 0; // oops @@ -261,7 +287,7 @@ static demuxer_t* demux_open_gif(demuxer_t* demuxer) gif = DGifOpen(demuxer->stream, my_read_gif); #endif if (!gif) { - PrintGifError(); + print_gif_error(NULL); free(priv); return NULL; } @@ -303,7 +329,7 @@ static void demux_close_gif(demuxer_t* demuxer) gif_priv_t *priv = demuxer->priv; if (!priv) return; if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR) - PrintGifError(); + print_gif_error(priv->gif); free(priv->refimg); free(priv); } diff --git a/libvo/vo_gif89a.c b/libvo/vo_gif89a.c index b808f81..160291a 100644 --- a/libvo/vo_gif89a.c +++ b/libvo/vo_gif89a.c @@ -44,13 +44,13 @@ * entire argument being interpretted as the filename. */ -#include - #include #include #include #include +#include + #include "config.h" #include "subopt-helper.h" #include "video_out.h" @@ -69,6 +69,12 @@ static const vo_info_t info = { const LIBVO_EXTERN(gif89a) +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 +#define EGifOpenFileName(a, b) EGifOpenFileName(a, b, NULL) +#define MakeMapObject GifMakeMapObject +#define FreeMapObject GifFreeMapObject +#define QuantizeBuffer GifQuantizeBuffer +#endif // how many frames per second we are aiming for during output. static float target_fps; @@ -156,7 +162,7 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { -#ifdef CONFIG_GIF_4 +#if defined CONFIG_GIF_4 || GIFLIB_MAJOR >= 5 // these are control blocks for the gif looping extension. char LB1[] = "NETSCAPE2.0"; char LB2[] = { 1, 0, 0 }; @@ -185,23 +191,25 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t d_width, return 1; } + new_gif = EGifOpenFileName(gif_filename, 0); + if (new_gif == NULL) { + mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: error opening file \"%s\" for output.\n", gif_filename); + return 1; + } + +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 + EGifSetGifVersion(new_gif, 1); +#elif defined CONFIG_GIF_4 // the EGifSetGifVersion line causes segfaults in certain // earlier versions of libungif. i don't know exactly which, // but certainly in all those before v4. if you have problems, // you need to upgrade your gif library. -#ifdef CONFIG_GIF_4 EGifSetGifVersion("89a"); #else mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Your version of libungif needs to be upgraded.\n"); mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: Some functionality has been disabled.\n"); #endif - new_gif = EGifOpenFileName(gif_filename, 0); - if (new_gif == NULL) { - mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: error opening file \"%s\" for output.\n", gif_filename); - return 1; - } - slice_data = malloc(img_width * img_height * 3); if (slice_data == NULL) { mp_msg(MSGT_VO, MSGL_ERR, "GIF89a: malloc failed.\n"); @@ -231,7 +239,12 @@ static int config(uint32_t s_width, uint32_t s_height, uint32_t d_width, // set the initial width and height info. EGifPutScreenDesc(new_gif, s_width, s_height, 256, 0, reduce_cmap); -#ifdef CONFIG_GIF_4 +#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5 + EGifPutExtensionLeader(new_gif, 0xFF); + EGifPutExtensionBlock(new_gif, 11, LB1); + EGifPutExtensionBlock(new_gif, 3, LB2); + EGifPutExtensionTrailer(new_gif); +#elif defined CONFIG_GIF_4 // version 3 of libungif does not support multiple control blocks. // looping requires multiple control blocks. // therefore, looping is only enabled for v4 and up. -- 1.7.1