powered by nequal
Home » IO_SWF » Timeline » 2496

Changeset 2496 -- 2011-06-14 23:04:03

Author
よや
Comment
package released (2.0.3-stable) (@yoya)

Diffs

IO_SWF/tags/2.0.3-stable-20110614230402/sample/jpeg_dump.php

@@ -0,0 +1,34 @@
+<?php
+
+require_once 'IO/SWF/JPEG.php';
+
+function usage() {
+    echo "Usage: php jpeg_dump.php <dump|jpegtables|imagedata>".PHP_EOL;
+}
+
+if ($argc != 3) {
+    usage();
+    exit(1);
+}
+
+$jpegdata = file_get_contents($argv[2]);
+
+$jpeg = new IO_SWF_JPEG();
+$jpeg->input($jpegdata);
+
+switch($argv[1]) {
+  case 'dump':
+    $jpeg->dumpChunk();
+    break;
+  case 'jpegtables':
+    echo $jpeg->getEncodingTables();
+    break;
+  case 'imagedata':
+    echo $jpeg->getImageData();
+    break;
+  default:
+    usage();
+    exit(1);
+}
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfcopy.php

@@ -0,0 +1,22 @@
+<?php
+
+require 'IO/SWF.php';
+// require dirname(__FILE__).'/../IO/SWF.php';
+
+if ($argc != 2) {
+    echo "Usage: php swfcopy.php <swf_file>\n";
+    echo "ex) php swfdopy.php test.swf\n";
+    exit(1);
+}
+
+assert(is_readable($argv[1]));
+
+$swfdata = file_get_contents($argv[1]);
+
+$swf = new IO_SWF();
+
+$swf->parse($swfdata);
+
+echo $swf->build();
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfreplaceactionstring.php

