1
/****************************************************************************
2
* RRDtool 1.0.42 Copyright Tobias Oetiker, 1997 - 2000
3
****************************************************************************
4
* gifsize.c provides the function gifsize which determines the size of a gif
5
****************************************************************************/
7
/* This is built from code originally created by: */
9
/* +-------------------------------------------------------------------+ */
10
/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
11
/* | Permission to use, copy, modify, and distribute this software | */
12
/* | and its documentation for any purpose and without fee is hereby | */
13
/* | granted, provided that the above copyright notice appear in all | */
14
/* | copies and that both that copyright notice and this permission | */
15
/* | notice appear in supporting documentation. This software is | */
16
/* | provided "as is" without express or implied warranty. | */
17
/* +-------------------------------------------------------------------+ */
26
#define MAXCOLORMAPSIZE 256
36
#define LOCALCOLORMAP 0x80
37
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
39
#define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
41
#define LM_to_uint(a,b) (((b)<<8)|(a))
49
} Gif89 = { -1, -1, -1, 0 };
51
static int ReadColorMap (FILE *fd, int number, unsigned char (*buffer)[256]);
52
static int DoExtension (FILE *fd, int label, int *Transparent);
53
static int GetDataBlock (FILE *fd, unsigned char *buf);
58
GifSize(FILE *fd, long *width, long *height)
65
int Transparent = (-1);
66
unsigned char buf[16];
68
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
71
ZeroDataBlock = FALSE;
74
if (! ReadOK(fd,buf,6)) {
77
if (strncmp((char *)buf,"GIF",3) != 0) {
80
strncpy(version, (char *)buf + 3, 3);
83
if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
86
if (! ReadOK(fd,buf,7)) {
89
BitPixel = 2<<(buf[4]&0x07);
90
ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
94
if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
95
if (ReadColorMap(fd, BitPixel, ColorMap)) {
100
if (! ReadOK(fd,&c,1)) {
103
if (c == ';') { /* GIF terminator */
104
if (imageCount < imageNumber) {
109
if (c == '!') { /* Extension */
110
if (! ReadOK(fd,&c,1)) {
113
DoExtension(fd, c, &Transparent);
117
if (c != ',') { /* Not a valid start character */
123
if (! ReadOK(fd,buf,9)) {
127
(*width) = LM_to_uint(buf[4],buf[5]);
128
(*height) = LM_to_uint(buf[6],buf[7]);
134
ReadColorMap(FILE *fd, int number, unsigned char (*buffer)[256])
137
unsigned char rgb[3];
140
for (i = 0; i < number; ++i) {
141
if (! ReadOK(fd, rgb, sizeof(rgb))) {
144
buffer[CM_RED][i] = rgb[0] ;
145
buffer[CM_GREEN][i] = rgb[1] ;
146
buffer[CM_BLUE][i] = rgb[2] ;
154
DoExtension(FILE *fd, int label, int *Transparent)
156
static unsigned char buf[256];
159
case 0xf9: /* Graphic Control Extension */
160
(void) GetDataBlock(fd, (unsigned char*) buf);
161
Gif89.disposal = (buf[0] >> 2) & 0x7;
162
Gif89.inputFlag = (buf[0] >> 1) & 0x1;
163
Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
164
if ((buf[0] & 0x1) != 0)
165
*Transparent = buf[3];
167
while (GetDataBlock(fd, (unsigned char*) buf) != 0)
173
while (GetDataBlock(fd, (unsigned char*) buf) != 0)
180
GetDataBlock(FILE *fd, unsigned char *buf)
184
if (! ReadOK(fd,&count,1)) {
188
ZeroDataBlock = count == 0;
190
if ((count != 0) && (! ReadOK(fd, buf, count))) {