Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

1096
Engine/lib/lungif/dgif_lib.c Normal file

File diff suppressed because it is too large Load diff

120
Engine/lib/lungif/gif_err.c Normal file
View file

@ -0,0 +1,120 @@
/*****************************************************************************
* "Gif-Lib" - Yet another gif library.
*
* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989
*****************************************************************************
* Handle error reporting for the GIF library.
*****************************************************************************
* History:
* 17 Jun 89 - Version 1.0 by Gershon Elber.
****************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "gif_lib.h"
int _GifError = 0;
/*****************************************************************************
* Return the last GIF error (0 if none) and reset the error.
****************************************************************************/
int
GifLastError(void) {
int i = _GifError;
_GifError = 0;
return i;
}
#ifndef _GBA_NO_FILEIO
/*****************************************************************************
* Print the last GIF error to stderr.
****************************************************************************/
void
PrintGifError(void) {
char *Err;
switch (_GifError) {
case E_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case E_GIF_ERR_WRITE_FAILED:
Err = "Failed to Write to given file";
break;
case E_GIF_ERR_HAS_SCRN_DSCR:
Err = "Screen Descriptor already been set";
break;
case E_GIF_ERR_HAS_IMAG_DSCR:
Err = "Image Descriptor is still active";
break;
case E_GIF_ERR_NO_COLOR_MAP:
Err = "Neither Global Nor Local color map";
break;
case E_GIF_ERR_DATA_TOO_BIG:
Err = "#Pixels bigger than Width * Height";
break;
case E_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Fail to allocate required memory";
break;
case E_GIF_ERR_DISK_IS_FULL:
Err = "Write failed (disk full?)";
break;
case E_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case E_GIF_ERR_NOT_WRITEABLE:
Err = "Given file was not opened for write";
break;
case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case D_GIF_ERR_READ_FAILED:
Err = "Failed to Read from given file";
break;
case D_GIF_ERR_NOT_GIF_FILE:
Err = "Given file is NOT GIF file";
break;
case D_GIF_ERR_NO_SCRN_DSCR:
Err = "No Screen Descriptor detected";
break;
case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
case D_GIF_ERR_NO_COLOR_MAP:
Err = "Neither Global Nor Local color map";
break;
case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
case D_GIF_ERR_DATA_TOO_BIG:
Err = "#Pixels bigger than Width * Height";
break;
case D_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Fail to allocate required memory";
break;
case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case D_GIF_ERR_NOT_READABLE:
Err = "Given file was not opened for read";
break;
case D_GIF_ERR_IMAGE_DEFECT:
Err = "Image is defective, decoding aborted";
break;
case D_GIF_ERR_EOF_TOO_SOON:
Err = "Image EOF detected, before image complete";
break;
default:
Err = NULL;
break;
}
if (Err != NULL)
fprintf(stderr, "\nGIF-LIB error: %s.\n", Err);
else
fprintf(stderr, "\nGIF-LIB undefined error %d.\n", _GifError);
}
#endif /* _GBA_NO_FILEIO */

336
Engine/lib/lungif/gif_lib.h Normal file
View file

