forked from: gif format

by wh0 forked from gif format (diff: 108)
♥0 | Line 98 | Modified 2010-12-26 08:21:35 | MIT License
play

ActionScript3 source code

/**
 * Copyright wh0 ( http://wonderfl.net/user/wh0 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sh3O
 */

// forked from wh0's gif format
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.UncaughtErrorEvent;
    import flash.net.LocalConnection;
    import flash.utils.Endian;
    import flash.utils.ByteArray;
    
    import com.bit101.components.PushButton;
    import com.bit101.components.Text;
    import mx.utils.Base64Encoder;
    public class FlashTest extends Sprite {
        
        private static const TRANSPARENT:uint = 0x1000000;
        private var input:Text;
        private var output:Text;
        private var button:PushButton;
        
        public function FlashTest() {
            loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, function(e:UncaughtErrorEvent):void { new LocalConnection().send('we' + loaderInfo.parameters.ticket, 'onSendMessageToJS', e.error + '\n'); })
            input = new Text(this, 0, 0);
            input.width = 200;
            input.height = 435;
            output = new Text(this, 210, 0);
            output.width = 255;
            output.height = 465;
            button = new PushButton(this, 0, 445, 'compile', compile);
            button.width = 200;
            button.height = 20;
        }
        
        private function compile(e:Event):void {
            output.text = 'compiling';
            var lines:Array = input.text.split('\r');
            var front:ByteArray = new ByteArray();
            front.endian = Endian.LITTLE_ENDIAN;
            var back:ByteArray = new ByteArray();
            back.endian = Endian.LITTLE_ENDIAN;
            
            // header
            front.writeUTFBytes('GIF'); // signature
            front.writeUTFBytes('89a'); // version
            
            // logical screen descriptor
            front.writeShort(1); // logical screen width
            front.writeShort(1); // logical screen height
            front.writeByte(0xf6); // packed fields
                // global color table flag (immediately follows)
                // color resolution (8 bits)
                // sort flag (not ordered)
                // size of global color table (128 entries)
            front.writeByte(0); // background color index
            front.writeByte(0); // pixel aspect ratio
            
            if (lines[0] == 'loop') {
                lines.shift();
                // application extension
                back.writeByte(0x21); // extension introducer
                back.writeByte(0xff); // application extension label
                back.writeByte(11); // block size
                back.writeUTFBytes('NETSCAPE'); // application identifier
                back.writeUTFBytes('2.0'); // application authentication code
                back.writeByte(3); // length of data sub-block
                back.writeByte(1); // 1
                back.writeShort(0); // number of iterations
                back.writeByte(0); // data sub-block terminator
            }
            
            for (var i:int = 0; i < lines.length; i++) {
                var line:Array = lines[i].split(/\s+/);
                var color:uint = parseInt(line[0], 16);
                var delay:int = parseInt(line[1], 10);
                
                // global color table
                front.writeByte(color >> 16); // red
                front.writeByte(color >> 8); // green
                front.writeByte(color); // blue
                
                // graphic control extension
                back.writeByte(0x21); // extension introducer
                back.writeByte(0xf9); // graphic control label
                back.writeByte(4); // block size
                if (color & TRANSPARENT) {
                    back.writeByte(0x09); // packed fields
                        // reserved (0)
                        // disposal method (restore to background)
                        // user input flag (not expected)
                        // transparent color flag (given)
                } else {
                    back.writeByte(0x08); // packed fields
                        // reserved (0)
                        // disposal method (restore to background)
                        // user input flag (not expected)
                        // transparent color flag (not given)
                }
                back.writeShort(delay); // delay time
                back.writeByte(i); // transparency index
                back.writeByte(0); // block terminator
                
                // image descriptor
                back.writeByte(0x2c); // image separator
                back.writeShort(0); // image left position
                back.writeShort(0); // image top position
                back.writeShort(1); // image width
                back.writeShort(1); // image height
                back.writeByte(0x00); // packed fields
                    // local color table flag (not present)
                    // interlace flag (not interlaced)
                    // sort flag (not ordered)
                    // size of local color table (0 entries)
                
                // table based image data
                back.writeByte(7); // lzw minimum code size
                back.writeByte(3); // block size
                back.writeByte(128); // clear code
                back.writeByte(i); // this one is actually data
                back.writeByte(129); // end of information code
                back.writeByte(0); // block terminator
            }
            
            while (i++ < 128) {
                front.writeByte(0);
                front.writeByte(0);
                front.writeByte(0);
            }

            
            // trailer
            back.writeByte(0x3b); // GIF trailer
            front.writeBytes(back, 0, back.length);
            var enc:Base64Encoder = new Base64Encoder();
            enc.insertNewLines = false;
            enc.encodeBytes(front, 0, front.length);
            
            output.text = 'data:image/gif;base64,' + enc.toString();
        }
        
    }
}