Diffs
IO_SWF/tags/1.0.5-stable-20110128011402/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/1.0.5-stable-20110128011402/sample/swfcopy.php
@@ -0,0 +1,21 @@
+<?php
+
+require '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/1.0.5-stable-20110128011402/sample/swfreplacepng.php
@@ -0,0 +1,152 @@
+<?php
+
+require_once 'IO/SWF/Editor.php';
+
+if ($argc != 4) {
+ echo "Usage: php swfreplacepng.php <swf_file> <image_id> <png_file>\n";
+ echo "ex) php swfreplacepng.php test.swf 1 test.png\n";
+ exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+assert(is_readable($argv[3]));
+
+$swfdata = file_get_contents($argv[1]);
+$image_id = (int) $argv[2];
+
+$swf = new IO_SWF_Editor();
+$swf->parse($swfdata);
+$swf->setCharacterId($swfdata);
+
+$pngfile = $argv[3];
+
+// png2lossless format translation
+
+$im = imagecreatefrompng($pngfile);
+
+if ($im === false) {
+ echo "$pngfile is not PNG file\n";
+ exit (1);
+}
+
+$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);
+
+// DefineBits,DefineBitsJPEG2,3, DefineBitsLossless,DefineBitsLossless2
+$tag_code = array(6, 21, 35, 20, 36);
+
+$content = pack('v', $image_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);
+$ret = $swf->replaceTagByCharacterId($tag_code, $image_id, $tag);
+
+if ($ret == 0) {
+ echo "Error: not found tag_code=".implode(',',$tag_code)." and image_id=$image_id tag".PHP_EOL;
+ exit (1);
+}
+
+echo $swf->build();
+
+exit(0);
IO_SWF/tags/1.0.5-stable-20110128011402/sample/swfreplacegif.php
@@ -0,0 +1,96 @@
+<?php
+
+require_once 'IO/SWF/Editor.php';
+
+if ($argc != 4) {
+ echo "Usage: php swfreplacegif.php <swf_file> <image_id> <gif_file>\n";
+ echo "ex) php swfreplacegif.php test.swf 1 test.gif\n";
+ exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+assert(is_readable($argv[3]));
+
+$swfdata = file_get_contents($argv[1]);
+$image_id = (int) $argv[2];
+
+$swf = new IO_SWF_Editor();
+$swf->parse($swfdata);
+$swf->setCharacterId($swfdata);
+
+$giffile = $argv[3];
+
+// gif2lossless format translation
+
+$im = imagecreatefromgif($giffile);
+
+if ($im === false) {
+ echo "$giffile is not GIF file\n";
+ exit (1);
+}
+
+$colortable_num = imagecolorstotal($im);
+$transparent_index = imagecolortransparent($im);
+
+$colortable = '';
+
+if ($transparent_index < 0) {
+ for ($i = 0 ; $i < $colortable_num ; $i++) {
+ $rgb = imagecolorsforindex($im, $i);
+ $colortable .= chr($rgb['red']);
+ $colortable .= chr($rgb['green']);
+ $colortable .= chr($rgb['blue']);
+ }
+} else {
+ for ($i = 0 ; $i < $colortable_num ; $i++) {
+ $rgb = imagecolorsforindex($im, $i);
+ $colortable .= chr($rgb['red']);
+ $colortable .= chr($rgb['green']);
+ $colortable .= chr($rgb['blue']);
+ $colortable .= ($i == $transparent_index)?chr(0):chr(255);
+ }
+}
+
+$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++;
+ }
+}
+
+imagedestroy($im);
+
+// DefineBits,DefineBitsJPEG2,3, DefineBitsLossless,DefineBitsLossless2
+$tag_code = array(6, 21, 35, 20, 36);
+
+$format = 3; // palette format
+$content = pack('v', $image_id).chr($format).pack('v', $width).pack('v', $height);
+$content .= chr($colortable_num - 1).gzcompress($colortable.$pixeldata);
+
+if ($transparent_index < 0) {
+ $tagCode = 20; // DefineBitsLossless
+} else {
+ $tagCode = 36; // DefineBitsLossless2
+}
+$tag = array('Code' => $tagCode,
+ 'Content' => $content);
+$ret = $swf->replaceTagByCharacterId($tag_code, $image_id, $tag);
+
+if ($ret == 0) {
+ echo "Error: not found tag_code=".implode(',',$tag_code)." and image_id=$image_id tag".PHP_EOL;
+ exit (1);
+}
+
+echo $swf->build();
+
+exit(0);
IO_SWF/tags/1.0.5-stable-20110128011402/sample/swfreplacejpeg.php
@@ -0,0 +1,63 @@
+<?php
+
+require_once 'IO/SWF/Editor.php';
+require_once 'IO/SWF/JPEG.php';
+
+if (($argc != 4) && ($argc != 5)) {
+ echo "Usage: php swfreplacejpeg.php <swf_file> <image_id> <jpeg_file> [<alpha_file>]\n";
+ echo "ex) php swfreplacejpeg.php test.swf 1 test.jpg test.alpha\n";
+ exit(1);
+}
+
+assert(is_readable($argv[1]));
+assert(is_numeric($argv[2]));
+assert(is_readable($argv[3]));
+
+$swfdata = file_get_contents($argv[1]);
+$image_id = (int) $argv[2];
+
+if (isset($argv[4])) { // with alphadata
+ assert(is_readable($argv[4]));
+ $alphadata = file_get_contents($argv[4]);
+} else {
+ $alphadata = null;
+}
+
+$swf = new IO_SWF_Editor();
+$swf->parse($swfdata);
+$swf->setCharacterId($swfdata);
+
+$erroneous_header = pack('CCCC', 0xFF, 0xD9, 0xFF, 0xD8);
+$jpegdata = file_get_contents($argv[3]);
+
+$tag_code = array(6, 21, 35); // DefineBits, DefineBitsJPEG2,3
+
+$swf_jpeg = new IO_SWF_JPEG();
+$swf_jpeg->input($jpegdata);
+$jpeg_table = $swf_jpeg->getEncodingTables();
+$jpeg_image = $swf_jpeg->getImageData();
+
+if (is_null($alphadata)) {
+ // 21: DefineBitsJPEG2
+ $content = pack('v', $image_id).$jpeg_table.$jpeg_image;
+ $tag = array('Code' => 21,
+ 'Content' => $content);
+ $ret = $swf->replaceTagByCharacterId($tag_code, $image_id, $tag);
+} else {
+ // 35: DefineBitsJPEG3
+ $jpeg_data = $jpeg_table.$jpeg_image;
+ $compressed_alphadata = gzcompress($alphadata);
+ $content = pack('v', $image_id).pack('V', strlen($jpeg_data)).$jpeg_data.$compressed_alphadata;
+ $tag = array('Code' => 35,
+ 'Content' => $content);
+ $ret = $swf->replaceTagByCharacterId($tag_code, $image_id, $tag);
+}
+
+if ($ret == 0) {
+ echo "Error: not found tag_code=".implode(',',$tag_code)." and image_id=$image_id tag".PHP_EOL;
+ exit (1);
+}
+
+echo $swf->build();
+
+exit(0);
IO_SWF/tags/1.0.5-stable-20110128011402/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/1.0.5-stable-20110128011402/sample/swfdump.php
@@ -0,0 +1,21 @@
+<?php
+
+require 'IO/SWF/Dumper.php';
+
+if ($argc != 2) {
+ echo "Usage: php swfdump.php <swf_file>\n";
+ echo "ex) php swfdump.php test.swf\n";
+ exit(1);
+}
+
+assert(is_readable($argv[1]));
+
+$swfdata = file_get_contents($argv[1]);
+
+$swf = new IO_SWF_Dumper();
+
+$swf->parse($swfdata);
+
+$swf->dump();
+
+exit(0);
IO_SWF/tags/1.0.5-stable-20110128011402/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/1.0.5-stable-20110128011402/IO/SWF/Dumper.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * 2010/8/12- (c) yoya@awm.jp
+ */
+
+require_once dirname(__FILE__).'/../SWF.php';
+require_once dirname(__FILE__).'/Shape.php';
+
+class IO_SWF_Dumper extends IO_SWF {
+ // instance variable
+ // var $_headers = array(); // protected
+ // var $_tags = array(); // protected
+
+ function dump() {
+ /* 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: '.PHP_EOL;
+ echo "\tXmin: ".($this->_headers['FrameSize']['Xmin'] / 20).PHP_EOL;
+ echo "\tXmax: ".($this->_headers['FrameSize']['Xmax'] / 20).PHP_EOL;
+ echo "\tYmin: ".($this->_headers['FrameSize']['Ymin'] / 20).PHP_EOL;
+ echo "\tYmax: ".($this->_headers['FrameSize']['Ymax'] / 20).PHP_EOL;
+ echo 'FrameRate: '.($this->_headers['FrameRate'] / 0x100).PHP_EOL;
+ echo 'FrameCount: '.$this->_headers['FrameCount'].PHP_EOL;
+
+ /* SWF Tags */
+
+ echo 'Tags:'.PHP_EOL;
+ foreach ($this->_tags as $tag) {
+ $code = $tag['Code'];
+ $length = $tag['Length'];
+ echo "\tCode: $code Length: $length".PHP_EOL;
+ switch ($code) {
+ case 2: // DefineShape
+ case 22: // DefineShape2
+ case 32: // DefineShape3
+ $shape = new IO_SWF_Shape();
+ $shape->parse($code, $tag['Content']);
+ $shape->dump();
+ break;
+ }
+ }
+ }
+}
IO_SWF/tags/1.0.5-stable-20110128011402/IO/SWF/Shape.php
@@ -0,0 +1,282 @@
+<?php
+
+require_once 'IO/Bit.php';
+
+class IO_SWF_Shape {
+ var $_shapeId;
+ var $_shapeBounds;
+ var $_fillStyles = array(), $_lineStyles = array();
+ var $_shapeRecords = array();
+ function parse($tagCode, $content) {
+ $reader = new IO_Bit();
+ $reader->input($content);
+ $this->_shapeId = $reader->getUI16LE();
+ $this->_shapeBounds = IO_SWF_Type::parseRECT($reader);
+
+ $this->_parseFILLSTYLEARRAY($reader);
+ $this->_parseLINESTYLEARRAY($reader);
+
+ $reader->byteAlign();
+ $numFillBits = $reader->getUIBits(4);
+ $numLineBits = $reader->getUIBits(4);
+ $currentDrawingPositionX = 0;
+ $currentDrawingPositionY = 0;
+ $currentFillStyle0 = 0;
+ $currentFillStyle1 = 0;
+ $currentLineStyle = 0;
+ $done = false;
+ while ($done === false) {
+ $shapeRecord = array();
+ $typeFlag = $reader->getUIBit();
+ $shapeRecord['TypeFlag'] = $typeFlag;
+ if ($typeFlag == 0) {
+ $endOfShape = $reader->getUIBits(5); // XXX not 4 ?
+ if ($endOfShape == 0) {
+ $shapeRecord['EndOfShape'] = $endOfShape;
+ $done = true;
+ } else {
+ $reader->incrementOffset(0, -5); // XXX not 4 ?
+ $stateNewStyles = $reader->getUIBit();
+ $stateLineStyle = $reader->getUIBit();
+ $stateFillStyle1 = $reader->getUIBit();
+ $stateFillStyle0 = $reader->getUIBit();
+// $shapeRecord['(StateNewStyles)'] = $stateNewStyles;
+// $shapeRecord['(StateLineStyle)'] = $stateLineStyle;
+// $shapeRecord['(StateFillStyle1)'] = $stateFillStyle1;
+// $shapeRecord['(StateFillStyle0)'] = $stateFillStyle0;
+ //
+ $stateMoveTo = $reader->getUIBit();
+// $shapeRecord['(StateMoveTo)'] = $stateMoveTo;
+ 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['(MoveDeltaX)'] = $moveDeltaX;
+// $shapeRecord['(MoveDeltaY)'] = $moveDeltaY;
+ $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) {
+ $this->_parseFILLSTYLEARRAY($reader);
+ $this->_parseLINESTYLEARRAY($reader);
+
+ $reader->byteAlign();
+ $numFillBits = $reader->getUIBits(4);
+ $numLineBits = $reader->getUIBits(4);
+ }
+ }
+ } else { // Edge
+ $shapeRecord['StraightFlag'] = $reader->getUIBit();
+ if ($shapeRecord['StraightFlag']) { // Straight Edge
+ $numBits = $reader->getUIBits(4);
+// $shapeRecord['(NumBits)'] = $numBits;
+ $generalLineFlag = $reader->getUIBit();
+// $shapeRecord['(GeneralLineFlag)'] = $generalLineFlag;
+ if ($generalLineFlag == 0) {
+ $vertLineFlag = $reader->getUIBit();
+// $shapeRecord['(VertLineFlag)'] = $vertLineFlag;
+ }
+ if ($generalLineFlag || ($vertLineFlag == 0)) {
+ $deltaX = $reader->getSIBits($numBits + 2);
+// $shapeRecord['(DeltaX)'] = $deltaX;
+ $currentDrawingPositionX += $deltaX;
+ }
+ if ($generalLineFlag || $vertLineFlag) {
+ $deltaY = $reader->getSIBits($numBits + 2);
+// $shapeRecord['(DeltaY)'] = $deltaY;
+ $currentDrawingPositionY += $deltaY;
+ }
+ $shapeRecord['X'] = $currentDrawingPositionX;
+ $shapeRecord['Y'] = $currentDrawingPositionY;
+ } else { // Curved Edge
+ $numBits = $reader->getUIBits(4);
+// $shapeRecord['(NumBits)'] = $numBits;
+ $controlDeltaX = $reader->getSIBits($numBits + 2);
+ $controlDeltaY = $reader->getSIBits($numBits + 2);
+// $shapeRecord['(ControlDeltaX)'] = $controlDeltaX;
+// $shapeRecord['(ControlDeltaY)'] = $controlDeltaY;
+ $currentDrawingPositionX += $controlDeltaX;
+ $currentDrawingPositionY += $controlDeltaY;
+ $shapeRecord['ControlX'] = $currentDrawingPositionX;
+ $shapeRecord['ControlY'] = $currentDrawingPositionY;
+ $anchorDeltaX = $reader->getSIBits($numBits + 2);
+ $anchorDeltaY = $reader->getSIBits($numBits + 2);
+// $shapeRecord['(AnchorDeltaX)'] = $anchorDeltaX;
+// $shapeRecord['(AnchorDeltaY)'] = $anchorDeltaY;
+ $currentDrawingPositionX += $anchorDeltaX;
+ $currentDrawingPositionY += $anchorDeltaY;
+ $shapeRecord['AnchorX'] = $currentDrawingPositionX;
+ $shapeRecord['AnchorY'] = $currentDrawingPositionY;
+ }
+ }
+ $this->_shapeRecords []= $shapeRecord;
+ }
+
+ }
+ function _parseFILLSTYLEARRAY($reader) {
+ // FillStyle
+ $fillStyleCount = $reader->getUI8();
+ if (($tagCode > 2) && ($fillStyleCount == 0xff)) {
+ // DefineShape2 以降は 0xffff サイズまで扱える
+ $fillStyleCount = $reader->getUI16LE();
+ }
+ for ($i = 0 ; $i < $fillStyleCount ; $i++) {
+ $fillStyle = array();
+ $fillStyleType = $reader->getUI8();
+ switch ($fillStyleType) {
+ case 0x00: // solid fill
+ $fillStyle['FillStyleType'] = $fillStyleType;
+ if ($tagCode < 32 ) { // 32:DefineShape3
+ $fillStyle['Color'] = IO_SWF_Type::parseRGB($reader);
+ } else {
+ $fillStyle['Color'] = IO_SWF_Type::parseRGBA($reader);
+ }
+ break;
+ case 0x10: // linear gradient fill
+ case 0x12: // radianar gradient fill
+ $fillStyle['SpreadMode'] = $reader->getUIBits(2);
+ $fillStyle['InterpolationMode'] = $reader->getUIBits(2);
+ $numGradients = $reader->getUIBits(4);
+ $fillStyle['NumGradients'] = $numGradients;
+ $fillStyle['GradientRecords'] = array();
+ for ($i = 0 ; $i < $numGradients ; $i++) {
+ $gradientRecord = array();
+ $gradientRecord['Ratio'] = $reader->getUI8();
+ if ($tagCode < 32 ) { // 32:DefineShape3
+ $gradientRecord['Color'] = IO_SWF_Type::parseRGB($reader);
+ } else {
+ $gradientRecord['Color'] = IO_SWF_Type::parseRGBA($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();
+ $fillStyle['BitmapMatrix'] = IO_SWF_Type::parseMATRIX($reader);
+ break;
+ default:
+ break 2; // XXX
+ }
+ $this->_fillStyles[] = $fillStyle;
+ }
+ }
+ function _parseLINESTYLEARRAY($reader) {
+ $lineStyleCount = $reader->getUI8();
+ if (($tagCode > 2) && ($lineStyleCount == 0xff)) {
+ // DefineShape2 以降は 0xffff サイズまで扱える
+ $lineStyleCount = $reader->getUI16LE();
+ }
+ for ($i = 0 ; $i < $lineStyleCount ; $i++) {
+ $lineStyle = array();
+ $lineStyle['Width'] = $reader->getUI16LE();
+ if ($tagCode < 32 ) { // 32:DefineShape3
+ $lineStyle['Color'] = IO_SWF_Type::parseRGB($reader);
+ } else {
+ $lineStyle['Color'] = IO_SWF_Type::parseRGBA($reader);
+ }
+ $this->_lineStyles[] = $lineStyle;
+ }
+ }
+ function dump() {
+ echo "ShapeId: {$this->_shapeId}\n";
+ echo "ShapeBounds:\n";
+ $Xmin = $this->_shapeBounds['Xmin'] / 20;
+ $Xmax = $this->_shapeBounds['Xmax'] / 20;
+ $Ymin = $this->_shapeBounds['Xmin'] / 20;
+ $Ymax = $this->_shapeBounds['Ymax'] / 20;
+ echo "\t($Xmin, $Ymin) - ($Xmax, $Ymax)\n";
+ echo "FillStyles:\n";
+ foreach ($this->_fillStyles as $fillStyle) {
+ $fillStyleType = $fillStyle['FillStyleType'];
+ switch ($fillStyleType) {
+ case 0x00: // solid fill
+ $color = $fillStyle['Color'];
+ $color_str = IO_SWF_Type::stringRGBorRGBA($color);
+ echo "\tsolid fill: $color_str\n";
+ break;
+ case 0x10: // linear gradient fill
+ case 0x12: // radianar gradient fill
+ if ($fillStyleType == 0x10) {
+ echo "\tlinear gradient fill\n";
+ } else {
+ echo "\tradianar gradient fill\n";
+ }
+ $spreadMode = $fillStyle['SpreadMode'];
+ $interpolationMode = $fillStyle['InterpolationMode'];
+ foreach ($fillStyle['GradientRecords'] as $gradientRecord) {
+ $ratio = $gradientRecords['Ratio'];
+ $color = $gradientRecords['Color'];
+ $color_str = IO_SWF_Type::stringRGBorRGBA($color);
+ echo "\t\tRatio: $radio Color:$color_str\n";
+ }
+ break;
+
+ }
+ }
+ echo "LineStyles:\n";
+ foreach ($this->_lineStyles as $lineStyle) {
+ $witdh = $lineStyle['Width'];
+ $color = $lineStyle['Color'];
+ $color_str = IO_SWF_Type::stringRGBorRGBA($color);
+ echo "\tWitdh: $width Color: $color_str\n";
+ }
+ echo "ShapeRecords:\n";
+ foreach ($this->_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";
+
+ }
+ } 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: ($anchorX, $anchorY) Control($controlX, $controlY)\n";
+ }
+ }
+ }
+ }
+ function build() {
+ $tagData = '';
+ return $tagData;
+ }
+
+}
IO_SWF/tags/1.0.5-stable-20110128011402/IO/SWF/Type.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * 2011/1/25- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+
+class IO_SWF_Type {
+ static function parseRECT($reader) {
+ $frameSize = array();
+ $nBits = $reader->getUIBits(5);
+// $frameSize['(NBits)'] = $nBits;
+ $frameSize['Xmin'] = $reader->getSIBits($nBits);
+ $frameSize['Xmax'] = $reader->getSIBits($nBits);
+ $frameSize['Ymin'] = $reader->getSIBits($nBits);
+ $frameSize['Ymax'] = $reader->getSIBits($nBits) ;
+ return $frameSize;
+ }
+ static function buildRECT($data) {
+ return '';
+ }
+ static function parseRGB($reader) {
+ $rgb = array();
+ $rgb['Red'] = $reader->getUI8();
+ $rgb['Green'] = $reader->getUI8();
+ $rgb['Blue'] = $reader->getUI8();
+ return $rgb;
+ }
+ static function buildRGB($d) {
+ return '';
+ }
+ static function stringRGB($color) {
+ return sprintf("#%02x%02x%02x", $color['Red'], $color['Green'], $color['Blue']);
+ }
+ static function parseRGBA($reader) {
+ $rgba = array();
+ $rgba['Red'] = $reader->getUI8();
+ $rgba['Green'] = $reader->getUI8();
+ $rgba['Blue'] = $reader->getUI8();
+ $rgba['Alpha'] = $reader->getUI8();
+ return $rgba;
+ }
+ static function buildRGBA($d) {
+ return '';
+ }
+ static function stringRGBA($color) {
+ return sprintf("#%02x%02x%02x(02x)", $color['Red'], $color['Green'], $color['Blue'], $color['Alpha']);
+ }
+ static function stringRGBorRGBA($color) {
+ if (isset($color['Alpha'])) {
+ return self::stringRGBA($color);
+ } else {
+ return self::stringRGB($color);
+ }
+ }
+ static function parseMATRIX($reader) {
+ $matrix = array();
+ $hasScale = $reader->getUIBit();
+ if ($hasScale) {
+ $nScaleBits = $reader->getUIBits(5);
+// $matrix['(NScaleBits)'] = $nScaleBits;
+ $matrix['ScaleX'] = $reader->getSIBits($nScaleBits);
+ $matrix['ScaleY'] = $reader->getSIBits($nScaleBits);
+ }
+ $hasRotate = $reader->getUIBit();
+ if ($hasRotate) {
+ $nRotateBits = $reader->getUIBits(5);
+// $matrix['(NRotateBits)'] = $nRotateBits;
+ $matrix['RotateSkew0'] = $reader->getSIBits($nRotateBits);
+ $matrix['RotateSkew1'] = $reader->getSIBits($nRotateBits);
+ }
+ $nTranslateBits = $reader->getUIBits(5);
+ $matrix['TranslateX'] = $reader->getSIBits($nTranslateBits);
+ $matrix['TranslateY'] = $reader->getSIBits($nTranslateBits);
+ return $matrix;
+ }
+ static function buildMATRIX($d) {
+ return '';
+ }
+}
\ No newline at end of file
IO_SWF/tags/1.0.5-stable-20110128011402/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/1.0.5-stable-20110128011402/IO/SWF/Editor.php
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * 2010/8/12- (c) yoya@awm.jp
+ */
+
+require_once dirname(__FILE__).'/../SWF.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: // DefineText
+ case 37: // DefineTextEdit
+ $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['Length'] = strlen($content);
+ $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 = 0;
+ foreach ($this->_tags as &$tag) {
+ if (in_array($tag['Code'], $tagCode) && isset($tag['CharacterId'])) {
+ if ($tag['CharacterId'] == $characterId) {
+ $tag['Length'] = 2 + strlen($content_after_character_id);
+ $tag['Content'] = pack('v', $characterId).$content_after_character_id;
+ $ret = 1;
+ 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;
+ }
+}
IO_SWF/tags/1.0.5-stable-20110128011402/IO/SWF.php
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * 2010/8/11- (c) yoya@awm.jp
+ */
+
+require_once 'IO/Bit.php';
+require_once dirname(__FILE__).'/SWF/Type.php';
+
+class IO_SWF {
+ // instance variable
+ var $_headers = array(); // protected
+ var $_tags = array(); // protected
+
+ function parse($swfdata) {
+ $reader = new IO_Bit();
+ $reader->input($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;
+ }
+ $reader = new IO_Bit();
+ $reader->input($uncompressed_data);
+ }
+ /* SWF Movie Header */
+ $this->_headers['FrameSize'] = IO_SWF_Type::parseRECT($reader);
+ $reader->byteAlign();
+ $this->_headers['FrameRate'] = $reader->getUI16LE();
+ $this->_headers['FrameCount'] = $reader->getUI16LE();
+
+ /* SWF Tags */
+ while (true) {
+ $tag = Array();
+ $tagAndLength = $reader->getUI16LE();
+ $code = $tagAndLength >> 6;
+ $length = $tagAndLength & 0x3f;
+ if ($length == 0x3f) { // long format
+ $length = $reader->getUI32LE();
+ $tag['LongFormat'] = true;
+ }
+ $tag['Code'] = $code;
+ $tag['Length'] = $length;
+ $tag['Content'] = $reader->getData($length);
+ $this->_tags[] = $tag;
+ if ($code == 0) { // END Tag
+ break;
+ }
+ }
+ return true;
+ }
+ // function dump() => IO_SWF_Dumper
+
+ 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 */
+ $nBits = $this->_headers['FrameSize']['NBits'];
+ $writer->putUIBits($nBits, 5);
+ $writer->putSIBits($this->_headers['FrameSize']['Xmin'], $nBits);
+ $writer->putSIBits($this->_headers['FrameSize']['Xmax'], $nBits);
+ $writer->putSIBits($this->_headers['FrameSize']['Ymin'], $nBits);
+ $writer->putSIBits($this->_headers['FrameSize']['Ymax'], $nBits);
+ $writer->byteAlign();
+ $writer->putUI16LE($this->_headers['FrameRate']);
+ $writer->putUI16LE($this->_headers['FrameCount']);
+
+ /* SWF Tags */
+ foreach ($this->_tags as $tag) {
+ $code = $tag['Code'];
+ $length = $tag['Length'];
+ if (empty($tag['LongFormat']) && ($length < 0x3f)) {
+ $tagAndLength = ($code << 6) | $length;
+ $writer->putUI16LE($tagAndLength);
+ } else {
+ $tagAndLength = ($code << 6) | 0x3f;
+ $writer->putUI16LE($tagAndLength);
+ $writer->putUI32LE($length);
+ }
+ $writer->putData($tag['Content']);
+ }
+ 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();
+ }
+}