See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  GIF Export
  Submitted by



Here's a code snippet that will save a block of memory to disk as a Gif compressed image. You must provide a pointer to the block of memory and an optional pointer to the associated color palette as a series of 256 8 bit RGB values. If no color palette is specified then the image is assumed to be grayscale. That's all there is to it. John W. Ratcliff
jratcliff@verant.com


Download Associated File: gifsave.cpp (6,157 bytes)

Here's a code snippet that will save a block of memory to disk as a
Gif compressed image.  You must provide a pointer to the block of memory
and an optional pointer to the associated color palette as a series of
256 8 bit RGB values.  If no color palette is specified then the image is
assumed to be grayscale.

That's all there is to it.

John W. Ratcliff jratcliff@verant.com

//******************************************************************* //** Begin SGIF.H header file. //******************************************************************* #ifndef SGIF_H

#define SGIF_H

class SGif { public: static int SaveGif(const char *filename, // filename to save as. int wid, // width of image int hit, // height of image const unsigned char *image, // image data const unsigned char *pal=0); // color palette 256 3 byte RGB tuples // If no color palette assigned, then grayscale // is assumed. };

#endif

//******************************************************************* //** Begin SGIF.CPP //*******************************************************************

#include <stdlib.h> #include <stdio.h> #include <string.h>

#include "sgif.h"

static void initialize(void);

static struct { char name[3]; char version[3]; short xres, yres; unsigned short packed; char back_col_index; char aspect_ratio; } gif_header;

static void write_code(unsigned short code);

static FILE *fsave; static short clear, codebits, colors, end, length, lastentry, nbits, nbytes, entries, actual, startbits, xres, yres; static unsigned char buffer[16384],block[266],test[100]; static unsigned short hashcode, next, str_index[5003];

int SGif::SaveGif(const char *filename, int wid, int hit, const unsigned char *image, const unsigned char *cpal) { short i, row, col, color,temp; unsigned short hashentry; unsigned char bits; unsigned char pal[768];

if ( cpal ) // if color palette specified, copy it { memcpy(pal,cpal,768); } else { // Set up default grayscale color palette. for (int i=0; i<256; i++) { pal[i*3+0] = i; pal[i*3+1] = i; pal[i*3+2] = i; } }

xres = (short) wid; yres = (short) hit;

fsave = fopen(filename, "wb");

if ( fsave== NULL ) { return 0; }

strcpy(gif_header.name,"GIF"); strcpy(gif_header.version, "87a");

gif_header.xres = (short) wid; gif_header.yres = (short) hit; gif_header.packed = 0xF7; bits = 8; colors = 256;

gif_header.back_col_index = 0; gif_header.aspect_ratio = 0; fwrite(&gif_header,1,13,fsave);

fwrite(pal,1,768,fsave);

fputc(',',fsave); fputc(0,fsave); fputc(0,fsave); fputc(0,fsave); fputc(0,fsave); fwrite(&xres,1,2,fsave); fwrite(&yres,1,2,fsave); fputc(0,fsave); startbits = bits+1; clear = 1 << (startbits - 1); end = clear+1; fputc(bits,fsave); codebits = startbits; nbytes = 0; nbits = 0; for (i = 0; i < 266; i++) block[i] = 0; initialize();

for (row = 0; row < yres; row++) { for (col = 0; col < xres; col++) { color = (short) *image++; test[0] = (unsigned char) ++length; test[length] = (unsigned char) color; switch(length) { case 1: lastentry = color; break; case 2: hashcode = 301 * (test[1]+1); default: hashcode *= (color + length); hashentry = ++hashcode % 5003; for( i = 0; i < 5003; i++) { hashentry = (hashentry + 1) % 5003; if (memcmp(&buffer[str_index[hashentry]+2], test,length+1) == 0) break; if (str_index[hashentry] == 0) i = 5003; } if (str_index[hashentry] != 0 && length < 97) { memcpy(&lastentry,&buffer[str_index[hashentry]],2); break; } write_code(lastentry); entries++; if (str_index[hashentry] == 0) { temp = entries+end; str_index[hashentry] = next; memcpy(&buffer[next],&temp,2); memcpy(&buffer[next+2],test,length+1); next += length+3; actual++; } test[0] = 1; test[1] = (unsigned char) color; length = 1; lastentry = color; if ((entries+end) == (1<<codebits)) codebits++; if ( entries + end > 4093 || actual > 3335 || next > 15379) { write_code(lastentry); initialize(); } } } } write_code(lastentry); write_code(end); fputc(0,fsave); fputc(';',fsave); fclose(fsave); return(1); }

void initialize(void) { write_code(clear); entries = 0; actual = 0; next = 1; length = 0; codebits = startbits; buffer[0] = 0; memset(str_index,0x00,10006); }

void write_code(unsigned short code) { block[nbytes ] |= ((code << nbits) & 0xFF); block[nbytes+1] |= ((code >> (8 - nbits)) & 0xFF); block[nbytes+2] |= (((code>>(8 - nbits)) >> 8) & 0xFF); nbits += codebits;

while (nbits >= 8) { nbits -= 8; nbytes++; }

if (nbytes < 251 && code != end) return; if (code == end) { while (nbits > 0) { nbits -= 8; nbytes++; } } fputc(nbytes,fsave); fwrite(block,nbytes,1,fsave); memcpy(block,&block[nbytes],5); memset(&block[5],0x00,260); nbytes = 0; }

//******************************************************************* //** Test application demonstrating usage of the Sgif utility //******************************************************************* #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h>

#include "sgif.h"

void main(int argc,char **argv) { // gif saving test program. int wid = 256; int hit = 256; unsigned char *image = new unsigned char[wid*hit]; for (int y=0; y<hit; y++) { memset( &image[y*wid], y, wid); // build gradient }

printf("Saving test1.gif\n");

SGif::SaveGif("test1.gif",wid,hit,image);

// now create a test color palette. unsigned char pal[768]; for (int i=0; i<256; i++) { pal[i*3+0] = i; // set red component. pal[i*3+1] = i/2; // set green component. pal[i*3+2] = i/4; // set blue component. }

printf("Saving test2.gif\n");

SGif::SaveGif("test2.gif",wid,hit,image,pal);

delete image; }


The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.