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();
+ }
+}