pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pkg/48074 (libgdiplus fails build with the latest giflib)
The following reply was made to PR pkg/48074; it has been noted by GNATS.
From: Onno van der Linden <o.vd.linden%quicknet.nl@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: pkg/48074 (libgdiplus fails build with the latest giflib)
Date: Sun, 5 Jan 2014 15:30:52 +0100
Yes it compiles. But it can cause a crash due to calling
DGifGetExtension() with
&temp_save.ExtensionBlocks[temp_save.ExtensionBlockCount].Function
as the second parameter.
If the ExtensionBlocks pointer is NULL .........
Here's one line from a mono stack trace and some debug output
with some printfs in libgdiplus' DGifSlurpMono() and in
giflib's DGifGetExtension()
$ mono /usr/local/CUETools_2.1.5/CUETools.exe
ExtensionBlockCount = 0 ExtensionBlocks = 0x0 <----------
GifFile = 0xb9595380 ExtCode = 0x8 Extension = 0xbfbfd8d8
Before IS_READABLE
Before READ
Before *ExtCode
Stacktrace:
at (wrapper managed-to-native)
System.Drawing.GDIPlus.GdipLoadImageFromDelegate_linux
(System.Drawing.GDIPlus/StreamGetHeaderDelegate,System.Drawing.GDIPlus/StreamGetBytesDelegate,System.Drawing.GDIPlus/StreamPutBytesDelegate,System.Drawing.GDIPlus/StreamSeekDelegate,System.Drawing.GDIPlus/StreamCloseDelegate,System.Drawing.GDIPlus/StreamSizeDelegate,intptr&)
<0xffffffff>
Here's the (complete) gifcodec diff which seems to work for me:
--- gifcodec.c.orig 2011-01-13 23:28:19.000000000 +0100
+++ gifcodec.c 2014-01-05 15:23:43.000000000 +0100
@@ -39,8 +39,12 @@
#include "gifcodec.h"
-/* giflib declares this incorrectly as EgifOpen */
+/* giflib declares this incorrectly as EgifOpen up to 4.1.2
+ GIF_LIB_VERSION is defined up to 4.1.6, and prototype is changed in 5.0,
+ so it is safe to use it as check condition */
+#ifdef GIF_LIB_VERSION
extern GifFileType *EGifOpen(void *userData, OutputFunc writeFunc);
+#endif
/* Data structure used for callback */
typedef struct
@@ -105,7 +109,7 @@
*/
static int
-AddExtensionBlockMono(SavedImage *New, int Len, BYTE ExtData[])
+AddExtensionBlockMono(SavedImage *New, int ExtCode, int Len, BYTE ExtData[])
{
ExtensionBlock *ep;
@@ -129,7 +133,7 @@
if (ExtData) {
memcpy(ep->Bytes, ExtData, Len);
- ep->Function = New->Function;
+ ep->Function = ExtCode;
}
return (GIF_OK);
@@ -232,20 +236,31 @@
}
case EXTENSION_RECORD_TYPE: {
+#if GIFLIB_MAJOR >= 5
+ int ExtCode;
+ if (DGifGetExtension(GifFile, &ExtCode,
&ExtData) == GIF_ERROR) {
+#else
if (DGifGetExtension(GifFile,
&temp_save.Function, &ExtData) == GIF_ERROR) {
+#endif
return (GIF_ERROR);
}
while (ExtData != NULL) {
/* Create an extension block with our
data */
- if (AddExtensionBlockMono(&temp_save,
ExtData[0], &ExtData[1]) == GIF_ERROR) {
+#if GIFLIB_MAJOR >= 5
+ if (AddExtensionBlockMono(&temp_save,
ExtCode, ExtData[0], &ExtData[1]) == GIF_ERROR) {
+#else
+ if (AddExtensionBlockMono(&temp_save,
temp_save.Function ExtData[0], &ExtData[1]) == GIF_ERROR) {
+#endif
return (GIF_ERROR);
}
if (DGifGetExtensionNext(GifFile,
&ExtData) == GIF_ERROR) {
return (GIF_ERROR);
}
+#if GIFLIB_MAJOR < 5
temp_save.Function = 0;
+#endif
}
break;
}
@@ -304,9 +319,17 @@
loop_counter = FALSE;
if (from_file) {
+#if GIFLIB_MAJOR >= 5
+ gif = DGifOpen(stream, &gdip_gif_fileinputfunc, NULL);
+#else
gif = DGifOpen(stream, &gdip_gif_fileinputfunc);
+#endif
} else {
+#if GIFLIB_MAJOR >= 5
+ gif = DGifOpen (stream, &gdip_gif_inputfunc, NULL);
+#else
gif = DGifOpen (stream, &gdip_gif_inputfunc);
+#endif
}
if (gif == NULL) {
@@ -662,9 +685,17 @@
}
if (from_file) {
+#if GIFLIB_MAJOR >= 5
+ fp = EGifOpenFileName (stream, 0, NULL);
+#else
fp = EGifOpenFileName (stream, 0);
+#endif
} else {
+#if GIFLIB_MAJOR >= 5
+ fp = EGifOpen (stream, gdip_gif_outputfunc, NULL);
+#else
fp = EGifOpen (stream, gdip_gif_outputfunc);
+#endif
}
if (!fp) {
@@ -703,7 +734,11 @@
goto error;
}
+#if GIFLIB_MAJOR >= 5
+ cmap = GifMakeMapObject(cmap_size, 0);
+#else
cmap = MakeMapObject(cmap_size, 0);
+#endif
pixbuf = GdipAlloc(pixbuf_size);
if (pixbuf == NULL) {
@@ -794,7 +829,11 @@
pixbuf = pixbuf_org;
} else {
cmap_size = 256;
+#if GIFLIB_MAJOR >= 5
+ cmap = GifMakeMapObject (cmap_size, 0);
+#else
cmap = MakeMapObject (cmap_size, 0);
+#endif
red = GdipAlloc(pixbuf_size);
green = GdipAlloc(pixbuf_size);
@@ -825,13 +864,21 @@
v += 4;
}
}
+#if GIFLIB_MAJOR >= 5
+ if (GifQuantizeBuffer(bitmap_data->width,
bitmap_data->height, &cmap_size,
+#else
if (QuantizeBuffer(bitmap_data->width,
bitmap_data->height, &cmap_size,
+#endif
red, green, blue, pixbuf,
cmap->Colors) == GIF_ERROR) {
goto error;
}
}
+#if GIFLIB_MAJOR >= 5
+ cmap->BitsPerPixel = GifBitSize (cmap_size);
+#else
cmap->BitsPerPixel = BitSize (cmap_size);
+#endif
cmap->ColorCount = 1 << cmap->BitsPerPixel;
if ((frame == 0) && (k == 0)) {
@@ -849,8 +896,15 @@
Buffer[0] = 1;
Buffer[1] = ptr[0];
Buffer[2] = ptr[1];
+#if GIFLIB_MAJOR >= 5
+ EGifPutExtensionLeader(fp,
APPLICATION_EXT_FUNC_CODE);
+ EGifPutExtensionBlock(fp, 11,
"NETSCAPE2.0");
+ EGifPutExtensionBlock(fp, 3,
Buffer);
+ EGifPutExtensionTrailer(fp);
+#else
EGifPutExtensionFirst(fp,
APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
EGifPutExtensionLast(fp,
APPLICATION_EXT_FUNC_CODE, 3, Buffer);
+#endif
}
}
@@ -902,7 +956,11 @@
pixbuf += bitmap_data->width;
}
+#if GIFLIB_MAJOR >= 5
+ GifFreeMapObject (cmap);
+#else
FreeMapObject (cmap);
+#endif
if (red != NULL) {
GdipFree (red);
}
@@ -930,7 +988,11 @@
error:
if (cmap != NULL) {
+#if GIFLIB_MAJOR >= 5
+ GifFreeMapObject (cmap);
+#else
FreeMapObject (cmap);
+#endif
}
if (red != NULL) {
Home |
Main Index |
Thread Index |
Old Index