mirror of https://github.com/vitalif/phantomjs
Remove GIF format for screen capture export (render).
This is to reduce maintenance burden. A GIF representation of a web page can be produced by converting its PNG capture. There are numerous third-party tools which can do the job better (optimized palette, minimized loss, etc). https://github.com/ariya/phantomjs/issues/124802.0
parent
51c8c9cc62
commit
8cabfed4b3
|
@ -1 +0,0 @@
|
|||
#define UINT32 uint32_t
|
1111
src/gif/egif_lib.c
1111
src/gif/egif_lib.c
File diff suppressed because it is too large
Load Diff
|
@ -1,22 +0,0 @@
|
|||
VPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
DEFINES += HAVE_CONFIG_H
|
||||
DEFINES += HAVE_FCNTL_H
|
||||
DEFINES += HAVE_STDARG_H
|
||||
!win32-msvc* {
|
||||
DEFINES += HAVE_STDINT_H
|
||||
DEFINES += HAVE_UNISTD_H
|
||||
}
|
||||
|
||||
SOURCES += gif_err.c
|
||||
SOURCES += gifalloc.c
|
||||
SOURCES += egif_lib.c
|
||||
SOURCES += gif_hash.c
|
||||
SOURCES += quantize.c
|
||||
SOURCES += gifwriter.cpp
|
||||
|
||||
HEADERS += gif_hash.h
|
||||
HEADERS += gif_lib_private.h
|
||||
HEADERS += gif_lib.h
|
||||
HEADERS += gifwriter.h
|
|
@ -1,120 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* "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 */
|
|
@ -1,160 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library. *
|
||||
* *
|
||||
* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 *
|
||||
******************************************************************************
|
||||
* Module to support the following operations: *
|
||||
* *
|
||||
* 1. InitHashTable - initialize hash table. *
|
||||
* 2. ClearHashTable - clear the hash table to an empty state. *
|
||||
* 2. InsertHashTable - insert one item into data structure. *
|
||||
* 3. ExistsHashTable - test if item exists in data structure. *
|
||||
* *
|
||||
* This module is used to hash the GIF codes during encoding. *
|
||||
******************************************************************************
|
||||
* History: *
|
||||
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Find a thirty-two bit int type */
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <io.h>
|
||||
#include <alloc.h>
|
||||
#include <sys\stat.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif /* HAVE_FCNTL_H */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gif_lib.h"
|
||||
#include "gif_hash.h"
|
||||
#include "gif_lib_private.h"
|
||||
|
||||
/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
static long NumberOfTests = 0,
|
||||
NumberOfMisses = 0;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
static int KeyItem(UINT32 Item);
|
||||
|
||||
/******************************************************************************
|
||||
* Initialize HashTable - allocate the memory needed and clear it. *
|
||||
******************************************************************************/
|
||||
GifHashTableType *_InitHashTable(void)
|
||||
{
|
||||
GifHashTableType *HashTable;
|
||||
|
||||
if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
|
||||
== NULL)
|
||||
return NULL;
|
||||
|
||||
_ClearHashTable(HashTable);
|
||||
|
||||
return HashTable;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to clear the HashTable to an empty state. *
|
||||
* This part is a little machine depended. Use the commented part otherwise. *
|
||||
******************************************************************************/
|
||||
void _ClearHashTable(GifHashTableType *HashTable)
|
||||
{
|
||||
memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(UINT32));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to insert a new Item into the HashTable. The data is assumed to be *
|
||||
* new one. *
|
||||
******************************************************************************/
|
||||
void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code)
|
||||
{
|
||||
int HKey = KeyItem(Key);
|
||||
UINT32 *HTable = HashTable -> HTable;
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfTests++;
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
HKey = (HKey + 1) & HT_KEY_MASK;
|
||||
}
|
||||
HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to test if given Key exists in HashTable and if so returns its code *
|
||||
* Returns the Code if key was found, -1 if not. *
|
||||
******************************************************************************/
|
||||
int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key)
|
||||
{
|
||||
int HKey = KeyItem(Key);
|
||||
UINT32 *HTable = HashTable -> HTable, HTKey;
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfTests++;
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
|
||||
HKey = (HKey + 1) & HT_KEY_MASK;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to generate an HKey for the hashtable out of the given unique key. *
|
||||
* The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
|
||||
* new postfix character, while the upper 12 bits are the prefix code. *
|
||||
* Because the average hit ratio is only 2 (2 hash references per entry), *
|
||||
* evaluating more complex keys (such as twin prime keys) does not worth it! *
|
||||
******************************************************************************/
|
||||
static int KeyItem(UINT32 Item)
|
||||
{
|
||||
return ((Item >> 12) ^ Item) & HT_KEY_MASK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
/******************************************************************************
|
||||
* Debugging routine to print the hit ratio - number of times the hash table *
|
||||
* was tested per operation. This routine was used to test the KeyItem routine *
|
||||
******************************************************************************/
|
||||
void HashTablePrintHitRatio(void)
|
||||
{
|
||||
printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
|
||||
NumberOfMisses, NumberOfTests,
|
||||
NumberOfMisses * 100 / NumberOfTests);
|
||||
}
|
||||
#endif /* DEBUG_HIT_RATE */
|
|
@ -1,61 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Declarations, global to other of the GIF-HASH.C module. *
|
||||
* *
|
||||
* Written by Gershon Elber, Jun 1989 *
|
||||
*******************************************************************************
|
||||
* History: *
|
||||
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _GIF_HASH_H_
|
||||
#define _GIF_HASH_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Find a thirty-two bit int type */
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else if defined(Q_CC_MSVC)
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BASETSD_H
|
||||
#include <basetsd.h>
|
||||
#endif
|
||||
|
||||
#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. */
|
||||
/* 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)
|
||||
|
||||
typedef struct GifHashTableType {
|
||||
UINT32 HTable[HT_SIZE];
|
||||
} GifHashTableType;
|
||||
|
||||
GifHashTableType *_InitHashTable(void);
|
||||
void _ClearHashTable(GifHashTableType *HashTable);
|
||||
void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code);
|
||||
int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key);
|
||||
|
||||
#endif /* _GIF_HASH_H_ */
|
|
@ -1,336 +0,0 @@
|
|||
/******************************************************************************
|
||||
* 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 */
|
|
@ -1,59 +0,0 @@
|
|||
#ifndef _GIF_LIB_PRIVATE_H
|
||||
#define _GIF_LIB_PRIVATE_H
|
||||
|
||||
#include "gif_lib.h"
|
||||
#include "gif_hash.h"
|
||||
|
||||
#define PROGRAM_NAME "GIFLIB"
|
||||
|
||||
#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];
|
||||
GifHashTableType *HashTable;
|
||||
} GifFilePrivateType;
|
||||
|
||||
extern int _GifError;
|
||||
|
||||
#endif /* _GIF_LIB_PRIVATE_H */
|
|
@ -1,443 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* "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;
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gifwriter.h"
|
||||
|
||||
#include "gif_lib.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QFile>
|
||||
|
||||
static int saveGifBlock(GifFileType *gif, const GifByteType *data, int i)
|
||||
{
|
||||
QFile *file = (QFile*)(gif->UserData);
|
||||
return file->write((const char*)data, i);
|
||||
}
|
||||
|
||||
bool exportGif(const QImage &img, const QString &fileName)
|
||||
{
|
||||
QFile file;
|
||||
file.setFileName(fileName);
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage image = img;
|
||||
|
||||
int dim = image.width() * image.height();
|
||||
GifByteType *rBuffer = new GifByteType[dim];
|
||||
GifByteType *gBuffer = new GifByteType[dim];
|
||||
GifByteType *bBuffer = new GifByteType[dim];
|
||||
for (int i = 0; i < image.width(); ++i) {
|
||||
for (int j = 0; j < image.height(); ++j) {
|
||||
QRgb color = image.pixel(i, j);
|
||||
rBuffer[i + j * image.width()] = qRed(color);
|
||||
gBuffer[i + j * image.width()] = qGreen(color);
|
||||
bBuffer[i + j * image.width()] = qBlue(color);
|
||||
}
|
||||
}
|
||||
|
||||
int ColorMapSize = 255;
|
||||
ColorMapObject cmap;
|
||||
cmap.ColorCount = ColorMapSize;
|
||||
cmap.BitsPerPixel = 8;
|
||||
cmap.Colors = new GifColorType[ColorMapSize];
|
||||
GifByteType *outputBuffer = new GifByteType[dim];
|
||||
QuantizeBuffer(image.width(), image.height(), &ColorMapSize,
|
||||
rBuffer, gBuffer, bBuffer, outputBuffer, cmap.Colors);
|
||||
|
||||
QVector<QRgb> colorTable;
|
||||
colorTable.reserve(256);
|
||||
for (int i = 0; i < ColorMapSize; ++i) {
|
||||
GifColorType color = cmap.Colors[i];
|
||||
colorTable += qRgb(color.Red, color.Green, color.Blue);
|
||||
}
|
||||
colorTable += qRgba(0, 0, 0, 0);
|
||||
while (colorTable.count() < 256)
|
||||
colorTable += qRgb(0, 0, 0);
|
||||
|
||||
delete [] outputBuffer;
|
||||
delete [] rBuffer;
|
||||
delete [] gBuffer;
|
||||
delete [] bBuffer;
|
||||
|
||||
image = image.convertToFormat(QImage::Format_Indexed8, colorTable);
|
||||
|
||||
colorTable = image.colorTable();
|
||||
cmap.ColorCount = 256;
|
||||
cmap.BitsPerPixel = 8;
|
||||
int bgcolor = -1;
|
||||
for (int c = 0; c < 256; ++c) {
|
||||
cmap.Colors[c].Red = qRed(colorTable[c]);
|
||||
cmap.Colors[c].Green = qGreen(colorTable[c]);
|
||||
cmap.Colors[c].Blue = qBlue(colorTable[c]);
|
||||
if (qAlpha(colorTable[c]) == 0)
|
||||
bgcolor = c;
|
||||
}
|
||||
EGifSetGifVersion("87a");
|
||||
|
||||
GifFileType *gif = EGifOpen(&file, saveGifBlock);
|
||||
gif->ImageCount = 1;
|
||||
EGifPutScreenDesc(gif, image.width(), image.height(), 256, 0, &cmap);
|
||||
if (bgcolor >= 0) {
|
||||
char extension[] = { 1, 0, 0, bgcolor };
|
||||
EGifPutExtension(gif, GRAPHICS_EXT_FUNC_CODE, 4, extension);
|
||||
}
|
||||
EGifPutImageDesc(gif, 0, 0, image.width(), image.height(), 0, &cmap);
|
||||
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
if (EGifPutLine(gif, (GifPixelType*)(image.scanLine(y)), img.width()) == GIF_ERROR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EGifCloseFile(gif);
|
||||
file.close();
|
||||
|
||||
delete [] cmap.Colors;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GIFWRITER_H
|
||||
#define GIFWRITER_H
|
||||
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
|
||||
bool exportGif(const QImage &image, const QString &fileName);
|
||||
|
||||
#endif
|
|
@ -1,330 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* "Gif-Lib" - Yet another gif library.
|
||||
*
|
||||
* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989
|
||||
******************************************************************************
|
||||
* Module to quatize high resolution image into lower one. You may want to
|
||||
* peek into the following article this code is based on:
|
||||
* "Color Image Quantization for frame buffer Display", by Paul Heckbert
|
||||
* SIGGRAPH 1982 page 297-307.
|
||||
******************************************************************************
|
||||
* History:
|
||||
* 5 Jan 90 - Version 1.0 by Gershon Elber.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#include <dos.h>
|
||||
#include <alloc.h>
|
||||
#include <graphics.h>
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "gif_lib.h"
|
||||
#include "gif_lib_private.h"
|
||||
|
||||
#define ABS(x) ((x) > 0 ? (x) : (-(x)))
|
||||
|
||||
/* The colors are stripped to 5 bits per primary color if non MSDOS system
|
||||
* or to 4 (not enough memory...) if MSDOS as first step.
|
||||
*/
|
||||
#ifdef __MSDOS__
|
||||
#define COLOR_ARRAY_SIZE 4096
|
||||
#define BITS_PER_PRIM_COLOR 4
|
||||
#define MAX_PRIM_COLOR 0x0f
|
||||
#else
|
||||
#define COLOR_ARRAY_SIZE 2097152
|
||||
#define BITS_PER_PRIM_COLOR 7
|
||||
#define MAX_PRIM_COLOR 0x7f
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
static int SortRGBAxis;
|
||||
|
||||
typedef struct QuantizedColorType {
|
||||
GifByteType RGB[3];
|
||||
GifByteType NewColorIndex;
|
||||
long Count;
|
||||
struct QuantizedColorType *Pnext;
|
||||
} QuantizedColorType;
|
||||
|
||||
typedef struct NewColorMapType {
|
||||
GifByteType RGBMin[3], RGBWidth[3];
|
||||
unsigned int NumEntries; /* # of QuantizedColorType in linked list below */
|
||||
unsigned long Count; /* Total number of pixels in all the entries */
|
||||
QuantizedColorType *QuantizedColors;
|
||||
} NewColorMapType;
|
||||
|
||||
static int SubdivColorMap(NewColorMapType * NewColorSubdiv,
|
||||
unsigned int ColorMapSize,
|
||||
unsigned int *NewColorMapSize);
|
||||
static int SortCmpRtn(const VoidPtr Entry1, const VoidPtr Entry2);
|
||||
|
||||
/******************************************************************************
|
||||
* Quantize high resolution image into lower one. Input image consists of a
|
||||
* 2D array for each of the RGB colors with size Width by Height. There is no
|
||||
* Color map for the input. Output is a quantized image with 2D array of
|
||||
* indexes into the output color map.
|
||||
* Note input image can be 24 bits at the most (8 for red/green/blue) and
|
||||
* the output has 256 colors at the most (256 entries in the color map.).
|
||||
* ColorMapSize specifies size of color map up to 256 and will be updated to
|
||||
* real size before returning.
|
||||
* Also non of the parameter are allocated by this routine.
|
||||
* This function returns GIF_OK if succesfull, GIF_ERROR otherwise.
|
||||
******************************************************************************/
|
||||
int
|
||||
QuantizeBuffer(unsigned int Width,
|
||||
unsigned int Height,
|
||||
int *ColorMapSize,
|
||||
GifByteType * RedInput,
|
||||
GifByteType * GreenInput,
|
||||
GifByteType * BlueInput,
|
||||
GifByteType * OutputBuffer,
|
||||
GifColorType * OutputColorMap) {
|
||||
|
||||
unsigned int Index, NumOfEntries;
|
||||
int i, j, MaxRGBError[3];
|
||||
unsigned int NewColorMapSize;
|
||||
long Red, Green, Blue;
|
||||
NewColorMapType NewColorSubdiv[256];
|
||||
QuantizedColorType *ColorArrayEntries, *QuantizedColor;
|
||||
|
||||
ColorArrayEntries = (QuantizedColorType *)malloc(
|
||||
sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE);
|
||||
if (ColorArrayEntries == NULL) {
|
||||
_GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
|
||||
return GIF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < COLOR_ARRAY_SIZE; i++) {
|
||||
ColorArrayEntries[i].RGB[0] = i >> (2 * BITS_PER_PRIM_COLOR);
|
||||
ColorArrayEntries[i].RGB[1] = (i >> BITS_PER_PRIM_COLOR) &
|
||||
MAX_PRIM_COLOR;
|
||||
ColorArrayEntries[i].RGB[2] = i & MAX_PRIM_COLOR;
|
||||
ColorArrayEntries[i].Count = 0;
|
||||
}
|
||||
|
||||
/* Sample the colors and their distribution: */
|
||||
for (i = 0; i < (int)(Width * Height); i++) {
|
||||
Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
(2 * BITS_PER_PRIM_COLOR)) +
|
||||
((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
BITS_PER_PRIM_COLOR) +
|
||||
(BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
|
||||
ColorArrayEntries[Index].Count++;
|
||||
}
|
||||
|
||||
/* Put all the colors in the first entry of the color map, and call the
|
||||
* recursive subdivision process. */
|
||||
for (i = 0; i < 256; i++) {
|
||||
NewColorSubdiv[i].QuantizedColors = NULL;
|
||||
NewColorSubdiv[i].Count = NewColorSubdiv[i].NumEntries = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
NewColorSubdiv[i].RGBMin[j] = 0;
|
||||
NewColorSubdiv[i].RGBWidth[j] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the non empty entries in the color table and chain them: */
|
||||
for (i = 0; i < COLOR_ARRAY_SIZE; i++)
|
||||
if (ColorArrayEntries[i].Count > 0)
|
||||
break;
|
||||
QuantizedColor = NewColorSubdiv[0].QuantizedColors = &ColorArrayEntries[i];
|
||||
NumOfEntries = 1;
|
||||
while (++i < COLOR_ARRAY_SIZE)
|
||||
if (ColorArrayEntries[i].Count > 0) {
|
||||
QuantizedColor->Pnext = &ColorArrayEntries[i];
|
||||
QuantizedColor = &ColorArrayEntries[i];
|
||||
NumOfEntries++;
|
||||
}
|
||||
QuantizedColor->Pnext = NULL;
|
||||
|
||||
NewColorSubdiv[0].NumEntries = NumOfEntries; /* Different sampled colors */
|
||||
NewColorSubdiv[0].Count = ((long)Width) * Height; /* Pixels */
|
||||
NewColorMapSize = 1;
|
||||
if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) !=
|
||||
GIF_OK) {
|
||||
free((char *)ColorArrayEntries);
|
||||
return GIF_ERROR;
|
||||
}
|
||||
if (NewColorMapSize < *ColorMapSize) {
|
||||
/* And clear rest of color map: */
|
||||
for (i = NewColorMapSize; i < *ColorMapSize; i++)
|
||||
OutputColorMap[i].Red = OutputColorMap[i].Green =
|
||||
OutputColorMap[i].Blue = 0;
|
||||
}
|
||||
|
||||
/* Average the colors in each entry to be the color to be used in the
|
||||
* output color map, and plug it into the output color map itself. */
|
||||
for (i = 0; i < NewColorMapSize; i++) {
|
||||
if ((j = NewColorSubdiv[i].NumEntries) > 0) {
|
||||
QuantizedColor = NewColorSubdiv[i].QuantizedColors;
|
||||
Red = Green = Blue = 0;
|
||||
while (QuantizedColor) {
|
||||
QuantizedColor->NewColorIndex = i;
|
||||
Red += QuantizedColor->RGB[0];
|
||||
Green += QuantizedColor->RGB[1];
|
||||
Blue += QuantizedColor->RGB[2];
|
||||
QuantizedColor = QuantizedColor->Pnext;
|
||||
}
|
||||
OutputColorMap[i].Red = (Red << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
OutputColorMap[i].Green = (Green << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
OutputColorMap[i].Blue = (Blue << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
} else
|
||||
fprintf(stderr,
|
||||
"\n%s: Null entry in quantized color map - that's weird.\n",
|
||||
PROGRAM_NAME);
|
||||
}
|
||||
|
||||
/* Finally scan the input buffer again and put the mapped index in the
|
||||
* output buffer. */
|
||||
MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0;
|
||||
for (i = 0; i < (int)(Width * Height); i++) {
|
||||
Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
(2 * BITS_PER_PRIM_COLOR)) +
|
||||
((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
BITS_PER_PRIM_COLOR) +
|
||||
(BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
|
||||
Index = ColorArrayEntries[Index].NewColorIndex;
|
||||
OutputBuffer[i] = Index;
|
||||
if (MaxRGBError[0] < ABS(OutputColorMap[Index].Red - RedInput[i]))
|
||||
MaxRGBError[0] = ABS(OutputColorMap[Index].Red - RedInput[i]);
|
||||
if (MaxRGBError[1] < ABS(OutputColorMap[Index].Green - GreenInput[i]))
|
||||
MaxRGBError[1] = ABS(OutputColorMap[Index].Green - GreenInput[i]);
|
||||
if (MaxRGBError[2] < ABS(OutputColorMap[Index].Blue - BlueInput[i]))
|
||||
MaxRGBError[2] = ABS(OutputColorMap[Index].Blue - BlueInput[i]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n",
|
||||
MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]);
|
||||
#endif /* DEBUG */
|
||||
|
||||
free((char *)ColorArrayEntries);
|
||||
|
||||
*ColorMapSize = NewColorMapSize;
|
||||
|
||||
return GIF_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Routine to subdivide the RGB space recursively using median cut in each
|
||||
* axes alternatingly until ColorMapSize different cubes exists.
|
||||
* The biggest cube in one dimension is subdivide unless it has only one entry.
|
||||
* Returns GIF_ERROR if failed, otherwise GIF_OK.
|
||||
******************************************************************************/
|
||||
static int
|
||||
SubdivColorMap(NewColorMapType * NewColorSubdiv,
|
||||
unsigned int ColorMapSize,
|
||||
unsigned int *NewColorMapSize) {
|
||||
|
||||
int MaxSize;
|
||||
unsigned int i, j, Index = 0, NumEntries, MinColor, MaxColor;
|
||||
long Sum, Count;
|
||||
QuantizedColorType *QuantizedColor, **SortArray;
|
||||
|
||||
while (ColorMapSize > *NewColorMapSize) {
|
||||
/* Find candidate for subdivision: */
|
||||
MaxSize = -1;
|
||||
for (i = 0; i < *NewColorMapSize; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if ((((int)NewColorSubdiv[i].RGBWidth[j]) > MaxSize) &&
|
||||
(NewColorSubdiv[i].NumEntries > 1)) {
|
||||
MaxSize = NewColorSubdiv[i].RGBWidth[j];
|
||||
Index = i;
|
||||
SortRGBAxis = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxSize == -1)
|
||||
return GIF_OK;
|
||||
|
||||
/* Split the entry Index into two along the axis SortRGBAxis: */
|
||||
|
||||
/* Sort all elements in that entry along the given axis and split at
|
||||
* the median. */
|
||||
SortArray = (QuantizedColorType **)malloc(
|
||||
sizeof(QuantizedColorType *) *
|
||||
NewColorSubdiv[Index].NumEntries);
|
||||
if (SortArray == NULL)
|
||||
return GIF_ERROR;
|
||||
for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors;
|
||||
j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL;
|
||||
j++, QuantizedColor = QuantizedColor->Pnext)
|
||||
SortArray[j] = QuantizedColor;
|
||||
|
||||
qsort(SortArray, NewColorSubdiv[Index].NumEntries,
|
||||
sizeof(QuantizedColorType *), SortCmpRtn);
|
||||
|
||||
/* Relink the sorted list into one: */
|
||||
for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++)
|
||||
SortArray[j]->Pnext = SortArray[j + 1];
|
||||
SortArray[NewColorSubdiv[Index].NumEntries - 1]->Pnext = NULL;
|
||||
NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0];
|
||||
free((char *)SortArray);
|
||||
|
||||
/* Now simply add the Counts until we have half of the Count: */
|
||||
Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count;
|
||||
NumEntries = 1;
|
||||
Count = QuantizedColor->Count;
|
||||
while ((Sum -= QuantizedColor->Pnext->Count) >= 0 &&
|
||||
QuantizedColor->Pnext != NULL &&
|
||||
QuantizedColor->Pnext->Pnext != NULL) {
|
||||
QuantizedColor = QuantizedColor->Pnext;
|
||||
NumEntries++;
|
||||
Count += QuantizedColor->Count;
|
||||
}
|
||||
/* Save the values of the last color of the first half, and first
|
||||
* of the second half so we can update the Bounding Boxes later.
|
||||
* Also as the colors are quantized and the BBoxes are full 0..255,
|
||||
* they need to be rescaled.
|
||||
*/
|
||||
MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */
|
||||
MinColor = QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */
|
||||
MaxColor <<= (8 - BITS_PER_PRIM_COLOR);
|
||||
MinColor <<= (8 - BITS_PER_PRIM_COLOR);
|
||||
|
||||
/* Partition right here: */
|
||||
NewColorSubdiv[*NewColorMapSize].QuantizedColors =
|
||||
QuantizedColor->Pnext;
|
||||
QuantizedColor->Pnext = NULL;
|
||||
NewColorSubdiv[*NewColorMapSize].Count = Count;
|
||||
NewColorSubdiv[Index].Count -= Count;
|
||||
NewColorSubdiv[*NewColorMapSize].NumEntries =
|
||||
NewColorSubdiv[Index].NumEntries - NumEntries;
|
||||
NewColorSubdiv[Index].NumEntries = NumEntries;
|
||||
for (j = 0; j < 3; j++) {
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[j] =
|
||||
NewColorSubdiv[Index].RGBMin[j];
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[j] =
|
||||
NewColorSubdiv[Index].RGBWidth[j];
|
||||
}
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] =
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] +
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - MinColor;
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor;
|
||||
|
||||
NewColorSubdiv[Index].RGBWidth[SortRGBAxis] =
|
||||
MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis];
|
||||
|
||||
(*NewColorMapSize)++;
|
||||
}
|
||||
|
||||
return GIF_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Routine called by qsort to compare to entries.
|
||||
****************************************************************************/
|
||||
static int
|
||||
SortCmpRtn(const VoidPtr Entry1,
|
||||
const VoidPtr Entry2) {
|
||||
|
||||
return (*((QuantizedColorType **) Entry1))->RGB[SortRGBAxis] -
|
||||
(*((QuantizedColorType **) Entry2))->RGB[SortRGBAxis];
|
||||
}
|
|
@ -62,7 +62,6 @@ OTHER_FILES += \
|
|||
modules/cookiejar.js \
|
||||
repl.js
|
||||
|
||||
include(gif/gif.pri)
|
||||
include(mongoose/mongoose.pri)
|
||||
include(linenoise/linenoise.pri)
|
||||
include(qcommandline/qcommandline.pri)
|
||||
|
|
|
@ -56,8 +56,6 @@
|
|||
#include <QImageWriter>
|
||||
#include <QUuid>
|
||||
|
||||
#include <gifwriter.h>
|
||||
|
||||
#include "phantom.h"
|
||||
#include "networkaccessmanager.h"
|
||||
#include "utils.h"
|
||||
|
@ -922,9 +920,6 @@ bool WebPage::render(const QString &fileName, const QVariantMap &option)
|
|||
else if (fileName.endsWith(".pdf", Qt::CaseInsensitive) ){
|
||||
format = "pdf";
|
||||
}
|
||||
else if (fileName.endsWith(".gif", Qt::CaseInsensitive) ){
|
||||
format = "gif";
|
||||
}
|
||||
|
||||
if( option.contains("quality") ){
|
||||
quality = option.value("quality").toInt();
|
||||
|
@ -934,10 +929,6 @@ bool WebPage::render(const QString &fileName, const QVariantMap &option)
|
|||
if ( format == "pdf" ){
|
||||
retval = renderPdf(outFileName);
|
||||
}
|
||||
else if ( format == "gif" ) {
|
||||
QImage rawPageRendering = renderImage();
|
||||
retval = exportGif(rawPageRendering, outFileName);
|
||||
}
|
||||
else{
|
||||
QImage rawPageRendering = renderImage();
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB |
|
@ -2210,14 +2210,6 @@ xdescribe("WebPage render image", function(){
|
|||
render_test("pdf", { format: "pdf" });
|
||||
});
|
||||
|
||||
it("should render GIF file", function(){
|
||||
render_test("gif");
|
||||
});
|
||||
|
||||
it("should render GIF file with format option", function(){
|
||||
render_test("gif", { format: "gif" });
|
||||
});
|
||||
|
||||
it("should render PNG file", function(){
|
||||
render_test("png");
|
||||
});
|
||||
|
|
|
@ -35,10 +35,6 @@ QCommandLine - http://xf.iksaif.net/dev/qcommandline.html
|
|||
License: GNU Lesser General Public License (LGPL) version 2.1.
|
||||
Reference: http://dev.iksaif.net/projects/qcommandline/repository/revisions/master/entry/COPYING
|
||||
|
||||
GIFLIB - http://giflib.sourceforge.net/
|
||||
License: MIT
|
||||
Reference: http://giflib.cvs.sourceforge.net/viewvc/giflib/giflib/COPYING
|
||||
|
||||
wkhtmlpdf - http://code.google.com/p/wkhtmltopdf/
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
Reference: http://code.google.com/p/wkhtmltopdf/
|
||||
|
|
Loading…
Reference in New Issue