#include <stdlib.h>
#include <string.h>
-#include "ungif.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
+#include "ungif.h"
+
static void *ungif_alloc( size_t sz )
{
return HeapAlloc( GetProcessHeap(), 0, sz );
Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == NULL) {
+ ungif_free(Object);
return NULL;
}
}
static int
-AddExtensionBlock(SavedImage * New,
+AddExtensionBlock(Extensions *New,
int Len,
const unsigned char ExtData[]) {
ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
- ep->ByteCount=Len;
- ep->Bytes = ungif_alloc(ep->ByteCount);
+ ep->ByteCount=Len + 3;
+ ep->Bytes = ungif_alloc(ep->ByteCount + 3);
if (ep->Bytes == NULL)
return (GIF_ERROR);
+ /* Extension Header */
+ ep->Bytes[0] = 0x21;
+ ep->Bytes[1] = New->Function;
+ ep->Bytes[2] = Len;
+
if (ExtData) {
- memcpy(ep->Bytes, ExtData, Len);
+ memcpy(ep->Bytes + 3, ExtData, Len);
ep->Function = New->Function;
}
return (GIF_OK);
}
+static int
+AppendExtensionBlock(Extensions *New,
+ int Len,
+ const unsigned char ExtData[])
+{
+ ExtensionBlock *ep;
+
+ if (New->ExtensionBlocks == NULL)
+ return (GIF_ERROR);
+
+ ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1];
+
+ ep->Bytes = ungif_realloc(ep->Bytes, ep->ByteCount + Len + 1);
+ if (ep->Bytes == NULL)
+ return (GIF_ERROR);
+
+ ep->Bytes[ep->ByteCount] = Len;
+
+ if (ExtData)
+ memcpy(ep->Bytes + ep->ByteCount + 1, ExtData, Len);
+
+ ep->ByteCount += Len + 1;
+
+ return (GIF_OK);
+}
+
static void
-FreeExtension(SavedImage * Image)
+FreeExtension(Extensions *Extensions)
{
ExtensionBlock *ep;
- if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
+ if ((Extensions == NULL) || (Extensions->ExtensionBlocks == NULL)) {
return;
}
- for (ep = Image->ExtensionBlocks;
- ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
+ for (ep = Extensions->ExtensionBlocks;
+ ep < (Extensions->ExtensionBlocks + Extensions->ExtensionBlockCount); ep++)
ungif_free(ep->Bytes);
- ungif_free(Image->ExtensionBlocks);
- Image->ExtensionBlocks = NULL;
+ ungif_free(Extensions->ExtensionBlocks);
+ Extensions->ExtensionBlocks = NULL;
}
/******************************************************************************
ungif_free(sp->RasterBits);
- if (sp->ExtensionBlocks)
- FreeExtension(sp);
+ if (sp->Extensions.ExtensionBlocks)
+ FreeExtension(&sp->Extensions);
}
ungif_free(GifFile->SavedImages);
GifFile->SavedImages=NULL;
static int
DGifGetScreenDesc(GifFileType * GifFile) {
- int i, BitsPerPixel;
+ int i, BitsPerPixel, SortFlag;
GifByteType Buf[3];
/* Put the screen descriptor into the file: */
return GIF_ERROR;
}
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
+ SortFlag = (Buf[0] & 0x08) != 0;
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
+ GifFile->SAspectRatio = Buf[2];
if (Buf[0] & 0x80) { /* Do we have global color map? */
GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
}
/* Get the global color map: */
+ GifFile->SColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->SColorMap);
static int
DGifGetImageDesc(GifFileType * GifFile) {
- int i, BitsPerPixel;
+ int i, BitsPerPixel, SortFlag;
GifByteType Buf[3];
GifFilePrivateType *Private = GifFile->Private;
SavedImage *sp;
return GIF_ERROR;
}
BitsPerPixel = (Buf[0] & 0x07) + 1;
+ SortFlag = (Buf[0] & 0x20) != 0;
GifFile->Image.Interlace = (Buf[0] & 0x40);
if (Buf[0] & 0x80) { /* Does this image have local color map? */
}
/* Get the image local color map: */
+ GifFile->Image.ColorMap->SortFlag = SortFlag;
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->Image.ColorMap);
if (sp->ImageDesc.ColorMap == NULL) {
return GIF_ERROR;
}
+ sp->ImageDesc.ColorMap->SortFlag = GifFile->Image.ColorMap->SortFlag;
}
sp->RasterBits = NULL;
- sp->ExtensionBlockCount = 0;
- sp->ExtensionBlocks = NULL;
+ sp->Extensions.ExtensionBlockCount = 0;
+ sp->Extensions.ExtensionBlocks = NULL;
GifFile->ImageCount++;
GifRecordType RecordType;
SavedImage *sp;
GifByteType *ExtData;
- SavedImage temp_save;
+ Extensions temp_save;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
GIF_ERROR)
return (GIF_ERROR);
if (temp_save.ExtensionBlocks) {
- sp->ExtensionBlocks = temp_save.ExtensionBlocks;
- sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
+ sp->Extensions.ExtensionBlocks = temp_save.ExtensionBlocks;
+ sp->Extensions.ExtensionBlockCount = temp_save.ExtensionBlockCount;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
/* FIXME: The following is wrong. It is left in only for
* backwards compatibility. Someday it should go away. Use
* the sp->ExtensionBlocks->Function variable instead. */
- sp->Function = sp->ExtensionBlocks[0].Function;
+ sp->Extensions.Function = sp->Extensions.ExtensionBlocks[0].Function;
}
break;
case EXTENSION_RECORD_TYPE:
- if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
- GIF_ERROR)
+ {
+ int Function;
+ Extensions *Extensions;
+
+ if (DGifGetExtension(GifFile, &Function, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
+
+ if (GifFile->ImageCount || Function == GRAPHICS_EXT_FUNC_CODE)
+ Extensions = &temp_save;
+ else
+ Extensions = &GifFile->Extensions;
+
+ Extensions->Function = Function;
+
+ /* Create an extension block with our data */
+ if (AddExtensionBlock(Extensions, ExtData[0], &ExtData[1]) == GIF_ERROR)
+ return (GIF_ERROR);
+
while (ExtData != NULL) {
+ int Len;
+ GifByteType *Data;
- /* Create an extension block with our data */
- if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
- == GIF_ERROR)
+ if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
- if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
+ if (ExtData)
+ {
+ Len = ExtData[0];
+ Data = &ExtData[1];
+ }
+ else
+ {
+ Len = 0;
+ Data = NULL;
+ }
+
+ if (AppendExtensionBlock(Extensions, Len, Data) == GIF_ERROR)
return (GIF_ERROR);
- temp_save.Function = 0;
}
break;
+ }
case TERMINATE_RECORD_TYPE:
break;
GifFile->SavedImages = NULL;
}
+ FreeExtension(&GifFile->Extensions);
+
ungif_free(GifFile);
return GIF_OK;