8328999: Update GIFlib to 5.2.2

Reviewed-by: tr, dnguyen, prr
This commit is contained in:
Alisen Chung 2024-05-02 15:36:10 +00:00
parent 7a41a525de
commit 6969a9e0b2
8 changed files with 730 additions and 656 deletions

@ -1,4 +1,4 @@
## GIFLIB v5.2.1
## GIFLIB v5.2.2
### GIFLIB License
```
@ -24,7 +24,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
https://sourceforge.net/p/giflib/code/ci/master/tree/openbsd-reallocarray.c
tree/README
Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
== Authors ==
Gershon Elber <gershon[AT]cs.technion.sc.il>
original giflib code
Toshio Kuratomi <toshio[AT]tiki-lounge.com>
uncompressed gif writing code
former maintainer
Eric Raymond <esr[AT]snark.thyrsus.com>
current as well as long time former maintainer of giflib code
There have been many other contributors; see the attributions in the
version-control history to learn more.
tree/openbsd-reallocarray.c
Copyright (C) 2008 Otto Moerbeek <otto@drijf.net>
SPDX-License-Identifier: MIT
```

File diff suppressed because it is too large Load Diff

@ -38,82 +38,80 @@ SPDX-License-Identifier: MIT
/*****************************************************************************
Return a string description of the last GIF error
*****************************************************************************/
const char *
GifErrorString(int ErrorCode)
{
const char *GifErrorString(int ErrorCode) {
const char *Err;
switch (ErrorCode) {
case E_GIF_ERR_OPEN_FAILED:
case E_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case E_GIF_ERR_WRITE_FAILED:
case E_GIF_ERR_WRITE_FAILED:
Err = "Failed to write to given file";
break;
case E_GIF_ERR_HAS_SCRN_DSCR:
case E_GIF_ERR_HAS_SCRN_DSCR:
Err = "Screen descriptor has already been set";
break;
case E_GIF_ERR_HAS_IMAG_DSCR:
case E_GIF_ERR_HAS_IMAG_DSCR:
Err = "Image descriptor is still active";
break;
case E_GIF_ERR_NO_COLOR_MAP:
case E_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
case E_GIF_ERR_DATA_TOO_BIG:
case E_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
case E_GIF_ERR_NOT_ENOUGH_MEM:
case E_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
case E_GIF_ERR_DISK_IS_FULL:
case E_GIF_ERR_DISK_IS_FULL:
Err = "Write failed (disk full?)";
break;
case E_GIF_ERR_CLOSE_FAILED:
case E_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case E_GIF_ERR_NOT_WRITEABLE:
case E_GIF_ERR_NOT_WRITEABLE:
Err = "Given file was not opened for write";
break;
case D_GIF_ERR_OPEN_FAILED:
case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case D_GIF_ERR_READ_FAILED:
case D_GIF_ERR_READ_FAILED:
Err = "Failed to read from given file";
break;
case D_GIF_ERR_NOT_GIF_FILE:
case D_GIF_ERR_NOT_GIF_FILE:
Err = "Data is not in GIF format";
break;
case D_GIF_ERR_NO_SCRN_DSCR:
case D_GIF_ERR_NO_SCRN_DSCR:
Err = "No screen descriptor detected";
break;
case D_GIF_ERR_NO_IMAG_DSCR:
case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
case D_GIF_ERR_NO_COLOR_MAP:
case D_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
case D_GIF_ERR_WRONG_RECORD:
case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
case D_GIF_ERR_DATA_TOO_BIG:
case D_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
case D_GIF_ERR_NOT_ENOUGH_MEM:
case D_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
case D_GIF_ERR_CLOSE_FAILED:
case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case D_GIF_ERR_NOT_READABLE:
case D_GIF_ERR_NOT_READABLE:
Err = "Given file was not opened for read";
break;
case D_GIF_ERR_IMAGE_DEFECT:
case D_GIF_ERR_IMAGE_DEFECT:
Err = "Image is defective, decoding aborted";
break;
case D_GIF_ERR_EOF_TOO_SOON:
case D_GIF_ERR_EOF_TOO_SOON:
Err = "Image EOF detected before image complete";
break;
default:
default:
Err = NULL;
break;
}

@ -33,27 +33,25 @@ SPDX-License-Identifier: MIT
#ifndef _GIF_HASH_H_
#define _GIF_HASH_H_
/** Begin JDK modifications to support building on Windows **/
#ifndef _WIN32
#include <unistd.h>
#endif
/** End JDK modifications to support building on Windows **/
#endif /* _WIN32 */
#include <stdint.h>
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
/* The 32 bits of the long are divided into two parts for the key & code: */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
/* The key is the upper 20 bits. The code is the lower 12. */
#define HT_GET_KEY(l) (l >> 12)
#define HT_GET_CODE(l) (l & 0x0FFF)
#define HT_PUT_KEY(l) (l << 12)
#define HT_PUT_CODE(l) (l & 0x0FFF)
#define HT_GET_KEY(l) (l >> 12)
#define HT_GET_CODE(l) (l & 0x0FFF)
#define HT_PUT_KEY(l) (l << 12)
#define HT_PUT_CODE(l) (l & 0x0FFF)
typedef struct GifHashTableType {
uint32_t HTable[HT_SIZE];

@ -39,27 +39,19 @@ extern "C" {
#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 2
#define GIFLIB_RELEASE 1
#define GIFLIB_RELEASE 2
#define GIF_ERROR 0
#define GIF_OK 1
#define GIF_ERROR 0
#define GIF_OK 1
#include <stdbool.h>
#include <stddef.h>
/** Begin JDK modifications to support building using old compilers**/
//#include <stdbool.h>
#ifdef bool
#undef bool
#endif
typedef int bool;
#define false 0
#define true 1
/** End JDK modifications to support building using old compilers**/
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#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_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. */
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
@ -75,24 +67,24 @@ typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
bool SortFlag;
GifColorType *Colors; /* on malloc(3) heap */
GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height; /* Current image dimensions. */
bool Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
GifWord Left, Top, Width, Height; /* Current image dimensions. */
bool Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct ExtensionBlock {
int ByteCount;
GifByteType *Bytes; /* on malloc(3) heap */
int Function; /* The block function code */
#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
GifByteType *Bytes; /* on malloc(3) heap */
int Function; /* The block function code */
#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
} ExtensionBlock;
typedef struct SavedImage {
@ -103,22 +95,22 @@ typedef struct SavedImage {
} SavedImage;
typedef struct GifFileType {
GifWord SWidth, SHeight; /* Size of virtual canvas */
GifWord SColorResolution; /* How many colors can we generate? */
GifWord SBackGroundColor; /* Background color for virtual canvas */
GifByteType AspectByte; /* Used to compute pixel aspect ratio */
ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
int ImageCount; /* Number of current image (both APIs) */
GifImageDesc Image; /* Current image (low-level API) */
SavedImage *SavedImages; /* Image sequence (high-level API) */
int ExtensionBlockCount; /* Count extensions past last image */
GifWord SWidth, SHeight; /* Size of virtual canvas */
GifWord SColorResolution; /* How many colors can we generate? */
GifWord SBackGroundColor; /* Background color for virtual canvas */
GifByteType AspectByte; /* Used to compute pixel aspect ratio */
ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
int ImageCount; /* Number of current image (both APIs) */
GifImageDesc Image; /* Current image (low-level API) */
SavedImage *SavedImages; /* Image sequence (high-level API) */
int ExtensionBlockCount; /* Count extensions past last image */
ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
int Error; /* Last error condition reported */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
#define GIF_ASPECT_RATIO(n) ((n) + 15.0 / 64.0)
typedef enum {
UNDEFINED_RECORD_TYPE,
@ -129,12 +121,12 @@ typedef enum {
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
typedef int (*InputFunc)(GifFileType *, GifByteType *, int);
/* func type to write gif data to arbitrary targets.
* Returns count of bytes written. (MRB)
*/
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
typedef int (*OutputFunc)(GifFileType *, const GifByteType *, int);
/******************************************************************************
GIF89 structures
@ -142,14 +134,14 @@ typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
typedef struct GraphicsControlBlock {
int DisposalMode;
#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
#define DISPOSE_DO_NOT 1 /* Leave image in place */
#define DISPOSE_BACKGROUND 2 /* Set area too background color */
#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
bool UserInputFlag; /* User confirmation required before disposal */
int DelayTime; /* pre-display delay in 0.01sec units */
int TransparentColor; /* Palette index for transparency, -1 if none */
#define NO_TRANSPARENT_COLOR -1
#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
#define DISPOSE_DO_NOT 1 /* Leave image in place */
#define DISPOSE_BACKGROUND 2 /* Set area too background color */
#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
bool UserInputFlag; /* User confirmation required before disposal */
int DelayTime; /* pre-display delay in 0.01sec units */
int TransparentColor; /* Palette index for transparency, -1 if none */
#define NO_TRANSPARENT_COLOR -1
} GraphicsControlBlock;
/******************************************************************************
@ -161,49 +153,44 @@ GifFileType *EGifOpenFileName(const char *GifFileName,
const bool GifTestExistence, int *Error);
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
int EGifSpew(GifFileType * GifFile);
int EGifSpew(GifFileType *GifFile);
const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
#define E_GIF_SUCCEEDED 0
#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_SUCCEEDED 0
#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
#define E_GIF_ERR_DISK_IS_FULL 8
#define E_GIF_ERR_CLOSE_FAILED 9
#define E_GIF_ERR_NOT_WRITEABLE 10
/* These are legacy. You probably do not want to call them directly */
int EGifPutScreenDesc(GifFileType *GifFile,
const int GifWidth, const int GifHeight,
const int GifColorRes,
int EGifPutScreenDesc(GifFileType *GifFile, const int GifWidth,
const int GifHeight, const int GifColorRes,
const int GifBackGround,
const ColorMapObject *GifColorMap);
int EGifPutImageDesc(GifFileType *GifFile,
const int GifLeft, const int GifTop,
int EGifPutImageDesc(GifFileType *GifFile, const int GifLeft, const int GifTop,
const int GifWidth, const int GifHeight,
const bool GifInterlace,
const ColorMapObject *GifColorMap);
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
int GifLineLen);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, const char *GifComment);
int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
int EGifPutExtensionBlock(GifFileType *GifFile,
const int GifExtLen, const void *GifExtension);
int EGifPutExtensionBlock(GifFileType *GifFile, const int GifExtLen,
const void *GifExtension);
int EGifPutExtensionTrailer(GifFileType *GifFile);
int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
const int GifExtLen,
const void *GifExtension);
const int GifExtLen, const void *GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
const GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile,
const GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile, const GifByteType *GifCodeBlock);
/******************************************************************************
GIF decoding routines
@ -212,24 +199,25 @@ int EGifPutCodeNext(GifFileType *GifFile,
/* Main entry points */
GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
int DGifSlurp(GifFileType *GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc,
int *Error); /* new one (TVT) */
int DGifCloseFile(GifFileType *GifFile, int *ErrorCode);
#define D_GIF_SUCCEEDED 0
#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_SUCCEEDED 0
#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
#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
/* These are legacy. You probably do not want to call them directly */
int DGifGetScreenDesc(GifFileType *GifFile);
@ -247,11 +235,10 @@ int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
const char *DGifGetGifVersion(GifFileType *GifFile);
/******************************************************************************
Error handling and reporting.
******************************************************************************/
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
/*****************************************************************************
Everything below this point is new after version 1.2, supporting `slurp
@ -263,26 +250,26 @@ extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
******************************************************************************/
extern ColorMapObject *GifMakeMapObject(int ColorCount,
const GifColorType *ColorMap);
const GifColorType *ColorMap);
extern void GifFreeMapObject(ColorMapObject *Object);
extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[]);
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);
/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
extern void GifApplyTranslation(SavedImage *Image,
const GifPixelType Translation[]);
extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks,
int Function,
ExtensionBlock **ExtensionBlocks, int Function,
unsigned int Len, unsigned char ExtData[]);
extern void GifFreeExtensions(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks);
extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
const SavedImage *CopyFrom);
const SavedImage *CopyFrom);
extern void GifFreeSavedImages(GifFileType *GifFile);
/******************************************************************************
@ -295,37 +282,31 @@ int DGifExtensionToGCB(const size_t GifExtensionLength,
size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
GifByteType *GifExtension);
int DGifSavedExtensionToGCB(GifFileType *GifFile,
int ImageIndex,
int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex,
GraphicsControlBlock *GCB);
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
GifFileType *GifFile,
int ImageIndex);
GifFileType *GifFile, int ImageIndex);
/******************************************************************************
The library's internal utility font
******************************************************************************/
#define GIF_FONT_WIDTH 8
#define GIF_FONT_WIDTH 8
#define GIF_FONT_HEIGHT 8
extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
extern void GifDrawText8x8(SavedImage *Image,
const int x, const int y,
const char *legend, const int color);
extern void GifDrawText8x8(SavedImage *Image, const int x, const int y,
const char *legend, const int color);
extern void GifDrawBox(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawBox(SavedImage *Image, const int x, const int y, const int w,
const int d, const int color);
extern void GifDrawRectangle(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawRectangle(SavedImage *Image, const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawBoxedText8x8(SavedImage *Image,
const int x, const int y,
const char *legend,
const int border, const int bg, const int fg);
extern void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y,
const char *legend, const int border,
const int bg, const int fg);
#ifdef __cplusplus
}

@ -33,52 +33,54 @@ SPDX-License-Identifier: MIT
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
#include "gif_lib.h"
#include "gif_hash.h"
#include "gif_lib.h"
#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#define SIZE_MAX UINTPTR_MAX
#endif
#define EXTENSION_INTRODUCER 0x21
#define DESCRIPTOR_INTRODUCER 0x2c
#define TERMINATOR_INTRODUCER 0x3b
#define EXTENSION_INTRODUCER 0x21
#define DESCRIPTOR_INTRODUCER 0x2c
#define TERMINATOR_INTRODUCER 0x3b
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#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 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 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)
#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. */
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. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
GifHashTableType *HashTable;
bool gif89;

@ -30,59 +30,59 @@ SPDX-License-Identifier: MIT
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_lib_private.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/******************************************************************************
Miscellaneous utility functions
******************************************************************************/
/* return smallest bitfield size n will fit in */
int
GifBitSize(int n)
{
int GifBitSize(int n) {
register int i;
for (i = 1; i <= 8; i++)
if ((1 << i) >= n)
for (i = 1; i <= 8; i++) {
if ((1 << i) >= n) {
break;
}
}
return (i);
}
/******************************************************************************
Color map object functions
Color map object functions
******************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
ColorMapObject *
GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
{
ColorMapObject *GifMakeMapObject(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? */
* make the user know that or should we automatically round up instead?
*/
if (ColorCount != (1 << GifBitSize(ColorCount))) {
return ((ColorMapObject *) NULL);
return ((ColorMapObject *)NULL);
}
Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
if (Object == (ColorMapObject *) NULL) {
return ((ColorMapObject *) NULL);
if (Object == (ColorMapObject *)NULL) {
return ((ColorMapObject *)NULL);
}
Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *) NULL) {
Object->Colors =
(GifColorType *)calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *)NULL) {
free(Object);
return ((ColorMapObject *) NULL);
return ((ColorMapObject *)NULL);
}
Object->ColorCount = ColorCount;
@ -90,19 +90,17 @@ GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
Object->SortFlag = false;
if (ColorMap != NULL) {
memcpy((char *)Object->Colors,
(char *)ColorMap, ColorCount * sizeof(GifColorType));
memcpy((char *)Object->Colors, (char *)ColorMap,
ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*******************************************************************************
Free a color map object
Free a color map object
*******************************************************************************/
void
GifFreeMapObject(ColorMapObject *Object)
{
void GifFreeMapObject(ColorMapObject *Object) {
if (Object != NULL) {
(void)free(Object->Colors);
(void)free(Object);
@ -110,17 +108,14 @@ GifFreeMapObject(ColorMapObject *Object)
}
#ifdef DEBUG
void
DumpColorMap(ColorMapObject *Object,
FILE * fp)
{
void DumpColorMap(ColorMapObject *Object, FILE *fp) {
if (Object != NULL) {
int i, j, Len = Object->ColorCount;
for (i = 0; i < Len; i += 4) {
for (j = 0; j < 4 && j < Len; j++) {
(void)fprintf(fp, "%3d: %02x %02x %02x ", i + j,
Object->Colors[i + j].Red,
(void)fprintf(fp, "%3d: %02x %02x %02x ",
i + j, Object->Colors[i + j].Red,
Object->Colors[i + j].Green,
Object->Colors[i + j].Blue);
}
@ -137,11 +132,9 @@ DumpColorMap(ColorMapObject *Object,
copied iff they didn't exist before. ColorTransIn2 maps the old
ColorIn2 into the ColorUnion color map table./
*******************************************************************************/
ColorMapObject *
GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[])
{
ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[]) {
int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
ColorMapObject *ColorUnion;
@ -152,17 +145,19 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
*/
/* Allocate table which will hold the result for sure. */
ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
ColorIn2->ColorCount) * 2, NULL);
ColorUnion = GifMakeMapObject(
MAX(ColorIn1->ColorCount, ColorIn2->ColorCount) * 2, NULL);
if (ColorUnion == NULL)
if (ColorUnion == NULL) {
return (NULL);
}
/*
* Copy ColorIn1 to ColorUnion.
*/
for (i = 0; i < ColorIn1->ColorCount; i++)
for (i = 0; i < ColorIn1->ColorCount; i++) {
ColorUnion->Colors[i] = ColorIn1->Colors[i];
}
CrntSlot = ColorIn1->ColorCount;
/*
@ -172,22 +167,25 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
* 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)
while (ColorIn1->Colors[CrntSlot - 1].Red == 0 &&
ColorIn1->Colors[CrntSlot - 1].Green == 0 &&
ColorIn1->Colors[CrntSlot - 1].Blue == 0) {
CrntSlot--;
}
/* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
/* Let's see if this color already exists: */
for (j = 0; j < ColorIn1->ColorCount; j++)
if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
sizeof(GifColorType)) == 0)
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 {
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++;
@ -196,7 +194,7 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
if (CrntSlot > 256) {
GifFreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
return ((ColorMapObject *)NULL);
}
NewGifBitSize = GifBitSize(CrntSlot);
@ -210,16 +208,17 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
* We know these slots exist because of the way ColorUnion's
* start dimension was computed.
*/
for (j = CrntSlot; j < RoundUpTo; j++)
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) {
GifColorType *new_map = (GifColorType *)reallocarray(Map,
RoundUpTo, sizeof(GifColorType));
if( new_map == NULL ) {
GifColorType *new_map = (GifColorType *)reallocarray(
Map, RoundUpTo, sizeof(GifColorType));
if (new_map == NULL) {
GifFreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
return ((ColorMapObject *)NULL);
}
ColorUnion->Colors = new_map;
}
@ -234,49 +233,49 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
/*******************************************************************************
Apply a given color translation to the raster bits of an image
*******************************************************************************/
void
GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
{
void GifApplyTranslation(SavedImage *Image, const GifPixelType Translation[]) {
register int i;
register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
register int RasterSize =
Image->ImageDesc.Height * Image->ImageDesc.Width;
for (i = 0; i < RasterSize; i++)
for (i = 0; i < RasterSize; i++) {
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
}
}
/******************************************************************************
Extension record functions
******************************************************************************/
int
GifAddExtensionBlock(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks,
int Function,
unsigned int Len,
unsigned char ExtData[])
{
int GifAddExtensionBlock(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks, int Function,
unsigned int Len, unsigned char ExtData[]) {
ExtensionBlock *ep;
if (*ExtensionBlocks == NULL)
*ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
else {
ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
(*ExtensionBlocks, (*ExtensionBlockCount + 1),
sizeof(ExtensionBlock));
if( ep_new == NULL )
if (*ExtensionBlocks == NULL) {
*ExtensionBlocks =
(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
} else {
ExtensionBlock *ep_new = (ExtensionBlock *)reallocarray(
*ExtensionBlocks, (*ExtensionBlockCount + 1),
sizeof(ExtensionBlock));
if (ep_new == NULL) {
return (GIF_ERROR);
}
*ExtensionBlocks = ep_new;
}
if (*ExtensionBlocks == NULL)
if (*ExtensionBlocks == NULL) {
return (GIF_ERROR);
}
ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
ep->Function = Function;
ep->ByteCount=Len;
ep->ByteCount = Len;
ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
if (ep->Bytes == NULL)
if (ep->Bytes == NULL) {
return (GIF_ERROR);
}
if (ExtData != NULL) {
memcpy(ep->Bytes, ExtData, Len);
@ -285,38 +284,36 @@ GifAddExtensionBlock(int *ExtensionBlockCount,
return (GIF_OK);
}
void
GifFreeExtensions(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks)
{
void GifFreeExtensions(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks) {
ExtensionBlock *ep;
if (*ExtensionBlocks == NULL)
if (*ExtensionBlocks == NULL) {
return;
}
for (ep = *ExtensionBlocks;
ep < (*ExtensionBlocks + *ExtensionBlockCount);
ep++)
ep < (*ExtensionBlocks + *ExtensionBlockCount); ep++) {
(void)free((char *)ep->Bytes);
}
(void)free((char *)*ExtensionBlocks);
*ExtensionBlocks = NULL;
*ExtensionBlockCount = 0;
}
/******************************************************************************
Image block allocation functions
Image block allocation functions
******************************************************************************/
/* Private Function:
* Frees the last image in the GifFile->SavedImages array
*/
void
FreeLastSavedImage(GifFileType *GifFile)
{
void FreeLastSavedImage(GifFileType *GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
return;
}
/* Remove one SavedImage from the GifFile */
GifFile->ImageCount--;
@ -329,54 +326,58 @@ FreeLastSavedImage(GifFileType *GifFile)
}
/* Deallocate the image data */
if (sp->RasterBits != NULL)
if (sp->RasterBits != NULL) {
free((char *)sp->RasterBits);
}
/* Deallocate any extensions */
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
/*** 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 GifFreeSavedImages 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.
* time. If this is used in GifFreeSavedImages 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 *
GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
{
if (GifFile->SavedImages == NULL)
SavedImage *GifMakeSavedImage(GifFileType *GifFile,
const SavedImage *CopyFrom) {
// cppcheck-suppress ctunullpointer
if (GifFile->SavedImages == NULL) {
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
else {
SavedImage* newSavedImages = (SavedImage *)reallocarray(GifFile->SavedImages,
(GifFile->ImageCount + 1), sizeof(SavedImage));
if( newSavedImages == NULL)
} else {
SavedImage *newSavedImages = (SavedImage *)reallocarray(
GifFile->SavedImages, (GifFile->ImageCount + 1),
sizeof(SavedImage));
if (newSavedImages == NULL) {
return ((SavedImage *)NULL);
}
GifFile->SavedImages = newSavedImages;
}
if (GifFile->SavedImages == NULL)
if (GifFile->SavedImages == NULL) {
return ((SavedImage *)NULL);
else {
} else {
SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
if (CopyFrom != NULL) {
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.
* 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 (CopyFrom->ImageDesc.ColorMap != NULL) {
sp->ImageDesc.ColorMap = GifMakeMapObject(
CopyFrom->ImageDesc.ColorMap->ColorCount,
CopyFrom->ImageDesc.ColorMap->Colors);
CopyFrom->ImageDesc.ColorMap->ColorCount,
CopyFrom->ImageDesc.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
@ -384,32 +385,36 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
}
/* next, the raster */
sp->RasterBits = (unsigned char *)reallocarray(NULL,
(CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width),
sizeof(GifPixelType));
sp->RasterBits = (unsigned char *)reallocarray(
NULL,
(CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width),
sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->RasterBits, CopyFrom->RasterBits,
sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
sizeof(GifPixelType) *
CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
/* finally, the extension blocks */
if (CopyFrom->ExtensionBlocks != NULL) {
sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL,
CopyFrom->ExtensionBlockCount,
sizeof(ExtensionBlock));
sp->ExtensionBlocks =
(ExtensionBlock *)reallocarray(
NULL, CopyFrom->ExtensionBlockCount,
sizeof(ExtensionBlock));
if (sp->ExtensionBlocks == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
memcpy(sp->ExtensionBlocks,
CopyFrom->ExtensionBlocks,
sizeof(ExtensionBlock) *
CopyFrom->ExtensionBlockCount);
}
}
else {
} else {
memset((char *)sp, '\0', sizeof(SavedImage));
}
@ -417,9 +422,7 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
}
}
void
GifFreeSavedImages(GifFileType *GifFile)
{
void GifFreeSavedImages(GifFileType *GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
@ -432,10 +435,12 @@ GifFreeSavedImages(GifFileType *GifFile)
sp->ImageDesc.ColorMap = NULL;
}
if (sp->RasterBits != NULL)
if (sp->RasterBits != NULL) {
free((char *)sp->RasterBits);
}
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
GifFreeExtensions(&sp->ExtensionBlockCount,
&sp->ExtensionBlocks);
}
free((char *)GifFile->SavedImages);
GifFile->SavedImages = NULL;

@ -28,24 +28,22 @@
* SPDX-License-Identifier: MIT
*/
#include <sys/types.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#define SIZE_MAX UINTPTR_MAX
#endif
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
{
void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size) {
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
errno = ENOMEM;
@ -93,7 +91,8 @@ openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
* fuzzing on one platform may not detect zero-size allocation
* problems on other platforms.
*/
if (size == 0 || nmemb == 0)
if (size == 0 || nmemb == 0) {
return NULL;
}
return realloc(optr, size * nmemb);
}