/*
* Copyright (c) 1997-2004 Alexandros Eleftheriadis, Danny Hong and
* Yuntai Kyong.
*
* This file is part of Flavor, developed at Columbia University
* (www.ee.columbia.edu/flavor).
*
* Flavor is free software; you can redistribute it and/or modify
* it under the terms of the Flavor Artistic License as described in
* the file COPYING.txt.
*
*/
/*
* Authors:
* Danny Hong <danny@ee.columbia.edu>
*
*/
/*
* Flavor description of the GIF87a bitstream specification.
*
*/
// Set array size to 256 and also allow tracing
%pragma array=256, trace
// Color map entries
class ColorEntry {
unsigned int(8) r;
unsigned int(8) g;
unsigned int(8) b;
}
// Color maps (argument is bits/pixel
class ColorMap(unsigned int bpp) {
ColorEntry color[1<<bpp];
}
// Screen descriptor
class ScreenDescriptor {
// GIF uses LSB ordering
little unsigned int(16) width;
little unsigned int(16) height;
// This flag is set if a global color map follows the descriptor
bit(1) M;
// Color resolution minus 1
unsigned int(3) cr;
// Marker (always 0)
bit(1) marker = 0;
// Bits/pixel in image minus 1
unsigned int(3) pixel;
// Index of background color
unsigned int(8) background;
// If M is set, we have a global colormap; its size is 2**(pixel+1)
if (M != 0)
ColorMap globalColorMap(pixel+1);
}
// Extension block (signalled by '!')
class ExtensionBlock {
unsigned int(8) function_code;
do {
unsigned int(8) byte_count;
if (byte_count != 0) {
unsigned int i;
for (i=0; i<byte_count; i++) {
unsigned int(8) data;
}
}
} while (byte_count != 0);
}
// The image data
class ImageData {
// Code size
unsigned int(8) code_size;
// Series of data blocks
do {
unsigned int(8) byte_count;
if (byte_count != 0) {
unsigned int i;
for (i=0; i<byte_count; i++)
unsigned int(8) data;
}
} while (byte_count != 0);
}
// Image descriptor (signalled by ',')
class ImageDescriptor {
little unsigned int(16) left;
little unsigned int(16) top;
little unsigned int(16) width;
little unsigned int(16) height;
/* If set, use local color map, and use 'pixel' below;
* otherwise ignore 'pixel' and use global colormap
*/
bit(1) M;
// Interlace flag
bit(1) I;
// Three reserved bits; must be 0
bit(3) markers = 0;
// Bits/pixel in this image minus 1 (valid only if M=1)
unsigned int(3) pixel;
// If M is set, we have a local colormap; its size is 2**(pixel+1)
if (M != 0)
ColorMap localColorMap(pixel+1);
// Image data
ImageData data;
}
class GIF87a {
// GIF signature
char(8) GIFsignature[6] = "GIF87a";
// Screen descriptor
ScreenDescriptor sd;
// One or more image descriptors
do {
unsigned int(8) end;
if (end == ',') { // We found an image descriptor
ImageDescriptor id;
}
if (end == '!') { // We found an extension block
ExtensionBlock eb;
}
// Everything else is ignored
} while (end != ';'); // ';' is the end-of-data marker
}
|