1 /****************************************************************************
2 * RRDtool 1.2rc5 Copyright by Tobi Oetiker, 1997-2005
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))) {