In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2011-5-12

Use as3swf Library
Use MinimalComps Library
Use FontLoader Class
Other
Get Adobe Flash player
by fujista 12 May 2011
/**
 * Copyright fujista ( http://wonderfl.net/user/fujista )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ajSX
 */

package {
    // Use as3swf Library
    import com.codeazur.as3swf.SWFData;
    import com.codeazur.as3swf.data.SWFRawTag;
    import com.codeazur.as3swf.data.SWFRecordHeader;
    import com.codeazur.as3swf.data.SWFRectangle;
    import com.codeazur.as3swf.factories.SWFTagFactory;
    import com.codeazur.as3swf.tags.IDefinitionTag;
    import com.codeazur.as3swf.tags.IDisplayListTag;
    import com.codeazur.as3swf.tags.ITag;
    import com.codeazur.as3swf.tags.TagDefineSprite;
    import com.codeazur.as3swf.tags.TagEnd;
    import com.codeazur.as3swf.tags.TagImportAssets;
    import com.codeazur.as3swf.tags.TagImportAssets2;
    import com.codeazur.as3swf.tags.TagPlaceObject;
    import com.codeazur.as3swf.tags.TagPlaceObject2;
    import com.codeazur.as3swf.tags.TagPlaceObject3;
    import com.codeazur.as3swf.tags.TagRemoveObject;
    import com.codeazur.as3swf.tags.TagRemoveObject2;
    import com.codeazur.as3swf.tags.TagShowFrame;
    
    // Use MinimalComps Library
    import com.bit101.components.Label;
    import com.bit101.components.ProgressBar;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    import com.bit101.components.Text;
    import com.bit101.components.TextArea;
    
    // Use FontLoader Class
    import net.wonderfl.utils.FontLoader;
    
    // Other
    import flash.display.Sprite;
    import flash.errors.IOError;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.net.FileReference;
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    
    public class MovieClipTranscoder extends Sprite {
        
        // swf headers
        public var version:uint;
        public var fileLength:uint;
        public var frameSize:SWFRectangle;
        public var frameRate:Number;
        public var frameCount:uint;
        public var compressed:Boolean;
        
        // minimalcomps
        protected var browse:PushButton;
        protected var filename:Text;
        protected var log:TextArea;
        protected var progress1:ProgressBar;
        protected var progress2:ProgressBar;
        protected var status:Label;
        protected var step:Label;
        
        protected var _file:FileReference;
        protected var _maxCharacterId:uint = 0;
        
        protected var _dictionary:Dictionary;
        protected var _spriteList:Dictionary;
        protected var _processList:Dictionary;
        
        protected var _steps:uint = 5;
        protected var _parentMessage:String;
        
        public function MovieClipTranscoder() {
            
            _dictionary = new Dictionary();
            _spriteList = new Dictionary();
            _processList = new Dictionary();
            
            initFileReference();
            initFontLoad();
        }
        
        public function transcode(ba:ByteArray):void {
            
            var source:SWFData = new SWFData();
            ba.readBytes(source);
            ba.clear();
            
            try {
                parse(source);
            //    build(source);
            } catch (e:Error) {
                
            }
            
            // save.enabled = true;
        }
        
        protected function parse(data:SWFData):void {
            
            try {
                updateStatus("Checking...", false);
                parseHeader(data);
                updateStatus("done.");
                
                setProgressMaximum(fileLength, "Parsing...");
                parseTimeline(data, frameCount);
                updateStatus("done.");
            } catch (e:Error) {
                updateStatus(e.toString());
            }
        }
        
        protected function parseHeader(data:SWFData):void {
            
            var header:Dictionary = new Dictionary();
            var signature:Array = [data.readUI8(), data.readUI8(), data.readUI8()];
            
            if ((signature[0] != 0x43 && signature[0] != 0x46) || signature[1] != 0x57 || signature[2] != 0x53) {
                throw( new Error("File is not swf.") );
            }

            this.version = data.readUI8();
            this.fileLength = data.readUI32();
            this.compressed = (signature[0] == 0x43) ? true : false;
            
            if (this.compressed) {
                updateStatus("Uncompressing...", false);
                data.swfUncompress();
                if (this.fileLength != data.length) {
                    throw( new Error("File uncompress error") );
                }
            }
            
            this.frameSize = data.readRECT();
            this.frameRate = data.readFIXED8();
            this.frameCount = data.readUI16();
        }
        
        protected function parseTimeline(data:SWFData, frameCount:uint, parentCharacterId:uint = 0):void {
            
            var pos:uint;
            var raw:SWFRawTag;
            var tag:ITag;
            var currentFrame:uint = 1;
            
            var display:Dictionary;
            var displayList:Dictionary = new Dictionary();
            
            do {
                pos = parentCharacterId ? data.position + _dictionary[parentCharacterId] : data.position;
                raw = data.readRawTag();
                
                data.position += raw.header.contentLength;
                tag = parseTag(raw.bytes, pos);
                
                switch (tag.type) {
                    
                    // Except
                    case TagPlaceObject.TYPE:
                    case TagImportAssets.TYPE:
                    case TagImportAssets2.TYPE:
                        throw( new Error(tag.name + " not support.") );
                    
                    case TagShowFrame.TYPE:
                        
                        for (var key:String in displayList) {
                            displayList[key]["count"]++;
                        }
                        
                        currentFrame++;
                        break;
                        
                    case TagPlaceObject2.TYPE:
                    case TagPlaceObject3.TYPE:
                    
                        var placeObject:TagPlaceObject = tag as TagPlaceObject;
                         
                        if (placeObject.hasMove && displayList[placeObject.depth]) {
                            if (placeObject.hasCharacter) {
                                display = displayList[placeObject.depth];
                                _processList[display["id"]] = Math.max(display["count"], _processList[display["id"]]);
                            } else {
                                //
                            }
                        }
                        
                        if (placeObject.hasCharacter && _spriteList[placeObject.characterId]) {
                            
                            display = new Dictionary();
                            display["id"] = placeObject.characterId;
                            display["count"] = 0;
                            display["depth"] = placeObject.depth;
                            display["offset"] = currentFrame;
                            displayList[placeObject.depth] = display;
                            
                            if (parentCharacterId > 0 && !_spriteList[parentCharacterId]) {
                                _spriteList[parentCharacterId] = true;
                                _processList[parentCharacterId] = 0;
                            }
                        }
                        
                        break;
                        
                    case TagRemoveObject.TYPE:
                    case TagRemoveObject2.TYPE:
                        var removeObject:TagRemoveObject = tag as TagRemoveObject;
                        if (displayList[removeObject.depth]) {
                            display = displayList[removeObject.depth];
                            _processList[display["id"]] = Math.max(display["count"], _processList[display["id"]]);
                            delete displayList[removeObject.depth];
                        }
                        break;
                }
                
                setProgressValue(pos + raw.header.contentLength);
                
            } while (tag.type != TagEnd.TYPE);
        }
        
        protected function parseTag(data:SWFData, pos:uint):ITag {
            
            var header:SWFRecordHeader = data.readTagHeader();
            var tag:ITag = SWFTagFactory.create(header.type, null);
            
            updateStatus(tag.name);
            
            if (tag is IDefinitionTag) {
                var characterId:uint = data.readUI16();
                _dictionary[characterId] = pos;
                _maxCharacterId = Math.max(_maxCharacterId, characterId);
                
                if (tag is TagDefineSprite) {
                    var frameCount:uint = data.readUI16();
                    if (frameCount > 1) {
                        _spriteList[characterId] = true;
                        _processList[characterId] = 0;
                    }

                    parseTimeline(data, frameCount, characterId);
                }
            } else if (tag is IDisplayListTag) {
                tag.parse(data, header.contentLength, this.version);
            }
            
            return tag;
        }
        
        protected function build(data:SWFData):void {
            
            buildHeader(data);
            
        }
        
        protected function buildHeader(data:SWFData):void {
            data.writeUI8(this.compressed ? 0x43 : 0x46);
            data.writeUI8(0x57);
            data.writeUI8(0x53);
            data.writeUI8(this.version);
            data.writeUI32(this.fileLength);
            data.writeRECT(this.frameSize);
            data.writeFIXED8(this.frameRate);
            data.writeUI16(this.frameCount);
        }
        
        protected function buildTimeline(source:SWFData, data:SWFData):void {
            
        }
        
        protected function buildTag():void {
            
        }
        
        protected function buildSprite():void {
            
        }
        
        protected function test(characterId:uint, frame:uint):void {
            
            var truncate:Dictionary;
            var display:Dictionary;
            
            do {
                
                
                
                
            } while (true);

            
        }


        
        protected function setProgressMaximum(value:uint, message:String = null):void {
            progress2.maximum = value;
            progress1.value++;
            if (message) {
                updateStatus(message, false);
                step.text = Math.floor( value / progress2.maximum * 100 ) + "%";
            }
        }
        
        protected function setProgressValue(value:uint, append:Boolean = false):void {
            value += append ? progress2.value : 0;
            progress2.value = value;
            step.text = Math.floor( value / progress2.maximum * 100 ) + "%";
        }
        
        protected function updateStatus(text:String, append:Boolean = true, override:Boolean = true):void {
            _parentMessage = (!append && override) ? text : _parentMessage;
            status.text = append ? _parentMessage + "  " + text : text;
            log.text += status.text + "\n";
        }
        
        protected function initFileReference():void {
            _file = new FileReference();
            _file.addEventListener(Event.SELECT, function(e:Event):void{
                setProgressMaximum(e.target.size, "Loading...");
                filename.text = e.target.name;
                browse.enabled = false;
                e.target.load();
            });
            _file.addEventListener(Event.COMPLETE, function(e:Event):void{
                setProgressValue(e.target.data.length);
                updateStatus("done.");
                transcode(e.target.data);
            });
            _file.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void{
                setProgressValue(e.bytesLoaded);
            });
            _file.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOError):void{
                updateStatus(e.toString());
            });
        }
        
        protected function initFontLoad():void {
            var font:FontLoader = new FontLoader();
            font.addEventListener(Event.COMPLETE, function(e:Event):void {
                initMinimalComps();
                progress1.maximum = 5;
                updateStatus("Please push \"Browse\" button and select target file.", false);
            });
            font.load("IPAGP");
        }
        
        protected function initMinimalComps():void {
            
            var format:TextFormat;
            
            Style.fontSize = 12;
            Style.fontName = "IPAGP";
            
            new Label(this, 5, 5, "File:");
            browse = new PushButton(this, 360, 25, "Browse", function(e:MouseEvent):void{
                _file.browse();
            });
            filename = new Text(this, 5, 25, null);
            filename.width = 350;
            filename.height = 20;
            filename.editable = false;
            
            new Label(this, 5, 55, "Progress:");
            progress1 = new ProgressBar(this, 5, 75);
            progress1.width = 455;
            progress2 = new ProgressBar(this, 5, 86);
            progress2.width = 455;
            new Label(this, 5, 100, ">>");
            status = new Label(this, 25, 100);
            status.width = 400;
            status.autoSize = false;
            step = new Label(this, 410, 100);
            step.width = 50;
            step.autoSize = false;
            format = step.textField.defaultTextFormat;
            format.align = TextFormatAlign.RIGHT;
            step.textField.defaultTextFormat = format;
            
            //new PushButton(this, 180, 180, "SAVE");
            
            new Label(this, 5, 280, "Information:");
            log = new TextArea(this, 5, 300, null);
            log.width = 455;
            log.height = 160;
            log.editable = false;
        }
    }
}