This is gifbmap.c in view mode; [Download] [Up]
/* gifbmap.h gifheader.c, gifbmap.c, and gif.h are based on "giftoppm" of David Koblas. They are modified by T. Ogihara. (1995) */ /* +-------------------------------------------------------------------+ */ /* | Copyright 1990, David Koblas. | */ /* | Permission to use, copy, modify, and distribute this software | */ /* | and its documentation for any purpose and without fee is hereby | */ /* | granted, provided that the above copyright notice appear in all | */ /* | copies and that both that copyright notice and this permission | */ /* | notice appear in supporting documentation. This software is | */ /* | provided "as is" without express or implied warranty. | */ /* +-------------------------------------------------------------------+ */ #include <signal.h> #include <setjmp.h> #include "gif.h" #include "strfunc.h" static int ReadColorMap(FILE *, gifHeader *); static int DoExtension(FILE *, gifHeader *); static int ReadImage(FILE *, const gifHeader *, unsigned char **); static void (*sav_violation)() = NULL; static void (*sav_buserror)() = NULL; static jmp_buf sav_env; static void catch_violation(int sig) { longjmp(sav_env, sig); } int gifGetImage(FILE *fp, gifHeader *gh, unsigned char **planes) { int c, rtn = 0; if (gh->colormap) { /* Global Colormap */ if (ReadColorMap(fp, gh) == 0) return Err_FORMAT; } while ((c = getc(fp)) != ',' ) { /* start character */ if (c == EOF || c == ';') /* GIF terminator */ return Err_SHORT; if (c == '!') { /* Extension */ if (DoExtension(fp, gh) < 0) return Err_ILLG; } /* other chars are illegal... ignore */ } (void)get_long(fp); /* skip 4 bytes */ gh->width = get_short(fp); gh->height = get_short(fp); c = getc(fp); gh->interlace = BitSet(c, INTERLACE); if (BitSet(c, LOCALCOLORMAP)) { /* Use Local Color Map */ gh->colors = 2 << (c & 0x07); if (ReadColorMap(fp, gh) == 0) return Err_FORMAT; } if (gh->transp >= 0) { unsigned char *p = (unsigned char *)gh->palette[gh->transp]; p[RED] = p[GREEN] = p[BLUE] = 255; if (gh->colors - 1 == gh->transp) --gh->colors; /* if last of palette is transp. */ } gh->bits = howManyBits(gh->palette, gh->colors); gh->isgray = isGray(gh->palette, gh->colors); /* Initialize the Compression routines */ if (initGifLZW(fp) == EOF) return Err_SHORT; sav_violation = signal(SIGSEGV, catch_violation); sav_buserror = signal(SIGBUS, catch_violation); if (setjmp(sav_env) == 0) rtn = ReadImage(fp, gh, planes); else /* return from Segmentation Error */ rtn = Err_FORMAT; (void) signal(SIGSEGV, sav_violation); (void) signal(SIGBUS, sav_buserror); return rtn; } static int ReadColorMap(FILE *fd, gifHeader *gh) { int i, j, number; unsigned char *p, *q; number = gh->colors; for (i = 0; i < number; ++i) { p = (unsigned char *)gh->palette[i]; p[RED] = getc(fd); p[GREEN] = getc(fd); p[BLUE] = getc(fd); if (feof(fd)) return 0; } for (i = number - 1; i > 0; --i) { /* skip stab */ p = (unsigned char *)gh->palette[i]; q = (unsigned char *)gh->palette[i - 1]; for (j = 0; j < 3; j++) if (p[j] != q[j]) goto EXIT; } EXIT: gh->colors = i + 1; return 1; } static int DoExtension(FILE *fd, gifHeader *gh) { int cc; unsigned char buf[256]; switch (cc = getc(fd)) { case 0x01: /* Plain Text Extension */ case 0x2c: /* Image Descriptor */ case 0x3b: /* Trailer */ case 0xff: /* Application Extension */ break; case 0xf9: /* Graphic Control Extension */ while (GetDataBlock(fd, buf) != 0) { if (BitSet(buf[0], TRANSPARENCY)) gh->transp = buf[3]; /* Transparent Index */ } return cc; case 0xfe: /* Comment Extension */ while (GetDataBlock(fd, buf) != 0) { if (gh->memo == NULL) gh->memo = (unsigned char *)str_dup(buf); } return cc; default: return -1; /* ERROR */ } while (GetDataBlock(fd, buf) != 0) ; return cc; } static int ReadImage(FILE *fd, const gifHeader *gh, unsigned char **planes) { int i, xpos, ypos, xbyte, pass, pn, err; long wd; unsigned char *map[MAXPLANE]; unsigned char buffer[MAXWidth]; pn = (gh->isgray ? 1:3) + ((gh->transp >= 0) ? 1 : 0); err = allocImage(planes, gh->width, gh->height, gh->bits, pn); if (err) return err; pass = 0; xbyte = byte_length(gh->bits, gh->width); for (ypos = 0; ; ) { for (xpos = 0; xpos < gh->width; xpos++) buffer[xpos] = LWZReadByte(fd); map[0] = planes[0] + (wd = xbyte * ypos); for (i = 1; i < pn; i++) map[i] = planes[i] + wd; expandImage(map, buffer, (const paltype *)gh->palette, gh->bits, gh->width, gh->isgray, gh->transp); if (gh->interlace) { ypos += pass ? (0x10 >> pass) : 0x08; if (ypos >= gh->height) { if (++pass > 3) break; ypos = 8 >> pass; } }else { if (++ypos >= gh->height) break; } } return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.