Geek Hideout
giftab

giftab

giftab is a tiny utility that I wrote that changes the color table entries in a GIF file. It was written to be used at a Unix command prompt, and has been tested on OpenBSD and Linux. There should be no difficulty porting it to other platforms, and I suspect in many cases it will build without any modification.

This program is pretty simple and hardly worth being here at all. It exists because I wanted to make it easy to change the color scheme of my website without having to modify all the images individually. What giftab does is use the index provided as an entry into the color table, which starts at an offset of 13 in a GIF file. Individual entries are three bytes apart.

It is easy to use:

giftab index_number color [index_number color ...] filename

The index_number is a value from 0-255 that represents which table entry to change. color is an HTML formated color code that specifies the new color. Note, that while it is possible to use a octothorpe (#, also known as a pound sign) to prefix the color code, it will have to be encased in quotations to prevent the shell from interpreting the rest of the line as a comment.

The filename is simply the name of the GIF file that is to be worked upon. Note that no special GIF file sanity checking is performed.

I'm not providing a binary image, so you'll have to compile and link it yourself. Using gcc, this is a piece of cake:

gcc -o giftab giftab.c

The C source code can be downloaded here, or you can just copy and paste it from below:



#include <stdio.h>

int main(int argc, char *argv[]) {
  const char *usage = "Usage: index_number color [index_number color ...] " \
    "filename\n\n- index_number is an entry into the color table and ranges " \
    "from 0-255.\n- Color is an HTML formated color code, i.e.: 00CCFF\n" \
    "- filename is the name of the GIF file that is to have the color " \
    "replacement\n  performed on it.\n";
  FILE *f;
  int i;
  int var;
  char *val_ptr;
  int val;

  if (argc < 4) {
    fprintf(stderr, "Not enough arguments.\n\n%s", usage);
    return 1;
  }

  if (argc % 2 != 0) {
    fprintf(stderr, "Invalid number of arguments.\n\n%s", usage);
    return 1;
  }

  f = fopen(argv[argc - 1], "r+b");
  if (!f) {
    fprintf(stderr, "File %s cannot be opened for writing.\n", argv[argc -1]);
    return 1;
  }

  for (i = 1; i < argc - 1; i += 2) {
    var = atoi(argv[i]);
    val_ptr = argv[i + 1];
    if (*val_ptr == '#') val_ptr++;
    val = strtol(val_ptr, NULL, 16);
    val = (0x00FF00 & val) | ((0xFF0000 & val) >> 16) | ((0x0000FF & val) << 16);
    fseek(f, 13 + 3 * var, SEEK_SET);
    fwrite(&val, 3, 1, f);
  }

  fclose(f);
  return 0;
}