@ -0,0 +1,336 @@
/******************************************************************************
* In order to make life a little bit easier when using the GIF file format,
* this library was written, and which does all the dirty work...
*
* Written by Gershon Elber, Jun. 1989
* Hacks by Eric S. Raymond, Sep. 1992
******************************************************************************
* History:
* 14 Jun 89 - Version 1.0 by Gershon Elber.
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names)
* 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp)
* 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)
* 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code)
*****************************************************************************/
#ifndef _GIF_LIB_H_
#define _GIF_LIB_H_ 1
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIF_LIB_VERSION " Version 4.1, "
#define GIF_ERROR 0
#define GIF_OK 1
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef NULL
#define NULL 0
#endif /* NULL */
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
#ifdef _GBA_OPTMEM
typedef unsigned short GifPrefixType;
typedef short GifWord;
#else
typedef unsigned int GifPrefixType;
typedef int GifWord;
#endif
#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg)
#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); }
#ifdef SYSV
#define VoidPtr char *
#else
#define VoidPtr void *
#endif /* SYSV */
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height, /* Current image dimensions. */
Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct GifFileType {
GifWord SWidth, SHeight, /* Screen dimensions. */
SColorResolution, /* How many colors can we generate? */
SBackGroundColor; /* I hope you understand this one... */
ColorMapObject *SColorMap; /* NULL if not exists. */
int ImageCount; /* Number of current image */
GifImageDesc Image; /* Block describing current image */
struct SavedImage *SavedImages; /* Use this to accumulate file state */
VoidPtr UserData; /* hook to attach user data (TVT) */
VoidPtr Private; /* Don't mess with this! */
} GifFileType;
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* DumpScreen2Gif routine constants identify type of window/screen to dump.
* Note all values below 1000 are reserved for the IBMPC different display
* devices (it has many!) and are compatible with the numbering TC2.0
* (Turbo C 2.0 compiler for IBM PC) gives to these devices.
*/
typedef enum {
GIF_DUMP_SGI_WINDOW = 1000,
GIF_DUMP_X_WINDOW = 1001
} GifScreenDumpType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
/* func type to write gif data ro arbitrary targets.
* Returns count of bytes written. (MRB)
*/
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
/******************************************************************************
* GIF89 extension function codes
******************************************************************************/
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
/******************************************************************************
* O.K., here are the routines one can access in order to encode GIF file:
* (GIF_LIB file EGIF_LIB.C).
******************************************************************************/
GifFileType *EGifOpenFileName(const char *GifFileName,
int GifTestExistance);
GifFileType *EGifOpenFileHandle(int GifFileHandle);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc);
int EGifSpew(GifFileType * GifFile);
void EGifSetGifVersion(const char *Version);
int EGifPutScreenDesc(GifFileType * GifFile,
int GifWidth, int GifHeight, int GifColorRes,
int GifBackGround,
const ColorMapObject * GifColorMap);
int EGifPutImageDesc(GifFileType * GifFile, int GifLeft, int GifTop,
int Width, int GifHeight, int GifInterlace,
const ColorMapObject * GifColorMap);
int EGifPutLine(GifFileType * GifFile, GifPixelType * GifLine,
int GifLineLen);
int EGifPutPixel(GifFileType * GifFile, GifPixelType GifPixel);
int EGifPutComment(GifFileType * GifFile, const char *GifComment);
int EGifPutExtensionFirst(GifFileType * GifFile, int GifExtCode,
int GifExtLen, const VoidPtr GifExtension);
int EGifPutExtensionNext(GifFileType * GifFile, int GifExtCode,
int GifExtLen, const VoidPtr GifExtension);
int EGifPutExtensionLast(GifFileType * GifFile, int GifExtCode,
int GifExtLen, const VoidPtr GifExtension);
int EGifPutExtension(GifFileType * GifFile, int GifExtCode, int GifExtLen,
const VoidPtr GifExtension);
int EGifPutCode(GifFileType * GifFile, int GifCodeSize,
const GifByteType * GifCodeBlock);
int EGifPutCodeNext(GifFileType * GifFile,
const GifByteType * GifCodeBlock);
int EGifCloseFile(GifFileType * GifFile);
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
#define E_GIF_ERR_WRITE_FAILED 2
#define E_GIF_ERR_HAS_SCRN_DSCR 3
#define E_GIF_ERR_HAS_IMAG_DSCR 4
#define E_GIF_ERR_NO_COLOR_MAP 5
#define E_GIF_ERR_DATA_TOO_BIG 6
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
#define E_GIF_ERR_DISK_IS_FULL 8
#define E_GIF_ERR_CLOSE_FAILED 9
#define E_GIF_ERR_NOT_WRITEABLE 10
/******************************************************************************
* O.K., here are the routines one can access in order to decode GIF file:
* (GIF_LIB file DGIF_LIB.C).
*****************************************************************************/
#ifndef _GBA_NO_FILEIO
GifFileType *DGifOpenFileName(const char *GifFileName);
GifFileType *DGifOpenFileHandle(int GifFileHandle);
int DGifSlurp(GifFileType * GifFile);
#endif /* _GBA_NO_FILEIO */
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); /* new one
* (TVT) */
int DGifGetScreenDesc(GifFileType * GifFile);
int DGifGetRecordType(GifFileType * GifFile, GifRecordType * GifType);
int DGifGetImageDesc(GifFileType * GifFile);
int DGifGetLine(GifFileType * GifFile, GifPixelType * GifLine, int GifLineLen);
int DGifGetPixel(GifFileType * GifFile, GifPixelType GifPixel);
int DGifGetComment(GifFileType * GifFile, char *GifComment);
int DGifGetExtension(GifFileType * GifFile, int *GifExtCode,
GifByteType ** GifExtension);
int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
int DGifGetCode(GifFileType * GifFile, int *GifCodeSize,
GifByteType ** GifCodeBlock);
int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
int DGifGetLZCodes(GifFileType * GifFile, int *GifCode);
int DGifCloseFile(GifFileType * GifFile);
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/******************************************************************************
* O.K., here are the routines from GIF_LIB file QUANTIZE.C.
******************************************************************************/
int QuantizeBuffer(unsigned int Width, unsigned int Height,
int *ColorMapSize, GifByteType * RedInput,
GifByteType * GreenInput, GifByteType * BlueInput,
GifByteType * OutputBuffer,
GifColorType * OutputColorMap);
/******************************************************************************
* O.K., here are the routines from GIF_LIB file QPRINTF.C.
******************************************************************************/
extern int GifQuietPrint;
#ifdef HAVE_STDARG_H
extern void GifQprintf(char *Format, ...);
#elif defined (HAVE_VARARGS_H)
extern void GifQprintf();
#endif /* HAVE_STDARG_H */
/******************************************************************************
* O.K., here are the routines from GIF_LIB file GIF_ERR.C.
******************************************************************************/
#ifndef _GBA_NO_FILEIO
extern void PrintGifError(void);
#endif /* _GBA_NO_FILEIO */
extern int GifLastError(void);
/******************************************************************************
* O.K., here are the routines from GIF_LIB file DEV2GIF.C.
******************************************************************************/
extern int DumpScreen2Gif(const char *FileName,
int ReqGraphDriver,
long ReqGraphMode1,
long ReqGraphMode2,
long ReqGraphMode3);
/*****************************************************************************
*
* Everything below this point is new after version 1.2, supporting `slurp
* mode' for doing I/O in two big belts with all the image-bashing in core.
*
*****************************************************************************/
/******************************************************************************
* Color Map handling from ALLOCGIF.C
*****************************************************************************/
extern ColorMapObject *MakeMapObject(int ColorCount,
const GifColorType * ColorMap);
extern void FreeMapObject(ColorMapObject * Object);
extern ColorMapObject *UnionColorMap(const ColorMapObject * ColorIn1,
const ColorMapObject * ColorIn2,
GifPixelType ColorTransIn2[]);
extern int BitSize(int n);
/******************************************************************************
* Support for the in-core structures allocation (slurp mode).
*****************************************************************************/
/* This is the in-core version of an extension record */
typedef struct {
int ByteCount;
char *Bytes; /* on malloc(3) heap */
int Function; /* Holds the type of the Extension block. */
} ExtensionBlock;
/* This holds an image header, its unpacked raster bits, and extensions */
typedef struct SavedImage {
GifImageDesc ImageDesc;
unsigned char *RasterBits; /* on malloc(3) heap */
int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
int ExtensionBlockCount;
ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */
} SavedImage;
extern void ApplyTranslation(SavedImage * Image, GifPixelType Translation[]);
extern void MakeExtension(SavedImage * New, int Function);
extern int AddExtensionBlock(SavedImage * New, int Len,
unsigned char ExtData[]);
extern void FreeExtension(SavedImage * Image);
extern SavedImage *MakeSavedImage(GifFileType * GifFile,
const SavedImage * CopyFrom);
extern void FreeSavedImages(GifFileType * GifFile);
/******************************************************************************
* The library's internal utility font
*****************************************************************************/
#define GIF_FONT_WIDTH 8
#define GIF_FONT_HEIGHT 8
extern unsigned char AsciiTable[][GIF_FONT_WIDTH];
#ifdef _WIN32
extern void DrawGifText(SavedImage * Image,
#else
extern void DrawText(SavedImage * Image,
#endif
const int x, const int y,
const char *legend, const int color);
extern void DrawBox(SavedImage * Image,
const int x, const int y,
const int w, const int d, const int color);
void DrawRectangle(SavedImage * Image,
const int x, const int y,
const int w, const int d, const int color);
extern void DrawBoxedText(SavedImage * Image,
const int x, const int y,
const char *legend,
const int border, const int bg, const int fg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _GIF_LIB_H */

View file

@ -0,0 +1,57 @@
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
#include "gif_lib.h"
#define PROGRAM_NAME "LIBUNGIF"
#ifdef SYSV
#define VersionStr "Gif library module,\t\tEric S. Raymond\n\
(C) Copyright 1997 Eric S. Raymond\n"
#else
#define VersionStr PROGRAM_NAME " IBMPC " GIF_LIB_VERSION \
" Eric S. Raymond, " __DATE__ ", " \
__TIME__ "\n" "(C) Copyright 1997 Eric S. Raymond\n"
#endif /* SYSV */
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
#define FILE_STATE_WRITE 0x01
#define FILE_STATE_SCREEN 0x02
#define FILE_STATE_IMAGE 0x04
#define FILE_STATE_READ 0x08
#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
typedef struct GifFilePrivateType {
GifWord FileState, FileHandle, /* Where all this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits, /* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
unsigned long PixelCount; /* Number of pixels in image. */
FILE *File; /* File as stream. */
InputFunc Read; /* function to read gif input (TVT) */
OutputFunc Write; /* function to write gif output (MRB) */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
} GifFilePrivateType;
extern int _GifError;
#endif /* _GIF_LIB_PRIVATE_H */

View file

@ -0,0 +1,443 @@
/*****************************************************************************
* "Gif-Lib" - Yet another gif library.
*
* Written by: Gershon Elber Ver 0.1, Jun. 1989
* Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992
*****************************************************************************
* GIF construction tools
*****************************************************************************
* History:
* 15 Sep 92 - Version 1.0 by Eric Raymond.
****************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/******************************************************************************
* Miscellaneous utility functions
*****************************************************************************/
/* return smallest bitfield size n will fit in */
int
BitSize(int n) {
register int i;
for (i = 1; i <= 8; i++)
if ((1 << i) >= n)
break;
return (i);
}
/******************************************************************************
* Color map object functions
*****************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
ColorMapObject *
MakeMapObject(int ColorCount,
const GifColorType * ColorMap) {
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
* make the user know that or should we automatically round up instead? */
if (ColorCount != (1 << BitSize(ColorCount))) {
return ((ColorMapObject *) NULL);
}
Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
if (Object == (ColorMapObject *) NULL) {
return ((ColorMapObject *) NULL);
}
Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *) NULL) {
return ((ColorMapObject *) NULL);
}
Object->ColorCount = ColorCount;
Object->BitsPerPixel = BitSize(ColorCount);
if (ColorMap) {
memcpy((char *)Object->Colors,
(char *)ColorMap, ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*
* Free a color map object
*/
void
FreeMapObject(ColorMapObject * Object) {
if (Object != NULL) {
free(Object->Colors);
free(Object);
/*** FIXME:
* When we are willing to break API we need to make this function
* FreeMapObject(ColorMapObject **Object)
* and do this assignment to NULL here:
* *Object = NULL;
*/
}
}
#ifdef DEBUG
void
DumpColorMap(ColorMapObject * Object,
FILE * fp) {
if (Object) {
int i, j, Len = Object->ColorCount;
for (i = 0; i < Len; i += 4) {
for (j = 0; j < 4 && j < Len; j++) {
fprintf(fp, "%3d: %02x %02x %02x ", i + j,
Object->Colors[i + j].Red,
Object->Colors[i + j].Green,
Object->Colors[i + j].Blue);
}
fprintf(fp, "\n");
}
}
}
#endif /* DEBUG */
/*
* Compute the union of two given color maps and return it. If result can't
* fit into 256 colors, NULL is returned, the allocated union otherwise.
* ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
* copied iff they didn't exist before. ColorTransIn2 maps the old
* ColorIn2 into ColorUnion color map table.
*/
ColorMapObject *
UnionColorMap(const ColorMapObject * ColorIn1,
const ColorMapObject * ColorIn2,
GifPixelType ColorTransIn2[]) {
int i, j, CrntSlot, RoundUpTo, NewBitSize;
ColorMapObject *ColorUnion;
/*
* Allocate table which will hold the result for sure.
*/
ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount,
ColorIn2->ColorCount) * 2, NULL);
if (ColorUnion == NULL)
return (NULL);
/* Copy ColorIn1 to ColorUnionSize; */
/*** FIXME: What if there are duplicate entries into the colormap to begin
* with? */
for (i = 0; i < ColorIn1->ColorCount; i++)
ColorUnion->Colors[i] = ColorIn1->Colors[i];
CrntSlot = ColorIn1->ColorCount;
/*
* Potentially obnoxious hack:
*
* Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
* of table 1. This is very useful if your display is limited to
* 16 colors.
*/
while (ColorIn1->Colors[CrntSlot - 1].Red == 0
&& ColorIn1->Colors[CrntSlot - 1].Green == 0
&& ColorIn1->Colors[CrntSlot - 1].Blue == 0)
CrntSlot--;
/* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */
for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
/* Let's see if this color already exists: */
/*** FIXME: Will it ever occur that ColorIn2 will contain duplicate
* entries? So we should search from 0 to CrntSlot rather than
* ColorIn1->ColorCount?
*/
for (j = 0; j < ColorIn1->ColorCount; j++)
if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
sizeof(GifColorType)) == 0)
break;
if (j < ColorIn1->ColorCount)
ColorTransIn2[i] = j; /* color exists in Color1 */
else {
/* Color is new - copy it to a new slot: */
ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
ColorTransIn2[i] = CrntSlot++;
}
}
if (CrntSlot > 256) {
FreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
}
NewBitSize = BitSize(CrntSlot);
RoundUpTo = (1 << NewBitSize);
if (RoundUpTo != ColorUnion->ColorCount) {
register GifColorType *Map = ColorUnion->Colors;
/*
* Zero out slots up to next power of 2.
* We know these slots exist because of the way ColorUnion's
* start dimension was computed.
*/
for (j = CrntSlot; j < RoundUpTo; j++)
Map[j].Red = Map[j].Green = Map[j].Blue = 0;
/* perhaps we can shrink the map? */
if (RoundUpTo < ColorUnion->ColorCount)
ColorUnion->Colors = (GifColorType *)realloc(Map,
sizeof(GifColorType) * RoundUpTo);
}
ColorUnion->ColorCount = RoundUpTo;
ColorUnion->BitsPerPixel = NewBitSize;
return (ColorUnion);
}
/*
* Apply a given color translation to the raster bits of an image
*/
void
ApplyTranslation(SavedImage * Image,
GifPixelType Translation[]) {
register int i;
register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
for (i = 0; i < RasterSize; i++)
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
}
/******************************************************************************
* Extension record functions
*****************************************************************************/
void
MakeExtension(SavedImage * New,
int Function) {
New->Function = Function;
/*** FIXME:
* Someday we might have to deal with multiple extensions.
* ??? Was this a note from Gershon or from me? Does the multiple
* extension blocks solve this or do we need multiple Functions? Or is
* this an obsolete function? (People should use AddExtensionBlock
* instead?)
* Looks like AddExtensionBlock needs to take the int Function argument
* then it can take the place of this function. Right now people have to
* use both. Fix AddExtensionBlock and add this to the deprecation list.
*/
}
int
AddExtensionBlock(SavedImage * New,
int Len,
unsigned char ExtData[]) {
ExtensionBlock *ep;
if (New->ExtensionBlocks == NULL)
New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
else
New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks,
sizeof(ExtensionBlock) *
(New->ExtensionBlockCount + 1));
if (New->ExtensionBlocks == NULL)
return (GIF_ERROR);
ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
ep->ByteCount=Len;
ep->Bytes = (char *)malloc(ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
if (ExtData) {
memcpy(ep->Bytes, ExtData, Len);
ep->Function = New->Function;
}
return (GIF_OK);
}
void
FreeExtension(SavedImage * Image)
{
ExtensionBlock *ep;
if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
return;
}
for (ep = Image->ExtensionBlocks;
ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
(void)free((char *)ep->Bytes);
free((char *)Image->ExtensionBlocks);
Image->ExtensionBlocks = NULL;
}
/******************************************************************************
* Image block allocation functions
******************************************************************************/
/* Private Function:
* Frees the last image in the GifFile->SavedImages array
*/
void
FreeLastSavedImage(GifFileType *GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
return;
/* Remove one SavedImage from the GifFile */
GifFile->ImageCount--;
sp = &GifFile->SavedImages[GifFile->ImageCount];
/* Deallocate its Colormap */
if (sp->ImageDesc.ColorMap) {
FreeMapObject(sp->ImageDesc.ColorMap);
sp->ImageDesc.ColorMap = NULL;
}
/* Deallocate the image data */
if (sp->RasterBits)
free((char *)sp->RasterBits);
/* Deallocate any extensions */
if (sp->ExtensionBlocks)
FreeExtension(sp);
/*** FIXME: We could realloc the GifFile->SavedImages structure but is
* there a point to it? Saves some memory but we'd have to do it every
* time. If this is used in FreeSavedImages then it would be inefficient
* (The whole array is going to be deallocated.) If we just use it when
* we want to free the last Image it's convenient to do it here.
*/
}
/*
* Append an image block to the SavedImages array
*/
SavedImage *
MakeSavedImage(GifFileType * GifFile,
const SavedImage * CopyFrom) {
SavedImage *sp;
if (GifFile->SavedImages == NULL)
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
else
GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
sizeof(SavedImage) * (GifFile->ImageCount + 1));
if (GifFile->SavedImages == NULL)
return ((SavedImage *)NULL);
else {
sp = &GifFile->SavedImages[GifFile->ImageCount++];
memset((char *)sp, '\0', sizeof(SavedImage));
if (CopyFrom) {
memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
/*
* Make our own allocated copies of the heap fields in the
* copied record. This guards against potential aliasing
* problems.
*/
/* first, the local color map */
if (sp->ImageDesc.ColorMap) {
sp->ImageDesc.ColorMap = MakeMapObject(
CopyFrom->ImageDesc.ColorMap->ColorCount,
CopyFrom->ImageDesc.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
}
/* next, the raster */
sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->RasterBits, CopyFrom->RasterBits,
sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
/* finally, the extension blocks */
if (sp->ExtensionBlocks) {
sp->ExtensionBlocks = (ExtensionBlock *)malloc(
sizeof(ExtensionBlock) *
CopyFrom->ExtensionBlockCount);
if (sp->ExtensionBlocks == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
/*
* For the moment, the actual blocks can take their
* chances with free(). We'll fix this later.
*** FIXME: [Better check this out... Toshio]
* 2004 May 27: Looks like this was an ESR note.
* It means the blocks are shallow copied from InFile to
* OutFile. However, I don't see that in this code....
* Did ESR fix it but never remove this note (And other notes
* in gifspnge?)
*/
}
}
return (sp);
}
}
void
FreeSavedImages(GifFileType * GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
return;
}
for (sp = GifFile->SavedImages;
sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
if (sp->ImageDesc.ColorMap) {
FreeMapObject(sp->ImageDesc.ColorMap);
sp->ImageDesc.ColorMap = NULL;
}
if (sp->RasterBits)
free((char *)sp->RasterBits);
if (sp->ExtensionBlocks)
FreeExtension(sp);
}
free((char *)GifFile->SavedImages);
GifFile->SavedImages=NULL;
}