RedGIF gif image decoder


read and decodes a .gif file from disk.

includes a simple makeWindow method to display the pixels.  (but you should really write your own.)


see http://www.onicos.com/staff/iz/formats/gif.html

http://local.wasp.uwa.edu.au/~pbourke/dataformats/gif/

http://www.daubnet.com/formats/GIF.html

http://www.cis.udel.edu/%7Eamer/CISC651/lzw.and.gif.explained.html



*read(path)

create a RedGIF by reading and decoding a .gif file from disk.

might take a long time to decode.

makeWindow(bounds)

as simple as possible.

<>type

string.  either "GIF87a" or "GIF89a".

<>width

<>height

image dimensions in pixels.

<>background

a Color.  can be nil if no globalColorMap.

<>aspectRatio

usually 0.

<>depth

colour depth.

<>globalColorMap

array of colours.

<>controls

array of RedGIFControl objects.  corresponding control also saved in each RedGIFImage.

see below.

<>comments

array of strings.

<>appId

<>appCode

optional strings.

<>appData

optional data as an array.

<>images

array of RedGIFImage objects.



helper classes:


RedGIFImage

holds the actual pixel data and other image specific settings.

a RedGIF consist of one or more RedGIFImage objects.

<bounds

image dimensions as a Rect.

<flags

semi-private image settings.  use the methods depth, hasColorMap, interlaced below instead.

<>colorMap

image specific (a.k.a. local) array of colours.

<>data

the pixel data as a 1-dimensional array of Color objects.

reading from left to right, top to bottom.

<>control

a RedGIFControl object.

depth

colour depth.

hasColorMap

boolean.  true if local colorMap.

interlaced

boolean.  indicates that this image needs to be drawn in separate passes.


RedGIFControl


holds data for specific images.

<>duration

integer.  if not 0 then specify delay time for animation in 1/100th of a second.

<>transparent

a Color.

<>disposalMethod

an Integer from 0 to 3 that indicated overdraw operations.

<>userInputFlag

a Boolean.  if animation should wait for user input or not.

<>transparentFlag

a Boolean.  if transparent colour used or not.




//--

a= RedGIF.read("/Library/Application Support/Apple/iChat Icons/Funk Animals/RedDog.gif");

a.dump;

a.makeWindow;



//--template for custom code to manipulate and display

(

var scale= 10;

var a= RedGIF.read("/Library/Application Support/Apple/iChat Icons/Funk Animals/RedDog.gif");

var win= Window("gif", Rect(300, 300, a.width*scale, a.height*scale), false);

a.background= Color.blue; //overwrite background colour

a.images[0].data= a.images[0].data.reverse; //mess with the image pixel data

win.view.background= a.background;

win.drawHook= {

Pen.smoothing= false;

a.images[0].data.do{|col, i|

if(a.controls[0].transparentFlag.not or:{a.controls[0].transparent!=col}, {

Pen.fillColor= col;

Pen.fillOval(Rect(i%a.width*scale, i.div(a.width)*scale, scale, scale));

});

};

};

win.front;

)


//--download example animated gif to desktop

"cd ~/Desktop; curl -o dog-03.gif http://www.gifanimations.com/GA/image/animations/animals/dogs/dog-03.gif".unixCmd;


//--template for animation (load an animated gif)

(

var scale= 2;

var a= RedGIF.read("~/Desktop/dog-03.gif");

var win= Window("gif", Rect(300, 300, a.width*scale, a.height*scale), false);

var index= 0, img;

win.drawHook= {

Pen.smoothing= false;

img= a.images.wrapAt(index);

img.data.do{|col, i|

if(img.control.transparentFlag.not or:{img.control.transparent!=col}, {

Pen.fillColor= col;

Pen.fillRect(Rect(i%a.width*scale, i.div(a.width)*scale, scale, scale));

});

};

};

win.front;

Routine({

while({win.isClosed.not}, {

win.refresh;

(img.control.duration*0.01).max(0.01).wait;

index= index+1;

});

}).play(AppClock);

)