@@ -0,0 +1,29 @@
+<?php
+
+require 'IO/SWF/Editor.php';
+// require dirname(__FILE__).'/../IO/SWF/Editor.php';
+
+if ($argc != 4) {
+    fprintf(STDERR, "Usage: php swfreplaceactionstring.phpp <swf_file> <from_str> <to_str>\n");
+    fprintf(STDERR, "ex) php swfreplaceactionstring.php test.swf foo baa\n");
+    exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(isset($argv[2]));
+assert(isset($argv[3]));
+
+$swfdata = file_get_contents($argv[1]);
+$from_str = $argv[2];
+$to_str = $argv[3];
+
+$swf = new IO_SWF_Editor();
+
+$swf->parse($swfdata);
+
+$swf->replaceActionStrings($from_str, $to_str);
+// $swf->replaceActionString($from_str, $to_str); // obsolute
+
+echo $swf->build();
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfcountshapeedges.php

@@ -0,0 +1,28 @@
+<?php
+
+require 'IO/SWF/Info.php';
+// require dirname(__FILE__).'/../IO/SWF/Info.php';
+
+if ($argc != 2) {
+    echo "Usage: php swfcountshapeedges.php <swf_file>\n";
+    echo "ex) php swfcountshapeedges.php test.swf\n";
+    exit(1);
+}
+
+$swfdata = file_get_contents($argv[1]);
+
+$swf = new IO_SWF_Info();
+
+$swf->parse($swfdata);
+
+$count_table = $swf->countShapeEdges();
+if ($count_table === false) {
+    printf("countShapeEdges return false\n");
+    exit(1);
+}
+
+foreach ($count_table as $shape_id => $count) {
+   echo "shape_id: $shape_id => edges_count: $count\n";
+}
+
+exit(0);
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfcountshapeedges.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfdeformeshape.php

@@ -0,0 +1,26 @@
+<?php
+
+require 'IO/SWF/Editor.php';
+// require dirname(__FILE__).'/../IO/SWF/Editor.php';
+
+if ($argc != 3) {
+    fprintf(STDERR, "Usage: php swfdeformeshape.php <swf_file> <threshold>\n");
+    fprintf(STDERR, "ex) php swfdeformeshape.php test.swf 10 \n");
+    exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+
+$swfdata = file_get_contents($argv[1]);
+$threshold = $argv[2];
+
+$swf = new IO_SWF_Editor();
+
+$swf->parse($swfdata);
+
+$swf->deformeShape($threshold);
+
+echo $swf->build();
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfsetbgcolor.php

@@ -0,0 +1,27 @@
+<?php
+
+require 'IO/SWF/Editor.php';
+
+if ($argc != 5) {
+    echo "Usage: php swfsetbgcolor.php <swf_file> <red> <green> <blue>\n";
+    echo "ex) php swfsetbgcolor.php test.swf 0 0 255\n";
+    exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+assert(is_numeric($argv[3]));
+assert(is_numeric($argv[4]));
+
+$swfdata = file_get_contents($argv[1]);
+
+$swf = new IO_SWF_Editor();
+
+$swf->parse($swfdata);
+
+$color = pack('CCC', $argv[2], $argv[3], $argv[4]);
+$swf->replaceTagContent(9, $color);
+
+echo $swf->build();
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfdump.php

@@ -0,0 +1,27 @@
+<?php
+
+require 'IO/SWF/Info.php';
+// require dirname(__FILE__).'/../IO/SWF/Info.php';
+
+$options = getopt("f:h");
+
+if (is_readable($options['f']) === false) {
+    echo "Usage: php swfdump.php -f <swf_file> [-h]\n";
+    echo "ex) php swfdump.php -f test.swf -h \n";
+    exit(1);
+}
+
+$swfdata = file_get_contents($options['f']);
+
+$swf = new IO_SWF_Info();
+
+$swf->parse($swfdata);
+
+$opts = array();
+if (isset($options['h'])) {
+    $opts['hexdump'] = true;
+}
+
+$swf->dump($opts);
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/sample/swfreplacebitmap.php

@@ -0,0 +1,37 @@
+<?php
+
+require_once 'IO/SWF/Editor.php';
+// require dirname(__FILE__).'/../IO/SWF/Editor.php';
+
+if (($argc != 4) && ($argc != 5)) {
+    echo "Usage: php swfreplacebitmap.php <swf_file> <bitmap_id> <bitmap_file> [<alpha_file>]\n";
+    echo "ex) php swfreplacebitmap.php test.swf 1 test.jpg test.alpha\n";
+    echo "ex) php swfreplacebitmap.php test.swf 1 test.png\n";
+    echo "ex) php swfreplacebitmap.php test.swf 1 test.git\n";
+    exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+assert(is_readable($argv[3]));
+
+$swfdata = file_get_contents($argv[1]);
+$bitmap_id = (int) $argv[2];
+$bitmapdata = file_get_contents($argv[3]);
+if (isset($argv[4])) { // with jpeg alphadata
+    assert(is_readable($argv[4]));
+    $jpeg_alphadata = file_get_contents($argv[4]);
+} else {
+    $jpeg_alphadata = null;
+}
+
+$swf = new IO_SWF_Editor();
+$swf->parse($swfdata);
+
+$swf->setCharacterId($swfdata);
+
+$ret = $swf->replaceBitmapData($bitmap_id, $bitmapdata, $jpeg_alphadata);
+
+echo $swf->build();
+
+exit(0);

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Former.php

@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * 2010/8/12- (c) yoya@awm.jp
+ */
+
+require_once dirname(__FILE__).'/../SWF.php';
+
+class IO_SWF_Former extends IO_SWF {
+    // var $_headers = array(); // protected
+    // var $_tags = array();    // protected
+
+    function form() {
+        foreach ($this->_tags as $idx => $tag) {
+            switch ($tag['Code']) {
+                case 26: // PlaceObject2
+                    $this->_form_26($tag);
+                    break;
+            }
+        }
+    }
+    function _form_26($tag) { // PlaceObject2
+        $reader = new IO_Bit();
+        $reader->input($tab['Content']);
+        $placeFlag = $reader->getUI8();
+        $depth = $reader->getUI16LE();
+        if ($placeFlag & 0x02) {
+            $characterId = $reader->getUI16LE();
+        }
+        //
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Info.php

@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * 2011/6/14 (c) yoya@awm.jp
+ */
+
+require_once dirname(__FILE__).'/../SWF.php';
+
+class IO_SWF_Info extends IO_SWF {
+    // var $_headers = array(); // protected
+    // var $_tags = array();    // protected
+    function dump($opts = array()) {
+        if (empty($opts['hexdump']) === false) {
+            $bitio = new IO_Bit();
+            $bitio->input($this->_swfdata);
+        }
+        /* SWF Header */
+        echo 'Signature: '.$this->_headers['Signature'].PHP_EOL;
+        echo 'Version: '.$this->_headers['Version'].PHP_EOL;
+        echo 'FileLength: '.$this->_headers['FileLength'].PHP_EOL;
+        echo 'FrameSize: '. IO_SWF_Type_RECT::string($this->_headers['FrameSize'])."\n";
+        echo 'FrameRate: '.($this->_headers['FrameRate'] / 0x100).PHP_EOL;
+        echo 'FrameCount: '.$this->_headers['FrameCount'].PHP_EOL;
+
+        if (empty($opts['hexdump']) === false) {
+            $bitio->hexdump(0, $this->_header_size);
+            $opts['bitio'] =& $bitio; // for tag
+        }
+
+        /* SWF Tags */
+
+        echo 'Tags:'.PHP_EOL;
+        foreach ($this->_tags as $tag) {
+    	    $tag->dump($opts);
+        }
+    }
+    function countShapeEdges($opts = array()) {
+        $count_table = array();
+        foreach ($this->_tags as $tag) {
+            $code = $tag->code;
+	    switch ($code) {
+	    case 2: // DefineShape
+	    case 22: // DefineShape2
+	    case 32: // DefineShape3
+	    case 46: // DefineMorphShape
+	      $shape = new IO_SWF_Tag_Shape();
+	      $opts = array('hasShapeId' => true);
+	      $shape->parseContent($code, $tag->content, $opts);
+	      list($shape_id, $edges_count) = $shape->countEdges();
+	      $count_table[$shape_id] = $edges_count;
+	    }
+	}
+	return $count_table;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Info.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag.php

@@ -0,0 +1,182 @@
+<?php
+
+require_once dirname(__FILE__).'/../SWF.php';
+require_once dirname(__FILE__).'/../SWF/Tag/Shape.php';
+
+class IO_SWF_Tag {
+    var $code = 0;
+    var $content = null;
+    var $tag = null;
+    var $byte_offset, $byte_size;
+    function getTagInfo($tagCode, $label) {
+        static $tagMap = array(
+         // code => array(name , klass)
+             0 => array('name' => 'End'),
+             1 => array('name' => 'ShowFrame'),
+             2 => array('name' => 'DefineShape',  'klass' => 'Shape'),
+//             3 => array('name' => 'FreeCharacter'), // ???
+             4 => array('name' => 'PlaceObject'),
+             5 => array('name' => 'RemoveObject'),
+             6 => array('name' => 'DefineBitsJPEG'),
+             7 => array('name' => 'DefineButton'),
+             8 => array('name' => 'JPEGTables'),
+             9 => array('name' => 'SetBackgroundColor', 'klass' => 'BGColor'),
+            10 => array('name' => 'DefineFont'),
+            11 => array('name' => 'DefineText'),
+            12 => array('name' => 'DoAction', 'klass' => 'Action'),
+            13 => array('name' => 'DefineFontInfo'),
+            14 => array('name' => 'DefineSound'),
+            15 => array('name' => 'StartSound'),
+            // 16 missing
+            17 => array('name' => 'DefineButtonSound'),
+            18 => array('name' => 'SoundStreamHead'),
+            19 => array('name' => 'SoundStreamBlock'),
+            20 => array('name' => 'DefineBitsLossless'),
+            21 => array('name' => 'DefineBitsJPEG2'),
+            22 => array('name' => 'DefineShape2', 'klass' => 'Shape'),
+            24 => array('name' => 'Protect'),
+            // 25 missing
+            26 => array('name' => 'PlaceObject2'),
+            // 27 missing
+            28 => array('name' => 'RemoveObject2'),
+            // 29,30,31 missing
+            32 => array('name' => 'DefineShape3', 'klass' => 'Shape'),
+            33 => array('name' => 'DefineText2'),
+            34 => array('name' => 'DefineButton2'),
+            35 => array('name' => 'DefineBitsJPEG3'),
+            36 => array('name' => 'DefineBitsLossless2'),
+            37 => array('name' => 'DefineEditText'),
+            // 38 missing
+            39 => array('name' => 'DefineSprite', 'klass' => 'Sprite'),
+            // 40,41,42 missing
+            43 => array('name' => 'FrameLabel'),
+            // 44 missing
+            45 => array('name' => 'SoundStreamHead2'),
+            46 => array('name' => 'DefineMorphShape', 'klass' => 'Shape'),
+//            46 => array('name' => 'DefineMorphShape'),
+            48 => array('name' => 'DefineFont2'),
+            56 => array('name' => 'Export'),
+            57 => array('name' => ''),
+            58 => array('name' => ''),
+            59 => array('name' => 'DoInitAction', 'klass' => 'Action'),
+            //
+            60 => array('name' => 'DefineVideoStream'),
+            61 => array('name' => 'videoFrame'),
+            62 => array('name' => 'DefineFontInfo2'),
+            // 63 missing
+            64 => array('name' => 'EnableDebugger2'),
+            65 => array('name' => 'ScriptLimits'),
+            66 => array('name' => 'SetTabIndex'),
+            // 67,68 missing
+            69 => array('name' => 'FileAttributes'),
+            70 => array('name' => 'PlaceObject3'),
+            71 => array('name' => 'ImportAssets2'),
+            // 72 missing
+            73 => array('name' => 'DefineFontAlignZones'),
+            74 => array('name' => 'CSMTextSettings'),
+            75 => array('name' => 'DefineFont3'),
+            76 => array('name' => 'SymbolClass'),
+            77 => array('name' => 'MetaData'),
+            78 => array('name' => 'DefineScalingGrid'),
+            // 79,80,81 missing
+            82 => array('name' => 'DoABC'),
+            83 => array('name' => 'DefineShape4'),
+            84 => array('name' => 'DefineMorphShape2'),
+            // 85 missing
+            86 => array('name' => 'DefineSceneAndFrameLabelData'),
+            87 => array('name' => 'DefineBinaryData'),
+            88 => array('name' => 'DefineFontName'),
+            89 => array('name' => 'StartSound2'),
+            90 => array('name' => 'DefineBitsJPEG4'),
+            91 => array('name' => 'DefineFont4'),
+            777 => array('name' => 'Reflex'), // swftools ?
+        );
+        if (isset($tagMap[$tagCode][$label])) {
+           return $tagMap[$tagCode][$label];
+        }
+        return false;
+    }
+    function parse(&$reader, $opts = array()) {
+        list($this->byte_offset, $dummy) = $reader->getOffset();
+        $tagAndLength = $reader->getUI16LE();
+        $this->code = $tagAndLength >> 6;
+        $length = $tagAndLength & 0x3f;
+        if ($length == 0x3f) { // long format
+            $length = $reader->getUI32LE();
+        }
+        $this->content = $reader->getData($length);
+        list($byte_offset, $dummy) = $reader->getOffset();
+        $this->byte_size = $byte_offset - $this->byte_offset;
+    }
+    function dump($opts = array()) {
+        $code = $this->code;
+        $name = $this->getTagInfo($code, 'name');
+        if ($name === false) {
+           $name = 'unknown';
+        }
+        $length = strlen($this->content);
+        echo "Code: $code($name)  Length: $length".PHP_EOL;
+        if ($this->parseTagContent()) {
+            $this->tag->dumpContent($code);
+        }
+        if (empty($opts['hexdump']) === false) {
+           $bitio =& $opts['bitio'];
+           $bitio->hexdump($this->byte_offset, $this->byte_size);
+        }
+    }
+    function build($opts = array()) {
+        $code = $this->code;
+        $content = $this->content;
+        $length = strlen($this->content);
+        $writer = new IO_Bit();
+        switch ($code) {
+          case 6:  // DefineBitsJPEG
+          case 21: // DefineBitsJPEG2
+          case 35: // DefineBitsJPEG3
+          case 20: // DefineBitsLossless
+          case 36: // DefineBitsLossless2
+          case 19: // SoundStreamBlock
+            $longFormat = true;
+            break;
+          default:
+            $longFormat = false;
+            break;
+        }
+        if (($longFormat === false) && ($length < 0x3f)) {
+            $tagAndLength = ($code << 6) | $length;
+            $writer->putUI16LE($tagAndLength);
+        } else {
+            $tagAndLength = ($code << 6) | 0x3f;
+            $writer->putUI16LE($tagAndLength);
+            $writer->putUI32LE($length);
+        }
+        return $writer->output() . $this->buildTagContent();
+    }
+    function parseTagContent() {
+        if (is_null($this->tag) === false) {
+            return true;
+        }
+        $code = $this->code;
+        $klass = self::getTagInfo($code, 'klass');
+        if ($klass === false) {
+            return false; // no parse
+        }
+        require_once dirname(__FILE__)."/Tag/$klass.php";
+        $klass = "IO_SWF_Tag_$klass";
+        $obj = new $klass();
+        $obj->parseContent($code, $this->content);
+        $this->tag = $obj;
+        return true;
+    }
+    function buildTagContent() {
+            if ((is_null($this->content) === false)) {
+            return $this->content;
+        }
+        if (is_null($this->tag)) {
+            return false; // throw Exception!
+        }
+        $code = $this->code;
+        $this->content = $this->tag->buildContent($code, $this->content);
+        return $this->content;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RGB.php

@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+
+class IO_SWF_Type_RGB extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+    	$rgb = array();
+    	$rgb['Red'] = $reader->getUI8();
+    	$rgb['Green'] = $reader->getUI8();
+    	$rgb['Blue'] = $reader->getUI8();
+    	return $rgb;
+    }
+    static function build(&$writer, $rgb, $opts = array()) {
+    	$writer->putUI8($rgb['Red']);
+    	$writer->putUI8($rgb['Green']);
+    	$writer->putUI8($rgb['Blue']);
+    }
+    static function string($color, $opts = array()) {
+    	return sprintf("#%02x%02x%02x", $color['Red'], $color['Green'], $color['Blue']);
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RGB.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RGBA.php

@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+
+class IO_SWF_Type_RGBA extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+    	$rgba = array();
+    	$rgba['Red'] = $reader->getUI8();
+    	$rgba['Green'] = $reader->getUI8();
+    	$rgba['Blue'] = $reader->getUI8();
+    	$rgba['Alpha'] = $reader->getUI8();
+    	return $rgba;
+    }
+    static function build(&$writer, $rgba, $opts = array()) {
+    	$writer->putUI8($rgba['Red']);
+	    $writer->putUI8($rgba['Green']);
+    	$writer->putUI8($rgba['Blue']);
+    	$writer->putUI8($rgba['Alpha']);
+    }
+    static function string($color, $opts = array()) {
+    	return sprintf("#%02x%02x%02x(%02x)", $color['Red'], $color['Green'], $color['Blue'], $color['Alpha']);
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RGBA.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/Action.php

@@ -0,0 +1,291 @@
+<?php
+
+/*
+ * 2011/06/03- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/String.php';
+
+class IO_SWF_Type_Action extends IO_SWF_Type {
+    static $action_code_table = array(
+        // Opecode only
+        0x04 => 'ActionNextFrame',
+        0x05 => 'ActionPreviousFrame',
+        0x06 => 'ActionPlay',
+        0x07 => 'ActionStop',
+        0x08 => 'ActionToggleQuality',
+        0x09 => 'ActionStopSounds',
+        //
+        0x0A => 'ActionAdd',
+        0x0B => 'ActionSubstract',
+        0x0C => 'ActionMultiply',
+        0x0D => 'ActionDivide',
+        0x0E => 'ActionEquals',
+        0x0F => 'ActionLess',
+        0x10 => 'ActionAnd',
+        0x11 => 'ActionOr',
+        0x12 => 'ActionNot',
+        0x13 => 'ActionStringEquals',
+        0x14 => 'ActionStringLength',
+        0x15 => 'ActionStringExtract',
+        //
+        0x17 => 'ActionPop',
+        0x18 => 'ActionToInteger',
+        //
+        0x1C => 'ActionGetVariable',
+        0x1D => 'ActionSetVariable',
+        //
+        0x20 => 'ActionSetTarget2',
+        0x21 => 'ActionStringAdd',
+        0x22 => 'ActionGetProperty',
+        0x23 => 'ActionSetProperty',
+        0x24 => 'ActionCloneSprite',
+        0x25 => 'ActionRemoveSprite',
+        0x26 => 'ActionTrace',
+        //
+        0x27 => 'ActionStartDrag',
+        0x28 => 'ActionEndDrag',
+        0x29 => 'ActionStringLess',
+        //
+        0x30 => 'ActionRandomNumber',
+        0x31 => 'ActionMBStringLength',
+        0x32 => 'ActionCharToAscii',
+        0x33 => 'ActionAsciiToChar',
+        0x34 => 'ActionGetTime',
+        0x35 => 'ActionMBStringExtract',
+        0x36 => 'ActionMBCharToAscii',
+        0x37 => 'ActionMBAsciiToChar',
+
+        //
+        // has Operand
+        0x81 => 'ActionGotoFrame',
+        0x83 => 'ActionGetURL',
+        0x88 => 'ActionConstantPool',
+        0x8A => 'ActionWaitForFrame',
+        0x8B => 'ActionSetTarget',
+        0x8C => 'ActionGoToLabel',
+        0x8D => 'ActionWaitForFrame2',
+        0x96 => 'ActionPush',
+        //
+        0x99 => 'ActionJump',
+        0x9A => 'ActionGetURL2',
+        //
+        0x9D => 'ActionIf',
+        0x9E => 'ActionCall', // why it >=0x80 ?
+        0x9E => 'ActionGotoFrame2',
+        );
+    static function getCodeName($code) {
+        if (isset(self::$action_code_table[$code])) {
+            return self::$action_code_table[$code];
+        } else {
+            return "Unknown";
+        }
+    }
+    static function parse(&$reader, $opts = array()) {
+    	$action = array();
+        $code = $reader->getUI8();
+        $action['Code'] = $code;
+        if ($code >= 0x80) {
+            $length = $reader->getUI16LE();
+            $action['Length'] = $length;
+            switch ($code) {
+            case 0x81: // ActionGotoFrame
+                $action['Frame'] = $reader->getUI16LE();
+                break;
+            case 0x83: // ActionGetURL
+                $data = $reader->getData($length);
+                $strs = explode("\0", $data);
+                $action['UrlString'] = $strs[0];
+                $data = $reader->getData($length);
+                $strs = explode("\0", $data, 2+1);
+                $action['UrlString'] = $strs[0];
+                $action['TargetString'] = $strs[1];
+                break;
+            case 0x88: // ActionConstantPool
+                $count = $reader->getUI16LE();
+                $action['Count'] = $count;
+                $data = $reader->getData($length - 2);
+                $strs = explode("\0", $data, $count+1);
+                $action['ConstantPool'] = array_splice($strs, 0, $count);
+                break;
+            case 0x8A: // ActionWaitForFrame
+                $action['Frame'] = $reader->getUI16LE();
+                $action['SkipCount'] = $reader->getUI8();
+                break;
+            case 0x8B: // ActionSetTarget
+                $data = $reader->getData($length);
+                $strs = explode("\0", $data, 1+1);
+                $action['TargetName'] = $strs[0];
+                break;
+            case 0x8C: // ActionSetTarget
+                $data = $reader->getData($length);
+                $strs = explode("\0", $data, 1+1);
+                $action['Label'] = $strs[0];
+                break;
+            case 0x8D: // ActionWaitForFrame2
+                $action['Frame'] = $reader->getUI16LE();
+                $action['SkipCount'] = $reader->getUI8();
+                break;
+            case 0x96: // ActionPush
+                $type = $reader->getUI8();
+                $action['Type'] = $type;
+                switch ($type) {
+                case 0: // STRING
+                    $action['String'] = IO_SWF_Type_String::parse($reader);
+                    break;
+                default:
+                    $action['Data'] = $reader->getData($length - 1);
+                    break;
+                }
+                break;
+            case 0x99: // ActionJump
+                $action['BranchOffset'] = $reader->getSI16LE();
+                break;
+            case 0x9A: // ActionGetURL2
+                $action['SendVarsMethod'] = $reader->getUIBits(2);
+                $action['(Reserved)'] = $reader->getUIBits(4);
+                $action['LoadTargetFlag'] = $reader->getUIBit();
+                $action['LoadVariablesFlag'] = $reader->getUIBit();
+            case 0x9D: // ActionIf
+                $action['Offset'] = $reader->getSI16LE();
+                break;
+            case 0x9F: // ActionGotoFrame2
+                $action['(Reserved)'] = $reader->getUIBits(6);
+                $sceneBlasFlag = $reader->getUIBit();
+                $action['SceneBlasFlag'] = $sceneBlasFlag;
+                $action['PlayFlag'] =  $reader->getUIBit();
+                if ($sceneBlasFlag) {
+                    $action['SceneBias'] = $reader->getUI16LE();
+                }
+            default:
+                $action['Data'] =  $reader->getData($length);
+                break;
+            }
+        }
+    	return $action;
+    }
+    static function build(&$writer, $action, $opts = array()) {
+        $code = $action['Code'];
+    	$writer->putUI8($code);
+        if (0x80 <= $code) {
+            switch ($code) {
+            case 0x81: // ActionGotoFrame
+                $writer->putUI16LE(2);
+                $writer->putUI16LE($action['Frame']);
+                break;
+            case 0x83: // ActionGetURL
+                $data = $action['UrlString']."\0".$action['TargetString']."\0";
+                $writer->putUI16LE(strlen($data));
+                $writer->putData($data);
+                break;
+            case 0x88: // ActionConstantPool
+                $count = count($action['ConstantPool']);
+                $data = implode("\0", $action['ConstantPool'])."\0";
+                $writer->putUI16LE(strlen($data) + 2);
+                $writer->putUI16LE($count);
+                $writer->putData($data);
+                break;
+            case 0x8A: // ActionWaitForFrame
+                $writer->putUI16LE($action['Frame']);
+                $writer->putUI8($action['SkipCount']);
+                break;
+            case 0x8B: // ActionSetTarget
+                $data = $action['TargetName']."\0";
+                $writer->putUI16LE(strlen($data));
+                $writer->putData($data);
+                break;
+            case 0x8C: // ActionGoToLabel
+                $data = $action['Label']."\0";
+                $writer->putUI16LE(strlen($data));
+                $writer->putData($data);
+                break;
+            case 0x8D: // ActionWaitForFrame2
+                $writer->putUI16LE($action['Frame']);
+                $writer->putUI8($action['SkipCount']);
+                break;
+            case 0x96: // ActionPush
+                $type = $action['Type'];
+                switch ($type) {
+                case 0: // STRING
+                    $str = $action['String'];
+                    $pos = strpos($str, "\0");
+                    if ($pos === false) {
+                        $str .= "\0";
+                    } else {
+                        $length = $pos + 1;
+                        $str = substr($str, 0, $pos);
+                    }
+                    $writer->putUI16LE(1 + strlen($str));
+                    $writer->putUI8($type);
+                    $writer->putData($str);
+                    break;
+                default:
+                    $writer->putUI16LE(1 + strlen($action['Data']));
+                    $writer->putUI8($type);
+                    $writer->putData($action['Data']);
+                    break;
+                }
+                break;
+            case 0x99: // ActionJump
+                $writer->putUI16LE(2);
+                $writer->putSI16LE($action['BranchOffset']);
+                break;
+            case 0x9A: // ActionGetURL2
+                $writer->putUI16LE(1);
+                $writer->putUIBits($action['SendVarsMethod'], 2);
+                $writer->putUIBits(0, 4); // Reserved
+                $writer->putUIBit($action['LoadTargetFlag']);
+                $writer->putUIBit($action['LoadVariablesFlag']);
+            case 0x9D: // ActionIf
+                $writer->putUI16LE(2);
+                $writer->putSI16LE($action['Offset']);
+                break;
+            case 0x9F: // ActionGotoFrame2
+                if (isset($action['SceneBias'])) {
+                    $sceneBlasFlag = 1;
+                    $writer->putUI16LE(3);
+                } else {
+                    $sceneBlasFlag = 0;
+                    $writer->putUI16LE(1);
+                }
+                $writer->putUIBits(0, 6); // Reserved
+                $writer->putUIBit($sceneBlasFlag);
+                $writer->putUIBit($action['PlayFlag']);
+                if ($sceneBlasFlag) {
+                    $writer->putUI16LE($action['SceneBias']);
+                }
+            default:
+                $data = $action['Data'];
+                $writer->putUI16LE(strlen($data));
+                $writer->putData($data);
+                break;
+            }
+        }
+    }
+    static function string($action, $opts = array()) {
+        $code = $action['Code'];
+    	$str = sprintf('%s(Code=0x%02X)', self::getCodeName($code), $code);
+        if (isset($action['Length'])) {
+            $str .= sprintf(" (Length=%d):", $action['Length']);
+            $str .= PHP_EOL."\t";
+            switch ($code) {
+            case 0x88: // ActonConstantPool
+                $str .= " Count=".$action['Count'].PHP_EOL;
+                foreach ($action['ConstantPool'] as $idx => $c) {
+                    $str .= "\t[$idx] $c".PHP_EOL;
+                }
+                break;
+            default:
+                $data_keys = array_diff(array_keys($action), array('Code', 'Length'));
+                foreach ($data_keys as $key) {
+                    $value = $action[$key];
+                    $str .= "   " ."$key=$value";
+                }
+                break;
+            }
+        }
+        return $str;
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RECT.php

@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+
+class IO_SWF_Type_RECT extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $frameSize = array();
+        $reader->byteAlign();
+        $nBits = $reader->getUIBits(5);
+        $frameSize['Xmin'] = $reader->getSIBits($nBits);
+        $frameSize['Xmax'] = $reader->getSIBits($nBits);
+        $frameSize['Ymin'] = $reader->getSIBits($nBits);
+        $frameSize['Ymax'] = $reader->getSIBits($nBits) ;
+    	return $frameSize;
+    }
+    static function build(&$writer, $frameSize, $opts = array()) {
+        $nBits = 0;
+    	foreach ($frameSize as $size) {
+	        if ($size == 0){
+	            $bits = 0;
+    	    } else {
+	            $bits = $writer->need_bits_signed($size);
+	        }
+    	    $nBits = max($nBits, $bits);
+    	}
+        $writer->byteAlign();
+	    $writer->putUIBits($nBits, 5);
+        $writer->putSIBits($frameSize['Xmin'], $nBits);
+        $writer->putSIBits($frameSize['Xmax'], $nBits);
+        $writer->putSIBits($frameSize['Ymin'], $nBits);
+        $writer->putSIBits($frameSize['Ymax'], $nBits);
+    }
+    static function string($rect, $opts = array()) {
+        return "Xmin: ".($rect['Xmin'] / 20).
+               " Xmax: ".($rect['Xmax'] / 20).
+               " Ymin: ".($rect['Ymin'] / 20).
+               " Ymax: ".($rect['Ymax'] / 20);
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/RECT.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/SHAPE.php

@@ -0,0 +1,330 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/../Type/FILLSTYLEARRAY.php';
+require_once dirname(__FILE__).'/../Type/LINESTYLEARRAY.php';
+
+class IO_SWF_Type_SHAPE extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $shapeRecords = array();
+
+    	$reader->byteAlign();
+    	// 描画スタイルを参照するインデックスのビット幅
+    	$numFillBits = $reader->getUIBits(4);
+	    $numLineBits = $reader->getUIBits(4);
+
+    	$currentDrawingPositionX = 0;
+    	$currentDrawingPositionY = 0;
+    	$currentFillStyle0 = 0;
+    	$currentFillStyle1 = 0;
+    	$currentLineStyle = 0;
+    	$done = false;
+
+    	// ShapeRecords
+    	while ($done === false) {
+    	    $shapeRecord = array();
+            $typeFlag = $reader->getUIBit();
+            $shapeRecord['TypeFlag'] = $typeFlag;
+            if ($typeFlag == 0) {
+                $endOfShape = $reader->getUIBits(5);
+               if ($endOfShape == 0) {
+                    // EndShapeRecord
+                    $shapeRecord['EndOfShape'] = $endOfShape;
+                    $done = true;
+               } else {
+                    // StyleChangeRecord
+                    $reader->incrementOffset(0, -5);
+                    $stateNewStyles = $reader->getUIBit();
+                    $stateLineStyle = $reader->getUIBit();
+                    $stateFillStyle1 = $reader->getUIBit();
+                    $stateFillStyle0 = $reader->getUIBit();
+
+                    $stateMoveTo = $reader->getUIBit();
+                    if ($stateMoveTo) {
+                    $moveBits = $reader->getUIBits(5);
+//                        $shapeRecord['(MoveBits)'] = $moveBits;
+                        $moveDeltaX = $reader->getSIBits($moveBits);
+                        $moveDeltaY = $reader->getSIBits($moveBits);
+//                        $currentDrawingPositionX += $moveDeltaX;
+//                        $currentDrawingPositionY += $moveDeltaY;
+                        $currentDrawingPositionX = $moveDeltaX;
+                        $currentDrawingPositionY = $moveDeltaY;
+                        $shapeRecord['MoveX'] = $currentDrawingPositionX;
+                        $shapeRecord['MoveY'] = $currentDrawingPositionY;
+                    }
+                    $shapeRecord['MoveX'] = $currentDrawingPositionX;
+                    $shapeRecord['MoveY'] = $currentDrawingPositionY;
+
+                    if ($stateFillStyle0) {
+                        $currentFillStyle0 = $reader->getUIBits($numFillBits);
+                    }
+                    if ($stateFillStyle1) {
+                        $currentFillStyle1 = $reader->getUIBits($numFillBits);
+                    }
+                    if ($stateLineStyle) {
+                        $currentLineStyle = $reader->getUIBits($numLineBits);
+                    }
+                    $shapeRecord['FillStyle0'] = $currentFillStyle0;
+                    $shapeRecord['FillStyle1'] = $currentFillStyle1;
+                    $shapeRecord['LineStyle']  = $currentLineStyle;
+                    if ($stateNewStyles) {
+                        $opts = array('tagCode' => $tagCode);
+                        $shapeRecord['FillStyles'] = IO_SWF_TYPE_FILLSTYLEARRAY::parse($reader, $opts);
+                        $shapeRecord['LineStyles'] = IO_SWF_TYPE_LINESTYLEARRAY::parse($reader, $opts);
+                        $reader->byteAlign();
+                        $numFillBits = $reader->getUIBits(4);
+                        $numLineBits = $reader->getUIBits(4);
+                    }
+                }
+            } else { // Edge records
+                $shapeRecord['StraightFlag'] = $reader->getUIBit();
+                if ($shapeRecord['StraightFlag']) {
+                    // StraightEdgeRecord
+                    $numBits = $reader->getUIBits(4);
+//                    $shapeRecord['(NumBits)'] = $numBits;
+                     $generalLineFlag = $reader->getUIBit();
+                    if ($generalLineFlag == 0) {
+                        $vertLineFlag = $reader->getUIBit();
+                    }
+                    if ($generalLineFlag || ($vertLineFlag == 0)) {
+                        $deltaX = $reader->getSIBits($numBits + 2);
+                        $currentDrawingPositionX += $deltaX;
+                    }
+                    if ($generalLineFlag || $vertLineFlag) {
+                        $deltaY = $reader->getSIBits($numBits + 2);
+                        $currentDrawingPositionY += $deltaY;
+                    }
+                    $shapeRecord['X'] = $currentDrawingPositionX;
+                    $shapeRecord['Y'] = $currentDrawingPositionY;
+                } else {
+                    // CurvedEdgeRecord
+                    $numBits = $reader->getUIBits(4);
+//                    $shapeRecord['(NumBits)'] = $numBits;
+
+                    $controlDeltaX = $reader->getSIBits($numBits + 2);
+                    $controlDeltaY = $reader->getSIBits($numBits + 2);
+                    $anchorDeltaX = $reader->getSIBits($numBits + 2);
+                    $anchorDeltaY = $reader->getSIBits($numBits + 2);
+
+                    $currentDrawingPositionX += $controlDeltaX;
+                    $currentDrawingPositionY += $controlDeltaY;
+                    $shapeRecord['ControlX'] = $currentDrawingPositionX;
+                    $shapeRecord['ControlY'] = $currentDrawingPositionY;
+
+                    $currentDrawingPositionX += $anchorDeltaX;
+                    $currentDrawingPositionY += $anchorDeltaY;
+                    $shapeRecord['AnchorX'] = $currentDrawingPositionX;
+                    $shapeRecord['AnchorY'] = $currentDrawingPositionY;
+                }
+            }
+            $shapeRecords []= $shapeRecord;
+       }
+    	return $shapeRecords;
+    }
+    static function build(&$writer, $shapeRecords, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $fillStyleCount = $opts['fillStyleCount'];
+        $lineStyleCount = $opts['lineStyleCount'];
+        if ($fillStyleCount == 0) {
+            $numFillBits = 0;
+        } else {
+            // $fillStyleCount == fillStyle MaxValue because 'undefined' use 0
+            $numFillBits = $writer->need_bits_unsigned($fillStyleCount);
+        }
+        if ($lineStyleCount == 0) {
+            $numLineBits = 0;
+        } else {
+            // $lineStyleCount == lineStyle MaxValue because 'undefined' use 0
+            $numLineBits = $writer->need_bits_unsigned($lineStyleCount);
+        }
+
+        $writer->byteAlign();
+        $writer->putUIBits($numFillBits, 4);
+        $writer->putUIBits($numLineBits, 4);
+        $currentDrawingPositionX = 0;
+        $currentDrawingPositionY = 0;
+        $currentFillStyle0 = 0;
+        $currentFillStyle1 = 0;
+        $currentLineStyle = 0;
+        foreach ($shapeRecords as $shapeRecordIndex => $shapeRecord) {
+            $typeFlag = $shapeRecord['TypeFlag'];
+            $writer->putUIBit($typeFlag);
+            if($typeFlag == 0) {
+                if (isset($shapeRecord['EndOfShape']) && ($shapeRecord['EndOfShape']) == 0) {
+                    // EndShapeRecord
+                    $writer->putUIBits(0, 5);
+                } else {
+                    // StyleChangeRecord
+                    $stateNewStyles =  isset($shapeRecord['FillStyles'])?1:0;
+                    $stateLineStyle = ($shapeRecord['LineStyle'] != $currentLineStyle)?1:0;
+                    $stateFillStyle1 = ($shapeRecord['FillStyle1'] != $currentFillStyle1)?1:0;
+                    $stateFillStyle0 = ($shapeRecord['FillStyle0'] != $currentFillStyle0)?1:0;
+
+                    $writer->putUIBit($stateNewStyles);
+                    $writer->putUIBit($stateLineStyle);
+                    $writer->putUIBit($stateFillStyle1);
+                    $writer->putUIBit($stateFillStyle0);
+
+                    if (($shapeRecord['MoveX'] != $currentDrawingPositionX) || ($shapeRecord['MoveY'] != $currentDrawingPositionY)) {
+                        $stateMoveTo = true;
+                    } else {
+                        $stateMoveTo = false;
+                    }
+                    $writer->putUIBit($stateMoveTo);
+                    if ($stateMoveTo) {
+                        $moveX = $shapeRecord['MoveX'];
+                        $moveY = $shapeRecord['MoveY'];
+                        $currentDrawingPositionX = $moveX;
+                        $currentDrawingPositionY = $moveY;
+                        if ($moveX | $moveY) {
+                            $XmoveBits = $writer->need_bits_signed($moveX);
+                            $YmoveBits = $writer->need_bits_signed($moveY);
+                            $moveBits = max($XmoveBits, $YmoveBits);
+                        } else {
+                            $moveBits = 0;
+                        }
+                        $writer->putUIBits($moveBits, 5);
+                        $writer->putSIBits($moveX, $moveBits);
+                        $writer->putSIBits($moveY, $moveBits);
+                    }
+                    if ($stateFillStyle0) {
+                        $currentFillStyle0 = $shapeRecord['FillStyle0'];
+                        $writer->putUIBits($currentFillStyle0, $numFillBits);
+                    }
+                    if ($stateFillStyle1) {
+                        $currentFillStyle1 = $shapeRecord['FillStyle1'];
+                        $writer->putUIBits($currentFillStyle1, $numFillBits);
+                    }
+                    if ($stateLineStyle) {
+                        $currentLineStyle = $shapeRecord['LineStyle'];
+                        $writer->putUIBits($currentLineStyle, $numLineBits);
+                    }
+                    if ($stateNewStyles) {
+                        $opts = array('tagCode' => $tagCode);
+                        IO_SWF_Type_FILLSTYLEARRAY::build($writer, $shapeRecord['FillStyles'], $opts);
+                        IO_SWF_Type_LINESTYLEARRAY::build($writer, $shapeRecord['LineStyles'], $opts);
+                        $fillStyleCount = count($shapeRecord['FillStyles']);
+                        if ($fillStyleCount == 0) {
+                            $numFillBits = 0;
+                        } else {
+                            // $fillStyleCount == fillStyle MaxValue because 'undefined' use 0
+                            $numFillBits = $writer->need_bits_unsigned($fillStyleCount);
+                        }
+                        if ($lineStyleCount == 0) {
+                            $numLineBits = 0;
+                        } else {
+                            // $lineStyleCount == lineStyle MaxValue because 'undefined' use 0
+                            $numLineBits = $writer->need_bits_unsigned($lineStyleCount);
+                        }
+                        $writer->byteAlign();
+                        $writer->putUIBits($numFillBits, 4);
+                        $writer->putUIBits($numLineBits, 4);
+                    }
+                }
+            } else {
+                $straightFlag = $shapeRecord['StraightFlag'];
+                $writer->putUIBit($straightFlag);
+                if ($straightFlag) {
+                    $deltaX = $shapeRecord['X'] - $currentDrawingPositionX;
+                    $deltaY = $shapeRecord['Y'] - $currentDrawingPositionY;
+                    if ($deltaX | $deltaY) {
+                       $XNumBits = $writer->need_bits_signed($deltaX);
+                       $YNumBits = $writer->need_bits_signed($deltaY);
+                       $numBits = max($XNumBits, $YNumBits);
+                    } else {
+                        $numBits = 0;
+                    }
+                    if ($numBits < 2) {
+                        $numBits = 2;
+                    }
+                    $writer->putUIBits($numBits - 2, 4);
+                    if ($deltaX && $deltaY) {
+                        $writer->putUIBit(1); // GeneralLineFlag
+                        $writer->putSIBits($deltaX, $numBits);
+                        $writer->putSIBits($deltaY, $numBits);
+                    } else {
+                        $writer->putUIBit(0); // GeneralLineFlag
+                        if ($deltaX) {
+                           $writer->putUIBit(0); // VertLineFlag
+                           $writer->putSIBits($deltaX, $numBits);
+                        } else {
+                           $writer->putUIBit(1); // VertLineFlag
+                           $writer->putSIBits($deltaY, $numBits);
+                        }
+                    }
+                    $currentDrawingPositionX = $shapeRecord['X'];
+                    $currentDrawingPositionY = $shapeRecord['Y'];
+                } else {
+                    $controlDeltaX = $shapeRecord['ControlX'] - $currentDrawingPositionX;
+                    $controlDeltaY = $shapeRecord['ControlY'] - $currentDrawingPositionY;
+                    $currentDrawingPositionX = $shapeRecord['ControlX'];
+                    $currentDrawingPositionY = $shapeRecord['ControlY'];
+                    $anchorDeltaX = $shapeRecord['AnchorX'] - $currentDrawingPositionX;
+                    $anchorDeltaY = $shapeRecord['AnchorY'] - $currentDrawingPositionY;
+                    $currentDrawingPositionX = $shapeRecord['AnchorX'];
+                    $currentDrawingPositionY = $shapeRecord['AnchorY'];
+
+                    $numBitsControlDeltaX = $writer->need_bits_signed($controlDeltaX);
+                    $numBitsControlDeltaY = $writer->need_bits_signed($controlDeltaY);
+                    $numBitsAnchorDeltaX = $writer->need_bits_signed($anchorDeltaX);
+                    $numBitsAnchorDeltaY = $writer->need_bits_signed($anchorDeltaY);
+                    $numBits = max($numBitsControlDeltaX, $numBitsControlDeltaY, $numBitsAnchorDeltaX, $numBitsAnchorDeltaY);
+                    if ($numBits < 2) {
+                       $numBits = 2;
+                    }
+                    $writer->putUIBits($numBits - 2, 4);
+                    $writer->putSIBits($controlDeltaX, $numBits);
+                    $writer->putSIBits($controlDeltaY, $numBits);
+                    $writer->putSIBits($anchorDeltaX, $numBits);
+                    $writer->putSIBits($anchorDeltaY, $numBits);
+                }
+            }
+        }
+        return true;
+    }
+    static function string($shapeRecords, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        foreach ($shapeRecords as $shapeRecord) {
+            $typeFlag = $shapeRecord['TypeFlag'];
+            if ($typeFlag == 0) {
+               if (isset($shapeRecord['EndOfShape'])) {
+                   break;
+               } else {
+                   $moveX = $shapeRecord['MoveX'] / 20;
+                   $moveY = $shapeRecord['MoveY'] / 20;
+                   echo "\tChangeStyle: MoveTo: ($moveX, $moveY)";
+                   $style_list = array('FillStyle0', 'FillStyle1', 'LineStyle');
+                   echo "  FillStyle: ".$shapeRecord['FillStyle0']."|".$shapeRecord['FillStyle1'];
+                   echo "  LineStyle: ".$shapeRecord['LineStyle']."\n";
+                   if (isset($shapeRecord['FillStyles'])) {
+                       echo "    FillStyles:\n";
+                       echo IO_SWF_Type_FILLSTYLEARRAY::string($shapeRecord['FillStyles'], $opts);
+                   }
+                   if (isset($shapeRecord['LineStyles'])) {
+                        echo "    LineStyles:\n";
+                        echo IO_SWF_Type_FILLSTYLEARRAY::string($shapeRecord['LineStyles'], $opts);
+                   }
+               }
+            } else {
+                $straightFlag = $shapeRecord['StraightFlag'];
+                if ($straightFlag) {
+                    $x = $shapeRecord['X'] / 20;
+                    $y = $shapeRecord['Y'] / 20;
+                    echo "\tStraightEdge: MoveTo: ($x, $y)\n";
+                } else {
+                    $controlX = $shapeRecord['ControlX'] / 20;
+                    $controlY = $shapeRecord['ControlY'] / 20;
+                    $anchorX = $shapeRecord['AnchorX'] / 20;
+                    $anchorY = $shapeRecord['AnchorY'] / 20;
+                    echo "\tCurvedEdge: MoveTo: Control($controlX, $controlY) Anchor($anchorX, $anchorY)\n";
+                }
+            }
+        }
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/SHAPE.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/MATRIX.php

@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+
+class IO_SWF_Type_MATRIX extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+    	$matrix = array();
+
+        $reader->byteAlign();
+        $hasScale = $reader->getUIBit();
+    	if ($hasScale) {
+    	    $nScaleBits = $reader->getUIBits(5);
+//  	    $matrix['(NScaleBits)'] = $nScaleBits;
+    	    $matrix['ScaleX'] = $reader->getSIBits($nScaleBits);
+    	    $matrix['ScaleY'] = $reader->getSIBits($nScaleBits);
+    	} else {
+    	    $matrix['ScaleX'] = 20;
+    	    $matrix['ScaleY'] = 20;
+    	}
+        $hasRotate = $reader->getUIBit();
+    	if ($hasRotate) {
+    	    $nRotateBits = $reader->getUIBits(5);
+//	        $matrix['(NRotateBits)'] = $nRotateBits;
+    	    $matrix['RotateSkew0'] = $reader->getSIBits($nRotateBits);
+    	    $matrix['RotateSkew1'] = $reader->getSIBits($nRotateBits);
+    	} else  {
+    	    $matrix['RotateSkew0'] = 0;
+    	    $matrix['RotateSkew1'] = 0;
+    	}
+        $nTranslateBits = $reader->getUIBits(5);
+    	$matrix['TranslateX'] = $reader->getSIBits($nTranslateBits);
+    	$matrix['TranslateY'] = $reader->getSIBits($nTranslateBits);
+    	return $matrix;
+    }
+    static function build(&$writer, $matrix, $opts = array()) {
+//        $writer->byteAlign();
+        if ($matrix['ScaleX'] | $matrix['ScaleY']) {
+	        $writer->putUIBit(1); // HasScale;
+    	    if ($matrix['ScaleX'] | $matrix['ScaleY']) {
+    	        $xNBits = $writer->need_bits_signed($matrix['ScaleX']);
+    	        $yNBits = $writer->need_bits_signed($matrix['ScaleY']);
+    	        $nScaleBits = max($xNBits, $yNBits);
+    	    } else {
+    	        $nScaleBits = 0;
+    	    }
+    	    $writer->putUIBits($nScaleBits, 5);
+    	    $writer->putSIBits($matrix['ScaleX'], $nScaleBits);
+    	    $writer->putSIBits($matrix['ScaleY'], $nScaleBits);
+       	} else {
+    	    $writer->putUIBit(0); // HasScale;
+       	}
+    	if ($matrix['RotateSkew0'] | $matrix['RotateSkew1']) {
+    	    $writer->putUIBit(1); // HasRotate
+    	    if ($matrix['RotateSkew0'] | $matrix['RotateSkew1']) {
+    	        $rs0NBits = $writer->need_bits_signed($matrix['RotateSkew0']);
+    	        $rs1NBits = $writer->need_bits_signed($matrix['RotateSkew1']);
+    	        $nRotateBits = max($rs0NBits, $rs1NBits);
+    	    } else {
+	            $nRotateBits = 0;
+    	    }
+    	    $writer->putUIBits($nRotateBits, 5);
+    	    $writer->putSIBits($matrix['RotateSkew0'], $nRotateBits);
+    	    $writer->putSIBits($matrix['RotateSkew1'], $nRotateBits);
+    	} else {
+    	    $writer->putUIBit(0); // HasRotate
+        }
+    	if ($matrix['TranslateX'] | $matrix['TranslateY']) {
+    	    $xNTranslateBits = $writer->need_bits_signed($matrix['TranslateX']);
+    	    $yNTranslateBits = $writer->need_bits_signed($matrix['TranslateY']);
+    	    $nTranslateBits = max($xNTranslateBits, $yNTranslateBits);
+    	} else {
+    	    $nTranslateBits = 0;
+    	}
+    	$writer->putUIBits($nTranslateBits, 5);
+    	$writer->putSIBits($matrix['TranslateX'], $nTranslateBits);
+    	$writer->putSIBits($matrix['TranslateY'], $nTranslateBits);
+    }
+
+    static function string($matrix, $opts = array()) {
+        $indent = 0;
+        if (isset($opts['indent'])) {
+            $indent = $opts['indent'];
+        }
+	   $text_fmt = <<< EOS
+%s| %3.3f %3.3f |  %3.2f
+%s| %3.3f %3.3f |  %3.2f
+EOS;
+	return 	sprintf($text_fmt,
+		str_repeat("\t", $indent),
+		$matrix['ScaleX'] / 0x10000 / 20,
+		$matrix['RotateSkew0'] / 0x10000 / 20,
+		$matrix['TranslateX'] / 20,
+		str_repeat("\t", $indent),
+		$matrix['RotateSkew1'] / 0x10000 / 20,
+		$matrix['ScaleY'] / 0x10000 / 20,
+		$matrix['TranslateY'] / 20);
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/MATRIX.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/FILLSTYLEARRAY.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/FILLSTYLE.php';
+
+class IO_SWF_Type_FILLSTYLEARRAY extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $fillStyles = array();
+
+        // FillStyle
+        $fillStyleCount = $reader->getUI8();
+        if (($tagCode > 2) && ($fillStyleCount == 0xff)) {
+           // DefineShape2 以降は 0xffff サイズまで扱える
+           $fillStyleCount = $reader->getUI16LE();
+        }
+        for ($i = 0 ; $i < $fillStyleCount ; $i++) {
+            $fillStyles[] = IO_SWF_Type_FILLSTYLE::parse($reader, $opts);
+        }
+        return $fillStyles;
+    }
+    static function build(&$writer, $fillStyles, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $fillStyleCount = count($fillStyles);
+        if ($fillStyleCount < 0xff) {
+            $writer->putUI8($fillStyleCount);
+        } else {
+            $writer->putUI8(0xff);
+            if ($tagCode > 2) {
+                $writer->putUI16LE($fillStyleCount);
+            } else {
+                $fillStyleCount = 0xff; // DefineShape(1)
+            }
+        }
+        foreach ($fillStyles as $fillStyle) {
+            IO_SWF_Type_FILLSTYLE::build($writer, $fillStyle, $opts);
+        }
+        return true;
+    }
+    static function string($fillStyles, $opts = array()) {
+        $text = '';
+        foreach ($fillStyles as $fillStyle) {
+            $text .= IO_SWF_Type_FILLSTYLE::string($fillStyle, $opts);
+        }
+        return $text;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/FILLSTYLEARRAY.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/String.php

@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+
+class IO_SWF_Type_String extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $str = '';
+        while (true) {
+            $c = $reader->getData(1);
+            if ($c === "\0") {
+                break;
+            }
+            $str .= $c;
+        }
+    	return $str;
+    }
+    static function build(&$writer, $str, $opts = array()) {
+        $writer->putData($str."\0", strlen($str) + 1);
+    }
+    static function string($str, $opts = array()) {
+    	return $str;
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/FILLSTYLE.php

@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/../Exception.php';
+require_once dirname(__FILE__).'/../Type/MATRIX.php';
+require_once dirname(__FILE__).'/../Type/RGB.php';
+require_once dirname(__FILE__).'/../Type/RGBA.php';
+
+class IO_SWF_Type_FILLSTYLE extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+
+        $fillStyle = array();
+        $fillStyleType = $reader->getUI8();
+        $fillStyle['FillStyleType'] = $fillStyleType;
+        switch ($fillStyleType) {
+          case 0x00: // solid fill
+            if ($isMorph === false) {
+                if ($tagCode < 32 ) { // 32:DefineShape3
+                    $fillStyle['Color'] = IO_SWF_Type_RGB::parse($reader);
+                } else {
+                    $fillStyle['Color'] = IO_SWF_Type_RGBA::parse($reader);
+                }
+            } else {
+                    $fillStyle['StartColor'] = IO_SWF_Type_RGBA::parse($reader);
+                    $fillStyle['EndColor'] = IO_SWF_Type_RGBA::parse($reader);
+            }
+            break;
+          case 0x10: // linear gradient fill
+          case 0x12: // radial gradient fill
+            if ($isMorph === false) {
+                $fillStyle['GradientMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+            } else {
+                $fillStyle['StartGradientMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+                $fillStyle['EndGradientMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+            }
+            $reader->byteAlign();
+            if ($isMorph === false) {
+                $fillStyle['SpreadMode'] = $reader->getUIBits(2);
+                $fillStyle['InterpolationMode'] = $reader->getUIBits(2);
+                $numGradients = $reader->getUIBits(4);
+            } else {
+                $numGradients = $reader->getUI8();
+            }
+            $fillStyle['GradientRecords'] = array();
+            for ($j = 0 ; $j < $numGradients ; $j++) {
+                $gradientRecord = array();
+                if ($isMorph === false) {
+                    $gradientRecord['Ratio'] = $reader->getUI8();
+                    if ($tagCode < 32 ) { // 32:DefineShape3
+                        $gradientRecord['Color'] = IO_SWF_Type_RGB::parse($reader);
+                    } else {
+                        $gradientRecord['Color'] = IO_SWF_Type_RGBA::parse($reader);
+                    }
+                } else { // Morph
+                    $gradientRecord['StartRatio'] = $reader->getUI8();
+                    $gradientRecord['EndRatio'] = $reader->getUI8();
+                    $gradientRecord['StartColor'] = IO_SWF_Type_RGBA::parse($reader);
+                    $gradientRecord['EndColor'] = IO_SWF_Type_RGBA::parse($reader);
+                }
+                $fillStyle['GradientRecords'] []= $gradientRecord;
+            }
+            break;
+          // case 0x13: // focal gradient fill // 8 and later
+          // break;
+          case 0x40: // repeating bitmap fill
+          case 0x41: // clipped bitmap fill
+          case 0x42: // non-smoothed repeating bitmap fill
+          case 0x43: // non-smoothed clipped bitmap fill
+                $fillStyle['BitmapId'] = $reader->getUI16LE();
+            if ($isMorph === false) {
+                $fillStyle['BitmapMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+            } else {
+                $fillStyle['StartBitmapMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+                $fillStyle['EndBitmapMatrix'] = IO_SWF_Type_MATRIX::parse($reader);
+            }
+            break;
+          default:
+            throw new IO_SWF_Exception("Unknown FillStyleType=$fillStyleType tagCode=$tagCode");
+        }
+        return $fillStyle;
+    }
+    static function build(&$writer, $fillStyle, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+
+        $fillStyleType = $fillStyle['FillStyleType'];
+        $writer->putUI8($fillStyleType);
+        switch ($fillStyleType) {
+          case 0x00: // solid fill
+            if ($tagCode < 32 ) { // 32:DefineShape3
+                IO_SWF_Type_RGB::build($writer, $fillStyle['Color']);
+            } else {
+                IO_SWF_Type_RGBA::build($writer, $fillStyle['Color']);
+            }
+            break;
+          case 0x10: // linear gradient fill
+          case 0x12: // radial gradient fill
+            IO_SWF_Type_MATRIX::build($writer, $fillStyle['GradientMatrix']);
+            $writer->byteAlign();
+            $writer->putUIBits($fillStyle['SpreadMode'], 2);
+            $writer->putUIBits($fillStyle['InterpolationMode'], 2);
+            $numGradients = count($fillStyle['GradientRecords']);
+            $writer->putUIBits($numGradients , 4);
+            foreach ($fillStyle['GradientRecords'] as $gradientRecord) {
+                $writer->putUI8($gradientRecord['Ratio']);
+                if ($tagCode < 32 ) { // 32:DefineShape3
+                    IO_SWF_Type_RGB::build($writer, $gradientRecord['Color']);
+                } else {
+                    IO_SWF_Type_RGBA::build($writer, $gradientRecord['Color']);
+                }
+            }
+          break;
+          // case 0x13: // focal gradient fill // 8 and later
+          // break;
+          case 0x40: // repeating bitmap fill
+          case 0x41: // clipped bitmap fill
+          case 0x42: // non-smoothed repeating bitmap fill
+          case 0x43: // non-smoothed clipped bitmap fill
+            $writer->putUI16LE($fillStyle['BitmapId']);
+            IO_SWF_Type_MATRIX::build($writer, $fillStyle['BitmapMatrix']);
+            break;
+          default:
+            throw new IO_SWF_Exception("Unknown FillStyleType=$fillStyleType tagCode=$tagCode");
+        }
+        return true;
+    }
+    static function string($fillStyle, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+
+        $text = '';
+        $fillStyleType = $fillStyle['FillStyleType'];
+        switch ($fillStyleType) {
+          case 0x00: // solid fill
+            $color = $fillStyle['Color'];
+            if ($tagCode < 32 ) { // 32:DefineShape3
+                $color_str = IO_SWF_Type_RGB::string($color);
+            } else {
+                $color_str = IO_SWF_Type_RGBA::string($color);
+            }
+            $text .= "\tsolid fill: $color_str\n";
+            break;
+          case 0x10: // linear gradient fill
+          case 0x12: // radial gradient fill
+            if ($fillStyleType == 0x10) {
+                $text .= "\tlinear gradient fill\n";
+            } else {
+                $text .= "\tradial gradient fill\n";
+            }
+            $opts = array('indent' => 2);
+            if ($isMorph === false) {
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['GradientMatrix'], $opts);
+                $text .= $matrix_str . "\n";
+                $spreadMode = $fillStyle['SpreadMode'];
+                $interpolationMode = $fillStyle['InterpolationMode'];
+            } else {
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['StartGradientMatrix'], $opts);
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['EndGradientMatrix'], $opts);
+                $text .= $matrix_str . "\n";
+            }
+
+            foreach ($fillStyle['GradientRecords'] as $gradientRecord) {
+                if ($isMorph === false) {
+                    $ratio = $gradientRecord['Ratio'];
+                    $color = $gradientRecord['Color'];
+                    if ($tagCode < 32 ) { // 32:DefineShape3
+                        $color_str = IO_SWF_Type_RGB::string($color);
+                    } else {
+                        $color_str = IO_SWF_Type_RGBA::string($color);
+                    }
+                    $text .= "\t\tRatio: $ratio Color:$color_str\n";
+                } else {
+                    $startRatio = $gradientRecord['StartRatio'];
+                    $endRatio   = $gradientRecord['EndRatio'];
+                    $startColorStr = IO_SWF_Type_RGBA::string($gradientRecord['StartColor']);
+                    $endColorStr = IO_SWF_Type_RGBA::string($gradientRecord['EndColor']);
+                    $text .= "\t\tRatio: $startRatio => $endRatio Color:$startColorStr => endColorStr\n";
+                }
+            }
+            break;
+          case 0x40: // repeating bitmap fill
+          case 0x41: // clipped bitmap fill
+          case 0x42: // non-smoothed repeating bitmap fill
+          case 0x43: // non-smoothed clipped bitmap fill
+            $text .= "\tBigmap($fillStyleType): ";
+            $text .= "  BitmapId: ".$fillStyle['BitmapId']."\n";
+            if ($isMorph === false) {
+                $text .= "\tBitmapMatrix:\n";
+                $opts = array('indent' => 2);
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['BitmapMatrix'], $opts);
+                $text .= $matrix_str . "\n";
+            } else {
+                $opts = array('indent' => 2);
+                $text .= "\tStartBitmapMatrix:\n";
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['StartBitmapMatrix'], $opts);
+                $text .= $matrix_str . "\n";
+                $text .= "\tEndBitmapMatrix:\n";
+                $matrix_str = IO_SWF_Type_MATRIX::string($fillStyle['EndBitmapMatrix'], $opts);
+                $text .= $matrix_str . "\n";
+            }
+            break;
+          default:
+            $text .= "Unknown FillStyleType($fillStyleType)\n";
+        }
+        return $text;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/FILLSTYLE.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/LINESTYLEARRAY.php

@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/LINESTYLE.php';
+
+
+class IO_SWF_Type_LINESTYLEARRAY extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $lineStyles = array();
+        // LineStyle
+        $lineStyleCount = $reader->getUI8();
+        if (($tagCode > 2) && ($lineStyleCount == 0xff)) {
+            // DefineShape2 以降は 0xffff サイズまで扱える
+            $lineStyleCount = $reader->getUI16LE();
+        }
+        for ($i = 0 ; $i < $lineStyleCount ; $i++) {
+            $lineStyles[] = IO_SWF_Type_LINESTYLE::parse($reader, $opts);
+        }
+        return $lineStyles;
+    }
+    static function build(&$writer, $lineStyles, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $lineStyleCount = count($lineStyles);
+        if ($lineStyleCount < 0xff) {
+            $writer->putUI8($lineStyleCount);
+        } else {
+            $writer->putUI8(0xff);
+            if ($tagCode > 2) {
+                $writer->putUI16LE($lineStyleCount);
+            } else {
+                $lineStyleCount = 0xff; // DefineShape(1)
+            }
+        }
+        foreach ($lineStyles as $lineStyle) {
+            IO_SWF_Type_LINESTYLE::build($writer, $lineStyle);
+        }
+        return true;
+    }
+    static function string($lineStyles, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $text = '';
+        foreach ($lineStyles as $lineStyle) {
+            $text .= IO_SWF_Type_LINESTYLE::string($lineStyle, $opts);
+        }
+        return $text;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/LINESTYLEARRAY.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/LINESTYLE.php

@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * 2011/4/15- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/../Type.php';
+require_once dirname(__FILE__).'/../Type/RGB.php';
+require_once dirname(__FILE__).'/../Type/RGBA.php';
+
+class IO_SWF_Type_LINESTYLE extends IO_SWF_Type {
+    static function parse(&$reader, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+        $lineStyle = array();
+        if ($isMorph === false) {
+            $lineStyle['Width'] = $reader->getUI16LE();
+            if ($tagCode < 32 ) { // 32:DefineShape3
+                $lineStyle['Color'] = IO_SWF_Type_RGB::parse($reader);
+            } else {
+                $lineStyle['Color'] = IO_SWF_Type_RGBA::parse($reader);
+            }
+        } else {
+            $lineStyle['StartWidth'] = $reader->getUI16LE();
+            $lineStyle['EndWidth']   = $reader->getUI16LE();
+            $lineStyle['StartColor'] = IO_SWF_Type_RGBA::parse($reader);
+            $lineStyle['EndColor']   = IO_SWF_Type_RGBA::parse($reader);
+        }
+        return  $lineStyle;
+    }
+    static function build(&$writer, $lineStyle, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+        if ($isMorph === false) {
+            $writer->putUI16LE($lineStyle['Width']);
+            if ($tagCode < 32 ) { // 32:DefineShape3
+                IO_SWF_Type_RGB::build($writer, $lineStyle['Color']);
+            } else {
+                IO_SWF_Type_RGBA::build($writer, $lineStyle['Color']);
+            }
+        } else {
+            $writer->putUI16LE($lineStyle['StartWidth']);
+            $writer->putUI16LE($lineStyle['EndWidth']);
+            IO_SWF_Type_RGBA::build($writer, $lineStyle['StartColor']);
+            IO_SWF_Type_RGBA::build($writer, $lineStyle['EndColor']);
+        }
+        return true;
+    }
+    static function string($lineStyle, $opts = array()) {
+        $tagCode = $opts['tagCode'];
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+        $text = '';
+
+        if ($isMorph === false) {
+            $width = $lineStyle['Width'];
+            if ($tagCode < 32 ) { // 32:DefineShape3
+                $color_str = IO_SWF_Type_RGB::string($lineStyle['Color']);
+            } else {
+                $color_str = IO_SWF_Type_RGBA::string($lineStyle['Color']);
+            }
+            $text .= "\tWitdh: $width Color: $color_str\n";
+        } else {
+            $startWidth = $lineStyle['StartWidth'];
+            $endWidth = $lineStyle['EndWidth'];
+            $startColorStr = IO_SWF_Type_RGBA::string($lineStyle['StartColor']);
+            $endColorStr = IO_SWF_Type_RGBA::string($lineStyle['EndColor']);
+            $text .= "\tWitdh: $startWidth => $endWidth Color: $startColorStr => $endColorStr\n";
+        }
+        return $text;
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type/LINESTYLE.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Exception.php

@@ -0,0 +1,3 @@
+<?php
+
+class IO_SWF_Exception extends Exception { }
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Exception.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Type.php

@@ -0,0 +1,13 @@
+<?php
+
+/*
+ * 2011/1/25- (c) yoya@awm.jp
+ */
+
+// require_once 'IO/Bit.php';
+
+abstract class IO_SWF_Type {
+    abstract static function parse(&$reader, $opts = array());
+    abstract static function build(&$writer, $data, $opts = array());
+    abstract static function string($data, $opts = array());
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/JPEG.php

@@ -0,0 +1,145 @@
+<?php
+
+require_once 'IO/Bit.php';
+
+class IO_SWF_JPEG {
+    var $marker_name_table = array(
+        0xD8 => 'SOI',
+        0xE0 => 'APP0',  0xE1 => 'APP1',  0xE2 => 'APP2',  0xE3 => 'APP3',
+        0xE4 => 'APP4',  0xE5 => 'APP5',  0xE6 => 'APP6',  0xE7 => 'APP7',
+        0xE8 => 'APP8',  0xE9 => 'APP9',  0xEA => 'APP10', 0xEB => 'APP11',
+        0xEC => 'APP12', 0xED => 'APP13', 0xEE => 'APP14', 0xEF => 'APP15',
+        0xFE => 'COM',
+        0xDB => 'DQT',
+        0xC0 => 'SOF0', 0xC1 => 'SOF1',  0xC2 => 'SOF2',  0xC3 => 'SOF3',
+        0xC5 => 'SOF5', 0xC6 => 'SOF6',  0xC7 => 'SOF7',
+        0xC8 => 'JPG',  0xC9 => 'SOF9',  0xCA => 'SOF10', 0xCB => 'SOF11',
+        0xCC => 'DAC',  0xCD => 'SOF13', 0xCE => 'SOF14', 0xCF => 'SOF15',
+        0xC4 => 'DHT',
+        0xDA => 'SOS',
+        0xD0 => 'RST0', 0xD1 => 'RST1', 0xD2 => 'RST2', 0xD3 => 'RST3',
+        0xD4 => 'RST4', 0xD5 => 'RST5', 0xD6 => 'RST6', 0xD7 => 'RST7',
+        0xDD => 'DRI',
+        0xD9 => 'EOI',
+        0xDC => 'DNL',   0xDE => 'DHP',  0xDF => 'EXP',
+        0xF0 => 'JPG0',  0xF1 => 'JPG1', 0xF2 => 'JPG2',  0xF3 => 'JPG3',
+        0xF4 => 'JPG4',  0xF5 => 'JPG5', 0xF6 => 'JPG6',  0xF7 => 'JPG7',
+        0xF8 => 'JPG8',  0xF9 => 'JPG9', 0xFA => 'JPG10', 0xFB => 'JPG11',
+        0xFC => 'JPG12', 0xFD => 'JPG13'
+        );
+    var $_jpegdata = null;
+    var $_jpegChunk = array();
+    function input($jpegdata) {
+        $this->_jpegdata = $jpegdata;
+    }
+    function _splitChunk() {
+        $bitin = new IO_Bit();
+        $bitin->input($this->_jpegdata);
+        while ($marker1 = $bitin->getUI8()) {
+            if ($marker1 != 0xFF) {
+                fprintf(STDERR, "dumpChunk: marker1=0x%02X", $marker1);
+                return false;
+            }
+            $marker2 = $bitin->getUI8();
+            switch ($marker2) {
+            case 0xD8: // SOI (Start of Image)
+                $this->_jpegChunk[] = array('marker' => $marker2, 'data' => null, 'length' => null);
+                continue;
+            case 0xD9: // EOE (End of Image)
+                $this->_jpegChunk[] = array('marker' => $marker2, 'data' => null, 'length' => null);
+                break 2; // while break;
+            case 0xDA: // SOS
+            case 0xD0: case 0xD1: case 0xD2: case 0xD3: // RST
+            case 0xD4: case 0xD5: case 0xD6: case 0xD7: // RST
+                list($chunk_data_offset, $dummy) = $bitin->getOffset();
+                while (true) {
+                    $next_marker1 = $bitin->getUI8();
+                    if ($next_marker1 != 0xFF) {
+                        continue;
+                    }
+                    $next_marker2 = $bitin->getUI8();
+                    if ($next_marker2 == 0x00) {
+                        continue;
+                    }
+
+                    $bitin->incrementOffset(-2, 0); // back from next marker
+                    list($next_chunk_offset, $dummy) = $bitin->getOffset();
+                    $length = $next_chunk_offset - $chunk_data_offset;
+                    $bitin->setOffset($chunk_data_offset, 0);
+                    $this->_jpegChunk[] = array('marker' => $marker2, 'data' => $bitin->getData($length), 'length' => null);
+                    break;
+                }
+                break;
+            default:
+                $length = $bitin->getUI16BE();
+                $this->_jpegChunk[] = array('marker' => $marker2, 'data' => $bitin->getData($length - 2), 'length' => $length);
+                continue;
+            }
+        }
+    }
+    // from: SOI APP* DQT SOF* DHT SOS EOI
+    // to:  SOI APP* SOF* SOS EOI
+    function getImageData() {
+        if (count($this->_jpegChunk) == 0) {
+            $this->_splitChunk();
+        }
+        $bitout = new IO_Bit();
+        foreach ($this->_jpegChunk as $chunk) {
+            $marker = $chunk['marker'];
+            if (($marker == 0xDB) || ($marker == 0xC4)) {
+                continue;  // skip DQT(0xDB) or DHT(0xC4)
+            }
+            $bitout->putUI8(0xFF);
+            $bitout->putUI8($marker);
+            if (is_null($chunk['data'])) { // SOI or EOI
+                ; // nothing to do
+            } else {
+                if (! is_null($chunk['length'])) {
+                    $bitout->putUI16BE($chunk['length']);
+                }
+                $bitout->putData($chunk['data']);
+            }
+        }
+        return $bitout->output();
+    }
+    // from: SOI APP* DQT SOF* DHT SOS EOI
+    // to:   SOI DQT DHT EOI
+    function getEncodingTables() {
+        if (count($this->_jpegChunk) == 0) {
+            $this->_splitChunk();
+        }
+        $bitout = new IO_Bit();
+        $bitout->putUI8(0xFF);
+        $bitout->putUI8(0xD8); // SOI;
+        foreach ($this->_jpegChunk as $chunk) {
+            $marker = $chunk['marker'];
+            if (($marker != 0xDB) && ($marker != 0xC4)) {
+                continue;  // skip not ( DQT(0xDB) or DHT(0xC4) )
+            }
+            $bitout->putUI8(0xFF);
+            $bitout->putUI8($marker);
+            $bitout->putUI16BE($chunk['length']);
+            $bitout->putData($chunk['data']);
+        }
+        $bitout->putUI8(0xFF);
+        $bitout->putUI8(0xD9); // EOI;
+        return $bitout->output();
+
+    }
+    function dumpChunk() { // for debug
+        if (count($this->_jpegChunk) == 0) {
+            $this->_splitChunk();
+        }
+        foreach ($this->_jpegChunk as $chunk) {
+            $marker = $chunk['marker'];
+            $marker_name = $this->marker_name_table{$marker};
+            if (is_null($chunk['data'])) {
+                echo "$marker_name:".PHP_EOL;
+            } else {
+                $length = strlen($chunk['data']);
+                $md5 = md5($chunk['data']);
+                echo "$marker_name: length=$length md5=$md5".PHP_EOL;
+            }
+        }
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/Base.php

@@ -0,0 +1,7 @@
+<?php
+
+abstract class IO_SWF_Tag_Base {
+    abstract function parseContent($tagCode, $content, $opts = array());
+    abstract function dumpContent($tagCode, $opts = array());
+    abstract function buildContent($tagCode, $opts = array());
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/Action.php

@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * 2011/06/03- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/Base.php';
+require_once dirname(__FILE__).'/../Type/Action.php';
+
+class IO_SWF_Tag_Action extends IO_SWF_Tag_Base {
+    var $_actions = array();
+    var $_spriteId = null; // DoInitAction
+    function parseContent($tagCode, $content, $opts = array()) {
+        $reader = new IO_Bit();
+    	$reader->input($content);
+        if ($tagCode == 59) { // DoInitAction
+            $this->_spriteId = $reader->getUI16LE();
+        }
+        while ($reader->getUI8() != 0) {
+            $reader->incrementOffset(-1, 0); // 1 byte back
+            $action = IO_SWF_Type_Action::parse($reader);
+            $this->_actions [] = $action;
+        }
+        // ActionEndFlag
+    }
+
+    function dumpContent($tagCode, $opts = array()) {
+        echo "    Actions:";
+        if ($tagCode == 59) { // DoInitAction
+            echo " SpriteID=".$this->_spriteId;
+        }
+        echo "\n";
+        foreach ($this->_actions as $action) {
+            $action_str = IO_SWF_Type_Action::string($action);
+            echo "\t$action_str\n";
+        }
+    }
+
+    function buildContent($tagCode, $opts = array()) {
+        $writer = new IO_Bit();
+        if ($tagCode == 59) { // DoInitAction
+            $writer->putUI16LE($this->_spriteId);
+        }
+        foreach ($this->_actions as $action) {
+            IO_SWF_Type_Action::build($writer, $action);
+        }
+        $writer->putUI8(0); // ActionEndFlag
+    	return $writer->output();
+    }
+    function replaceActionStrings($from_str, $to_str) {
+        foreach ($this->_actions as &$action) {
+            switch($action['Code']) {
+            case 0x83: // ActionGetURL
+                ;
+                if ($action['UrlString'] === $from_str) {
+                    $action['UrlString'] = $to_str;
+                }
+                if ($action['TargetString'] === $from_str) {
+                    $action['TargetString'] = $to_str;
+                }
+                break;
+            case 0x88: // ActionConstantPool
+                foreach ($action['ConstantPool'] as $idx_cp => $cp) {
+                    if ($cp === $from_str) {
+                        $action['ConstantPool'][$idx_cp] = $to_str;
+                    }
+                }
+                break;
+            case 0x96: // ActionPush
+                if ($action['Type'] == 0) { // Type String
+                    if ($action['String'] === $from_str) {
+                        $action['String'] = $to_str;
+                    }
+                }
+                break;
+
+            }
+
+        }
+        // don't touch $action, danger!
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/Shape.php

@@ -0,0 +1,335 @@
+<?php
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/Base.php';
+require_once dirname(__FILE__).'/../Type/RECT.php';
+require_once dirname(__FILE__).'/../Type/FILLSTYLEARRAY.php';
+require_once dirname(__FILE__).'/../Type/LINESTYLEARRAY.php';
+require_once dirname(__FILE__).'/../Type/SHAPE.php';
+
+class IO_SWF_Tag_Shape extends IO_SWF_Tag_Base {
+    var $_shapeId = null;
+    // DefineShape, DefineShape2, DefineShape3
+    var $_shapeBounds;
+    var $_fillStyles, $_lineStyles;
+    var $_shapeRecords;
+    // DefineMorphShape
+    var $_startBounds, $_endBounds;
+    var $_offset;
+    var $_morphFillStyles, $_morphLineStyles;
+    var $_startEdge, $_endEdges;
+
+   function parseContent($tagCode, $content, $opts = array()) {
+
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+
+        $reader = new IO_Bit();
+    	$reader->input($content);
+        $this->_shapeId = $reader->getUI16LE();
+
+        $opts = array('tagCode' => $tagCode, 'isMorph' => $isMorph);
+
+        if ($isMorph === false) {
+        	// 描画スタイル
+            $this->_shapeBounds = IO_SWF_TYPE_RECT::parse($reader);
+            $this->_fillStyles = IO_SWF_TYPE_FILLSTYLEARRAY::parse($reader, $opts);
+        	$this->_lineStyles = IO_SWF_TYPE_LINESTYLEARRAY::parse($reader, $opts);
+        	// 描画枠
+            $this->_shapeRecords = IO_SWF_Type_SHAPE::parse($reader, $opts);
+        } else {
+            $this->_startBounds = IO_SWF_TYPE_RECT::parse($reader);
+            $this->_endBounds = IO_SWF_TYPE_RECT::parse($reader);
+            $this->_offset = $reader->getUI32LE();
+        	// 描画スタイル
+            $this->_morphFillStyles = IO_SWF_TYPE_FILLSTYLEARRAY::parse($reader, $opts);
+        	$this->_morphLineStyles = IO_SWF_TYPE_LINESTYLEARRAY::parse($reader, $opts);
+        	// 描画枠
+            $this->_startEdge = IO_SWF_Type_SHAPE::parse($reader, $opts);
+            $this->_endEdge   = IO_SWF_Type_SHAPE::parse($reader, $opts);
+        }
+    }
+
+    function dumpContent($tagCode, $opts = array()) {
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+        if (is_null($this->_shapeId) === false) {
+            echo "    ShapeId: {$this->_shapeId}\n";
+        }
+        $opts = array('tagCode' => $tagCode, 'isMorph' => $isMorph);
+
+        if ($isMorph === false) {
+            echo "    ShapeBounds: ". IO_SWF_Type_RECT::string($this->_shapeBounds)."\n";
+            echo "    FillStyles:\n";
+            echo IO_SWF_Type_FILLSTYLEARRAY::string($this->_fillStyles, $opts);
+            echo "    LineStyles:\n";
+            echo IO_SWF_Type_LINESTYLEARRAY::string($this->_lineStyles, $opts);
+
+            echo "    ShapeRecords:\n";
+            echo IO_SWF_Type_SHAPE::string($this->_shapeRecords, $opts);
+        } else {
+            echo "    StartBounds: ". IO_SWF_Type_RECT::string($this->_startBounds)."\n";
+            echo "    EndBounds: ". IO_SWF_Type_RECT::string($this->_endBounds)."\n";
+            echo "    FillStyles:\n";
+            echo IO_SWF_Type_FILLSTYLEARRAY::string($this->_morphFillStyles, $opts);
+            echo "    LineStyles:\n";
+            echo IO_SWF_Type_LINESTYLEARRAY::string($this->_morphLineStyles, $opts);
+
+            echo "    StartEdge:\n";
+            echo IO_SWF_Type_SHAPE::string($this->_startEdge, $opts);
+            echo "    endEdge:\n";
+            echo IO_SWF_Type_SHAPE::string($this->_endEdge, $opts);
+        }
+    }
+
+    function buildContent($tagCode, $opts = array()) {
+        $isMorph = ($tagCode == 46) || ($tagCode == 84);
+        $writer = new IO_Bit();
+        if (isset($opts['hasShapeId']) && $opts['hasShapeId']) {
+            $writer->putUI16LE($this->_shapeId);
+        }
+        $opts = array('tagCode' => $tagCode);
+
+        if ($isMorph === false) {
+            IO_SWF_Type_RECT::build($writer, $this->_shapeBounds);
+            // 描画スタイル
+            IO_SWF_Type_FILLSTYLEARRAY::build($writer, $this->_fillStyles, $opts);
+            IO_SWF_Type_LINESTYLEARRAY::build($writer, $this->_lineStyles, $opts);
+        	// 描画枠
+            $opts['fillStyleCount'] = count($this->_fillStyles);
+            $opts['lineStyleCount'] = count($this->_lineStyles);
+            IO_SWF_Type_SHAPE::build($writer, $this->_shapeRecords, $opts);
+        } else {
+            IO_SWF_Type_RECT::build($writer, $this->_startBounds);
+            IO_SWF_Type_RECT::build($writer, $this->_endBounds);
+            // 描画スタイル
+            IO_SWF_Type_FILLSTYLEARRAY::build($writer, $this->_morphFillStyles, $opts);
+            IO_SWF_Type_LINESTYLEARRAY::build($writer, $this->_morphLineStyles, $opts);
+        	// 描画枠
+            $opts['fillStyleCount'] = count($this->_morphFillStyles);
+            $opts['lineStyleCount'] = count($this->_morphLineStyles);
+            IO_SWF_Type_SHAPE::build($writer, $this->_startEdge, $opts);
+            IO_SWF_Type_SHAPE::build($writer, $this->_endEdge, $opts);
+        }
+        return $writer->output();
+    }
+
+    function deforme($threshold) {
+        $startIndex = null;
+        foreach ($this->_shapeRecords as $shapeRecordIndex => $shapeRecord) {
+            if (($shapeRecord['TypeFlag'] == 0) && (isset($shapeRecord['EndOfShape']) === false)) {
+                // StyleChangeRecord
+                $endIndex = $shapeRecordIndex - 1;
+                if (is_null($startIndex) === false) {
+                    $this->deformeShapeRecordUnit($threshold, $startIndex, $endIndex);
+                }
+                $startIndex = $shapeRecordIndex;
+            }
+            if (isset($shapeRecord['EndOfShape']) && ($shapeRecord['EndOfShape']) == 0) {
+                // EndShapeRecord
+                $endIndex = $shapeRecordIndex - 1;
+               $this->deformeShapeRecordUnit($threshold, $startIndex, $endIndex);
+            }
+        }
+        $this->_shapeRecords = array_values($this->_shapeRecords);
+    }
+
+    function deformeShapeRecordUnit($threshold, $startIndex, $endIndex) {
+//        return $this->deformeShapeRecordUnit_1($threshold, $startIndex, $endIndex);
+        return $this->deformeShapeRecordUnit_2($threshold, $startIndex, $endIndex);
+    }
+    function deformeShapeRecordUnit_1($threshold, $startIndex, $endIndex) {
+        $threshold_2 = $threshold * $threshold;
+        $shapeRecord = $this->_shapeRecords[$startIndex];
+        $prevIndex = null;
+        $currentDrawingPositionX = $shapeRecord['MoveX'];
+        $currentDrawingPositionY = $shapeRecord['MoveY'];
+        for ($i = $startIndex + 1 ;$i <= $endIndex; $i++) {
+            $shapeRecord = & $this->_shapeRecords[$i];
+            if ($shapeRecord['StraightFlag'] == 0) {
+                // 曲線に対する処理
+                $diff_x = $shapeRecord['ControlX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['ControlY'] - $currentDrawingPositionY;
+                $distance_2_control = $diff_x * $diff_x + $diff_y * $diff_y;
+                $diff_x = $shapeRecord['AnchorX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['AnchorY'] - $currentDrawingPositionY;
+                $distance_2_anchor = $diff_x * $diff_x + $diff_y * $diff_y;
+//                if (max($distance_2_control, $distance_2_anchor) > $threshold_2) {
+                if (($distance_2_control +  $distance_2_anchor) > $threshold_2) {
+                    // 何もしない
+                    $prevIndex = $i;
+                    $prevDrawingPositionX = $currentDrawingPositionX;
+                    $prevDrawingPositionY = $currentDrawingPositionY;
+                    $currentDrawingPositionX = $shapeRecord['AnchorX'];
+                    $currentDrawingPositionY = $shapeRecord['AnchorY'];
+                    continue; // skip
+                }
+                // 直線に変換する
+                $shapeRecord['StraightFlag'] = 1; // to Straight
+                $shapeRecord['X'] = $shapeRecord['AnchorX'];
+                $shapeRecord['Y'] = $shapeRecord['AnchorY'];
+                unset($shapeRecord['ControlX'], $shapeRecord['ControlY']);
+                unset($shapeRecord['AnchorX'], $shapeRecord['AnchorY']);
+            }
+            if (is_null($prevIndex)) {
+                // 何もしない
+                $prevIndex = $i;
+                $prevDrawingPositionX = $currentDrawingPositionX;
+                $prevDrawingPositionY = $currentDrawingPositionY;
+                $currentDrawingPositionX = $shapeRecord['X'];
+                $currentDrawingPositionY = $shapeRecord['Y'];
+                continue; // skip
+            }
+            $diff_x = $shapeRecord['X'] - $prevDrawingPositionX;
+            $diff_y = $shapeRecord['Y'] - $prevDrawingPositionY;
+            $distance_2 = $diff_x * $diff_x + $diff_y * $diff_y;
+            if ($distance_2 > $threshold_2) {
+                // 何もしない
+                $prevIndex = $i;
+                $prevDrawingPositionX = $currentDrawingPositionX;
+                $prevDrawingPositionY = $currentDrawingPositionY;
+                $currentDrawingPositionX = $shapeRecord['X'];
+                $currentDrawingPositionY = $shapeRecord['Y'];
+                continue; // skip
+            }
+            // 前の直線にくっつける。
+            $prevShapeRecord = & $this->_shapeRecords[$prevIndex];
+            $prevShapeRecord['X'] = $shapeRecord['X'];
+            $prevShapeRecord['Y'] = $shapeRecord['Y'];
+            $currentDrawingPositionX = $shapeRecord['X'];
+            $currentDrawingPositionY = $shapeRecord['Y'];
+            unset($this->_shapeRecords[$i]);
+        }
+    }
+
+    function deformeShapeRecordUnit_2($threshold, $startIndex, $endIndex) {
+        $this->deformeShapeRecordUnit_2_curve($threshold, $startIndex, $endIndex);
+        while ($this->deformeShapeRecordUnit_2_line($threshold, $startIndex, $endIndex));
+    }
+
+    function deformeShapeRecordUnit_2_curve($threshold, $startIndex, $endIndex) {
+        $threshold_2 = $threshold * $threshold;
+        $shapeRecord = $this->_shapeRecords[$startIndex];
+        $currentDrawingPositionX = $shapeRecord['MoveX'];
+        $currentDrawingPositionY = $shapeRecord['MoveY'];
+        for ($i = $startIndex + 1 ;$i <= $endIndex; $i++) {
+            $shapeRecord = & $this->_shapeRecords[$i];
+            if ($shapeRecord['StraightFlag'] == 0) {
+            // 曲線に対する処理
+                $diff_x = $shapeRecord['ControlX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['ControlY'] - $currentDrawingPositionY;
+                $distance_2_control = $diff_x * $diff_x + $diff_y * $diff_y;
+                $diff_x = $shapeRecord['AnchorX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['AnchorY'] - $currentDrawingPositionY;
+                $distance_2_anchor = $diff_x * $diff_x + $diff_y * $diff_y;
+                if (($distance_2_control +  $distance_2_anchor) > $threshold_2) {
+                    // 何もしない
+                    $currentDrawingPositionX = $shapeRecord['AnchorX'];
+                    $currentDrawingPositionY = $shapeRecord['AnchorY'];
+                    continue; // skip
+                }
+                // 直線に変換する
+                $shapeRecord['StraightFlag'] = 1; // to Straight
+                $shapeRecord['X'] = $shapeRecord['AnchorX'];
+                $shapeRecord['Y'] = $shapeRecord['AnchorY'];
+                unset($shapeRecord['ControlX'], $shapeRecord['ControlY']);
+                unset($shapeRecord['AnchorX'], $shapeRecord['AnchorY']);
+                $currentDrawingPositionX = $shapeRecord['X'];
+                $currentDrawingPositionY = $shapeRecord['Y'];
+            }
+        }
+    }
+
+    function deformeShapeRecordUnit_2_line($threshold, $startIndex, $endIndex) {
+        $threshold_2 = $threshold * $threshold;
+        $shapeRecord = $this->_shapeRecords[$startIndex];
+        $prevIndex = null;
+        $currentDrawingPositionX = $shapeRecord['MoveX'];
+        $currentDrawingPositionY = $shapeRecord['MoveY'];
+        $distance_list_short = array();
+        $distance_table_all = array();
+        for ($i = $startIndex + 1 ;$i <= $endIndex; $i++) {
+            $shapeRecord = & $this->_shapeRecords[$i];
+            if ($shapeRecord['StraightFlag'] == 0) {
+                $diff_x = $shapeRecord['ControlX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['ControlY'] - $currentDrawingPositionY;
+                $distance_2_control = $diff_x * $diff_x + $diff_y * $diff_y;
+                $diff_x = $shapeRecord['AnchorX'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['AnchorY'] - $currentDrawingPositionY;
+                $distance_2_anchor = $diff_x * $diff_x + $diff_y * $diff_y;
+//                $distance_list[$i] = $distance_2_control +  $distance_2_anchor;
+                $distance_table_all[$i] = $distance_2_control +  $distance_2_anchor;
+                $currentDrawingPositionX = $shapeRecord['AnchorX'];
+                $currentDrawingPositionY = $shapeRecord['AnchorY'];
+            } else {
+                $diff_x = $shapeRecord['X'] - $currentDrawingPositionX;
+                $diff_y = $shapeRecord['Y'] - $currentDrawingPositionY;
+            $distance_2 = $diff_x * $diff_x + $diff_y * $diff_y;
+            if ($distance_2 < $threshold_2) {
+               $distance_list_short[] = $i;
+            }
+            $distance_table_all[$i] = $distance_2;
+            $currentDrawingPositionX = $shapeRecord['X'];
+            $currentDrawingPositionY = $shapeRecord['Y'];
+        }
+    }
+    sort($distance_list_short);
+    $deforme_number = 0;
+    foreach ($distance_list_short as $i) {
+        $distance_2 = $distance_table_all[$i];
+        if ($distance_2 > $threshold_2) {
+            continue; // 一定距離以上の線分は処理しない
+        }
+        if (empty($distance_list_all[$i-1]) && empty($distance_list_all[$i+1])) {
+            // 隣の線分が吸収され済みor曲線の場合は処理しない
+
+        }
+        $index_to_merge;
+        if (empty($distance_list_all[$i-1])) {
+            if (empty($distance_list_all[$i+1])) {
+                // 隣の線分が吸収されている場合は処理しない
+                continue;
+            } else {
+                $index_to_merge = $i+1;
+            }
+        } else {
+            if (empty($distance_list_all[$i+1])) {
+                $index_to_merge = $i-1;
+            } else {
+                $index_to_merge = $i-1; // XXX 後で選択する処理を入れる
+            }
+        }
+        // line merge 処理
+        $shapeRecord = $this->_shapeRecords[$i];
+        $shapeRecord_toMerge = & $this->_shapeRecords[$index_to_merge];
+        if ($i > $index_to_merge) {
+            if ($shapeRecord['StraightFlag']) {
+                $shapeRecord_toMerge['X'] = $shapeRecord['X'];
+                $shapeRecord_toMerge['Y'] = $shapeRecord['Y'];
+            } else {
+                $shapeRecord_toMerge['AnchorX'] = $shapeRecord['X'];
+                $shapeRecord_toMerge['AnchorY'] = $shapeRecord['Y'];
+            }
+        }
+        $distance_list_all[$index_to_merge] += $distance_list_all[$i];
+//        unset($distance_list_all[$i]);
+          unset($this->_shapeRecords[$i]);
+          $deforme_number += 1;
+        }
+        return $deforme_number;
+    }
+    function countEdges() {
+        $edges_count = 0;
+	if (isset($this->_shapeRecords)) {
+	    $shapeRecords = $this->_shapeRecords;
+	} elseif (isset($this->_startEdge)) {
+	    $shapeRecords = $this->_startEdge;
+	} else {
+	    $shapeRecords = array(); // nothing to do.
+	}
+	foreach ($shapeRecords as $shapeRecordIndex => $shapeRecord) {
+	    if (isset($shapeRecord['StraightFlag'])) { // XXX
+	        $edges_count++;
+	    }
+	}
+	return array($this->_shapeId, $edges_count);
+    }
+}
属性に変更があったパス: IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/Shape.php
___________________________________________________________________
追加: svn:mergeinfo

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/Sprite.php

@@ -0,0 +1,49 @@
+<?php
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/Base.php';
+require_once dirname(__FILE__).'/../Tag.php';
+
+class IO_SWF_Tag_Sprite extends IO_SWF_Tag_Base {
+    var $_spriteId = null;
+    var $_frameCount = null;
+    var $_controlTags = array();
+    function parseContent($tagCode, $content, $opts = array()) {
+        $reader = new IO_Bit();
+    	$reader->input($content);
+
+        $this->_spriteId = $reader->getUI16LE();
+        $this->_frameCount = $reader->getUI16LE();
+        /* SWF Tags */
+        while (true) {
+            $tag = new IO_SWF_Tag();
+            $tag->parse($reader);
+            $this->_controlTags[] = $tag;
+            if ($tag->code == 0) { // END Tag
+                break;
+            }
+        }
+        return true;
+    }
+
+    function dumpContent($tagCode, $opts = array()) {
+        echo "\tSprite: SpriteID={$this->_spriteId} FrameCount={$this->_frameCount}\n";
+        foreach ($this->_controlTags as $tag) {
+            echo "  ";
+            $tag->dump($opts);
+        }
+    }
+
+    function buildContent($tagCode, $opts = array()) {
+        $writer = new IO_Bit();
+        $writer->putUI16LE($this->_spriteId);
+        $writer->putUI16LE($this->_frameCount);
+        foreach ($this->_controlTags as $tag) {
+            $tagData = $tag->build();
+            if ($tagData != false) {
+                $writer->putData($tag->build());
+            }
+        }
+    	return $writer->output();
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Tag/BGColor.php

@@ -0,0 +1,26 @@
+<?php
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/Base.php';
+require_once dirname(__FILE__).'/../Type/RGB.php';
+
+class IO_SWF_Tag_BGColor extends IO_SWF_Tag_Base {
+    var $_color;
+
+   function parseContent($tagCode, $content, $opts = array()) {
+        $reader = new IO_Bit();
+    	$reader->input($content);
+        $this->_color = IO_SWF_Type_RGB::parse($reader);
+    }
+
+    function dumpContent($tagCode, $opts = array()) {
+        $color_str = IO_SWF_Type_RGB::string($this->_color);
+        echo "\tColor: $color_str\n";
+    }
+
+    function buildContent($tagCode, $opts = array()) {
+        $writer = new IO_Bit();
+        IO_SWF_Type_RGB::build($writer, $this->_color);
+    	return $writer->output();
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Editor.php

@@ -0,0 +1,199 @@
+<?php
+
+/*
+ * 2010/8/12- (c) yoya@awm.jp
+ */
+
+require_once dirname(__FILE__).'/../SWF.php';
+require_once dirname(__FILE__).'/../SWF/Tag/Shape.php';
+require_once dirname(__FILE__).'/../SWF/Tag/Action.php';
+require_once dirname(__FILE__).'/../SWF/Tag/Sprite.php';
+require_once dirname(__FILE__).'/../SWF/Lossless.php';
+
+class IO_SWF_Editor extends IO_SWF {
+    // var $_headers = array(); // protected
+    // var $_tags = array();    // protected
+
+    function setCharacterId() {
+        foreach ($this->_tags as &$tag) {
+            $content_reader = new IO_Bit();
+            $content_reader->input($tag->content);
+            switch ($tag->code) {
+              case 4:  // PlaceObject
+              case 5:  // RemoveObject
+              case 6:  // DefineBits
+              case 21: // DefineBitsJPEG2
+              case 35: // DefineBitsJPEG3
+              case 20: // DefineBitsLossless
+              case 46: // DefineMorphShape
+              case 2:  // DefineShape (ShapeId)
+              case 22: // DefineShape2 (ShapeId)
+              case 11: // DefineText
+              case 33: // DefineText2
+              case 37: // DefineTextEdit
+              case 39: // DefineSprite
+                $tag->characterId = $content_reader->getUI16LE();
+                break;
+              case 26: // PlaceObject2 (PlaceFlagHasCharacter)
+                $tag->placeFlag = $content_reader->getUI8();
+                if ($tag->placeFlag & 0x02) {
+                    $tag->characterId = $content_reader->getUI16LE();
+                }
+                break;
+            }
+        }
+    }
+
+    function replaceTagContent($tagCode, $content, $limit = 1) {
+        $count = 0;
+        foreach ($this->_tags as &$tag) {
+            if ($tag->code == $tagCode) {
+                $tag->content = $content;
+                $count += 1;
+                if ($limit <= $count) {
+                    break;
+                }
+            }
+        }
+        return $count;
+    }
+    function getTagContent($tagCode) {
+        $count = 0;
+        foreach ($this->_tags as &$tag) {
+            if ($tag->code == $tagCode) {
+                return $tag->content;
+            }
+        }
+        return null;
+    }
+
+    function replaceTagContentByCharacterId($tagCode, $characterId, $content_after_character_id) {
+        if (! is_array($tagCode)) {
+            $tagCode = array($tagCode);
+        }
+        $ret = false;
+        foreach ($this->_tags as &$tag) {
+            if (in_array($tag->code, $tagCode) && isset($tag->characterId)) {
+                if ($tag->characterId == $characterId) {
+                    $tag->content = pack('v', $characterId).$content_after_character_id;
+                    $ret = true;
+                    break;
+                }
+            }
+        }
+        return $ret;
+    }
+
+    function replaceTagByCharacterId($tagCode, $characterId, $replaceTag) {
+        if (! is_array($tagCode)) {
+            $tagCode = array($tagCode);
+        }
+        $ret = 0;
+        foreach ($this->_tags as &$tag) {
+            if (in_array($tag->code, $tagCode) && isset($tag->characterId)) {
+                if ($tag->characterId == $characterId) {
+                    if (isset($replaceTag['Code'])) {
+                        $tag->code = $replaceTag['Code'];
+                    }
+                    $tag->length = strlen($replaceTag['Content']);
+                    $tag->content = $replaceTag['Content'];
+                    $ret = 1;
+                    break;
+                }
+            }
+        }
+        return $ret;
+    }
+
+    function getTagContentByCharacterId($tagCode, $characterId) {
+        foreach ($this->_tags as $tag) {
+            if (($tag->code == $tagCode) && isset($tag->characterId)) {
+                if ($tag->characterId == $characterId) {
+                    return $tag->content;
+                    break;
+                }
+            }
+        }
+        return null;
+    }
+    function deformeShape($threshold) {
+        foreach ($this->_tags as &$tag) {
+            $code = $tag->code;
+            switch($code) {
+              case 2: // DefineShape
+              case 22: // DefineShape2
+              case 32: // DefineShape3
+                $shape = new IO_SWF_Tag_Shape();
+                $opts = array('hasShapeId' => true);
+                $shape->parseContent($code, $tag->content, $opts);
+                $shape->deforme($threshold);
+                $tag->content = $shape->buildContent($code, $opts);
+                break;
+            }
+        }
+    }
+    function replaceActionStrings($from_str, $to_str) {
+        foreach ($this->_tags as &$tag) {
+            $code = $tag->code;
+            switch($code) {
+              case 12: // DoAction
+//            case 59: // DoAction
+                $action = new IO_SWF_Tag_Action();
+                $action->parseContent($code, $tag->content);
+                $action->replaceActionStrings($from_str, $to_str);
+                $tag->content = $action->buildContent($code);
+                break;
+            case 39: // Sprite
+                $sprite = new IO_SWF_Tag_Sprite();
+                $sprite->parseContent($code, $tag->content);
+                foreach ($sprite->_controlTags as &$tag_in_sprite) {
+                    $code_in_sprite = $tag_in_sprite->code;
+                    switch ($code_in_sprite) {
+              case 12: // DoAction
+//            case 59: // DoAction
+                  $action_in_sprite = new IO_SWF_Tag_Action();
+                  $action_in_sprite->parseContent($code_in_sprite, $tag_in_sprite->content);
+                  $action_in_sprite->replaceActionStrings($from_str, $to_str);
+                  $tag_in_sprite->content = $action_in_sprite->buildContent($code_in_sprite);
+                  break;
+                    }
+                }
+                $tag->content = $sprite->buildContent($code);
+                break;
+            }
+        }
+    }
+    // 2.01 の互換性確保用。Strings の方が正しい。
+    function replaceActionString($from_str, $to_str) {
+        return $this->replaceActionStrings($from_str, $to_str);
+    }
+
+    function replaceBitmapData($bitmap_id, $bitmap_data, $jpeg_alphadata = null) {
+        $bitmap_head4 = substr($bitmap_data, 0, 4);
+        if ((strncmp($bitmap_head4, 'GIF', 3) == 0) ||
+            (strncmp($bitmap_head4, chr(0x89).'PNG', 4) == 0)) {
+            $tag = IO_SWF_Lossless::BitmapData2Lossless($bitmap_id, $bitmap_data);
+        } else if (strncmp($bitmap_data, chr(0xff).chr(0xd8).chr(0xff).chr(0xdb), 4) == 0) {
+            $erroneous_header = pack('CCCC', 0xFF, 0xD9, 0xFF, 0xD8);
+            if (is_null($jpeg_alphadata)) {
+                // 21: DefineBitsJPEG2
+                $content = $erroneous_header.$bitmap_data;
+                $tag = array('Code' => 21,
+                             'Content' => $content);
+            } else {
+                // 35: DefineBitsJPEG3
+                $jpeg_data = $erroneous_header.$bitmap_data;
+                $compressed_alphadata = gzcompress($jpeg_alphadata);
+                $content = pack('v', $bitmap_id).pack('V', strlen($jpeg_data)).$jpeg_data.$compressed_alphadata;
+                $tag = array('Code' => 35,
+                             'Content' => $content);
+            }
+        } else {
+            throw new IO_SWF_Exception("Unknown Bitmap Format: ".bin2hex($bitmap_head4));
+        }
+        // DefineBits,DefineBitsJPEG2,3, DefineBitsLossless,DefineBitsLossless2
+        $tag_code = array(6, 21, 35, 20, 36);
+        $ret = $this->replaceTagByCharacterId($tag_code, $bitmap_id, $tag);
+        return $ret;
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF/Lossless.php

@@ -0,0 +1,121 @@
+<?php
+
+class IO_SWF_Lossless {
+    /* PNG と GIF の Bitmap データを Lossless 形式に変換する
+     * return array('Code' => ..., 'Content' => ...)
+     */
+    function BitmapData2Lossless($bitmap_id, $bitmap_data) {
+        $im = imagecreatefromstring($bitmap_data);
+        if ($im === false) {
+            throw new IO_SWF_Exception("not Bitmap Image");
+        }
+
+        $colortable_size = imagecolorstotal($im);
+
+        if ((imageistruecolor($im) === false) && ($colortable_size <= 256)) {
+            $format = 3; // palette format
+            $transparent_exists = false;
+            for ($i = 0 ; $i < $colortable_size ; $i++) {
+                $rgba = imagecolorsforindex($im, $i);
+                if (array_key_exists('alpha', $rgba) && ($rgba['alpha'] > 0)) {
+                    $transparent_exists = true;
+                    break;
+                }
+            }
+            $colortable = '';
+            if ($transparent_exists == false) {
+                for ($i = 0 ; $i < $colortable_size ; $i++) {
+                    $rgb = imagecolorsforindex($im, $i);
+                    $colortable .= chr($rgb['red']);
+                    $colortable .= chr($rgb['green']);
+                    $colortable .= chr($rgb['blue']);
+                }
+            } else {
+                for ($i = 0 ; $i < $colortable_size ; $i++) {
+                    $rgba = imagecolorsforindex($im, $i);
+                    $alpha = $rgba['alpha'];
+                    $alpha = 2 * (127 - $alpha);
+                    $colortable .= chr($rgba['red']  * $alpha / 255);
+                    $colortable .= chr($rgba['green']* $alpha / 255);
+                    $colortable .= chr($rgba['blue'] * $alpha / 255);
+                    $colortable .= chr($alpha);
+                }
+            }
+
+            $pixeldata = '';
+            $i = 0;
+            $width  = imagesx($im);
+            $height = imagesy($im);
+
+            for ($y = 0 ; $y < $height ; $y++) {
+                for ($x = 0 ; $x < $width ; $x++) {
+                    $pixeldata .= chr(imagecolorat($im, $x, $y));
+                    $i++;
+                }
+                while (($i % 4) != 0) {
+                    $pixeldata .= chr(0);
+                    $i++;
+                }
+            }
+        } else { // truecolor
+            $format = 5; // trurcolor format
+            $transparent_exists = false;
+
+            $width  = imagesx($im);
+            $height = imagesy($im);
+            for ($y = 0 ; $y < $height ; $y++) {
+                for ($x = 0 ; $x < $width ; $x++) {
+                    $i = imagecolorat($im, $x, $y);
+                    $rgba = imagecolorsforindex($im, $i);
+                    if (array_key_exists('alpha', $rgba) && ($rgba['alpha'] > 0)) {
+                        $transparent_exists = true;
+                        break;
+                    }
+                }
+            }
+            $pixeldata = '';
+            if ($transparent_exists === false) {
+                for ($y = 0 ; $y < $height ; $y++) {
+                    for ($x = 0 ; $x < $width ; $x++) {
+                        $i = imagecolorat($im, $x, $y);
+                        $rgb = imagecolorsforindex($im, $i);
+                        $pixeldata .= 0; // Always 0
+                        $pixeldata .= chr($rgb['red']);
+                        $pixeldata .= chr($rgb['green']);
+                        $pixeldata .= chr($rgb['blue']);
+                    }
+                }
+            } else {
+                for ($y = 0 ; $y < $height ; $y++) {
+                    for ($x = 0 ; $x < $width ; $x++) {
+                        $i = imagecolorat($im, $x, $y);
+                        $rgba = imagecolorsforindex($im, $i);
+                        $alpha = $rgba['alpha'];
+                        $alpha = 2 * (127 - $alpha);
+                        $pixeldata .= chr($alpha);
+                        $pixeldata .= chr($rgba['red']  * $alpha / 255);
+                        $pixeldata .= chr($rgba['green']* $alpha / 255);
+                        $pixeldata .= chr($rgba['blue'] * $alpha / 255);
+                    }
+                }
+            }
+        }
+
+        imagedestroy($im);
+        $content = pack('v', $bitmap_id).chr($format).pack('v', $width).pack('v', $height);
+        if ($format == 3) {
+            $content .= chr($colortable_size - 1).gzcompress($colortable.$pixeldata);
+        } else {
+            $content .= gzcompress($pixeldata);
+        }
+
+        if ($transparent_exists === false) {
+            $tagCode = 20; // DefineBitsLossless
+        } else {
+            $tagCode = 36; // DefineBitsLossless2
+        }
+        $tag = array('Code' => $tagCode,
+                     'Content' => $content);
+        return $tag;
+    }
+}

IO_SWF/tags/2.0.3-stable-20110614230402/IO/SWF.php

@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * 2010/8/11- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/SWF/Type/RECT.php';
+require_once dirname(__FILE__).'/SWF/Type/MATRIX.php';
+require_once dirname(__FILE__).'/SWF/Tag.php';
+
+class IO_SWF {
+    // instance variable
+    var $_headers = array(); // protected
+    var $_header_size;
+    var $_tags = array();    // protected
+    // for debug
+    var $_swfdata = null;
+
+    function parse($swfdata) {
+        $reader = new IO_Bit();
+        $reader->input($swfdata);
+        $this->_swfdata  = $swfdata;
+        /* SWF Header */
+        $this->_headers['Signature'] = $reader->getData(3);
+        $this->_headers['Version'] = $reader->getUI8();
+        $this->_headers['FileLength'] = $reader->getUI32LE();
+        if ($this->_headers['Signature']{0} == 'C') {
+            // CWS の場合、FileLength の後ろが zlib 圧縮されている
+            $uncompressed_data = gzuncompress(substr($swfdata, 8));
+            if ($uncompressed_data === false) {
+                return false;
+            }
+            list($byte_offset, $dummy) = $reader->getOffset();
+            $reader->setOffset(0, 0);
+            $swfdata = $reader->getData($byte_offset) . $uncompressed_data;
+            $reader = new IO_Bit();
+            $reader->input($swfdata);
+            $this->_swfdata  = $swfdata;
+            $reader->setOffset($byte_offset, 0);
+        }
+        /* SWF Movie Header */
+        $this->_headers['FrameSize'] = IO_SWF_Type_RECT::parse($reader);
+        $reader->byteAlign();
+        $this->_headers['FrameRate'] = $reader->getUI16LE();
+        $this->_headers['FrameCount'] = $reader->getUI16LE();
+
+        list($this->_header_size, $dummy) = $reader->getOffset();
+
+        /* SWF Tags */
+        while (true) {
+      	    $tag = new IO_SWF_Tag();
+            $tag->parse($reader);
+            $this->_tags[] = $tag;
+            if ($tag->code == 0) { // END Tag
+                break;
+            }
+        }
+        return true;
+    }
+
+    function build() {
+        $writer_head = new IO_Bit();
+        $writer = new IO_Bit();
+
+        /* SWF Header */
+        $writer_head->putData($this->_headers['Signature']);
+        $writer_head->putUI8($this->_headers['Version']);
+        $writer_head->putUI32LE($this->_headers['FileLength']);
+
+        /* SWF Movie Header */
+	IO_SWF_Type_RECT::build($writer, $this->_headers['FrameSize']);
+        $writer->byteAlign();
+        $writer->putUI16LE($this->_headers['FrameRate']);
+        $writer->putUI16LE($this->_headers['FrameCount']);
+
+        /* SWF Tags */
+        foreach ($this->_tags as $tag) {
+            $tagData = $tag->build();
+	    if ($tagData != false) {
+                $writer->putData($tag->build());
+	    }
+        }
+        list($fileLength, $bit_offset_dummy) = $writer->getOffset();
+        $fileLength += 8; // swf header
+        $this->_headers['FileLength'] = $fileLength;
+        $writer_head->setUI32LE($fileLength, 4);
+        if ($this->_headers['Signature']{0} == 'C') {
+            return $writer_head->output() . gzcompress($writer->output());
+        }
+        return $writer_head->output().$writer->output();
+    }
+}