--- /dev/null
+% tar xvfz swfed-?.??.tar.gz
+% cd src
+% phpize
+% ./configure
+% make
+% su
+Password:
+# cp modules/swfed.so <php extension dir>/.
--- /dev/null
+ SWF Editor for PHP
+ 2008/08/08- yoya@awm.jp
+
+* introduce
+
+ this is php extension for edit SWF file.
+
+* require
+
+ - php on unix
+ - zlib and libpng
+
+
+* sample
+
+ - replace image id = 1 jpeg data
+ $swf = new SWFEditor();
+ $swf->input($swfdata);
+ $swf->replaceJpegData(1, $jpegdata);
+ echo $swf->output();
+
+ - other sample code
+ http://svn.sourceforge.jp/svnroot/swfed/sample/
+
+* demo
+
+ - http://awm.jp/~yoya/php/flash/swfdump/
+ - http://diary.awm.jp/~yoya/?20080331#200803311
+ - http://diary.awm.jp/~yoya/?20080514#200805141
+
+
+* download
+
+ - http://sourceforge.jp/projects/swfed/files/ release
+ - http://svn.sourceforge.jp/svnroot/swfed/ current
+
+* install
+
+ - see install.txt
+
+* more information
+
+ - http://sourceforge.jp/projects/swfed/wiki/
--- /dev/null
+<?php
+
+$compress = true;
+
+switch($argc) {
+ case 2:
+ $swf_filename = $argv[1];
+ break;
+ case 3:
+ if ($argv[1] == '-u') {
+ $compress = false;
+ $swf_filename = $argv[2];
+ break;
+ }
+ default:
+ fprintf(STDERR, "Usage: php swfcompress.phps [-u] <swf_file>\n");
+ exit(1);
+}
+
+$swf_data = file_get_contents($swf_filename);
+
+$swf = new SWFEditor();
+$swf->input($swf_data);
+$info = array('compress' => $compress);
+$swf->setHeaderInfo($info);
+
+echo $swf->output();
--- /dev/null
+<?php
+
+if ($argc < 2) {
+ fprintf(STDERR, "Usage: swfdump <swf_file>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+$obj->input($swfdata);
+$obj->swfInfo();
--- /dev/null
+<?php
+
+if ($argc != 3) {
+ fprintf(STDERR, "Usage: swfgeteditstrint <swf_file> <var_name>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$var_name = $argv[2];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+$obj->input($swfdata);
+
+echo $obj->getEditString($var_name) . "\n";
--- /dev/null
+<?php
+
+if ($argc != 3) {
+ fprintf(STDERR, "Usage: swfgetjpegalphadata <swf_file> <image_id>\n");
+ exit(1);
+}
+$swf_filename = $argv[1];
+$image_id = $argv[2];
+$swfdata = file_get_contents($swf_filename);
+$obj = new SWFEditor();
+$obj->input($swfdata);
+echo $obj->getJpegAlpha($image_id);
--- /dev/null
+<?php
+
+if ($argc != 3) {
+ fprintf(STDERR, "Usage: swfgetjpegdata <swf_file> <image_id>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$image_id = $argv[2];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+$obj->input($swfdata);
+
+echo $obj->getJpegData($image_id);
--- /dev/null
+<?php
+
+if ($argc != 3) {
+ fprintf(STDERR, "Usage: swfgetpngdata <swf_file> <image_id>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$image_id = $argv[2];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+$obj->input($swfdata);
+
+echo $obj->getPNGData($image_id);
--- /dev/null
+<?php
+
+if ($argc != 3) {
+ fprintf(STDERR, "Usage: swfgetsounddata <swf_file> <sound_id>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$sound_id = $argv[2];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+$obj->input($swfdata);
+
+echo $obj->getSoundData($sound_id);
--- /dev/null
+<?php
+
+if ($argc < 4) {
+ fprintf(STDERR, "Usage: swfreplaceeditstring <swf_file> <variable_name> <initial_text>\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+$variable_name = $argv[2];
+$initial_text = $argv[3];
+$swfdata = file_get_contents($swf_filename);
+
+$obj = new SWFEditor();
+if ($obj->input($swfdata) == false) {
+ fprintf(STDERR, "input failed\n");
+ exit (1);
+}
+if ($obj->replaceEditString($variable_name, $initial_text) == false) {
+ fprintf(STDERR, "replaceEditString($variable_name, ...) failed\n");
+ exit (1);
+
+}
+
+echo $obj->output();
--- /dev/null
+<?php
+
+if ($argc < 4) {
+ fprintf(STDERR, "Usage: swfreplacejpegdata <swf_file> <image_id> <jpeg_file> [alpha_file]\n");
+ exit(1);
+}
+
+if ($argc > 3) {
+ $swf_filename = $argv[1];
+ $image_id = $argv[2];
+ $jpeg_filename = $argv[3];
+ if ($argc > 4) {
+ $alpha_filename = $argv[4];
+ }
+}
+
+$swfdata = file_get_contents($swf_filename);
+$jpegdata = file_get_contents($jpeg_filename);
+
+if (! empty($alpha_filename)) {
+ $alphadata = file_get_contents($alpha_filename);
+}
+
+$obj = new SWFEditor();
+if ($obj->input($swfdata) == false) {
+ fprintf(STDERR, "input failed\n");
+ exit (1);
+}
+
+if (empty($alphadata)) {
+ $result = $obj->replaceJpegData($image_id, $jpegdata);
+} else {
+ $result = $obj->replaceJpegData($image_id, $jpegdata, $alphadata);
+}
+
+if ($result == false) {
+ fprintf(STDERR, "replaceJpegdata($image_id, ...) failed\n");
+ exit (1);
+}
+
+echo $obj->output();
--- /dev/null
+<?php
+
+if (($argc < 4) || ($argc%2 != 0)) {
+ fprintf(STDERR, "Usage: swfreplacemlddata <swf_file> <sound_id> <mld_file> [<sound_id2> <mld_file2> [...]]\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+
+$swfdata = file_get_contents($swf_filename);
+$obj = new SWFEditor();
+$obj->input($swfdata);
+
+for ($i=2 ; $i< $argc ; $i += 2) {
+ $sound_id = $argv[$i];
+ $mld_filename = $argv[$i+1];
+ $mlddata = file_get_contents($mld_filename);
+ $obj->replaceMLDData($sound_id, $mlddata);
+}
+
+echo $obj->output();
--- /dev/null
+<?php
+
+if (($argc < 4) || ($argc%2 != 0)) {
+ fprintf(STDERR, "Usage: swfreplacepngdata <swf_file> <image_id> <png_file> [<image_id2> <png_file2> [...]]\n");
+ exit(1);
+}
+
+$swf_filename = $argv[1];
+
+$swfdata = file_get_contents($swf_filename);
+$obj = new SWFEditor();
+if ($obj->input($swfdata) == false) {
+ fprintf(STDERR, "input failed\n");
+ exit (1);
+}
+
+for ($i=2 ; $i< $argc ; $i += 2) {
+ $image_id = $argv[$i];
+ $png_filename = $argv[$i+1];
+ $pngdata = file_get_contents($png_filename);
+ if ($obj->replacePNGData($image_id, $pngdata) == false) {
+ fprintf(STDERR, "replacePNGdata($image_id, ...) failed\n");
+ exit (1);
+ }
+}
+
+echo $obj->output();
--- /dev/null
+/*
+ * bit stream routine
+ * (C) 2008/03/09- yoya@awm.jp
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bitstream.h"
+
+static void bitstream_clear(bitstream_t *bs);
+
+bitstream_t *
+bitstream_open(void) {
+ bitstream_t *bs = (bitstream_t *) calloc(sizeof(*bs), 1);
+ bs->data = NULL;
+ bs->data_len = 0;
+ bs->data_alloc_len = 0;
+ bs->byte_offset = 0;
+ bs->bit_offset = 0;
+ return bs;
+}
+
+void
+bitstream_close(bitstream_t * bs) {
+ if (bs->data) {
+ free(bs->data);
+ }
+ free(bs);
+ return ;
+}
+
+static void
+bitstream_clear(bitstream_t *bs) {
+ if (bs->data) {
+ free(bs->data);
+ bs->data = NULL;
+ }
+ bs->data_len = 0;
+ bs->data_alloc_len = 0;
+ bs->byte_offset = 0;
+ bs->bit_offset = 0;
+ return ;
+}
+
+int
+bitstream_realloc(bitstream_t *bs) {
+ unsigned char *data;
+ bs->data_alloc_len *= 2;
+ if (bs->data_alloc_len < BITSTREAM_DATA_LEN_MIN) {
+ bs->data_alloc_len = BITSTREAM_DATA_LEN_MIN;
+ }
+ data = (unsigned char *) realloc(bs->data, bs->data_alloc_len);
+ if (! data) {
+ fprintf(stderr, "bitstream_realloc: Can't realloc memory (%p, %ld)\n",
+ data, bs->data_alloc_len);
+ return 1;
+ }
+ bs->data = data;
+ return 0;
+}
+
+int
+bitstream_input(bitstream_t *bs, unsigned char *data,
+ unsigned long data_len) {
+ bitstream_clear(bs);
+ bs->data_alloc_len = data_len;
+ bs->data = malloc(bs->data_alloc_len);
+ memcpy(bs->data, data, data_len);
+ bs->data_len = data_len;
+ return 0;
+}
+
+unsigned char *
+bitstream_steal(bitstream_t *bs, unsigned long *length) {
+ unsigned char *data, *tmp;
+ *length = 0;
+ if (! bs) {
+ return NULL;
+ }
+ data = bs->data;
+ *length = bs->data_len;
+ if ((tmp = realloc(data, *length)) == NULL) {
+ fprintf(stderr, "Can't realloc\n");
+ }
+ bs->data = NULL;
+ bs->data_len = 0;
+ bs->data_alloc_len = 0;
+ return data;
+}
+
+unsigned char *
+bitstream_output_sub(bitstream_t *bs, unsigned long offset, unsigned long length) {
+ unsigned char *data;
+ if (! bs) {
+ fprintf(stderr, "bs == NULL");
+ return NULL;
+ }
+ if (bs->data_len < offset + length ) {
+ fprintf(stderr, "bitstream_output_sub: bs->data_len(%lu) < offset(%lu)+length(%lu)\n",
+ bs->data_len, offset, length);
+ return NULL;
+ }
+ data = malloc(length);
+ if (data == NULL) {
+ fprintf(stderr, "bitstream_output_sub: Can't malloc\n");
+ return NULL;
+ }
+ memcpy(data, bs->data + offset, length);
+ return data;
+}
+
+/*
+ * byte stream
+ */
+
+int
+bitstream_putbyte(bitstream_t *bs, int byte) {
+ bitstream_align(bs);
+ if (bs->data_len < bs->byte_offset ) {
+ return 1;
+ }
+ if (bs->data_len == bs->byte_offset ) {
+ if (bs->data_alloc_len <= bs->byte_offset ) {
+ bitstream_realloc(bs);
+ }
+ bs->data_len ++;
+ }
+ byte &= 0xff;
+ bs->data[bs->byte_offset] = (unsigned char) byte ;
+ bs->byte_offset++;
+ return 0;
+}
+
+int
+bitstream_getbyte(bitstream_t *bs) {
+ int byte;
+ bitstream_align(bs);
+ if (bs->data_len <= bs->byte_offset) {
+ return -1; /* End of Stream */
+ }
+ byte = bs->data[bs->byte_offset] & 0xff;
+ bs->byte_offset++;
+ return byte;
+}
+
+int
+bitstream_putstring(bitstream_t *bs,
+ unsigned char *data, signed long data_len) {
+ bitstream_align(bs);
+ if (bs->data_len < bs->byte_offset ) {
+ return 1;
+ }
+ while(bs->data_alloc_len < bs->byte_offset + data_len) {
+ bitstream_realloc(bs);
+ }
+ bs->data_len = bs->byte_offset + data_len;
+ memcpy(bs->data + bs->byte_offset, data, data_len);
+ bs->byte_offset += data_len;
+ return 0;
+}
+
+int
+bitstream_getstring(bitstream_t *bs,
+ unsigned char *data, signed long data_len) {
+ bitstream_align(bs);
+ if (bs->data_len < bs->byte_offset + data_len) {
+ return -1; /* End of Stream */
+ }
+ memcpy(data, bs->data + bs->byte_offset, data_len);
+ bs->byte_offset += data_len;
+ return 0;
+}
+
+unsigned char *
+bitstream_outputstring(bitstream_t *bs) {
+ unsigned char *data;
+ unsigned long data_len;
+ bitstream_align(bs);
+ data_len = strlen((char *) bs->data + bs->byte_offset);
+ data_len += 1; // + '\0'
+ if (bs->data_len < bs->byte_offset + data_len) {
+ return NULL; /* End of Stream */
+ }
+ data = malloc(data_len);
+ if (data == NULL) {
+ fprintf(stderr, "bitstream_outputstring: can't malloc\n");
+ return NULL;
+ }
+ memcpy(data, bs->data + bs->byte_offset, data_len);
+ bs->byte_offset += data_len;
+ return data;
+}
+
+int
+bitstream_putbytesLE(bitstream_t *bs, unsigned long bytes, int byte_width) {
+ int i;
+ unsigned long byte;
+ for (i=0; i < byte_width; i++) {
+ byte = bytes & 0xff;
+ bitstream_putbyte(bs, byte);
+ bytes >>= 8;
+ }
+ return 0;
+}
+
+int
+bitstream_putbytesBE(bitstream_t *bs, unsigned long bytes, int byte_width) {
+ int i;
+ unsigned long byte;
+ for (i=0; i < byte_width; i++) {
+ byte = bytes >> ( 8 * (byte_width - 1 - i));
+ bitstream_putbyte(bs, byte & 0xff);
+ }
+ return 0;
+}
+
+unsigned long
+bitstream_getbytesLE(bitstream_t *bs, int byte_width) {
+ int i;
+ unsigned long byte, bytes = 0;
+ for (i=0; i < byte_width; i++) {
+ byte = bitstream_getbyte(bs);
+ byte <<= 8 * i;
+ bytes |= byte;
+ }
+ return bytes;
+}
+
+unsigned long
+bitstream_getbytesBE(bitstream_t *bs, int byte_width) {
+ int i;
+ unsigned long byte, bytes = 0;
+ for (i=0; i < byte_width; i++) {
+ bytes <<= 8;
+ byte = bitstream_getbyte(bs);
+ bytes |= byte;
+ }
+ return bytes;
+}
+
+/*
+ * bit stream
+ */
+
+int
+bitstream_putbit(bitstream_t *bs, int bit) {
+ int byte;
+ if (bs->data_len <= bs->byte_offset) {
+// fprintf(stderr, "bs->data_len(%ld) <= bs->byte_offset(%ld)\n",
+// bs->data_len, bs->byte_offset);
+ if (bs->data_alloc_len <= bs->byte_offset) {
+ fprintf(stderr, "bitstream_putbit: alloc_len=%lu\n", bs->data_alloc_len);
+ bitstream_realloc(bs);
+ }
+ bs->data[bs->byte_offset] = 0;
+ bs->data_len ++;
+// return 1;
+ }
+ bit &= 1;
+ byte = bs->data[bs->byte_offset];
+ byte |= bit << (7 - bs->bit_offset);
+ bs->data[bs->byte_offset] = byte;
+ bitstream_incrpos(bs, 0, 1);
+ return 0;
+}
+int
+bitstream_getbit(bitstream_t *bs) {
+ int bit, byte;
+ if (bs->data_len <= bs->byte_offset) {
+ fprintf(stderr, "bitstream_getbit: bs->data_len(%ld) <= bs->byte_offset(%ld)\n",
+ bs->data_len, bs->byte_offset);
+ return -1; /* End of Stream */
+ }
+ byte = bs->data[bs->byte_offset];
+ bit = byte >> (7 - bs->bit_offset);
+ bitstream_incrpos(bs, 0, 1);
+ return bit & 1;
+}
+
+int
+bitstream_putbits(bitstream_t *bs, unsigned long bits, int bit_width) {
+ int i, bit;
+ for (i=0; i < bit_width; i++) {
+ bit = bits >> (bit_width - 1 - i);
+ bit &= 1;
+ bitstream_putbit(bs, bit);
+ }
+ return 0;
+}
+
+unsigned long
+bitstream_getbits(bitstream_t *bs, int bit_width) {
+ int i;
+ int bit;
+ unsigned long bits = 0;
+ for (i=0; i < bit_width; i++) {
+ bit = bitstream_getbit(bs);
+ if (bit == -1) {
+ return -1;
+ }
+ bits |= bit << (bit_width - 1 - i);
+ }
+ return bits;
+}
+
+void
+bitstream_align(bitstream_t *bs) {
+ if (bs->bit_offset > 0) {
+ bs->byte_offset++;
+ bs->bit_offset = 0;
+ }
+}
+
+/*
+ * stream seek
+ */
+
+int
+bitstream_incrpos(bitstream_t *bs, signed long byte_incr,
+ unsigned long bit_incr) {
+ bs->byte_offset += byte_incr;
+ bs->bit_offset += bit_incr;
+ while (bs->bit_offset >= 8) {
+ bs->bit_offset -= 8;
+ bs->byte_offset ++;
+ }
+ return 0;
+}
+
+int
+bitstream_setpos(bitstream_t *bs, unsigned long byte_offset,
+ unsigned long bit_offset) {
+ if (bs->data_len <= byte_offset ) {
+ fprintf(stderr, "bitstream_setpos: bs->data_len(%ld) <= byte_offset(%ld)\n",
+ bs->data_len, byte_offset);
+ }
+ bs->byte_offset = byte_offset;
+ bs->bit_offset = bit_offset;
+ return 0;
+}
+
+unsigned long
+bitstream_getbytepos(bitstream_t *bs) {
+ return bs->byte_offset;
+}
+
+/*
+ * stream info
+ */
+
+unsigned char *
+bitstream_buffer(bitstream_t *bs, unsigned long byte_offset) {
+ return bs->data + byte_offset;
+}
+
+unsigned long
+bitstream_length(bitstream_t *bs) {
+ return bs->data_len;
+}
--- /dev/null
+#ifndef __BITSTREAM_H__
+#define __BITSTREAM_H__
+
+#include "swf_define.h" /* for malloc */
+
+/*
+ * bit stream routine
+ * (C) 2008/03/09- yoya@awm.jp
+ */
+
+typedef struct bitstream_ {
+ /* raw data */
+ unsigned char *data;
+ unsigned long data_len;
+ unsigned long data_alloc_len;
+ /* seek position */
+ unsigned long byte_offset;
+ unsigned long bit_offset;
+} bitstream_t;
+
+#define BITSTREAM_DATA_LEN_MIN 0x100
+
+extern bitstream_t *bitstream_open(void);
+extern void bitstream_close(bitstream_t * bs);
+
+/* load/save */
+extern int bitstream_input(bitstream_t *bs, unsigned char *data,
+ unsigned long data_len);
+extern unsigned char *bitstream_steal(bitstream_t *bs, unsigned long *length);
+extern unsigned char *bitstream_output_sub(bitstream_t *bs, unsigned long offset, unsigned long length);
+
+/* put/get */
+extern int bitstream_putbyte(bitstream_t *bs, int byte);
+extern int bitstream_getbyte(bitstream_t *bs);
+extern int bitstream_putstring(bitstream_t *bs,
+ unsigned char *data, signed long data_len);
+extern int bitstream_getstring(bitstream_t *bs,
+ unsigned char *data, signed long data_len);
+extern unsigned char *bitstream_outputstring(bitstream_t *bs);
+
+extern int bitstream_putbytesLE(bitstream_t *bs, unsigned long bytes, int byte_width);
+extern int bitstream_putbytesBE(bitstream_t *bs, unsigned long bytes, int byte_width);
+extern unsigned long bitstream_getbytesLE(bitstream_t *bs, int byte_width);
+extern unsigned long bitstream_getbytesBE(bitstream_t *bs, int byte_width);
+extern int bitstream_putbit(bitstream_t *bs, int bit);
+extern int bitstream_getbit(bitstream_t *bs);
+extern int bitstream_putbits(bitstream_t *bs, unsigned long bits, int bit_width);
+extern unsigned long bitstream_getbits(bitstream_t *bs, int bit_width);
+extern void bitstream_align(bitstream_t *bs);
+
+/* seeking */
+extern int bitstream_incrpos(bitstream_t *bs, signed long byte_incr,
+ unsigned long bit_incr);
+extern int bitstream_setpos(bitstream_t *bs, unsigned long byte_offset,
+ unsigned long bit_offset);
+extern unsigned long bitstream_getbytepos(bitstream_t *bs);
+
+extern int bitstream_realloc(bitstream_t *bs);
+
+/* direct access */
+extern unsigned char *bitstream_buffer(bitstream_t *bs, unsigned long byte_offset);
+extern unsigned long bitstream_length(bitstream_t *bs);
+
+#endif /* __BITSTREAM_H__ */
--- /dev/null
+dnl $Id$
+dnl config.m4 for extension swfed
+
+dnl Comments in this file start with the string 'dnl'.
+dnl Remove where necessary. This file will not work
+dnl without editing.
+
+dnl If your extension references something external, use with:
+
+dnl PHP_ARG_WITH(swfed, for swfed support,
+dnl Make sure that the comment is aligned:
+dnl [ --with-swfed Include swfed support])
+
+dnl Otherwise use enable:
+
+PHP_ARG_ENABLE(swfed, whether to enable swfed support,
+Make sure that the comment is aligned:
+[ --enable-swfed Enable swfed support])
+
+if test "$PHP_SWFED" != "no"; then
+ dnl Write more examples of tests here...
+
+ dnl # --with-swfed -> check with-path
+ dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
+ dnl SEARCH_FOR="/include/swfed.h" # you most likely want to change this
+ dnl if test -r $PHP_SWFED/$SEARCH_FOR; then # path given as parameter
+ dnl SWFED_DIR=$PHP_SWFED
+ dnl else # search default path list
+ dnl AC_MSG_CHECKING([for swfed files in default path])
+ dnl for i in $SEARCH_PATH ; do
+ dnl if test -r $i/$SEARCH_FOR; then
+ dnl SWFED_DIR=$i
+ dnl AC_MSG_RESULT(found in $i)
+ dnl fi
+ dnl done
+ dnl fi
+ dnl
+ dnl if test -z "$SWFED_DIR"; then
+ dnl AC_MSG_RESULT([not found])
+ dnl AC_MSG_ERROR([Please reinstall the swfed distribution])
+ dnl fi
+
+ dnl # --with-swfed -> add include path
+ dnl PHP_ADD_INCLUDE($SWFED_DIR/include)
+
+ dnl # --with-swfed -> check for lib and symbol presence
+ dnl LIBNAME=swfed # you may want to change this
+ dnl LIBSYMBOL=swfed # you most likely want to change this
+
+ dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
+ dnl [
+ dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $SWFED_DIR/lib, SWFED_SHARED_LIBADD)
+ dnl AC_DEFINE(HAVE_SWFEDLIB,1,[ ])
+ dnl ],[
+ dnl AC_MSG_ERROR([wrong swfed lib version or lib not found])
+ dnl ],[
+ dnl -L$SWFED_DIR/lib -lm -ldl
+ dnl ])
+ dnl
+ dnl PHP_SUBST(SWFED_SHARED_LIBADD)
+
+ PHP_NEW_EXTENSION(swfed, swfed.c swf_object.c swf_header.c swf_rect.c swf_tag.c swf_tag_jpeg.c swf_tag_edit.c swf_tag_action.c swf_tag_lossless.c swf_tag_sound.c swf_rgb.c swf_rgba.c swf_argb.c swf_xrgb.c swf_action.c swf_jpeg.c bitstream.c jpeg_segment.c swf_png.c swf_debug.c, $ext_shared)
+fi
--- /dev/null
+/*
+ ref code) http://diary.awm.jp/~yoya/data/2008/02/03/jpegdump.phps
+
+ gcc -W -Wall -D__COMPONENT_DEBUG__ jpeg_segment.c bitstream.c
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitstream.h"
+#include "jpeg_segment.h"
+#include "swf_define.h"
+
+typedef struct jpeg_marker_name_ {
+ int marker;
+ char *name;
+} jpeg_marker_name_t;
+
+jpeg_marker_name_t jpeg_marker_name_table[] = {
+ {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"}, {0xC21, "SOF2"},
+ {0xC4, "DHT"},
+ {0xDA, "SOS"},
+ {0xD0, "RST0"}, {0xD1, "RST1"}, {0xD2, "RST2"}, {0xD3, "RST3"},
+ {0xD4, "RST4"} ,{0xD5, "RST5"}, {0xD6, "RST6"}, {0xD7, "RST7"},
+ {0xDD, "DRI"},
+ {0xD9, "EOI"},
+};
+
+#define NumOfTable(t) (sizeof(t) / sizeof(*t))
+
+char *jpeg_segment_get_marker_name(int marker) {
+ int i, marker_name_num = NumOfTable(jpeg_marker_name_table);
+ for(i=0; i < marker_name_num; i++) {
+ if (marker == jpeg_marker_name_table[i].marker) {
+ return jpeg_marker_name_table[i].name;
+ }
+ }
+ return "Unknown";
+}
+
+jpeg_segment_t *jpeg_segment_create(void) {
+ jpeg_segment_t *jpeg_seg = calloc(sizeof(*jpeg_seg), 1);
+ if (jpeg_seg == NULL) {
+ fprintf(stderr, "jpeg_segment_create: Can't alloc memory\n");
+ return NULL;
+ }
+ jpeg_seg->head = NULL;
+ jpeg_seg->tail = NULL;
+ return jpeg_seg;
+}
+
+void jpeg_segment_append(jpeg_segment_t *jpeg_seg,
+ int marker,
+ unsigned char *data_ref, unsigned long data_len) {
+ jpeg_segment_node_t *node = jpeg_seg->head;
+ jpeg_segment_node_t *new_node;
+ new_node = calloc(sizeof(*node), 1);
+ if (new_node == NULL) {
+ fprintf(stderr, "jpeg_segment_append: jpeg_segment_create failed\n");
+ return ;
+ }
+ if (jpeg_seg->head == NULL) {
+ jpeg_seg->head = new_node;
+ } else {
+ jpeg_seg->tail->next = new_node;
+ }
+ jpeg_seg->tail = new_node;
+ new_node->marker = marker;
+ new_node->data_ref = data_ref;
+ new_node->data_len = data_len;
+ return ;
+}
+
+jpeg_segment_t *jpeg_segment_parse(unsigned char *data,
+ unsigned long data_len) {
+ bitstream_t *bs;
+ jpeg_segment_t *jpeg_seg;
+ int marker1;
+ unsigned len;
+ bs = bitstream_open();
+ bitstream_input(bs, data, data_len);
+ jpeg_seg = jpeg_segment_create();
+
+ while((marker1 = bitstream_getbyte(bs)) >= 0) {
+ if (marker1 != 0xFF) {
+ fprintf(stderr, "marker1=0x%02X", marker1);
+ jpeg_segment_destroy(jpeg_seg);
+ bitstream_close(bs);
+ return NULL;
+ }
+ int marker2 = bitstream_getbyte(bs);
+ int next_marker2;
+ switch(marker2) {
+ unsigned long sos_offset;
+ case -1:
+ /* removed segment */
+ break;
+ case 0xD8: // SOI (Start of Image)
+ case 0xD9: // EOI (End of Image)
+ jpeg_segment_append(jpeg_seg, marker2, NULL, 0);
+ break;
+ case 0xDA: // SOS
+ case 0xD0: case 0xD1: case 0xD2: case 0xD3: // RST
+ case 0xD4: case 0xD5: case 0xD6: case 0xD7: // RST
+ sos_offset = bitstream_getbytepos(bs);
+ while((marker1 = bitstream_getbyte(bs)) >= 0) {
+ if (marker1 != 0xFF) {
+ continue;
+ }
+ next_marker2 = bitstream_getbyte(bs);
+ if (next_marker2 == 0x00) {
+ continue;
+ }
+ bitstream_incrpos(bs, -2, 0);
+ jpeg_segment_append(jpeg_seg, marker2, data + sos_offset,
+ bitstream_getbytepos(bs) - sos_offset);
+ break;
+ }
+ break;
+ default:
+ len = bitstream_getbytesBE(bs, 2) - 2;
+ jpeg_segment_append(jpeg_seg, marker2,
+ data + bitstream_getbytepos(bs),
+ len);
+ bitstream_incrpos(bs, len, 0);
+ break;
+ }
+ }
+ bitstream_close(bs);
+ return jpeg_seg;
+}
+
+int jpeg_segment_contain(jpeg_segment_t *jpeg_seg, int marker) {
+ jpeg_segment_node_t *node;
+ for (node = jpeg_seg->head; node; node = node->next) {
+ if (node->marker == marker) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+unsigned char *jpeg_segment_steal_node(jpeg_segment_t *jpeg_seg,
+ int marker,
+ unsigned long *length) {
+ jpeg_segment_node_t *node;
+ unsigned char *data;
+ *length = 0;
+ for (node = jpeg_seg->head; node; node = node->next) {
+ if (node->marker == marker) {
+ data = node->data_ref;
+ *length = node->data_len;
+ node->marker = -1; // remove mark;
+ node->data_ref = NULL;
+ node->data_len = 0;
+ return data;
+ }
+ }
+ return NULL;
+}
+
+int
+jpeg_segment_delete_node(jpeg_segment_t *jpeg_seg, int marker) {
+ jpeg_segment_node_t *node;
+ int count = 0;
+ for (node = jpeg_seg->head; node; node = node->next) {
+ if (node->marker == marker) {
+ node->marker = -1; // remove mark;
+ if (node->data_ref) {
+ free(node->data_ref);
+ node->data_ref = NULL;
+ }
+ node->data_len = 0;
+ count ++;
+ }
+ }
+ return count;
+}
+int
+jpeg_segment_peek_marker(jpeg_segment_t *jpeg_seg) {
+ jpeg_segment_node_t *node;
+ for (node = jpeg_seg->head; node; node = node->next) {
+ if (node->marker != -1) {
+ return node->marker;
+ }
+ }
+ return -1;
+}
+
+void jpeg_segment_print(jpeg_segment_t *jpeg_seg) {
+ int i;
+ jpeg_segment_node_t *node;
+ if (jpeg_seg == NULL) {
+ fprintf(stderr, "jpeg_segment_print: jpeg_seg == NULL\n");
+ return ;
+ }
+ node = jpeg_seg->head;
+ for (i=0; node; i++) {
+ char *marker_name;
+ if (node->marker >= 0) {
+ marker_name = jpeg_segment_get_marker_name(node->marker);
+ printf("(%d) marker=%s(FF%02X): length=%lu\n",
+ i, marker_name?marker_name:"Unknown",
+ node->marker, node->data_len);
+ }
+ node = node->next;
+ }
+}
+
+extern unsigned char *jpeg_segment_output(jpeg_segment_t *jpeg_seg,
+ unsigned long *length) {
+ bitstream_t *bs;
+ unsigned char *data;
+ jpeg_segment_node_t *node;
+ *length = 0;
+ node = jpeg_seg->head;
+ bs = bitstream_open();
+ for (; node; node = node->next) {
+ int marker2 = node->marker;
+ if (marker2 == -1) {
+ continue;
+ }
+ bitstream_putbyte(bs, 0xFF); // marker1
+ bitstream_putbyte(bs, marker2); // marker2
+ switch(marker2) {
+ case 0xD8: // SOI (Start of Image)
+ case 0xD9: // EOI (End of Image)
+ /* nothing to do */
+ break;
+ default:
+ bitstream_putbytesBE(bs, node->data_len + 2, 2);
+ /* no break */
+ case 0xDA: // SOS
+ case 0xD0: case 0xD1: case 0xD2: case 0xD3: // RST
+ case 0xD4: case 0xD5: case 0xD6: case 0xD7: // RST
+ bitstream_putstring(bs, node->data_ref, node->data_len);
+ break;
+ }
+ }
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+void jpeg_segment_destroy(jpeg_segment_t *jpeg_seg) {
+ jpeg_segment_node_t *node, *next_node;
+ if (jpeg_seg == NULL) {
+ return ;
+ }
+ node = jpeg_seg->head;
+ while(node) {
+ next_node = node->next;
+ /* node->data_ref no free!! */
+ free(node);
+ node = next_node;
+ }
+ free(jpeg_seg);
+}
+
+#ifdef __COMPONENT_DEBUG__ /* for component debug */
+
+#include <sys/stat.h>
+
+int main(int argc, char **argv) {
+ char *filename;
+ struct stat sbuf;
+ FILE *fp, *fp_out = NULL;
+ unsigned char *data, *output_data;
+ unsigned long data_len, output_data_len;
+ jpeg_segment_t *jpeg_seg;
+ if ((argc != 2) && (argc != 3)) {
+ fprintf(stderr, "Usage: %s <jpeg_infile> [<jpeg_outfile>]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ filename = argv[1];
+ if (stat(filename, &sbuf)) {
+ fprintf(stderr, "Can't stat file(%s)\n", filename);
+ return EXIT_FAILURE;
+ }
+ data_len = sbuf.st_size;
+ fp = fopen(filename, "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "Can't open infile(%s)\n", filename);
+ return EXIT_FAILURE;
+ }
+ data = malloc(data_len);
+ if (fread(data, 1, data_len, fp) != data_len) {
+ fclose(fp);
+ return 1;
+ }
+ fclose(fp);
+ jpeg_seg = jpeg_segment_parse(data, data_len);
+ jpeg_segment_print(jpeg_seg);
+ if (argc == 3) {
+ fp_out = fopen(argv[2], "wb");
+ if (fp_out == NULL) {
+ fprintf(stderr, "Can't open outfile(%s)\n", argv[2]);
+ return EXIT_FAILURE;
+ }
+ output_data = jpeg_segment_output(jpeg_seg, &output_data_len);
+ fwrite(output_data, output_data_len, 1, fp_out);
+ fclose(fp_out);
+ free(output_data);
+ }
+ jpeg_segment_destroy(jpeg_seg);
+ free(data);
+ return EXIT_SUCCESS;
+}
+
+#endif
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+
+#ifndef __JPEG_SEGMENT_H__
+#define __JPEG_SEGMENT_H__
+
+typedef struct jpeg_segment_node_ {
+ int marker;
+ unsigned char *data_ref; /* do NOT free! */
+ unsigned long data_len;
+ struct jpeg_segment_node_ *next;
+} jpeg_segment_node_t;
+
+typedef struct jpeg_segment_ {
+ jpeg_segment_node_t *head, *tail;
+} jpeg_segment_t;
+
+extern jpeg_segment_t *jpeg_segment_create(void);
+
+extern void jpeg_segment_append(jpeg_segment_t *jpeg_seg_head,
+ int marker,
+ unsigned char *data,
+ unsigned long data_len);
+
+extern jpeg_segment_t *jpeg_segment_parse(unsigned char *data,
+ unsigned long data_len);
+
+extern int jpeg_segment_contain(jpeg_segment_t *jpeg_seg, int marker);
+extern unsigned char *jpeg_segment_steal_node(jpeg_segment_t *jpeg_seg,
+ int marker,
+ unsigned long *length);
+extern int jpeg_segment_delete_node(jpeg_segment_t *jpeg_seg, int marker);
+extern int jpeg_segment_peek_marker(jpeg_segment_t *jpeg_seg);
+
+extern void jpeg_segment_print(jpeg_segment_t *jpeg_seg);
+extern unsigned char *jpeg_segment_output(jpeg_segment_t *jpeg_seg,
+ unsigned long *length);
+extern void jpeg_segment_destroy(jpeg_segment_t *jpeg_seg);
+
+extern char *jpeg_segment_get_marker_name(int marker);
+
+#endif /* __JPEG_SEGMENT_H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2006 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: header,v 1.16.2.1 2006/01/01 12:50:00 sniper Exp $ */
+
+#ifndef PHP_SWFED_H
+#define PHP_SWFED_H
+
+extern zend_module_entry swfed_module_entry;
+#define phpext_swfed_ptr &swfed_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_SWFED_API __declspec(dllexport)
+#else
+#define PHP_SWFED_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+PHP_MINIT_FUNCTION(swfed);
+PHP_MSHUTDOWN_FUNCTION(swfed);
+PHP_RINIT_FUNCTION(swfed);
+PHP_RSHUTDOWN_FUNCTION(swfed);
+PHP_MINFO_FUNCTION(swfed);
+
+PHP_FUNCTION(confirm_swfed_compiled); /* For testing, remove later. */
+
+static zend_class_entry *swfeditor_ce;
+
+PHP_METHOD(swfed, __construct);
+PHP_METHOD(swfed, input);
+PHP_METHOD(swfed, output);
+PHP_METHOD(swfed, getHeaderInfo);
+PHP_METHOD(swfed, setHeaderInfo);
+PHP_METHOD(swfed, getTagList);
+PHP_METHOD(swfed, getTagDetail);
+PHP_METHOD(swfed, getTagInfo);
+PHP_METHOD(swfed, getTagData);
+PHP_METHOD(swfed, getJpegData);
+PHP_METHOD(swfed, getJpegAlpha);
+PHP_METHOD(swfed, replaceJpegData);
+PHP_METHOD(swfed, getPNGData);
+PHP_METHOD(swfed, replacePNGData);
+PHP_METHOD(swfed, getSoundData);
+PHP_METHOD(swfed, replaceMLDData);
+PHP_METHOD(swfed, getEditString);
+PHP_METHOD(swfed, replaceEditString);
+PHP_METHOD(swfed, getActionData);
+PHP_METHOD(swfed, disasmActionData);
+PHP_METHOD(swfed, swfInfo);
+
+/*
+ Declare any global variables you may need between the BEGIN
+ and END macros here:
+
+ZEND_BEGIN_MODULE_GLOBALS(swfed)
+ long global_value;
+ char *global_string;
+ZEND_END_MODULE_GLOBALS(swfed)
+*/
+
+/* In every utility function you add that needs to use variables
+ in php_swfed_globals, call TSRMLS_FETCH(); after declaring other
+ variables used by that function, or better yet, pass in TSRMLS_CC
+ after the last function argument and declare your utility function
+ with TSRMLS_DC after the last declared argument. Always refer to
+ the globals in your function as SWFED_G(variable). You are
+ encouraged to rename these macros something shorter, see
+ examples in any other php module directory.
+*/
+
+#ifdef ZTS
+#define SWFED_G(v) TSRMG(swfed_globals_id, zend_swfed_globals *, v)
+#else
+#define SWFED_G(v) (swfed_globals.v)
+#endif
+
+#endif /* PHP_SWFED_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include "bitstream.h"
+#include "swf_action.h"
+
+swf_action_info_t swf_action_info_table[] = {
+ { 0x00, "End" },
+ /* nothing 0x01 - 0x03 */
+ { 0x04, "Next Frame" },
+ { 0x05, "Previous Frame" },
+ { 0x06, "Play" },
+ { 0x07, "Stop" },
+ { 0x08, "Toggle Quality" },
+ { 0x09, "Stop Sound" },
+ { 0x0A, "Add" },
+ { 0x0B, "Subtract" },
+ { 0x0C, "Multiply" },
+ { 0x0D, "Divide" },
+ { 0x0E, "Equal" },
+ { 0x0F, "Less Than" },
+ { 0x10, "Logical And" },
+ { 0x11, "Logical Or " },
+ { 0x12, "Logical Not" },
+ { 0x13, "String Equal" },
+ { 0x14, "String Length" },
+ { 0x15, "SubString" },
+ /* nothing 0x16 */
+ { 0x17, "Pop"},
+ { 0x18, "Integral Part"},
+ /* nothing 0x19 - 0x1B */
+ { 0x1C, "Get Variable"},
+ { 0x1D, "Set Variable"},
+ /* nothing 0x1E - 0x1F */
+ { 0x20, "Set Target" },
+ { 0x21, "Concatenate Strings"},
+ { 0x22, "Get Property" },
+ { 0x23, "Set Property" },
+ { 0x24, "Duplicate Sprite" },
+ { 0x25, "Remove Sprite" },
+ { 0x26, "Trace" },
+ { 0x27, "Start Drag" },
+ { 0x28, "Stop Drag" },
+ { 0x29, "String Less Than"},
+ { 0x2A, "Throw" },
+ { 0x2B, "Cast Object" },
+ { 0x2C, "implements" },
+ { 0x2D, "FSCommand2" },
+ /* nothing 0x2E-2F */
+ { 0x30, "Random" },
+ { 0x31, "String Length(multibyte)" },
+ { 0x32, "Ord" },
+ { 0x33, "Chr"},
+ { 0x34, "Get Timer" },
+ { 0x35, "SubString(multibyte)" },
+ { 0x36, "Ord(multibyte)" },
+ { 0x37, "Chr(multibyte)" },
+ /* nothing 0x28-29 */
+ { 0x3A, "Delete" },
+ { 0x3B, "Delete All" },
+ { 0x3C, "Set Local Variable" },
+ { 0x3D, "Call Function" },
+ { 0x3E, "Return" },
+ { 0x3F, "Modulo" },
+ { 0x40, "New" },
+ { 0x41, "Declare Local Variable" },
+ { 0x42, "Declare Array" },
+ { 0x43, "Declare Object" },
+ { 0x44, "Type Of" },
+ { 0x45, "Get Targer" },
+ { 0x46, "Enumerate" },
+ { 0x47, "Add(typed)" },
+ { 0x48, "Less Than(typed)" },
+ { 0x49, "Equal(typed)" },
+ { 0x4A, "Number" },
+ { 0x4B, "String" },
+ { 0x4C, "Duplicate" },
+ { 0x4D, "Swap" },
+ { 0x4E, "Get Member" },
+ { 0x4F, "Set Member" },
+ { 0x50, "Increment" },
+ { 0x51, "Decrement" },
+ { 0x52, "Call Method" },
+ { 0x53, "New Method" },
+ { 0x54, "Instance Of" },
+ { 0x55, "Enumerate Object" },
+ /* nothing 0x56 - 0x5F */
+ { 0x60, "And" },
+ { 0x61, "Or" },
+ { 0x62, "XOr" },
+ { 0x63, "Shift Left" },
+ { 0x64, "Shift Right" },
+ { 0x65, "Shift Right Unsigned" },
+ { 0x66, "Strict Equal" },
+ { 0x67, "Greater Than(typed)" },
+ { 0x68, "String Greater Than(typed)" },
+ { 0x69, "Extends" },
+ /* nothing 0x6A - 0x80 */
+ { 0x81, "Goto Frame" },
+ /* nothing 0x82 */
+ { 0x83, "Get URL" },
+ /* nothing 0x84 - 0x86 */
+ { 0x87, "Store Register" },
+ { 0x88, "Declare Dictionary" },
+ { 0x89, "Strict Mode" },
+ { 0x8A, "Wait For Frame" },
+ { 0x8B, "Set Target" },
+ { 0x8C, "Goto Label" },
+ { 0x8D, "Wait For Frame(dynamic)" },
+ { 0x8E, "Declare Function (with 256 registers)"},
+ { 0x8F, "Try"},
+ /* nothing 0x90 - 0x93 */
+ { 0x94, "With"},
+ /* nothing 0x95 */
+ { 0x96, "Push Data" },
+ /* nothing 0x97 - 0x98 */
+ { 0x99, "Branch Always" },
+ { 0x9A, "Get URL2" },
+ { 0x9B, "Declare Function" },
+ /* nothing 0x9C */
+ { 0x9D, "Branch If True" },
+ { 0x9E, "Call Frame" },
+ { 0x9F, "Goto Expression" },
+};
+
+swf_action_info_t *
+get_swf_action_info(int action_id) {
+ int i, action_info_num = NumOfTable(swf_action_info_table);
+ for (i=0; i < action_info_num; i++) {
+ if (action_id == swf_action_info_table[i].id) {
+ return &(swf_action_info_table[i]);
+ }
+ }
+ return NULL;
+}
+
+int
+swf_action_parse(bitstream_t *bs, swf_action_t *act) {
+ unsigned long offset;
+ bitstream_align(bs);
+ act->action_id = bitstream_getbyte(bs);
+ if (act->action_id & 0x80) {
+ act->action_has_length = 1;
+ } else {
+ act->action_has_length = 0;
+ }
+ if (act->action_has_length) {
+ act->action_length = bitstream_getbytesLE(bs, 2);
+ offset = bitstream_getbytepos(bs);
+ act->action_data = malloc(act->action_length);
+ if (act->action_data == NULL) {
+ fprintf(stderr, "Can't alloc memory for act->action_data\n");
+ return 1;
+ }
+ bitstream_getstring(bs, act->action_data, act->action_length);
+ }
+ return 0;
+}
+
+int
+swf_action_build(bitstream_t *bs, swf_action_t *act) {
+ bitstream_align(bs);
+ /* bitstream_putbits(bs, act->action_has_length, 1); no need */
+ bitstream_putbyte(bs, act->action_id);
+ if (act->action_has_length) {
+ if (act->action_data == NULL) {
+ return 1; // error
+ }
+ bitstream_putbytesLE(bs, act->action_length, 2);
+ bitstream_putstring(bs, act->action_data, act->action_length);
+ }
+ return 0;
+}
+
+int
+swf_action_print(swf_action_t *act) {
+ swf_action_info_t *act_info = get_swf_action_info(act->action_id);
+ if (act_info && act_info->name) {
+ printf("%s", act_info->name);
+ } else {
+ printf("0x%02x", act->action_id);
+ }
+ if (act->action_has_length) {
+ int i, n;
+ unsigned char *d;
+ switch(act->action_id) {
+ case 0x83: // Get URL
+ printf(" (String)%s", act->action_data);
+ printf(" (String)%s",
+ act->action_data + strlen(act->action_data) + 1);
+ break;
+ case 0x88: // Declare Dictionary
+ d = act->action_data;
+ n = GetUShortLE(act->action_data); d += 2;
+ printf(":\n");
+ for(i=0; i<n; i++) {
+ printf("\t\t[%d]'", i);
+ d += printf("%s", d) + 1;
+ printf("'\n");
+ }
+ break;
+ case 0x96: // Push Data
+ swf_action_data_print(act->action_data, act->action_length);
+ break;
+ default:
+ printf(" len=%d", act->action_length);
+ break;
+ }
+ }
+ printf("\n");
+ return 0;
+}
+
+
+swf_action_list_t *
+swf_action_list_create(bitstream_t *bs) {
+ swf_action_list_t *action_list;
+ swf_action_t *action;
+ action_list = calloc(sizeof(*action_list), 1);
+ if (action_list == NULL) {
+ fprintf(stderr, "Can't alloc memory for action_list\n");
+ return NULL;
+ }
+ do {
+ action = calloc(sizeof(*action), 1);
+ if (action == NULL) {
+ fprintf(stderr, "Can't alloc memory for action\n");
+ break;
+ }
+ swf_action_parse(bs, action);
+ if (action_list->head == NULL) {
+ action_list->head = action_list->tail = action;
+ } else {
+ action_list->tail->next = action;
+ action_list->tail = action;
+ }
+ action->next = NULL;
+ } while(action->action_id != 0); // End Action;
+ return action_list;
+}
+unsigned char *
+swf_action_list_output(swf_action_list_t *list, unsigned long *length) {
+ swf_action_t *action;
+ bitstream_t *bs;
+ unsigned char *data;
+ *length = 0;
+ bs = bitstream_open();
+ for (action = list->head; action ; action = action->next) {
+ swf_action_build(bs, action);
+ }
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+void
+swf_action_list_destroy(swf_action_list_t *action_list) {
+
+ if (action_list) {
+ swf_action_t *action = action_list->head;
+ while (action) {
+ swf_action_t *action_next = action->next;
+ if (action->action_data) {
+ free(action->action_data);
+ }
+ free(action);
+ action = action_next;
+ }
+ free(action_list);
+ }
+}
+
+void
+swf_action_list_print(swf_action_list_t *action_list) {
+
+ if (action_list) {
+ swf_action_t *action = action_list->head;
+ while(action) {
+ printf("\t");
+ swf_action_print(action);
+ action = action->next;
+ }
+ }
+}
+
+int swf_action_data_print(unsigned char *action_data, unsigned short action_data_len) {
+ unsigned char type = action_data[0] & 0xff;
+ unsigned char *data = action_data+1;
+ unsigned short data_len = action_data_len - 1;
+ int result = 1; // type field
+ switch (type) {
+ case 0x00: // String
+ printf("(String)%*s", data_len, data);
+ result += strlen((char*) data) + 1; // text + \0
+ break;
+ case 0x01: // Float
+ printf("(Float)XXX");
+ break;
+ case 0x02: // NULL
+ printf("(NULL)");
+ break;
+ case 0x03: // Undefined
+ printf("(Undefined)");
+ break;
+ case 0x04: // Register
+ printf("(Register)%d", (data[0]&0xff));
+ break;
+ case 0x05: // Boolean
+ printf("(Boolean)%s", (data[0]&0xff)?"true":"false");
+ result += 1;
+ break;
+ case 0x06: // Double
+ printf("(Double)%f", GetDoubleIEEE(data));
+ break;
+ case 0x07: // Integer
+ printf("(Integer)%ld", GetULongLE(data));
+ result += 4;
+ break;
+ case 0x08: // Dictionary Lookup
+ printf("(Dictionary Lookup)%d", data[0] & 0xff);
+ result += 1;
+ break;
+ case 0x09: // Large Dictionary Lookup
+ printf("(Large Dictionary Lookup)%d", GetUShortLE(data) & 0xffff);
+ result += 2;
+ break;
+ default:
+ printf("type=0x%02x len=%d", type, data_len);
+ break;
+ }
+ return result;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_ACTION_H__
+#define __SWF_ACTION_H__
+
+typedef struct swf_action_ {
+ unsigned char action_has_length;
+ unsigned char action_id;
+ unsigned short action_length;
+ unsigned char *action_data;
+ struct swf_action_ *next; // self reference structure
+} swf_action_t;
+
+typedef struct swf_action_list_ {
+ swf_action_t *head, *tail;
+} swf_action_list_t;
+
+typedef struct swf_action_info_ {
+ int id;
+ char *name;
+} swf_action_info_t;
+
+extern swf_action_info_t *get_swf_action_info(int action_id);
+
+extern int swf_action_parse(bitstream_t *bs, swf_action_t *act);
+extern int swf_action_build(bitstream_t *bs, swf_action_t *act);
+extern int swf_action_print(swf_action_t *act);
+
+extern swf_action_list_t *swf_action_list_create(bitstream_t *bs);
+extern unsigned char *swf_action_list_output(swf_action_list_t *list,
+ unsigned long *length);
+extern void swf_action_list_destroy(swf_action_list_t *act_list);
+extern void swf_action_list_print(swf_action_list_t *act_list);
+
+extern int swf_action_data_print(unsigned char *action_data,
+ unsigned short action_data_len);
+
+#endif /* __SWF_ACTION_H__ */
--- /dev/null
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_argb.h"
+
+int
+swf_argb_parse(bitstream_t *bs, swf_argb_t *color) {
+ color->alpha = bitstream_getbyte(bs);
+ color->red = bitstream_getbyte(bs);
+ color->green = bitstream_getbyte(bs);
+ color->blue = bitstream_getbyte(bs);
+ return 0;
+}
+
+int
+swf_argb_build(bitstream_t *bs, swf_argb_t *color) {
+ bitstream_putbyte(bs, color->alpha);
+ bitstream_putbyte(bs, color->red);
+ bitstream_putbyte(bs, color->green);
+ bitstream_putbyte(bs, color->blue);
+ return 0;
+}
+
+int
+swf_argb_print(swf_argb_t *color) {
+ printf("alpha=0x%02x red=0x%02x green=0x%02X blue=0x%02x\n",
+ color->alpha, color->red, color->green, color->blue);
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_ARGB_H__
+#define __SWF_ARGB_H__
+
+typedef struct swf_argb_ {
+ unsigned char alpha;
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+} swf_argb_t;
+
+extern int swf_argb_parse(bitstream_t *bs, swf_argb_t *color);
+extern int swf_argb_build(bitstream_t *bs, swf_argb_t *color);
+extern int swf_argb_print(swf_argb_t *color);
+
+#endif /* __SWF_ARGB_H__ */
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+// #include "swf_define.h" no include
+
+int swf_debug = 0;
+
+#define MALLOC_DEBUG_TABLE_NUM 0x20000
+
+static struct malloc_debug_ {
+ void *ptr;
+ char *filename;
+ int linenum;
+} malloc_debug_table[MALLOC_DEBUG_TABLE_NUM];
+
+
+void malloc_debug_start(void) {
+ int i;
+ for(i=0; i<MALLOC_DEBUG_TABLE_NUM; i++) {
+ malloc_debug_table[i].ptr = NULL;
+ }
+}
+
+void malloc_debug_end(void) {
+ int i;
+ for(i=0; i<MALLOC_DEBUG_TABLE_NUM; i++) {
+ if (malloc_debug_table[i].ptr) {
+ fprintf(stderr, "XXX (%d) ptr=%p (%s, %d)\n",
+ i, malloc_debug_table[i].ptr,
+ malloc_debug_table[i].filename,
+ malloc_debug_table[i].linenum);
+ }
+ }
+}
+
+void *
+calloc_debug(size_t nmemb, size_t size, char *filename, int linenum) {
+ int i;
+ void *ptr;
+ ptr = calloc(nmemb, size);
+// fprintf(stderr, "calloc_debug: ptr=%p (%s,%d)\n", ptr, filename, linenum);
+ for(i=0; i<MALLOC_DEBUG_TABLE_NUM; i++) {
+ if (malloc_debug_table[i].ptr == NULL) {
+ malloc_debug_table[i].ptr = ptr;
+ malloc_debug_table[i].filename = filename;
+ malloc_debug_table[i].linenum = linenum;
+ break;
+ }
+ }
+ return ptr;
+}
+void *
+malloc_debug(size_t size, char *filename, int linenum) {
+ int i;
+ void *ptr;
+ ptr = malloc(size);
+// fprintf(stderr, "malloc_debug: ptr=%p (%s,%d)\n", ptr, filename, linenum);
+ for(i=0; i<MALLOC_DEBUG_TABLE_NUM; i++) {
+ if (malloc_debug_table[i].ptr == NULL) {
+ malloc_debug_table[i].ptr = ptr;
+ malloc_debug_table[i].filename = filename;
+ malloc_debug_table[i].linenum = linenum;
+// fprintf(stderr, "(%d)\n", i);
+ return ptr;
+ }
+ }
+ fprintf(stderr, "malloc: table full... ;_;\n");
+ return ptr;
+}
+
+void
+free_debug(void *ptr, char *filename, int linenum) {
+ int i;
+// fprintf(stderr, "free_debug: ptr=%p (%s,%d)\n", ptr, filename, linenum);
+ for(i = 0; i < MALLOC_DEBUG_TABLE_NUM; i++) {
+ if (malloc_debug_table[i].ptr == ptr) {
+ malloc_debug_table[i].ptr = NULL;
+ break;
+ }
+ }
+ if (i == MALLOC_DEBUG_TABLE_NUM) {
+ fprintf(stderr, "i == MALLOC_DEBUG_TABLE_NUM: ptr=%p (%s,%d)\n", ptr,
+ filename, linenum);
+ malloc_debug_end();
+ char *ptr = 0;
+ *ptr = 0;
+ }
+ free(ptr);
+}
+
+void *
+realloc_debug(void *ptr, size_t size, char *filename, int linenum) {
+ int i;
+ void *new_ptr;
+ new_ptr = realloc(ptr, size);
+// fprintf(stderr, "realloc_debug: ptr=%p => new_ptr=%p (%s,%d)\n",
+// ptr, new_ptr, filename, linenum);
+ for(i=0; i<MALLOC_DEBUG_TABLE_NUM; i++) {
+ if (malloc_debug_table[i].ptr == ptr) {
+ malloc_debug_table[i].ptr = new_ptr;
+ malloc_debug_table[i].filename = filename;
+ malloc_debug_table[i].linenum = linenum;
+ break;
+ }
+ }
+ return new_ptr;
+}
+
+#define HEXBIN_DISP_UNIT 0x10
+
+void
+print_hexbin(unsigned char *data, int data_len) {
+ int i;
+ printf("\n");
+ for(i=0; i<data_len; i++) {
+ if ((i%HEXBIN_DISP_UNIT) == 0) {
+ printf("0x%08x: ", i);
+ }
+#if 1
+ printf("%02x ", data[i] & 0xff);
+ if ((i%HEXBIN_DISP_UNIT) == HEXBIN_DISP_UNIT-1) {
+ printf("\n");
+ }
+#else
+ do {
+ unsigned char c = data[i];
+ signed int j;
+ if ((i%HEXBIN_DISP_UNIT) == 0) {
+ printf("\n");
+ }
+ for(j=7; j>=0; j--) {
+ printf("%d", (c >> j) & 1);
+
+ }
+ printf("\n");
+ } while(0);
+#endif
+ }
+ printf("\n");
+ return ;
+}
--- /dev/null
+#ifndef __SWF_DEFINE__H__
+#define __SWF_DEFINE__H__
+
+#include <stdlib.h>
+
+#define SWF_TWIPS 20
+#define SWF_MAGIC_SIZE 4
+#define SWF_FILE_LENGTH_SIZE 4
+#define SWF_HEADER_SIZE 8
+
+extern int swf_debug;
+
+extern void malloc_debug_start(void);
+extern void malloc_debug_end(void);
+
+#ifdef MALLOC_DEBUG /* malloc debug */
+extern void *calloc_debug(size_t nmemb, size_t size, char *filename, int linenum);
+extern void *malloc_debug(size_t size, char *filename, int linenum);
+extern void free_debug(void *ptr, char *filename, int linenum);
+extern void *realloc_debug(void *ptr, size_t size, char *filename, int linenum);
+
+#define calloc(n,s) calloc_debug(n,s,__FILE__,__LINE__)
+#define malloc(s) malloc_debug(s,__FILE__,__LINE__)
+#define free(p) free_debug(p,__FILE__,__LINE__)
+#define realloc(p,s) realloc_debug(p,s,__FILE__,__LINE__)
+
+extern void print_hexbin(unsigned char *data, int data_len);
+
+#endif
+
+#if 0 /* PHP Extension */
+#define calloc(n,s) ecalloc(n,s)
+#define malloc(s) emalloc(s)
+#define free(p) efree(p)
+#define realloc(p,s) erealloc(p,s)
+#endif
+
+#define NumOfTable(t) (sizeof(t) / sizeof(*t))
+
+
+#define GV2B(a,b) ((a << 8) + b)
+#define GV4B(a,b,c,d) GV2B(GV2B(GV2B(a,b),c),d)
+#define GV8B(a,b,c,d,e,f,g,h) GV2B(GV2B(GV2B(GV2B(GV2B(GV2B(GV2B(a,b),c),d),e),f),g),h)
+
+#define GetUShortLE(data) ((unsigned short) GV2B(data[1], data[0]))
+
+#define GetULongLE(data) ((unsigned long) GV4B(data[3], data[2], data[1], data[0]))
+#define GetDoubleIEEE(data) ((double) GV8B(data[4], data[5], data[6], data[7], data[0], data[1], data[2], data[3]))
+
+#endif /* __SWF_DEFINE__H__ */
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include "swf_define.h"
+#include "swf_header.h"
+
+int
+swf_header_parse(bitstream_t *bs, swf_header_t *header) {
+ bitstream_getstring(bs, header->magic, 3);
+ header->version = bitstream_getbyte(bs);
+ header->file_length = bitstream_getbytesLE(bs, 4);
+ return 0;
+}
+int
+swf_header_build(bitstream_t *bs, swf_header_t *header) {
+ if (bitstream_putstring(bs, header->magic, 3)) {
+ return 1;
+ }
+ if (bitstream_putbyte(bs, header->version)) {
+ return 1;
+ }
+ if (bitstream_putbytesLE(bs, header->file_length, 4)) {
+ return 1;
+ }
+ return 0;
+}
+
+int
+swf_header_movie_parse(bitstream_t *bs,
+ swf_header_movie_t *header_movie) {
+ swf_rect_parse(bs, &header_movie->frame_size);
+ header_movie->frame_rate_decimal = bitstream_getbyte(bs);
+ header_movie->frame_rate_integral = bitstream_getbyte(bs);
+ header_movie->frame_count = bitstream_getbytesLE(bs, 2);
+ return 0;
+}
+
+int
+swf_header_movie_build(bitstream_t *bs,
+ swf_header_movie_t *header_movie) {
+ swf_rect_build(bs, &header_movie->frame_size);
+ bitstream_putbyte(bs, header_movie->frame_rate_decimal);
+ bitstream_putbyte(bs, header_movie->frame_rate_integral);
+ bitstream_putbytesLE(bs, header_movie->frame_count, 2);
+ return 0;
+}
+
+int swf_header_print(swf_header_t *header) {
+ printf("magic=%s version=%d file_length=%lu\n",
+ header->magic, header->version, header->file_length);
+ return 0;
+}
+
+int swf_header_movie_print(swf_header_movie_t *header_movie) {
+ swf_rect_print(&header_movie->frame_size);
+ printf("frame_rate=%d.%d frame_count=%d\n",
+ header_movie->frame_rate_integral,
+ header_movie->frame_rate_decimal,
+ header_movie->frame_count);
+ return 0;
+}
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_HEADER_H__
+#define __SWF_HEADER_H__
+
+#include "bitstream.h"
+#include "swf_rect.h"
+
+typedef struct swf_header_ {
+ unsigned char magic[4]; // 'FWS' or 'CWS' + '\0';
+ unsigned char version;
+ unsigned long file_length;
+} swf_header_t;
+
+
+typedef struct swf_header_movie_ {
+ swf_rect_t frame_size;
+ unsigned short frame_rate_integral;
+ unsigned short frame_rate_decimal;
+ unsigned short frame_count;
+} swf_header_movie_t;
+
+extern int swf_header_parse(bitstream_t *bs, swf_header_t *header);
+extern int swf_header_build(bitstream_t *bs, swf_header_t *header);
+extern int swf_header_print(swf_header_t *header);
+
+extern int swf_header_movie_parse(bitstream_t *bs, swf_header_movie_t *header_movie);
+extern int swf_header_movie_build(bitstream_t *bs, swf_header_movie_t *header_movie);
+extern int swf_header_movie_print(swf_header_movie_t *header_movie);
+
+#endif /* __SWF_HEADER_H__ */
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitstream.h"
+#include "swf_jpeg.h"
+#include "jpeg_segment.h"
+
+unsigned char *
+jpegconv_std2swf(unsigned char *data, unsigned long data_len,
+ unsigned long *length) {
+ jpeg_segment_t *jpeg_data = NULL;
+ jpeg_segment_t *jpeg_output;
+ unsigned char *d;
+ unsigned long d_len;
+ int m;
+ unsigned char *ret_data;
+ jpeg_data = jpeg_segment_parse(data, data_len);
+ if (jpeg_data == NULL) {
+ fprintf(stderr, "jpegconv_std2swf: Can't create jpeg segment for data\n");
+ return NULL;
+ }
+ jpeg_output = jpeg_segment_create();
+ if (jpeg_output == NULL) {
+ fprintf(stderr,
+ "jpegconv_std2swf: Can't create jpeg segment for output\n");
+ jpeg_segment_destroy(jpeg_data);
+ return NULL;
+ }
+ /* 並び替え */
+ // 圧縮テーブル部
+ jpeg_segment_append(jpeg_output, 0xD8, NULL, 0); // SOI
+ while ((d = jpeg_segment_steal_node(jpeg_data, 0xDB, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_output, 0xDB, d, d_len); // DQT
+ }
+ while ((d = jpeg_segment_steal_node(jpeg_data, 0xC4, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_output, 0xC4, d, d_len); // DHT
+ }
+ jpeg_segment_append(jpeg_output, 0xD9, NULL, 0); // EOI
+ // 画像実データ部 (APP 等も含む)
+ while((m = jpeg_segment_peek_marker(jpeg_data)) >= 0) {
+ d = jpeg_segment_steal_node(jpeg_data, m, &d_len);
+ jpeg_segment_append(jpeg_output, m, d, d_len);
+ }
+ ret_data = jpeg_segment_output(jpeg_output, length);
+ jpeg_segment_destroy(jpeg_data);
+ jpeg_segment_destroy(jpeg_output);
+ return ret_data;
+}
+
+unsigned char *
+jpegconv_swf2std(unsigned char *data, unsigned long data_len,
+ unsigned long *length, unsigned char *table_data,
+ unsigned long table_data_len) {
+ jpeg_segment_t *jpeg_data, *jpeg_table = NULL;
+ jpeg_segment_t *jpeg_output;
+ int m;
+ unsigned char *d;
+ unsigned long d_len;
+ unsigned char *ret_data;
+ *length = 0;
+ jpeg_data = jpeg_segment_parse(data, data_len);
+ if (jpeg_data == NULL) {
+ fprintf(stderr, "jpegconv_swf2std: Can't create jpeg segment for data\n");
+ return NULL;
+ }
+ if (jpeg_segment_contain(jpeg_data, 0xDB)) {
+ /* 圧縮テーブルが含まれている場合 */
+ jpeg_table = jpeg_segment_create();
+ if (jpeg_table == NULL) {
+ fprintf(stderr,
+ "jpegconv_swf2std: Can't create jpeg segment for table\n");
+ jpeg_segment_destroy(jpeg_data);
+ return NULL;
+ }
+ while ((d = jpeg_segment_steal_node(jpeg_data, 0xDB, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_table, 0xDB, d, d_len); // DQT
+ }
+ while ((d = jpeg_segment_steal_node(jpeg_data, 0xC4, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_table, 0xC4, d, d_len); // DHT
+ }
+ } else if (table_data && table_data_len) {
+ /* 圧縮テーブルが入っていない場合は JPEGTables を参照 */
+ jpeg_table = jpeg_segment_parse(table_data, table_data_len);
+ if (jpeg_table == NULL) {
+ fprintf(stderr, "Can't create jpeg segment for table\n");
+ jpeg_segment_destroy(jpeg_data);
+ return NULL;
+ }
+ } else {
+ fprintf(stderr, "jpegconv_swf2std: not found jpeg table segment\n");
+ jpeg_segment_destroy(jpeg_data);
+ return NULL;
+ }
+ /* 並び替え */
+ jpeg_segment_delete_node(jpeg_data, 0xD8); // SOI
+ jpeg_segment_delete_node(jpeg_data, 0xD9); // EOI
+ jpeg_output = jpeg_segment_create();
+ if (jpeg_output == NULL) {
+ fprintf(stderr, "jpegconv_swf2std: Can't create jpeg segment for output\n");
+ jpeg_segment_destroy(jpeg_data);
+ jpeg_segment_destroy(jpeg_table);
+ return NULL;
+ }
+ jpeg_segment_append(jpeg_output, 0xD8, NULL, 0); // SOI
+ /* 圧縮テーブルを退避 */
+ /* SOF0,1,2 マーカーの手前まで構成 */
+ while((m = jpeg_segment_peek_marker(jpeg_data)) >= 0) {
+ if ((m == 0xC0) || (m == 0xC1) || (m == 0xC2)) { // SOF0,1,2
+ break;
+ }
+ d = jpeg_segment_steal_node(jpeg_data, m, &d_len);
+ jpeg_segment_append(jpeg_output, m, d, d_len);
+ };
+ while ((d = jpeg_segment_steal_node(jpeg_table, 0xDB, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_output, 0xDB, d, d_len); // DQT
+ }
+ /* SOF0,1,2 を構成 */
+ while((m = jpeg_segment_peek_marker(jpeg_data)) >= 0) {
+ if ((m != 0xC0) && (m != 0xC1) && (m != 0xC2)) { // SOF0,1,2
+ break;
+ }
+ d = jpeg_segment_steal_node(jpeg_data, m, &d_len);
+ jpeg_segment_append(jpeg_output, m, d, d_len);
+ }
+ while ((d = jpeg_segment_steal_node(jpeg_table, 0xC4, &d_len)) != NULL) {
+ jpeg_segment_append(jpeg_output, 0xC4, d, d_len); // DHT
+ }
+ while((m = jpeg_segment_peek_marker(jpeg_data)) >= 0) {
+ d = jpeg_segment_steal_node(jpeg_data, m, &d_len);
+ jpeg_segment_append(jpeg_output, m, d, d_len);
+ }
+ jpeg_segment_append(jpeg_output, 0xD9, NULL, 0); // EOI
+ ret_data = jpeg_segment_output(jpeg_output, length);
+ jpeg_segment_destroy(jpeg_data);
+ jpeg_segment_destroy(jpeg_table);
+ jpeg_segment_destroy(jpeg_output);
+ return ret_data;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_JPEG__H__
+#define __SWF_JPEG__H__
+
+/* for DefineBitsJPEG2,3*/
+extern unsigned char *jpegconv_std2swf(unsigned char *data,
+ unsigned long data_len,
+ unsigned long *length);
+/* for DefineBitsJPEG(1),2,3*/
+extern unsigned char *jpegconv_swf2std(unsigned char *data,
+ unsigned long data_len,
+ unsigned long *length,
+ unsigned char *table_data,
+ unsigned long table_data_len);
+
+#endif /* __SWF_JPEG__H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> // memcmp
+#include <zlib.h>
+#include "bitstream.h"
+#include "swf_define.h"
+#include "swf_tag_action.h"
+#include "swf_tag_jpeg.h"
+#include "swf_tag_lossless.h"
+#include "swf_action.h"
+#include "swf_object.h"
+
+swf_object_t *
+swf_object_open(void) {
+ swf_object_t *swf;
+ malloc_debug_start(); /* DEBUG XXX */
+ swf = (swf_object_t *) calloc(sizeof(*swf), 1);
+ return swf;
+}
+
+void
+swf_object_close(swf_object_t *swf) {
+ swf_tag_t *tag, *next_tag;
+ if (! swf) {
+ return ;
+ }
+ for(tag = swf->tag; tag; tag = next_tag) {
+ next_tag = tag->next;
+ swf_tag_destroy(tag);
+ }
+ free(swf);
+ malloc_debug_end(); /* DEBUG XXX */
+ return ;
+}
+int
+swf_object_input(swf_object_t *swf, unsigned char *data,
+ unsigned long data_len) {
+ int result;
+ bitstream_t *bs = bitstream_open();
+ swf_tag_t **tag;
+ bitstream_input(bs, data, data_len);
+ result = swf_header_parse(bs, &swf->header);
+ if (result) {
+ bitstream_close(bs);
+ return result;
+ }
+ if (memcmp(swf->header.magic, "FWS", 3) == 0) {
+ ; // OK
+ } else if (memcmp(swf->header.magic, "CWS", 3) == 0) {
+ int result;
+ unsigned char *old_buff, *new_buff;
+ unsigned long origsize;
+ old_buff = bitstream_buffer(bs, SWF_HEADER_SIZE);
+ origsize = swf->header.file_length - SWF_HEADER_SIZE;
+ new_buff = malloc(origsize);
+ result = uncompress(new_buff, &origsize, old_buff, bs->data_len - SWF_HEADER_SIZE);
+ if (result != Z_OK) {
+ if (result == Z_MEM_ERROR) {
+ fprintf(stderr, "swf_object_input: uncompress Z_MEM_ERROR: can't malloc\n");
+ } else if (result == Z_BUF_ERROR) {
+ fprintf(stderr, "swf_object_input: uncompress Z_BUF_ERROR: not enough buff size\n");
+ } else {
+ fprintf(stderr, "swf_object_input: uncompress failed by unknown reason\n");
+ }
+ free(new_buff);
+ bitstream_close(bs);
+ return 1; // FAILURE
+ }
+ bitstream_putstring(bs, new_buff, origsize);
+ free(new_buff);
+ bitstream_setpos(bs, SWF_HEADER_SIZE, 0);
+ } else {
+ fprintf(stderr, "swf_object_input: unknown magic %s\n", swf->header.magic);
+ bitstream_close(bs);
+ return 1; // FAILURE
+ }
+ result = swf_header_movie_parse(bs, &swf->header_movie);
+ if (result) {
+ bitstream_close(bs);
+ return result;
+ }
+ tag = &swf->tag;
+ while(1) {
+ long pos;
+ pos = bitstream_getbytepos(bs);
+ if ((pos == -1) || ((long) swf->header.file_length <= pos)) {
+ break;
+ }
+ *tag = swf_tag_create(bs);
+ if (tag == NULL) {
+ fprintf(stderr, "swf_object_input: swf_tag_create failed\n");
+ }
+ tag = &((*tag)->next);
+ }
+ bitstream_close(bs);
+ return 0;
+}
+
+unsigned char *
+swf_object_output(swf_object_t *swf, unsigned long *length) {
+ int result;
+ swf_tag_t *tag;
+ unsigned char *data;
+ bitstream_t *bs = bitstream_open();
+ *length = 0;
+ result = swf_header_build(bs, &swf->header);
+ if (result) {
+ bitstream_close(bs);
+ return NULL;
+ }
+ result = swf_header_movie_build(bs, &swf->header_movie);
+ if (result) {
+ bitstream_close(bs);
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ swf_tag_build(bs, tag, swf);
+ }
+ swf->header.file_length = bitstream_getbytepos(bs);
+ bitstream_setpos(bs, SWF_MAGIC_SIZE, 0);
+ bitstream_putbytesLE(bs, swf->header.file_length,
+ SWF_FILE_LENGTH_SIZE);
+ if (memcmp(swf->header.magic, "FWS", SWF_MAGIC_SIZE) == 0) {
+ ; // OK
+ } else if (memcmp(swf->header.magic, "CWS", SWF_MAGIC_SIZE) == 0) {
+ int result;
+ unsigned long compsize;
+ unsigned char *new_buff, *old_buff;
+ bitstream_setpos(bs, SWF_HEADER_SIZE, 0);
+ old_buff = bitstream_buffer(bs, SWF_HEADER_SIZE);
+ new_buff = malloc(swf->header.file_length - SWF_HEADER_SIZE);
+ result = compress(new_buff, &compsize, old_buff,
+ bs->data_len - SWF_HEADER_SIZE);
+ if (result != Z_OK) {
+ if (result == Z_MEM_ERROR) {
+ fprintf(stderr, "swf_object_output: compress Z_MEM_ERROR: can't malloc\n");
+ } else if (result == Z_BUF_ERROR) {
+ fprintf(stderr, "swf_object_output: compress Z_BUF_ERROR: not enough buff size\n");
+ } else {
+ fprintf(stderr, "swf_object_output: compress failed by unknown reason\n");
+ }
+ bitstream_close(bs);
+ return NULL; // FAILURE
+ }
+ bitstream_putstring(bs, new_buff, compsize);
+ free(new_buff);
+ } else {
+ fprintf(stderr, "swf_object_output: unknown magic %s\n", swf->header.magic);
+ bitstream_close(bs);
+ return NULL; // FAILURE
+ }
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+void
+swf_object_print(swf_object_t *swf) {
+ int i;
+ swf_tag_t *tag;
+ swf_header_print(&swf->header);
+ swf_header_movie_print(&swf->header_movie);
+ tag = swf->tag;
+ for (i=0; tag; i++) {
+ printf("[%d] ", i);
+ swf_tag_print(tag, swf);
+ if (tag->tag == 0) { // END Tag
+ break;
+ }
+ tag = tag->next;
+ }
+}
+
+
+/* --- */
+
+unsigned char *
+swf_object_get_jpegdata(swf_object_t *swf, unsigned long *length, int image_id) {
+ swf_tag_t *tag, *tag_jpegtables = NULL;
+ unsigned char *data = NULL;
+ *length = 0;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_get_jpegdata: swf == NULL\n");
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ if (tag->tag == 8) { // JPEGTables
+ tag_jpegtables = tag;
+ break;
+ }
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ if (tag->tag == 8) {
+ tag_jpegtables = tag;
+ continue;
+ }
+ // DefineBitsJPEG(1),2,3
+ if ((tag->tag != 6) && (tag->tag != 21) && (tag->tag != 35)) {
+ continue;
+ }
+ data = swf_tag_get_jpeg_data(tag, length, image_id, tag_jpegtables);
+ if (data) {
+ break;
+ }
+ }
+ return data;
+}
+
+unsigned char *
+swf_object_get_alphadata(swf_object_t *swf, unsigned long *length, int image_id) {
+ swf_tag_t *tag;
+ unsigned char *data = NULL;
+ *length = 0;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_get_alphadata: swf == NULL\n");
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ if (tag->tag != 35) { // ! DefineBitsJPEG3
+ continue;
+ }
+ data = swf_tag_get_alpha_data(tag, length, image_id);
+ if (data) {
+ break;
+ }
+ }
+ return data;
+}
+
+
+int
+swf_object_replace_jpegdata(swf_object_t *swf, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len) {
+ int result = 1;
+ swf_tag_t *tag;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_replace_jpegdata: swf == NULL\n");
+ return 1;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ result = swf_tag_replace_jpeg_data(tag, image_id,
+ jpeg_data, jpeg_data_len,
+ alpha_data, alpha_data_len);
+ if (! result) {
+ break;
+ }
+ }
+ return result;
+}
+
+
+unsigned char *
+swf_object_get_pngdata(swf_object_t *swf, unsigned long *length, int image_id) {
+ swf_tag_t *tag;
+ unsigned char *data = NULL;
+ *length = 0;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_get_pngdata: swf == NULL\n");
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ // DefineBitsLossless(1),2
+ if ((tag->tag != 20) && (tag->tag != 36)) {
+ continue;
+ }
+ data = swf_tag_get_png_data(tag, length, image_id);
+ if (data) {
+ break;
+ }
+ }
+ return data;
+}
+
+int
+swf_object_replace_pngdata(swf_object_t *swf, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len) {
+ int result = 1;
+ swf_tag_t *tag;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_replace_pngdata: swf == NULL\n");
+ return 1;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ result = swf_tag_replace_png_data(tag, image_id,
+ png_data, png_data_len);
+ if (! result) {
+ break;
+ }
+ }
+ return result;
+}
+
+unsigned char *
+swf_object_get_sounddata(swf_object_t *swf, unsigned long *length, int sound_id) {
+ swf_tag_t *tag;
+ unsigned char *data = NULL;
+ *length = 0;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_get_sounddata: swf == NULL\n");
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ // DefineSound
+ if (tag->tag != 14) {
+ continue;
+ }
+ data = swf_tag_get_sound_data(tag, length, sound_id);
+ if (data) {
+ break;
+ }
+ }
+ return data;
+}
+
+int
+swf_object_replace_melodata(swf_object_t *swf, int sound_id,
+ unsigned char *melo_data,
+ unsigned long melo_data_len) {
+ int result = 1;
+ swf_tag_t *tag;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_replace_melodata: swf == NULL\n");
+ return 1;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ result = swf_tag_replace_melo_data(tag, sound_id,
+ melo_data, melo_data_len);
+ if (! result) {
+ break;
+ }
+ }
+ return result;
+}
+
+char *
+swf_object_get_editstring(swf_object_t *swf,
+ char *variable_name,
+ int variable_name_len) {
+ swf_tag_t *tag;
+ char *data = NULL;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_get_editstring: swf == NULL\n");
+ return NULL;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ data = swf_tag_get_edit_string(tag, variable_name,
+ variable_name_len, swf);
+ if (data) {
+ break;
+ }
+ }
+ return data;
+}
+int
+swf_object_replace_editstring(swf_object_t *swf,
+ char *variable_name,
+ int variable_name_len,
+ char *initial_text,
+ int initial_text_len) {
+ int result = 1;
+ swf_tag_t *tag;
+ if (swf == NULL) {
+ fprintf(stderr, "swf_object_replace_editstring: swf == NULL\n");
+ return 1;
+ }
+ for (tag = swf->tag; tag; tag = tag->next) {
+ result = swf_tag_replace_edit_string(tag, variable_name,
+ variable_name_len,
+ initial_text,
+ initial_text_len,
+ swf);
+ if (! result) {
+ break;
+ }
+ }
+ return result;
+}
+
+unsigned char *
+swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqno) {
+ swf_tag_t *tag;
+ swf_tag_action_detail_t *swf_tag_action;
+ int i = 0;
+ for(tag = swf->tag; tag; tag = tag->next) {
+ if (i == tag_seqno) {
+ break;
+ }
+ i++;
+ }
+ if (tag == NULL) {
+ return NULL;
+ }
+ if ((tag->tag != 12) && (tag->tag != 59)) { // DoAction, DoInitAction
+ return NULL;
+ }
+ swf_tag_create_detail(tag, swf);
+ swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
+ *length = swf_tag_action->action_record_len;
+ return swf_tag_action->action_record;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_OBJECT_H__
+#define __SWF_OBJECT_H__
+
+#include "swf_header.h"
+#include "swf_header.h"
+#include "swf_tag.h"
+
+typedef struct swf_object_ {
+ swf_header_t header;
+ swf_header_movie_t header_movie;
+ swf_tag_t *tag;
+} swf_object_t;
+
+
+extern swf_object_t *swf_object_open(void);
+extern void swf_object_close(swf_object_t *swf);
+extern int swf_object_input(swf_object_t *swf, unsigned char *data, unsigned long data_len);
+extern unsigned char *swf_object_output(swf_object_t *swf, unsigned long *length);
+extern void swf_object_print(swf_object_t *swf);
+
+/* --- */
+extern unsigned char *swf_object_get_jpegdata(swf_object_t *swf, unsigned long *length, int image_id);
+extern unsigned char *swf_object_get_alphadata(swf_object_t *swf, unsigned long *length, int image_id);
+extern int swf_object_replace_jpegdata(swf_object_t *swf, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len);
+extern unsigned char *swf_object_get_pngdata(swf_object_t *swf, unsigned long *length, int image_id);
+extern int swf_object_replace_pngdata(swf_object_t *swf, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len);
+extern unsigned char *swf_object_get_sounddata(swf_object_t *swf, unsigned long *length, int sound_id);
+extern int swf_object_replace_melodata(swf_object_t *swf, int sound_id,
+ unsigned char *melo_data,
+ unsigned long melo_data_len);
+extern char *swf_object_get_editstring(swf_object_t *swf,
+ char *variable_name,
+ int variable_name_len);
+extern int swf_object_replace_editstring(swf_object_t *swf,
+ char *variable_name,
+ int variable_name_len,
+ char *initial_text,
+ int initial_text_len);
+extern unsigned char *swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqno);
+
+#endif /* __SWF_OBJECT_H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+#include "bitstream.h"
+#include "swf_rgb.h" // Lossless format=3
+#include "swf_rgba.h" // Lossless2 format=3
+#include "swf_xrgb.h" // Lossless format=5
+#include "swf_argb.h" // Lossless2 format=5
+#include "swf_png.h"
+
+typedef struct my_png_buffer_ {
+ unsigned char *data;
+ unsigned long data_len;
+ unsigned long data_offset;
+} my_png_buffer;
+
+/*
+ * png read
+ */
+
+static void png_data_read_func(png_structp png_ptr, png_bytep buf, png_size_t size){
+ my_png_buffer *png_buff = (my_png_buffer *)png_get_io_ptr(png_ptr);
+ if (png_buff->data_offset + size <= png_buff->data_len) {
+ memcpy(buf, png_buff->data + png_buff->data_offset, size);
+ png_buff->data_offset += size;
+ } else {
+ fprintf(stderr, "png_data_read_func: ! png_buff->data_offset(%lu) + size(%d) <= png_buff->data_len(%lu)\n",
+ png_buff->data_offset, size, png_buff->data_len);
+ png_error(png_ptr,"png_read_read_func failed");
+ }
+}
+
+static void png_data_read(png_structp png_ptr, my_png_buffer *png_buff) {
+ png_set_read_fn(png_ptr, (png_voidp) png_buff,
+ (png_rw_ptr)png_data_read_func);
+}
+
+/*
+ * png write
+ */
+
+void png_data_write_func(png_structp png_ptr, png_bytep buf, png_size_t size){
+ my_png_buffer *png_buff = (my_png_buffer *)png_get_io_ptr(png_ptr);
+ unsigned long new_data_len;
+ if (png_buff->data_offset + size > png_buff->data_len) {
+ new_data_len = 2 * png_buff->data_len;
+ if (png_buff->data_offset + size > new_data_len) {
+ new_data_len = png_buff->data_offset + size;
+ }
+ png_buff->data = realloc(png_buff->data, new_data_len);
+ if (png_buff->data == NULL) {
+ fprintf(stderr, "png_data_write_func: can't realloc: new_data_len(%lu), data_len(%lu)\n",
+ new_data_len, png_buff->data_len);
+ png_error(png_ptr,"png_data_write_func failed");
+
+ }
+ png_buff->data_len = new_data_len;
+ }
+ memcpy(png_buff->data + png_buff->data_offset, buf, size);
+ png_buff->data_offset += size;
+}
+
+void png_data_write(png_structp png_ptr, my_png_buffer *png_buff) {
+ png_set_write_fn(png_ptr, (png_voidp) png_buff,
+ (png_rw_ptr)png_data_write_func, NULL);
+}
+
+/*
+ *
+ */
+
+void *
+pngconv_png2lossless(unsigned char *png_data, unsigned long png_data_len,
+ int *tag_no, int *format,
+ unsigned short *width, unsigned short *height,
+ void **colormap, int *colormap_count) {
+ volatile png_structp png_ptr = NULL;
+ volatile png_infop png_info_ptr = NULL;
+ my_png_buffer png_buff;
+ int is_png;
+ int bpp, color_type;
+ png_uint_32 png_width = 0, png_height = 0;
+ volatile png_bytepp png_image_data = NULL;
+ png_uint_32 x, y;
+ void *image_data;
+ png_color *palette = NULL;
+ int palette_num = 0;
+ png_bytep trans = NULL;
+ int num_trans = 0;
+ png_color_16p trans_values = NULL;
+
+ is_png = png_check_sig((png_bytep)png_data, 8);
+ if (! is_png) {
+ fprintf(stderr, "pngconv_png2lossless: is not PNG!\n");
+ return NULL;
+ }
+ png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
+ if (! png_ptr) {
+ fprintf(stderr, "pngconv_png2lossless: can't create read_struct\n");
+ return NULL;
+ }
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fprintf(stderr, "pngconv_png2lossless: libpng error jump occured\n");
+ png_destroy_read_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr, NULL);
+ if (png_image_data) {
+ for ( y = 0 ; y < png_height ; y++) {
+ free(png_image_data[y]);
+ }
+ free(png_image_data);
+ }
+ return NULL;
+ }
+ png_info_ptr = png_create_info_struct(png_ptr);
+ if (! png_info_ptr) {
+ fprintf(stderr, "pngconv_png2lossless: can't create info_struct\n");
+ png_destroy_read_struct ((png_structpp)&png_ptr, NULL, NULL);
+ return NULL;
+ }
+ png_buff.data = png_data;
+ png_buff.data_len = png_data_len;
+ png_buff.data_offset = 0;
+
+ png_data_read(png_ptr, &png_buff);
+ png_read_info(png_ptr, png_info_ptr);
+ png_get_IHDR(png_ptr, png_info_ptr,
+ &png_width, &png_height, &bpp, &color_type,
+ NULL, NULL, NULL);
+ *width = (unsigned short) png_width;
+ *height = (unsigned short) png_height;
+ switch(color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ *format = 3;
+ png_get_PLTE(png_ptr, png_info_ptr, &palette, &palette_num);
+ if (png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans,
+ &trans_values) && (num_trans > 0)) {
+ *tag_no = 36; // DefineBitsLossless2
+ } else {
+ *tag_no = 20; // DefineBitsLossless
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ *format = 5;
+ *tag_no = 20; /* DefineBitsLossless */
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ *format = 5;
+ *tag_no = 36; /* DefineBitsLossless2 */
+ if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+ break;
+ default:
+ fprintf(stderr, "pngconv_png2lossless: color_type=%d not implemented yet.\n", color_type);
+ png_destroy_read_struct((png_structpp)&png_ptr,
+ (png_infopp)&png_info_ptr, NULL);
+ return NULL;
+ }
+ if (bpp != 8) {
+ fprintf(stderr, "pngconv_png2lossless: bpp=%d not implemented yet. accept only bpp=8\n", bpp);
+ png_destroy_read_struct((png_structpp)&png_ptr,
+ (png_infopp)&png_info_ptr, NULL);
+ return NULL;
+ }
+
+ png_image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
+ for (y=0; y < png_height; y++) {
+ png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info_ptr));
+ }
+ png_read_image(png_ptr, png_image_data);
+ /*
+ * image copy
+ */
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ int i;
+ *colormap_count = palette_num;
+ if (num_trans == 0) {
+ swf_rgb_t *result_colormap = malloc(sizeof(swf_rgb_t) * palette_num); // Lossless
+ for (i = 0 ; i < palette_num ; i++) {
+ result_colormap[i].red = palette[i].red;
+ result_colormap[i].green = palette[i].green;
+ result_colormap[i].blue = palette[i].blue;
+ }
+ *colormap = result_colormap;
+ } else {
+ swf_rgba_t *result_colormap = malloc(sizeof(swf_rgba_t) * palette_num); // Lossless2
+ for (i = 0 ; i < palette_num ; i++) {
+ result_colormap[i].red = palette[i].red;
+ result_colormap[i].green = palette[i].green;
+ result_colormap[i].blue = palette[i].blue;
+ if (i <= num_trans) {
+ result_colormap[i].alpha = trans[i];
+ } else {
+ result_colormap[i].alpha = 0xff; // XXX
+ }
+ }
+ *colormap = result_colormap;
+ }
+ unsigned char *indices_data = malloc(((png_width+ 3) & -4) * png_height);
+ for (y=0; y < png_height; y++) {
+ for (x=0; x < png_width; x++) {
+ indices_data[x+y*((png_width + 3) & -4)] = png_image_data[y][x]; // XXX
+ }
+ }
+ image_data = indices_data;
+ } else if (color_type == PNG_COLOR_TYPE_RGB) {
+ swf_xrgb_t *xrgb_list;
+ xrgb_list = malloc(sizeof(swf_xrgb_t) * png_width * png_height);
+ for (y=0; y < png_height; y++) {
+ for (x=0; x < png_width; x++) {
+ xrgb_list[x+y*png_width].red = png_image_data[y][3*x + 0];
+ xrgb_list[x+y*png_width].green = png_image_data[y][3*x + 1];
+ xrgb_list[x+y*png_width].blue = png_image_data[y][3*x + 2];
+ }
+ }
+ image_data = xrgb_list;
+ } else { // PNG_COLOR_TYPE_RGB_ALPHA
+ swf_argb_t *argb_list;
+ argb_list = malloc(sizeof(swf_argb_t) * png_width * png_height);
+ for (y=0; y < png_height; y++) {
+ for (x=0; x < png_width; x++) {
+ argb_list[x+y*png_width].red = png_image_data[y][4*x + 0];
+ argb_list[x+y*png_width].green = png_image_data[y][4*x + 1];
+ argb_list[x+y*png_width].blue = png_image_data[y][4*x + 2];
+ argb_list[x+y*png_width].alpha = png_image_data[y][4*x + 3];
+ }
+ }
+ image_data = argb_list;
+ }
+ for (y=0; y < png_height; y++) {
+ free(png_image_data[y]);
+ }
+ free(png_image_data);
+ /*
+ * destruct
+ */
+ png_destroy_read_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr, NULL);
+ return image_data;
+}
+
+unsigned char *
+pngconv_lossless2png(void *image_data,
+ unsigned short width, unsigned short height,
+ void *index_data,
+ unsigned short index_data_count,
+ int tag_no, int format,
+ unsigned long *length) {
+ volatile png_structp png_ptr = NULL;
+ volatile png_infop png_info_ptr = NULL;
+ volatile my_png_buffer png_buff;
+ png_uint_32 png_width = 0, png_height = 0;
+ int bpp, color_type;
+ volatile png_bytepp png_image_data = NULL;
+ png_uint_32 x, y;
+ volatile png_colorp png_palette = NULL;
+ if ((format != 3) && (format != 5)) {
+ fprintf(stderr, "jpegconv_lossless2png: format=%d not implemented yes.\n", format);
+ return NULL;
+ }
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
+ if (! png_ptr) {
+ fprintf(stderr, "jpegconv_lossless2png: can't create write_struct\n");
+ return NULL;
+ }
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fprintf(stderr, "pngconv_lossless2png: libpng error jump occured\n");
+ free(png_palette);
+ if (png_image_data) {
+ for ( y = 0; y < png_height ; y++) {
+ free(png_image_data[y]);
+ }
+ free(png_image_data);
+ }
+ free(png_buff.data);
+ png_destroy_write_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr);
+ return NULL;
+ }
+ png_info_ptr = png_create_info_struct(png_ptr);
+ if (! png_info_ptr) {
+ fprintf(stderr, "jpegconv_lossless2png: can't create info_struct\n");
+ png_destroy_write_struct((png_structpp) &png_ptr, NULL);
+ return NULL;
+ }
+ //
+ png_width = width;
+ png_height = height;
+ bpp = 8;
+ if (format == 3) {
+ color_type = PNG_COLOR_TYPE_PALETTE;
+ } else if (tag_no == 20) { /* DefineBitsLossless */
+ color_type = PNG_COLOR_TYPE_RGB;
+ } else if (tag_no == 36) { /* DefineBitsLossless2 */
+ color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ } else {
+ fprintf(stderr, "jpegconv_lossless2png: format!=3 and tag_no=%d not implemented.\n",
+ tag_no);
+ png_destroy_write_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr);
+ return NULL;
+ }
+ png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
+ png_set_IHDR(png_ptr, png_info_ptr,
+ png_width, png_height, bpp, color_type,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+ if (format == 3) {
+ int i;
+ if (index_data_count == 0) {
+ fprintf(stderr, "jpegconv_lossless2png: index_data_count == 0 at line(%d)\n", __LINE__);
+ png_destroy_write_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr);
+ return NULL;
+ }
+ png_palette = (png_colorp) malloc(sizeof(png_color)*index_data_count);
+ png_set_packing(png_ptr);
+ if (tag_no == 20) {
+ swf_rgb_t *rgb_list = index_data;
+ for (i=0; i<index_data_count; i++) {
+ png_palette[i].red = rgb_list[i].red;
+ png_palette[i].green = rgb_list[i].green;
+ png_palette[i].blue = rgb_list[i].blue;
+ }
+ } else {
+ swf_rgba_t *rgba_list = index_data;
+ for (i=0; i<index_data_count; i++) {
+ png_palette[i].red = rgba_list[i].red;
+ png_palette[i].green = rgba_list[i].green;
+ png_palette[i].blue = rgba_list[i].blue;
+// png_palette[i].alpha = rgba_list[i].alpha;
+ }
+ }
+ png_set_PLTE( png_ptr, png_info_ptr, png_palette, index_data_count);
+ free(png_palette);
+ }
+ png_set_gAMA(png_ptr, png_info_ptr, 1.0);
+ png_image_data = (png_bytepp) malloc(png_height * sizeof(png_bytep));
+ if (color_type == PNG_COLOR_TYPE_PALETTE) {
+ for (y=0; y < png_height; y++) {
+ png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info_ptr));
+ for (x=0; x < png_width; x++) {
+ unsigned char *data = image_data;
+ png_image_data[y][x] = data[x + y*((png_width +3) & -4)];
+ }
+ }
+
+ } else if (color_type == PNG_COLOR_TYPE_RGB) {
+ swf_xrgb_t *xrgb_list = image_data;
+ for (y=0; y < png_height; y++) {
+ png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info_ptr)) \
+ ;
+ for (x=0; x < png_width; x++) {
+ png_image_data[y][3*x] = xrgb_list[x+y*png_width].red;
+ png_image_data[y][3*x+1] = xrgb_list[x+y*png_width].green;
+ png_image_data[y][3*x+2] = xrgb_list[x+y*png_width].blue;
+ }
+ }
+ } else {
+ swf_argb_t *argb_list = image_data;
+ for (y=0; y < png_height; y++) {
+ png_image_data[y] = (png_bytep) malloc(png_get_rowbytes(png_ptr, png_info_ptr));
+ for (x=0; x < png_width; x++) {
+ png_image_data[y][4*x] = argb_list[x+y*png_width].red;
+ png_image_data[y][4*x+1] = argb_list[x+y*png_width].green;
+ png_image_data[y][4*x+2] = argb_list[x+y*png_width].blue;
+ png_image_data[y][4*x+3] = argb_list[x+y*png_width].alpha;
+ }
+ }
+
+ }
+ png_buff.data = NULL;
+ png_buff.data_len = 0;
+ png_buff.data_offset = 0;
+ png_data_write((png_structp) png_ptr, (my_png_buffer*) &png_buff);
+
+ png_write_info(png_ptr, png_info_ptr);
+ png_write_image(png_ptr, png_image_data);
+ png_write_end(png_ptr, png_info_ptr);
+ //
+ for (y=0; y < png_height; y++) {
+ free(png_image_data[y]);
+ }
+ free(png_image_data);
+ png_destroy_write_struct((png_structpp) &png_ptr,
+ (png_infopp) &png_info_ptr);
+ *length = png_buff.data_offset;
+ return png_buff.data;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+extern void *
+pngconv_png2lossless(unsigned char *png_data, unsigned long png_data_len,
+ int *tag, int *format,
+ unsigned short *width, unsigned short *height,
+ void **colormap, int *colormap_count);
+
+extern unsigned char *
+pngconv_lossless2png(void *image_data,
+ unsigned short width, unsigned short height,
+ void *index_data,
+ unsigned short index_data_count,
+ int tag, int format,
+ unsigned long *length);
--- /dev/null
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_rect.h"
+
+
+int two_negative(int num, int size) {
+ int msb = 1 << (size - 1);
+ int mask = msb - 1;
+ if (num & msb) {
+ return - ((num^mask) & mask) - 1;
+ }
+ return num;
+}
+
+int two_negative_reverse(int num, int size) { // dummy
+ int msb = 1 << (size - 1);
+ int mask = msb - 1;
+ if (num < 0) {
+ return - ((num^mask) & mask) - 1;
+ }
+ return num;
+}
+
+int
+swf_rect_parse(bitstream_t *bs, swf_rect_t *rect) {
+ unsigned char size;
+ bitstream_align(bs);
+ size = bitstream_getbits(bs, 5);
+ rect->size = size;
+ rect->x_min = bitstream_getbits(bs, size);
+ rect->x_max = bitstream_getbits(bs, size);
+ rect->y_min = bitstream_getbits(bs, size);
+ rect->y_max = bitstream_getbits(bs, size);
+ //
+ rect->x_min = two_negative(rect->x_min, size);
+ rect->x_max = two_negative(rect->x_max, size);
+ rect->y_min = two_negative(rect->y_min, size);
+ rect->y_max = two_negative(rect->y_max, size);
+ return 0;
+}
+
+int
+swf_rect_build(bitstream_t *bs, swf_rect_t *rect) {
+ unsigned char size = rect->size; // XXX
+ int x_min = two_negative_reverse(rect->x_min, size);
+ int x_max = two_negative_reverse(rect->x_max, size);
+ int y_min = two_negative_reverse(rect->y_min, size);
+ int y_max = two_negative_reverse(rect->y_max, size);
+ bitstream_align(bs);
+ bitstream_putbits(bs, size, 5);
+ bitstream_putbits(bs, x_min, size);
+ bitstream_putbits(bs, x_max, size);
+ bitstream_putbits(bs, y_min, size);
+ bitstream_putbits(bs, y_max, size);
+ return 0;
+}
+
+int
+swf_rect_print(swf_rect_t *rect) {
+ printf("rect=(%d, %d)-(%d, %d) (f_size=%d)\n",
+ rect->x_min / SWF_TWIPS,
+ rect->y_min / SWF_TWIPS,
+ rect->x_max / SWF_TWIPS,
+ rect->y_max / SWF_TWIPS,
+ rect->size);
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_RECT_H__
+#define __SWF_RECT_H__
+
+typedef struct swf_rect_ {
+ unsigned char size;
+ int x_min;
+ int x_max;
+ int y_min;
+ int y_max;
+} swf_rect_t;
+
+extern int swf_rect_parse(bitstream_t *bs, swf_rect_t *rect);
+extern int swf_rect_build(bitstream_t *bs, swf_rect_t *rect);
+extern int swf_rect_print(swf_rect_t *rect);
+
+#endif /* __SWF_RECT_H__ */
--- /dev/null
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_rgb.h"
+
+int
+swf_rgb_parse(bitstream_t *bs, swf_rgb_t *color) {
+ color->red = bitstream_getbyte(bs);
+ color->green = bitstream_getbyte(bs);
+ color->blue = bitstream_getbyte(bs);
+ return 0;
+}
+
+int
+swf_rgb_build(bitstream_t *bs, swf_rgb_t *color) {
+ bitstream_putbyte(bs, color->red);
+ bitstream_putbyte(bs, color->green);
+ bitstream_putbyte(bs, color->blue);
+ return 0;
+}
+
+int
+swf_rgb_print(swf_rgb_t *color) {
+ printf("red=0x%02x green=0x%02X blue=0x%02x\n",
+ color->red, color->green, color->blue);
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_RGB_H__
+#define __SWF_RGB_H__
+
+typedef struct swf_rgb_ {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+} swf_rgb_t;
+
+
+extern int swf_rgb_parse(bitstream_t *bs, swf_rgb_t *color);
+extern int swf_rgb_build(bitstream_t *bs, swf_rgb_t *color);
+extern int swf_rgb_print(swf_rgb_t *color);
+
+#endif /* __SWF_RGB_H__ */
--- /dev/null
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_rgba.h"
+
+int
+swf_rgba_parse(bitstream_t *bs, swf_rgba_t *color) {
+ color->red = bitstream_getbyte(bs);
+ color->green = bitstream_getbyte(bs);
+ color->blue = bitstream_getbyte(bs);
+ color->alpha = bitstream_getbyte(bs);
+ return 0;
+}
+
+int
+swf_rgba_build(bitstream_t *bs, swf_rgba_t *color) {
+ bitstream_putbyte(bs, color->red);
+ bitstream_putbyte(bs, color->green);
+ bitstream_putbyte(bs, color->blue);
+ bitstream_putbyte(bs, color->alpha);
+ return 0;
+}
+
+int
+swf_rgba_print(swf_rgba_t *color) {
+ printf("red=0x%02x green=0x%02X blue=0x%02x alpha=0x%02x\n",
+ color->red, color->green, color->blue, color->alpha);
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_RGBA_H__
+#define __SWF_RGBA_H__
+
+typedef struct swf_rgba_ {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned char alpha;
+} swf_rgba_t;
+
+extern int swf_rgba_parse(bitstream_t *bs, swf_rgba_t *color);
+extern int swf_rgba_build(bitstream_t *bs, swf_rgba_t *color);
+extern int swf_rgba_print(swf_rgba_t *color);
+
+#endif /* __SWF_RGBA_H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bitstream.h"
+#include "swf_define.h"
+#include "swf_tag.h"
+#include "swf_tag_jpeg.h"
+#include "swf_tag_lossless.h"
+#include "swf_tag_edit.h"
+#include "swf_tag_action.h"
+#include "swf_tag_sound.h"
+
+swf_tag_info_t swf_tag_info_table[] = {
+ { 0, "End", NULL },
+ { 1, "ShowFrame", NULL },
+ { 2, "DefineShape", NULL },
+ { 3, "FreeCharacter", NULL},
+ { 4, "PlaceObject", NULL},
+ { 5, "RemoveObject", NULL},
+ { 6, "DefineBitsJPEG", swf_tag_jpeg_detail_handler },
+ { 7, "DefineButton", NULL},
+ { 8, "JPEGTables", NULL },
+ { 9, "SetBackgroundColor", NULL },
+ { 10, "DefineFont ", NULL},
+ { 11, "DefineText", NULL },
+ { 12, "DoAction", swf_tag_action_detail_handler },
+ { 13, "DefineFontInfo", NULL },
+ { 14, "DefineSound", swf_tag_sound_detail_handler },
+ { 15, "StartSound", NULL },
+ { 16, "DefineButtonSound", NULL },
+ { 17, "DefineButtonSound", NULL },
+ { 18, "SoundStreamHead", NULL },
+ { 19, "SoundStreamBlock", NULL },
+ { 20, "DefineBitsLossless", swf_tag_lossless_detail_handler },
+ { 21, "DefineBitsJPEG2", swf_tag_jpeg_detail_handler },
+ { 22, "DefineShape2", NULL },
+ { 26, "PlaceObject2", NULL },
+ { 28, "RemoveObject2", NULL },
+ { 32, "DefineShape3", NULL },
+ { 33, "DefineText2", NULL },
+ { 34, "DefineButton2", NULL },
+ { 35, "DefineBitsJPEG3", swf_tag_jpeg3_detail_handler },
+ { 36, "DefineBitsLossless2", swf_tag_lossless_detail_handler },
+ { 37, "DefineEditText", swf_tag_edit_detail_handler },
+ { 39, "DefineSprite", NULL } ,
+ { 43, "FrameLabel", NULL } ,
+ { 48, "DefineFont2", NULL } ,
+ { 69, "FileAttributes", NULL },
+ { 73, "DefineFontAlignZones", NULL },
+ { 74, "CSMTextSettings", NULL },
+ { 75, "DefineFont3", NULL } ,
+ { 83, "DefineShape4", NULL },
+ { 88, "DefineFontName", NULL } ,
+ { 777,"Reflex", NULL } ,
+};
+
+swf_tag_info_t *get_swf_tag_info(int tag_id) {
+ int i, tag_info_num = NumOfTable(swf_tag_info_table);
+ for(i=0; i < tag_info_num; i++) {
+ if (tag_id == swf_tag_info_table[i].id) {
+ return &(swf_tag_info_table[i]);
+ }
+ }
+ return NULL;
+}
+
+swf_tag_t *swf_tag_create(bitstream_t *bs) {
+ swf_tag_t *tag = calloc(sizeof(*tag), 1);
+ unsigned short tag_and_length;
+ if (bs == NULL) {
+ fprintf(stderr, "swf_tag_create: bs == NULL\n");
+ return NULL;
+ }
+ tag_and_length = bitstream_getbytesLE(bs, 2);
+ if (tag_and_length == (unsigned short) -1) {
+ free(tag);
+ return NULL;
+ }
+ tag->tag = tag_and_length >> 6;
+ tag->length = tag_and_length & 0x3f;
+ tag->length_longformat = 0;
+ if (tag->length == 0x3f) {
+ tag->length = bitstream_getbytesLE(bs, 4);
+ if (tag_and_length == (unsigned short) -1) {
+ free(tag);
+ return NULL;
+ }
+ tag->length_longformat = 1;
+ }
+// printf("XXX: malloc length=%d\n", tag->length);
+ tag->data = malloc(tag->length);
+ bitstream_getstring(bs, tag->data, tag->length);
+ tag->detail = NULL;
+ return tag;
+}
+
+void swf_tag_destroy(swf_tag_t *tag) {
+ if (! tag) {
+ return;
+ }
+ if (tag->data) {
+ free(tag->data);
+ }
+ if (tag->detail) {
+ swf_tag_info_t *tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->destroy) {
+ detail_handler->destroy(tag->detail);
+ } else {
+ fprintf(stderr, "detail_handler->destroy == NULL (tag=%d)\n",
+ tag->tag);
+ }
+ } else {
+ fprintf(stderr, "not impremented yet. destroy tag detail\n");
+ }
+ }
+ free(tag);
+}
+
+static int swf_tag_and_length_build(bitstream_t *bs, swf_tag_t *tag) {
+ signed short tag_and_length;
+ if (bs == NULL) {
+ fprintf(stderr, "swf_tag_and_length_build: bs == NULL\n");
+ return 1;
+ }
+ if (tag->length >= 0x3f) {
+ tag->length_longformat = 1;
+ } else {
+ switch (tag->tag) {
+ case 6: // DefineBitsJPEG
+ case 21: // DefineBitsJPEG2
+ case 35: // DefineBitsJPEG3
+ case 20: // DefineBitsLossless
+ case 36: // DefineBitsLossless2
+ case 19: // SoundStreamBlock
+ tag->length_longformat = 1;
+ break;
+ default:
+ tag->length_longformat = 0;
+ break;
+ }
+ }
+ if (tag->length_longformat) {
+ tag_and_length = (tag->tag << 6) | 0x3f;
+ bitstream_putbytesLE(bs, tag_and_length, 2);
+ bitstream_putbytesLE(bs, tag->length, 4);
+ } else {
+ tag_and_length = (tag->tag << 6) | tag->length;
+ bitstream_putbytesLE(bs, tag_and_length, 2);
+ }
+ return 0;
+}
+extern int swf_tag_build(bitstream_t *bs, swf_tag_t *tag, struct swf_object_ *swf) {
+ swf_tag_info_t *tag_info;
+ unsigned char *data;
+ unsigned long data_len = 0;
+ swf_tag_detail_handler_t * detail_handler;
+ if (bs == NULL) {
+ fprintf(stderr, "swf_tag_and_length_build: bs == NULL\n");
+ return 1;
+ }
+// fprintf(stderr, "XXX: swf_tag_build: tag->tag=%d\n",tag->tag);
+ if (tag->data) {
+ swf_tag_and_length_build(bs, tag);
+ bitstream_putstring(bs, tag->data, tag->length);
+ } else if (tag->detail){
+ tag_info = get_swf_tag_info(tag->tag);
+ if ((tag_info == NULL) || (tag_info->detail_handler == NULL)) {
+ fprintf(stderr, "swf_tag_build: not implemented yet. detail build tag->tag=%d\n",
+ tag->tag);
+ return 1;
+ }
+ detail_handler = tag_info->detail_handler();
+ if (detail_handler->output == NULL) {
+ fprintf(stderr, "swf_tag_build: detail_handler->output == NULL: tag->tag=%d\n",
+ tag->tag);
+ return 1;
+ }
+ data = detail_handler->output(tag->detail, &data_len, tag, swf);
+ if (data == NULL) {
+ fprintf(stderr, "swf_tag_build: Can't output: data=%p data_len=%lu\n",
+ data, data_len);
+ }
+ tag->length = data_len;
+ swf_tag_and_length_build(bs, tag);
+ bitstream_putstring(bs, data, data_len);
+ free(data);
+ } else {
+ fprintf(stderr, "ERROR: not found tag data and detail\n");
+ return 1;
+ }
+ return 0;
+}
+
+void
+swf_tag_print(swf_tag_t *tag, struct swf_object_ *swf) {
+ swf_tag_info_t *tag_info;
+ const char *tag_name;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_print: tag == NULL\n");
+ return ;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ tag_name = (tag_info)?tag_info->name:"Unknown";
+ printf("tag=%s(%d)", tag_name, tag->tag);
+ if (tag->length > 0) {
+ printf(" length=%lu", tag->length);
+ }
+ printf("\n");
+ if (tag_info && tag_info->detail_handler) {
+ if (tag->detail == NULL) {
+ swf_tag_create_detail(tag, swf);
+ }
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->print) {
+ detail_handler->print(tag->detail, tag, swf);
+ }
+ }
+}
+
+int swf_tag_create_detail(swf_tag_t *tag, struct swf_object_ *swf) {
+ swf_tag_info_t *tag_info;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_create_detail: tag == NULL\n");
+ return 1;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->create == NULL) {
+ fprintf(stderr, "detail_handler->create == NULL (tag=%d)\n",
+ tag->tag);
+ return 1;
+ }
+ tag->detail = detail_handler->create(tag->data, tag->length, tag, swf);
+ if (tag->detail == NULL) {
+ fprintf(stderr, "can't create tag detail (tag=%d)\n", tag->tag);
+ return 1;
+ }
+ }
+ return 1;
+}
+
+unsigned char *
+swf_tag_get_jpeg_data(swf_tag_t *tag, unsigned long *length, int image_id, swf_tag_t *tag_jpegtables) {
+ swf_tag_info_t *tag_info;
+ *length = 0;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_get_jpeg_data: tag == NULL\n");
+ return NULL;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if ((tag->tag != 6) && (tag->tag != 21) && (tag->tag != 35)) {
+ return NULL;
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_get_jpeg_data: Can't create tag\n");
+ return NULL;
+ }
+ if (tag_jpegtables) {
+ return swf_tag_jpeg_get_jpeg_data(tag->detail, length, image_id,
+ tag_jpegtables->data,
+ tag_jpegtables->length);
+ } else {
+ return swf_tag_jpeg_get_jpeg_data(tag->detail, length, image_id,
+ NULL, 0);
+ }
+}
+
+unsigned char *
+swf_tag_get_alpha_data(swf_tag_t *tag, unsigned long *length, int image_id) {
+ swf_tag_info_t *tag_info;
+ *length = 0;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_get_alpha_data: tag == NULL\n");
+ return NULL;
+ }
+ if (tag->tag != 35) { // ! DefineBitsJPEG3
+ return NULL;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->identity) {
+ if (detail_handler->identity(tag->data, image_id, tag)) {
+ return NULL;
+ }
+ }
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_get_alpha_data: Can't create tag\n");
+ return NULL;
+ }
+ return swf_tag_jpeg_get_alpha_data(tag->detail, length, image_id);
+}
+
+int
+swf_tag_replace_jpeg_data(swf_tag_t *tag, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len) {
+ swf_tag_info_t *tag_info;
+ int result;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_replace_jpeg_data: tag == NULL\n");
+ return 1;
+ }
+ if ((tag->tag != 6) && (tag->tag != 21) && (tag->tag != 35)) { // DefineBitsJPEG or 2 or 3
+ return 1;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->identity) {
+ if (detail_handler->identity(tag->data, image_id, tag)) {
+ return 1;
+ }
+ }
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_replace_jpeg_data: Can't create tag\n");
+ return 1;
+ }
+ result= swf_tag_jpeg_replace_jpeg_data(tag->detail, image_id,
+ jpeg_data, jpeg_data_len,
+ alpha_data, alpha_data_len, tag);
+ if (result == 0) {
+ free(tag->data);
+ tag->data = NULL;
+ tag->length = 0;
+ }
+ return result;
+}
+
+unsigned char *
+swf_tag_get_png_data(swf_tag_t *tag, unsigned long *length, int image_id) {
+ swf_tag_info_t *tag_info;
+ *length = 0;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_get_png_data: tag == NULL\n");
+ return NULL;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if ((tag->tag != 20) && (tag->tag != 36)) {
+ return NULL;
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_get_png_data: Can't create tag\n");
+ return NULL;
+ }
+ return swf_tag_lossless_get_png_data(tag->detail, length, image_id, tag);
+}
+
+int
+swf_tag_replace_png_data(swf_tag_t *tag, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len) {
+ swf_tag_info_t *tag_info;
+ int result;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_replace_png_data: tag == NULL\n");
+ return 1;
+ }
+ if ((tag->tag != 20) && (tag->tag != 36)) { // DefineBitsLossless or 2
+ return 1;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->identity) {
+ if (detail_handler->identity(tag->data, image_id, tag)) {
+ return 1;
+ }
+ }
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_replace_png_data: Can't create tag\n");
+ return 1;
+ }
+ result= swf_tag_lossless_replace_png_data(tag->detail, image_id,
+ png_data, png_data_len, tag);
+ if (result == 0) {
+ free(tag->data);
+ tag->data = NULL;
+ tag->length = 0;
+ }
+ return result;
+}
+
+/*
+ * DefineSound
+ */
+
+unsigned char *
+swf_tag_get_sound_data(swf_tag_t *tag, unsigned long *length, int sound_id) {
+ swf_tag_info_t *tag_info;
+ *length = 0;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_get_sound_data: tag == NULL\n");
+ return NULL;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag->tag != 14) { // DefineSound
+ return NULL;
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_get_sound_data: Can't create tag detail\n");
+ return NULL;
+ }
+ return swf_tag_sound_get_sound_data(tag->detail, length, sound_id);
+}
+
+int
+swf_tag_replace_melo_data(swf_tag_t *tag, int sound_id,
+ unsigned char *melo_data,
+ unsigned long melo_data_len) {
+ swf_tag_info_t *tag_info;
+ int result;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_replace_melo_data: tag == NULL\n");
+ return 1;
+ }
+ if (tag->tag != 14) { // DefineSound
+ return 1;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->detail_handler) {
+ swf_tag_detail_handler_t * detail_handler = tag_info->detail_handler();
+ if (detail_handler->identity) {
+ if (detail_handler->identity(tag->data, sound_id, tag)) {
+ return 1;
+ }
+ }
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, NULL);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_replace_melog_data: Can't create tag\n");
+ return 1;
+ }
+ result= swf_tag_sound_replace_melo_data(tag->detail, sound_id,
+ melo_data, melo_data_len);
+ if (result == 0) {
+ free(tag->data);
+ tag->data = NULL;
+ tag->length = 0;
+ }
+ return result;
+}
+
+char *
+swf_tag_get_edit_string(swf_tag_t *tag,
+ char *variable_name, int variable_name_len,
+ struct swf_object_ *swf) {
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_get_edit_string: tag == NULL\n");
+ return NULL;
+ }
+ if (tag->tag != 37) { // DefineEditText
+ return NULL;
+ }
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, swf);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "Can't create tag\n");
+ return NULL;
+ }
+ return swf_tag_edit_get_string(tag->detail,
+ variable_name, variable_name_len);
+}
+
+
+int
+swf_tag_replace_edit_string(swf_tag_t *tag,
+ char *variable_name, int variable_name_len,
+ char *initial_text, int initial_text_len,
+ struct swf_object_ *swf) {
+ int result;
+ if (tag == NULL) {
+ fprintf(stderr, "swf_tag_replace_edit_string: tag == NULL\n");
+ return 1;
+ }
+ if (tag->tag != 37) { // DefineEditText
+ return 1;
+ }
+
+ if (! tag->detail) {
+ swf_tag_create_detail(tag, swf);
+ }
+ if (! tag->detail) {
+ fprintf(stderr, "swf_tag_replace_edit_string: Can't create tag\n");
+ return 1;
+ }
+ result = swf_tag_edit_replace_string(tag->detail,
+ variable_name, variable_name_len,
+ initial_text, initial_text_len);
+ if (result == 0) {
+ free(tag->data);
+ tag->data = NULL;
+ tag->length = 0;
+ }
+ return result;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_H__
+#define __SWF_TAG_H__
+
+#include "bitstream.h"
+struct swf_object_; // swf_object.h
+
+typedef struct swf_tag_ {
+ int tag;
+ unsigned long length;
+ int length_longformat;
+ //
+ unsigned char *data;
+ void *detail;
+ //
+ struct swf_tag_ *next;
+} swf_tag_t;
+
+typedef struct swf_tag_detail_handler_ {
+ void * (*create) (unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+ int (*identity) (unsigned char *data, int id,
+ swf_tag_t *tag);
+ unsigned char * (*output) (void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+ void (*print) (void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+ void (*destroy) (void *);
+} swf_tag_detail_handler_t;
+
+typedef struct swf_tag_info_ {
+ int id;
+ const char *name;
+ swf_tag_detail_handler_t *(*detail_handler)(void);
+} swf_tag_info_t;
+
+extern swf_tag_info_t *get_swf_tag_info(int tag_id);
+
+extern swf_tag_t *swf_tag_create(bitstream_t *bs);
+extern void swf_tag_destroy(swf_tag_t *tag);
+extern int swf_tag_build(bitstream_t *bs, swf_tag_t *tag, struct swf_object_ *swf);
+extern void swf_tag_print(swf_tag_t *tag, struct swf_object_ *swf);
+
+/* image */
+
+extern unsigned char *swf_tag_get_jpeg_data(swf_tag_t *tag, unsigned long *length, int image_id, swf_tag_t *tag_jpegtables);
+extern unsigned char *swf_tag_get_alpha_data(swf_tag_t *tag, unsigned long *length, int image_id);
+extern int swf_tag_replace_jpeg_data(swf_tag_t *tag, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len);
+
+extern unsigned char *swf_tag_get_png_data(swf_tag_t *tag, unsigned long *length, int image_id);
+extern int swf_tag_replace_png_data(swf_tag_t *tag, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len);
+/* sound */
+extern unsigned char *swf_tag_get_sound_data(swf_tag_t *tag,
+ unsigned long *length,
+ int sound_id);
+extern int swf_tag_replace_melo_data(swf_tag_t *tag, int sound_id,
+ unsigned char *melo_data,
+ unsigned long melo_data_len);
+/* edit text */
+
+extern char *swf_tag_get_edit_string(swf_tag_t *tag,
+ char *variable_name,
+ int variable_name_len,
+ struct swf_object_ *swf);
+extern int swf_tag_replace_edit_string(swf_tag_t *tag,
+ char *variable_name,
+ int variable_name_len,
+ char *initial_text,
+ int initial_text_len,
+ struct swf_object_ *swf);
+
+extern int swf_tag_create_detail(swf_tag_t *tag, struct swf_object_ *swf);
+
+#endif /* __SWF_TAG_H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "bitstream.h"
+#include "swf_tag_action.h"
+#include "swf_object.h"
+
+swf_tag_detail_handler_t action_detail_handler;
+
+swf_tag_detail_handler_t *
+swf_tag_action_detail_handler(void) {
+ action_detail_handler.create = swf_tag_action_create_detail;
+ action_detail_handler.identity = swf_tag_action_identity_detail;
+ action_detail_handler.output = swf_tag_action_output_detail;
+ action_detail_handler.print = swf_tag_action_print_detail;
+ action_detail_handler.destroy = swf_tag_action_destroy_detail;
+ return &action_detail_handler;
+}
+
+void *
+swf_tag_action_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_action_detail_t *swf_tag_action;
+ bitstream_t *bs;
+ unsigned long pos, len;
+ (void) swf;
+ swf_tag_action = calloc(sizeof(*swf_tag_action), 1);
+ if (swf_tag_action == NULL) {
+ fprintf(stderr, "ERROR: swf_tag_action_create_detail: can't calloc\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+
+ if (tag->tag == 59) { // DoInitAction
+ swf_tag_action->action_sprite = bitstream_getbytesLE(bs, 2);
+ } else { // DoAction
+ swf_tag_action->action_sprite = 0; // fail safe
+ }
+ pos = bitstream_getbytepos(bs);
+ len = bitstream_length(bs) - pos;
+ swf_tag_action->action_record = bitstream_output_sub(bs, pos, len);
+ swf_tag_action->action_record_len = len;
+ bitstream_close(bs);
+ return (void *) swf_tag_action;
+}
+
+int swf_tag_action_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag) {
+ (void) data;
+ (void) id;
+ (void) tag;
+ return 1;
+}
+
+unsigned char *
+swf_tag_action_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) detail;
+ bitstream_t *bs;
+ unsigned char *data;
+ *length = 0;
+
+ (void) swf;
+ bs = bitstream_open();
+ if (tag->tag == 59) { // DoInitAction
+ bitstream_putbytesLE(bs, swf_tag_action->action_sprite, 2);
+ } else { // DoAction
+ ; // nothing
+ }
+ bitstream_putstring(bs, swf_tag_action->action_record,
+ swf_tag_action->action_record_len);
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+void
+swf_tag_action_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ bitstream_t *bs;
+ swf_action_list_t *action_list;
+ swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) detail;
+ (void) swf;
+ if (tag->tag == 59) { // DoInitAction
+ printf("action_sprite=%d ", swf_tag_action->action_sprite);
+ }
+ printf("action_record =\n");
+ bs = bitstream_open();
+ bitstream_input(bs, swf_tag_action->action_record,
+ swf_tag_action->action_record_len);
+ action_list = swf_action_list_create(bs);
+ bitstream_close(bs);
+ swf_action_list_print(action_list);
+ swf_action_list_destroy(action_list);
+ return ;
+}
+
+void
+swf_tag_action_destroy_detail(void *detail) {
+ swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) detail;
+ if (swf_tag_action) {
+ free(swf_tag_action->action_record);
+ swf_tag_action->action_record = NULL;
+ free(swf_tag_action);
+ }
+ return ;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_ACTION__H__
+#define __SWF_TAG_ACTION__H__
+
+#include "swf_tag.h"
+#include "swf_action.h"
+
+typedef struct swf_tag_action_detail_ {
+ unsigned short action_sprite;
+ unsigned char *action_record;
+ unsigned long action_record_len;
+} swf_tag_action_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_action_detail_handler(void);
+
+extern void *swf_tag_action_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern int swf_tag_action_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag);
+extern unsigned char *swf_tag_action_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_action_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_action_destroy_detail(void *detail);
+
+#endif /* __SWF_TAG_ACTION__H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "bitstream.h"
+#include "swf_tag_edit.h"
+#include "swf_object.h"
+#include "swf_rgba.h"
+
+swf_tag_detail_handler_t edit_detail_handler;
+
+swf_tag_detail_handler_t *
+swf_tag_edit_detail_handler(void) {
+ edit_detail_handler.create = swf_tag_edit_create_detail;
+ edit_detail_handler.identity = swf_tag_edit_identity_detail;
+ edit_detail_handler.output = swf_tag_edit_output_detail;
+ edit_detail_handler.print = swf_tag_edit_print_detail;
+ edit_detail_handler.destroy = swf_tag_edit_destroy_detail;
+ return &edit_detail_handler;
+}
+
+void *
+swf_tag_edit_create_detail(unsigned char *data, unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_edit_detail_t *swf_tag_edit;
+ bitstream_t *bs;
+ (void) tag;
+ swf_tag_edit = calloc(sizeof(*swf_tag_edit), 1);
+ if (swf_tag_edit == NULL) {
+ fprintf(stderr, "ERROR: swf_tag_edit_create_detail: can't calloc\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+ swf_tag_edit->edit_id = bitstream_getbytesLE(bs, 2);
+ swf_rect_parse(bs, &swf_tag_edit->rect);
+ bitstream_align(bs);
+ swf_tag_edit->edit_has_text = bitstream_getbit(bs);
+ swf_tag_edit->edit_word_wrap = bitstream_getbit(bs);
+ swf_tag_edit->edit_multiline = bitstream_getbit(bs);
+ swf_tag_edit->edit_password = bitstream_getbit(bs);
+ swf_tag_edit->edit_readonly = bitstream_getbit(bs);
+ swf_tag_edit->edit_has_color = bitstream_getbit(bs);
+ swf_tag_edit->edit_has_max_length = bitstream_getbit(bs);
+ swf_tag_edit->edit_has_font = bitstream_getbit(bs);
+ if (swf && (swf->header.version >= 6)) {
+ (void) bitstream_getbit(bs); // reserved;
+ swf_tag_edit->edit_auto_size = bitstream_getbit(bs);
+ } else {
+ (void) bitstream_getbit(bs); // reserved;
+ (void) bitstream_getbit(bs); // reserved;
+ }
+ swf_tag_edit->edit_has_layout = bitstream_getbit(bs);
+ swf_tag_edit->edit_no_select = bitstream_getbit(bs);
+ swf_tag_edit->edit_border = bitstream_getbit(bs);
+ (void) bitstream_getbit(bs); // reserved;
+ swf_tag_edit->edit_html = bitstream_getbit(bs);
+ swf_tag_edit->edit_use_outlines = bitstream_getbit(bs);
+ if (swf_tag_edit->edit_has_font) {
+ swf_tag_edit->edit_font_id_ref = bitstream_getbytesLE(bs, 2);
+ swf_tag_edit->edit_font_height = bitstream_getbytesLE(bs, 2);
+ }
+ if (swf_tag_edit->edit_has_color) {
+ swf_rgba_parse(bs, &swf_tag_edit->edit_color);
+ }
+ if (swf_tag_edit->edit_has_max_length) {
+ swf_tag_edit->edit_max_length = bitstream_getbytesLE(bs, 2);
+ }
+ if (swf_tag_edit->edit_has_layout) {
+ swf_tag_edit->edit_align = bitstream_getbyte(bs);
+ swf_tag_edit->edit_left_margine = bitstream_getbytesLE(bs, 2);
+ swf_tag_edit->edit_right_margine = bitstream_getbytesLE(bs, 2);
+ swf_tag_edit->edit_indent = (signed) bitstream_getbytesLE(bs, 2);
+ swf_tag_edit->edit_leading = (signed) bitstream_getbytesLE(bs, 2);
+ }
+ swf_tag_edit->edit_variable_name = (char *) bitstream_outputstring(bs);
+ if (swf_tag_edit->edit_has_text) {
+ swf_tag_edit->edit_initial_text = (char *) bitstream_outputstring(bs);
+ } else {
+ swf_tag_edit->edit_initial_text = NULL;
+ }
+
+ bitstream_close(bs);
+ return (void *) swf_tag_edit;
+}
+
+int swf_tag_edit_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag) {
+ bitstream_t *bs;
+ int edit_id;
+ (void) tag;
+ bs = bitstream_open();
+ bitstream_input(bs, data, 2);
+ edit_id = bitstream_getbytesLE(bs, 2);
+ bitstream_close(bs);
+ if (id == edit_id) {
+ return 0;
+ }
+ return 1;
+}
+
+unsigned char *
+swf_tag_edit_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_edit_detail_t *swf_tag_edit = (swf_tag_edit_detail_t *) detail;
+ bitstream_t *bs;
+ unsigned char *data;
+ (void) tag;
+ *length = 0;
+ bs = bitstream_open();
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_id, 2);
+ swf_rect_build(bs, &swf_tag_edit->rect);
+ bitstream_align(bs);
+ bitstream_putbit(bs, swf_tag_edit->edit_has_text);
+ bitstream_putbit(bs, swf_tag_edit->edit_word_wrap);
+ bitstream_putbit(bs, swf_tag_edit->edit_multiline);
+ bitstream_putbit(bs, swf_tag_edit->edit_password );
+ bitstream_putbit(bs, swf_tag_edit->edit_readonly);
+ bitstream_putbit(bs, swf_tag_edit->edit_has_color );
+ bitstream_putbit(bs, swf_tag_edit->edit_has_max_length);
+ bitstream_putbit(bs, swf_tag_edit->edit_has_font);
+ if (swf && (swf->header.version >= 6)) {
+ bitstream_putbit(bs, 0); // reserved;
+ bitstream_putbit(bs, swf_tag_edit->edit_auto_size);
+ } else {
+ bitstream_putbit(bs, 0); // reserved;
+ bitstream_putbit(bs, 0); // reserved;
+ }
+ bitstream_putbit(bs, swf_tag_edit->edit_has_layout);
+ bitstream_putbit(bs, swf_tag_edit->edit_no_select);
+ bitstream_putbit(bs, swf_tag_edit->edit_border);
+ bitstream_putbit(bs, 0); // reserved;
+ bitstream_putbit(bs, swf_tag_edit->edit_html);
+ bitstream_putbit(bs, swf_tag_edit->edit_use_outlines);
+ if (swf_tag_edit->edit_has_font) {
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_font_id_ref, 2);
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_font_height, 2);
+ }
+ if (swf_tag_edit->edit_has_color) {
+ swf_rgba_build(bs, &swf_tag_edit->edit_color);
+ }
+ if (swf_tag_edit->edit_has_max_length) {
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_max_length, 2);
+ }
+ if (swf_tag_edit->edit_has_layout) {
+ bitstream_putbyte(bs, swf_tag_edit->edit_align);
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_left_margine, 2);
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_right_margine, 2);
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_indent, 2);
+ bitstream_putbytesLE(bs, swf_tag_edit->edit_leading, 2);
+ }
+ bitstream_putstring(bs,
+ (unsigned char *) swf_tag_edit->edit_variable_name,
+ strlen(swf_tag_edit->edit_variable_name) + 1);
+ if (swf_tag_edit->edit_has_text) {
+ bitstream_putstring(bs,
+ (unsigned char *)swf_tag_edit->edit_initial_text,
+ strlen(swf_tag_edit->edit_initial_text) + 1);
+ }
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+void
+swf_tag_edit_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_edit_detail_t *swf_tag_edit = (swf_tag_edit_detail_t *) detail;
+ (void) tag;
+ printf("\tedit_id=%d\n", swf_tag_edit->edit_id);
+ printf("\t");
+ swf_rect_print(&swf_tag_edit->rect);
+ printf("\ttext=%d wwrap=%d multi=%d pass=%d ro=%d col=%d maxlen=%d font=%d\n",
+ swf_tag_edit->edit_has_text?1:0,
+ swf_tag_edit->edit_word_wrap?1:0,
+ swf_tag_edit->edit_multiline?1:0,
+ swf_tag_edit->edit_password?1:0,
+ swf_tag_edit->edit_readonly?1:0,
+ swf_tag_edit->edit_has_color?1:0,
+ swf_tag_edit->edit_has_max_length?1:0,
+ swf_tag_edit->edit_has_font?1:0);
+ if (swf->header.version >= 6) {
+ printf("\tauto_size=%d\n", swf_tag_edit->edit_auto_size);
+ }
+ printf("\tlayout=%d no_sel=%d border=%d\n",
+ swf_tag_edit->edit_has_layout?1:0,
+ swf_tag_edit->edit_no_select?1:0,
+ swf_tag_edit->edit_border?1:0);
+ if (swf_tag_edit->edit_has_font) {
+ printf("\tfont_id=%d font_height=%d\n",
+ swf_tag_edit->edit_font_id_ref,
+ swf_tag_edit->edit_font_height / SWF_TWIPS);
+ }
+ if (swf_tag_edit->edit_has_color) {
+ printf("\t");
+ swf_rgba_print(&swf_tag_edit->edit_color);
+ }
+ if (swf_tag_edit->edit_has_max_length) {
+ printf("\tmax_length=%d\n",
+ swf_tag_edit->edit_max_length);
+ }
+ if (swf_tag_edit->edit_has_layout) {
+ printf("\talign=%d (left,right)_margine=(%d,%d) indent=%d leading=%d\n",
+ swf_tag_edit->edit_align,
+ swf_tag_edit->edit_left_margine,
+ swf_tag_edit->edit_right_margine,
+ swf_tag_edit->edit_indent,
+ swf_tag_edit->edit_leading);
+ }
+ if (swf_tag_edit->edit_variable_name) {
+ printf("\tvariable_name=%s\n",
+ swf_tag_edit->edit_variable_name);
+ }
+ if (swf_tag_edit->edit_initial_text) {
+ printf("\tinitial_text=%s\n",
+ swf_tag_edit->edit_initial_text);
+ }
+ return ;
+}
+
+void
+swf_tag_edit_destroy_detail(void *detail) {
+ swf_tag_edit_detail_t *swf_tag_edit = (swf_tag_edit_detail_t *) detail;
+ if (swf_tag_edit) {
+ free(swf_tag_edit->edit_variable_name);
+ free(swf_tag_edit->edit_initial_text);
+ swf_tag_edit->edit_variable_name = NULL;
+ swf_tag_edit->edit_initial_text = NULL;
+ free(swf_tag_edit);
+ }
+ return ;
+}
+
+char *
+swf_tag_edit_get_string(void *detail,
+ char *variable_name, int variable_name_len) {
+ swf_tag_edit_detail_t *swf_tag_edit = (swf_tag_edit_detail_t *) detail;
+ char *data, *initial_text;
+ if (strcmp(swf_tag_edit->edit_variable_name, variable_name)) {
+ if (atoi(variable_name) != swf_tag_edit->edit_id) {
+ return NULL;
+ }
+ }
+ initial_text = swf_tag_edit->edit_initial_text;
+ data = malloc(variable_name_len + 1);
+ if (data == NULL) {
+ fprintf(stderr, "swf_tag_edit_get_string: Can't malloc\n");
+ return NULL;
+ }
+ memcpy(data, initial_text, variable_name_len + 1);
+ return data;
+}
+
+int
+swf_tag_edit_replace_string(void *detail,
+ char *variable_name, int variable_name_len,
+ char *initial_text, int initial_text_len) {
+ char *new_str;
+ swf_tag_edit_detail_t *swf_tag_edit = (swf_tag_edit_detail_t *) detail;
+ if (((int) strlen(swf_tag_edit->edit_variable_name) != variable_name_len)
+ || memcmp(swf_tag_edit->edit_variable_name, variable_name,
+ variable_name_len)) {
+ if (atoi(variable_name) != swf_tag_edit->edit_id) {
+ return 1;
+ }
+ }
+ if (initial_text_len == 0) {
+ swf_tag_edit->edit_has_text = 0;
+ if (swf_tag_edit->edit_initial_text) {
+ free(swf_tag_edit->edit_initial_text);
+ swf_tag_edit->edit_initial_text = NULL;
+ }
+ return 0;
+ }
+ swf_tag_edit->edit_has_text = 1;
+ new_str = malloc(initial_text_len + 1);
+ if (new_str == NULL) {
+ fprintf(stderr, "swf_tag_edit_replace_string: Can't malloc\n");
+ return 1;
+ }
+ memcpy(new_str, initial_text, initial_text_len);
+ new_str[initial_text_len] = '\0';
+ if (swf_tag_edit->edit_initial_text) {
+ free(swf_tag_edit->edit_initial_text);
+ }
+ swf_tag_edit->edit_initial_text = new_str;
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_EDIT__H__
+#define __SWF_TAG_EDIT__H__
+
+#include "swf_tag.h"
+#include "swf_rect.h"
+#include "swf_rgba.h"
+
+typedef struct swf_tag_edit_detail_ {
+ int edit_id;
+ swf_rect_t rect;
+ int edit_has_text:1;
+ int edit_word_wrap:1;
+ int edit_multiline:1;
+ int edit_password:1;
+ int edit_readonly:1;
+ int edit_has_color:1;
+ int edit_has_max_length:1;
+ int edit_has_font:1;
+/* unsigned char edit_reserved; */
+ unsigned char edit_auto_size; // version >= 6
+ int edit_has_layout:1;
+ int edit_no_select:1;
+ int edit_border:1;
+/* int edit_researved:1; */
+ int edit_html:1;
+ int edit_use_outlines:1;
+ // edit has font -- begin
+ unsigned short edit_font_id_ref;
+ unsigned short edit_font_height;
+ // edit has font -- end
+ swf_rgba_t edit_color; // edit has color
+ unsigned short edit_max_length; // edit has max length
+ // edit has layout -- begin
+ unsigned char edit_align;
+ unsigned short edit_left_margine;
+ unsigned short edit_right_margine;
+ signed short edit_indent;
+ signed short edit_leading;
+ // edit has layout -- end
+ char *edit_variable_name;
+ char *edit_initial_text; // edit_has text
+} swf_tag_edit_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_edit_detail_handler(void);
+
+extern void *swf_tag_edit_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern int swf_tag_edit_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag);
+extern unsigned char *swf_tag_edit_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_edit_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_edit_destroy_detail(void *detail);
+
+extern char *swf_tag_edit_get_string(void *detail,
+ char *variable_name,
+ int variable_name_len);
+extern int swf_tag_edit_replace_string(void *detail,
+ char *variable_name,
+ int variable_name_len,
+ char *initial_text,
+ int initial_text_len);
+
+#endif /* __SWF_TAG_EDIT__H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strndup */
+#include <zlib.h>
+#include "bitstream.h"
+#include "swf_define.h"
+#include "swf_tag_jpeg.h"
+// #include "swf_tag.h"
+#include "swf_jpeg.h"
+#include "jpeg_segment.h"
+
+swf_tag_detail_handler_t jpeg_detail_handler;
+
+swf_tag_detail_handler_t *swf_tag_jpeg_detail_handler(void) {
+ jpeg_detail_handler.create = swf_tag_jpeg_create_detail;
+ jpeg_detail_handler.identity = swf_tag_jpeg_identity_detail;
+ jpeg_detail_handler.output = swf_tag_jpeg_output_detail;
+ jpeg_detail_handler.print = swf_tag_jpeg_print_detail;
+ jpeg_detail_handler.destroy = swf_tag_jpeg_destroy_detail;
+ return &jpeg_detail_handler;
+}
+
+swf_tag_detail_handler_t *swf_tag_jpeg3_detail_handler(void) {
+ jpeg_detail_handler.create = swf_tag_jpeg3_create_detail;
+ jpeg_detail_handler.identity = swf_tag_jpeg_identity_detail;
+ jpeg_detail_handler.output = swf_tag_jpeg3_output_detail;
+ jpeg_detail_handler.print = swf_tag_jpeg_print_detail;
+ jpeg_detail_handler.destroy = swf_tag_jpeg_destroy_detail;
+ return &jpeg_detail_handler;
+}
+
+void *
+swf_tag_jpeg_create_detail(unsigned char *data, unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg;
+ bitstream_t *bs;
+ (void) tag;
+ (void) swf;
+ swf_tag_jpeg = calloc(sizeof(*swf_tag_jpeg), 1);
+ if (swf_tag_jpeg == NULL) {
+ fprintf(stderr, "ERROR: swf_tag_jpeg_create_detail: can't calloc\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+ swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2);
+ swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2, length - 2);
+ swf_tag_jpeg->jpeg_data_len = length - 2;
+ swf_tag_jpeg->alpha_data = NULL;
+ swf_tag_jpeg->alpha_data_len = 0;
+ bitstream_close(bs);
+ return (void *) swf_tag_jpeg;
+}
+
+void *
+swf_tag_jpeg3_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg;
+ unsigned long offset_to_alpha;
+ bitstream_t *bs;
+ unsigned long offset, alpha_data_len;
+ unsigned char *old_buff_ref, *new_buff;
+ unsigned long origsize;
+ int result;
+ (void) tag;
+ (void) swf;
+ swf_tag_jpeg = calloc(sizeof(*swf_tag_jpeg), 1);
+ if (swf_tag_jpeg == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_create_detail: can't calloc\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+ swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2);
+ offset_to_alpha = bitstream_getbytesLE(bs, 4);
+ swf_tag_jpeg->offset_to_alpha = offset_to_alpha;
+ swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2 + 4 , offset_to_alpha);
+ if (swf_tag_jpeg->jpeg_data == NULL) {
+ free(swf_tag_jpeg);
+ bitstream_close(bs);
+ fprintf(stderr, "swf_tag_jpeg3_create_detail: swf_tag_jpeg->jpeg_data\n");
+ return NULL;
+ }
+
+ swf_tag_jpeg->jpeg_data_len = offset_to_alpha;
+ offset = 2 + 4 + offset_to_alpha;
+ alpha_data_len = length - offset;
+ origsize = 256 * alpha_data_len;
+ new_buff = malloc(origsize);
+ old_buff_ref = bitstream_buffer(bs, offset);
+ result = uncompress(new_buff, &origsize, old_buff_ref, alpha_data_len);
+ if (result == Z_OK) {
+ swf_tag_jpeg->alpha_data = realloc(new_buff, origsize);
+ swf_tag_jpeg->alpha_data = new_buff;
+ swf_tag_jpeg->alpha_data_len = origsize;
+ } else {
+ if (result == Z_MEM_ERROR) {
+ fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_MEM_ERROR: can't malloc\n");
+ } else if (result == Z_BUF_ERROR) {
+ fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_BUF_ERROR: not enough buff size\n");
+ } else if (result == Z_DATA_ERROR) {
+ fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data\n");
+ } else {
+ fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: failed by unknown reason (%d)\n", result);
+ }
+ free(new_buff);
+ }
+ bitstream_close(bs);
+ return (void *) swf_tag_jpeg;
+}
+
+int
+swf_tag_jpeg_identity_detail(unsigned char *data, int id, swf_tag_t *tag) {
+ int image_id;
+ if (tag->detail) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
+ if (swf_tag_jpeg->image_id == id) {
+ return 0;
+ }
+ return 1;
+ }
+ if (data == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_identity_detail: data==NULL\n");
+ return 1;
+ }
+ image_id = GetUShortLE(data);
+ if (id == image_id) {
+ return 0;
+ }
+ return 1;
+}
+
+unsigned char *
+swf_tag_jpeg_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ bitstream_t *bs;
+ unsigned char *data;
+ (void) tag;
+ (void) swf;
+ *length = 0;
+ bs = bitstream_open();
+ bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2);
+ bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len);
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+unsigned char *
+swf_tag_jpeg3_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ bitstream_t *bs;
+ unsigned char *data, *new_buff;
+ unsigned long offset_to_alpha;
+ unsigned long compsize;
+ (void) tag;
+ (void) swf;
+ *length = 0;
+ bs = bitstream_open();
+ bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2);
+ bitstream_putbytesLE(bs, swf_tag_jpeg->jpeg_data_len, 4);
+ bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len);
+ offset_to_alpha = swf_tag_jpeg->jpeg_data_len;
+ new_buff = malloc(swf_tag_jpeg->alpha_data_len); // too enough memory
+ compress(new_buff, &compsize, swf_tag_jpeg->alpha_data, swf_tag_jpeg->alpha_data_len);
+ bitstream_putstring(bs, new_buff, compsize);
+ free(new_buff);
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+void
+swf_tag_jpeg_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ jpeg_segment_t *jpeg_seg;
+ jpeg_segment_node_t *node;
+ (void) tag;
+ (void) swf;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_print_detail: detail == NULL\n");
+ return ;
+ }
+ printf("\timage_id=%d jpeg_data_size=%lu\n",
+ swf_tag_jpeg->image_id, swf_tag_jpeg->jpeg_data_len);
+ jpeg_seg = jpeg_segment_parse(swf_tag_jpeg->jpeg_data,
+ swf_tag_jpeg->jpeg_data_len);
+ if (jpeg_seg) {
+ for(node = jpeg_seg->head ; node ; node = node->next) {
+ char *name = jpeg_segment_get_marker_name(node->marker);
+ printf("\t\t%s(0x%02X): len=%lu\n", name?name:"Unknwon",
+ node->marker, node->data_len);
+ }
+ jpeg_segment_destroy(jpeg_seg);
+ } else {
+ printf("\t\t(invalid jpeg data)\n");
+ }
+ if (swf_tag_jpeg->alpha_data) {
+ printf(" alpha_data_size=%lu\n",
+ swf_tag_jpeg->alpha_data_len);
+ }
+}
+
+void
+swf_tag_jpeg_destroy_detail(void *detail) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ if (swf_tag_jpeg) {
+ free(swf_tag_jpeg->jpeg_data);
+ free(swf_tag_jpeg->alpha_data);
+ swf_tag_jpeg->jpeg_data = NULL;
+ swf_tag_jpeg->alpha_data = NULL;
+ free(swf_tag_jpeg);
+ }
+ return ;
+}
+
+unsigned char *swf_tag_jpeg_get_jpeg_data(void *detail,
+ unsigned long *length,
+ int image_id,
+ unsigned char *jpeg_table_data,
+ unsigned long jpeg_table_data_len) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ unsigned char *data;
+ *length = 0;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_get_jpeg_data: detail == NULL\n");
+ }
+ if (swf_tag_jpeg->image_id != image_id) {
+ return NULL;
+ }
+ if (swf_tag_jpeg->jpeg_data_len == 0) {
+ fprintf(stderr, "swf_tag_jpeg_get_jpeg_data: swf_tag_jpeg->jpeg_data_len\n");
+ return NULL;
+ }
+ data = jpegconv_swf2std(swf_tag_jpeg->jpeg_data,
+ swf_tag_jpeg->jpeg_data_len,
+ length,
+ jpeg_table_data,
+ jpeg_table_data_len);
+ return data;
+}
+
+unsigned char *swf_tag_jpeg_get_alpha_data(void *detail, unsigned long *length, int image_id) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ unsigned char *data;
+ *length = 0;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_get_alpha_data: detail == NULL\n");
+ return NULL;
+ }
+ if (swf_tag_jpeg->image_id != image_id) {
+ return NULL;
+ }
+ *length = swf_tag_jpeg->alpha_data_len;
+ if (*length == 0) {
+ return NULL;
+ }
+ data = malloc(*length);
+ memcpy(data, swf_tag_jpeg->alpha_data, *length);
+ return data;
+}
+
+int
+swf_tag_jpeg_replace_jpeg_data(void *detail, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len,
+ swf_tag_t *tag) {
+ swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_jpeg_replace_jpeg_data: detail == NULL\n");
+ return 1;
+ }
+ if (swf_tag_jpeg->image_id != image_id) {
+ return 1;
+ }
+ if (tag->tag == 6) { // DefineBitsJPEG
+ free(swf_tag_jpeg->jpeg_data);
+ swf_tag_jpeg->jpeg_data = malloc(jpeg_data_len);
+ memcpy(swf_tag_jpeg->jpeg_data, jpeg_data, jpeg_data_len);
+ swf_tag_jpeg->jpeg_data_len = jpeg_data_len;
+ } else {
+ if (jpeg_data) {
+ unsigned long length;
+ free(swf_tag_jpeg->jpeg_data);
+ swf_tag_jpeg->jpeg_data = jpegconv_std2swf(jpeg_data, jpeg_data_len,
+ &length);
+ swf_tag_jpeg->jpeg_data_len = length;
+ }
+ if (alpha_data) {
+ free(swf_tag_jpeg->alpha_data);
+ swf_tag_jpeg->alpha_data = malloc(alpha_data_len);
+ memcpy(swf_tag_jpeg->alpha_data, alpha_data, alpha_data_len);
+ swf_tag_jpeg->alpha_data_len = alpha_data_len;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_JPEG__H__
+#define __SWF_TAG_JPEG__H__
+
+#include "swf_tag.h"
+
+typedef struct swf_tag_jpeg_detail_ {
+ int image_id;
+ unsigned char *jpeg_data;
+ unsigned long jpeg_data_len;
+ unsigned long offset_to_alpha;
+ unsigned char *alpha_data;
+ unsigned long alpha_data_len;
+} swf_tag_jpeg_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_jpeg_detail_handler(void);
+extern swf_tag_detail_handler_t *swf_tag_jpeg3_detail_handler(void);
+
+extern void *swf_tag_jpeg_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern int swf_tag_jpeg_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag);
+extern void *swf_tag_jpeg3_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern unsigned char *swf_tag_jpeg_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern unsigned char *swf_tag_jpeg3_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_jpeg_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_jpeg_destroy_detail(void *detail);
+
+extern unsigned char *swf_tag_jpeg_get_jpeg_data(void *detail,
+ unsigned long *length,
+ int image_id,
+ unsigned char *jpeg_table_data,
+ unsigned long jpeg_table_data_len);
+extern unsigned char *swf_tag_jpeg_get_alpha_data(void *detail, unsigned long *length, int image_id);
+extern int swf_tag_jpeg_replace_jpeg_data(void *detail, int image_id,
+ unsigned char *jpeg_data,
+ unsigned long jpeg_data_len,
+ unsigned char *alpha_data,
+ unsigned long alpha_data_len,
+ swf_tag_t *tag);
+
+#endif /* __SWF_TAG_JPEG__H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strndup */
+#include <zlib.h>
+#include "bitstream.h"
+#include "swf_define.h"
+#include "swf_tag_lossless.h"
+#include "swf_png.h"
+
+swf_tag_detail_handler_t lossless_detail_handler;
+
+swf_tag_detail_handler_t *swf_tag_lossless_detail_handler(void) {
+ lossless_detail_handler.create = swf_tag_lossless_create_detail;
+ lossless_detail_handler.identity = swf_tag_lossless_identity_detail;
+ lossless_detail_handler.output = swf_tag_lossless_output_detail;
+ lossless_detail_handler.print = swf_tag_lossless_print_detail;
+ lossless_detail_handler.destroy = swf_tag_lossless_destroy_detail;
+ return &lossless_detail_handler;
+}
+
+void *
+swf_tag_lossless_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_lossless_detail_t *swf_tag_lossless;
+ bitstream_t *bs, *bs2;
+ (void) swf;
+ unsigned long i;
+ unsigned char *tmp_buff, *old_buff_ref;
+ unsigned long origsize, old_size, offset;
+ int result;
+
+ swf_tag_lossless = calloc(sizeof(*swf_tag_lossless), 1);
+ if (swf_tag_lossless == NULL) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: can't calloc swf_tag_lossless\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+ swf_tag_lossless->image_id = bitstream_getbytesLE(bs, 2);
+ swf_tag_lossless->format = bitstream_getbyte(bs);
+ swf_tag_lossless->width = bitstream_getbytesLE(bs, 2);
+ swf_tag_lossless->height = bitstream_getbytesLE(bs, 2);
+ if (swf_tag_lossless->format == 3) {
+ unsigned long indices_len;
+ int bytes_per_color;
+ swf_tag_lossless->colormap_count = bitstream_getbyte(bs) + 1;
+ indices_len = ((swf_tag_lossless->width + 3) & -4) * swf_tag_lossless->height;
+ if (tag->tag == 20) { // Lossless => rgb (3 bytes)
+ bytes_per_color = 3;
+ } else { // Lossless2 => rgba (4 bytes)
+ bytes_per_color = 4;
+ }
+ origsize = bytes_per_color * swf_tag_lossless->colormap_count + indices_len;
+ tmp_buff = malloc(origsize);
+ offset = bitstream_getbytepos(bs);
+ old_buff_ref = bitstream_buffer(bs, offset);
+ old_size = bitstream_length(bs) - offset;
+ result = uncompress(tmp_buff, &origsize, old_buff_ref, old_size);
+ if (result != Z_OK) {
+ if (result == Z_MEM_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_MEM_ERROR: can't malloc at line(%d)\n", __LINE__);
+ } else if (result == Z_BUF_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_BUF_ERROR: not enough buff size at line(%d)\n", __LINE__);
+ } else if (result == Z_DATA_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data at line(%d)\n", __LINE__);
+ } else {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: failed byunknown reason (%d) at line(%d)\n", result, __LINE__);
+ }
+ free(tmp_buff);
+ bitstream_close(bs);
+ return NULL;
+ }
+ if (indices_len != origsize - bytes_per_color * swf_tag_lossless->colormap_count) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: indices_len(%lu) != origsize(%lu) - %d * swf_tag_lossless->colormap_count(%d) at line(%d)\n",
+ indices_len, origsize, bytes_per_color,
+ swf_tag_lossless->colormap_count, __LINE__);
+ free(tmp_buff);
+ bitstream_close(bs);
+ return NULL;
+ }
+ bs2 = bitstream_open();
+ bitstream_input(bs2, tmp_buff, origsize);
+ if (tag->tag == 20) { // Lossless
+ swf_tag_lossless->colormap = malloc(sizeof(swf_rgb_t) * swf_tag_lossless->colormap_count);
+ for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
+ swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
+ swf_rgb_parse(bs2, rgb);
+ }
+ } else { // tag == 36 (Lossless2)
+ swf_tag_lossless->colormap2 = malloc(sizeof(swf_rgba_t) * swf_tag_lossless->colormap_count);
+ for (i=0; i<swf_tag_lossless->colormap_count; i++) {
+ swf_rgba_t *rgba = swf_tag_lossless->colormap2 + i;
+ swf_rgba_parse(bs2, rgba);
+ }
+ }
+ swf_tag_lossless->indices = malloc(indices_len);
+ bitstream_getstring(bs2, swf_tag_lossless->indices, indices_len);
+ bitstream_close(bs2);
+ free(tmp_buff);
+ } else { // format != 3
+ unsigned long bitmap_count;
+ bitmap_count = swf_tag_lossless->width * swf_tag_lossless->height;
+ origsize = 4 * bitmap_count; // xrgb or argb (4 bytes)
+ tmp_buff = malloc(origsize);
+ offset = bitstream_getbytepos(bs);
+ old_buff_ref = bitstream_buffer(bs, offset);
+ old_size = bitstream_length(bs) - offset;
+ result = uncompress(tmp_buff, &origsize, old_buff_ref, old_size);
+ if (result != Z_OK) {
+ if (result == Z_MEM_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_MEM_ERROR: can't malloc (origsize=%lu, old_size=%lu) at line(%d)\n",
+ origsize, old_size, __LINE__);
+ } else if (result == Z_BUF_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_BUF_ERROR: not enough buff size(origsize=%lu, old_size=%lu) at line(%d)\n",
+ origsize, old_size, __LINE__);
+ } else if (result == Z_DATA_ERROR) {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data at line(%d)\n", __LINE__);
+ } else {
+ fprintf(stderr, "swf_tag_lossless_create_detail: uncompress: failed byunknown reason (%d) at line(%d)\n", result, __LINE__);
+ }
+ free(tmp_buff);
+ bitstream_close(bs);
+ return NULL;
+ }
+ bs2 = bitstream_open();
+ bitstream_input(bs2, tmp_buff, origsize);
+ if (tag->tag == 20) { // Lossless
+ swf_tag_lossless->bitmap = malloc(bitmap_count * sizeof(swf_xrgb_t));
+ for (i=0; i<bitmap_count; i++) {
+ swf_xrgb_t *xrgb = swf_tag_lossless->bitmap + i;
+ swf_xrgb_parse(bs2, xrgb);
+ }
+ } else { // tag == 36 (Lossless2)
+ swf_tag_lossless->bitmap2 = malloc(bitmap_count * sizeof(swf_argb_t));
+ for (i=0; i<bitmap_count; i++) {
+ swf_argb_t *argb = swf_tag_lossless->bitmap2 + i;
+ swf_argb_parse(bs2, argb);
+ }
+ }
+ bitstream_close(bs2);
+ free(tmp_buff);
+ }
+ bitstream_close(bs);
+ return (void *) swf_tag_lossless;
+}
+
+int
+swf_tag_lossless_identity_detail(unsigned char *data, int id, swf_tag_t *tag) {
+ int image_id;
+ if (tag->detail) {
+ swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
+ if (swf_tag_lossless->image_id == id) {
+ return 0;
+ }
+ return 1;
+ }
+ if (data == NULL) {
+ fprintf(stderr, "swf_tag_lossless_identity_detail: data==NULL at line(%d)\n", __LINE__);
+ return 1;
+ }
+ image_id = GetUShortLE(data);
+ if (id == image_id) {
+ return 0;
+ }
+ return 1;
+}
+
+unsigned char *
+swf_tag_lossless_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
+ bitstream_t *bs, *bs2;
+ unsigned char *data;
+ unsigned long i;
+ unsigned char *tmp_buff, *old_buff_ref;
+ unsigned long compsize, old_size;
+ (void) swf;
+ *length = 0;
+ bs = bitstream_open();
+ bitstream_putbytesLE(bs, swf_tag_lossless->image_id, 2);
+ bitstream_putbyte(bs, swf_tag_lossless->format);
+ bitstream_putbytesLE(bs, swf_tag_lossless->width, 2);
+ bitstream_putbytesLE(bs, swf_tag_lossless->height, 2);
+ if (swf_tag_lossless->format == 3) {
+ unsigned long indices_len;
+ bitstream_putbyte(bs, swf_tag_lossless->colormap_count - 1); /* XXX */
+ bs2 = bitstream_open();
+ if (tag->tag == 20) { // Lossless
+ for (i=0; i<swf_tag_lossless->colormap_count; i++) {
+ swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
+ swf_rgb_build(bs2, rgb);
+ }
+ } else { // tag == 36 (Lossless2)
+ for (i=0; i<swf_tag_lossless->colormap_count; i++) {
+ swf_rgba_t *rgba = swf_tag_lossless->colormap2 + i;
+ swf_rgba_build(bs2, rgba);
+ }
+ }
+ indices_len = ((swf_tag_lossless->width + 3) & -4) * swf_tag_lossless->height;
+ bitstream_putstring(bs2, swf_tag_lossless->indices,
+ indices_len);
+ old_buff_ref = bitstream_buffer(bs2, 0);
+ old_size = bitstream_length(bs2);
+ tmp_buff = malloc(old_size); // too enough size
+ compress(tmp_buff, &compsize, old_buff_ref, old_size);
+ bitstream_putstring(bs, tmp_buff, compsize);
+ bitstream_close(bs2);
+ free(tmp_buff);
+ } else {
+ unsigned long bitmap_size;
+ bs2 = bitstream_open();
+ if (tag->tag == 20) { // Lossless
+ bitmap_size = swf_tag_lossless->width * swf_tag_lossless->height;
+ for (i=0; i<bitmap_size; i++) {
+ swf_xrgb_t *xrgb = swf_tag_lossless->bitmap + i;
+ swf_xrgb_build(bs2, xrgb);
+ }
+ } else { // tag == 36 (Lossless2)
+ bitmap_size = swf_tag_lossless->width * swf_tag_lossless->height;
+ for (i=0; i<bitmap_size; i++) {
+ swf_argb_t *argb = swf_tag_lossless->bitmap2 + i;
+ swf_argb_build(bs2, argb);
+ }
+ }
+ old_buff_ref = bitstream_buffer(bs2, 0);
+ old_size = bitstream_length(bs2);
+ compsize = old_size; // too enough size
+ tmp_buff = malloc(compsize);
+ compress(tmp_buff, &compsize, old_buff_ref, old_size);
+ bitstream_putstring(bs, tmp_buff, compsize);
+ bitstream_close(bs2);
+ free(tmp_buff);
+ }
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+void
+swf_tag_lossless_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
+ (void) tag;
+ (void) swf;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_lossless_print_detail: detail == NULL\n");
+ return ;
+ }
+ printf("\timage_id=%d format=%d width=%u height=%u\n",
+ swf_tag_lossless->image_id, swf_tag_lossless->format,
+ swf_tag_lossless->width, swf_tag_lossless->height);
+ if (swf_tag_lossless->colormap ||
+ swf_tag_lossless->colormap2) {
+ printf("\tcolormap_count=%d",
+ swf_tag_lossless->colormap_count);
+ if (swf_tag_lossless->colormap) {
+ printf(" rgb colormap exists");
+ } else {
+ printf(" rgba colormap exists");
+ }
+ if (swf_tag_lossless->indices) {
+ printf(" indices exists");
+ }
+ printf("\n");
+ }
+ if (swf_tag_lossless->bitmap) {
+ printf("\txrgb bitmap exists\n");
+ }
+ if (swf_tag_lossless->bitmap2) {
+ printf("\targb bitmap exists\n");
+ }
+}
+
+void
+swf_tag_lossless_destroy_detail(void *detail) {
+ swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
+ if (swf_tag_lossless) {
+ free(swf_tag_lossless->colormap);
+ free(swf_tag_lossless->colormap2);
+ free(swf_tag_lossless->indices);
+ free(swf_tag_lossless->bitmap);
+ free(swf_tag_lossless->bitmap2);
+ swf_tag_lossless->colormap = NULL;
+ swf_tag_lossless->colormap2 = NULL;
+ swf_tag_lossless->indices = NULL;
+ swf_tag_lossless->bitmap = NULL;
+ swf_tag_lossless->bitmap2 = NULL;
+ free(swf_tag_lossless);
+ }
+ return ;
+}
+
+unsigned char *swf_tag_lossless_get_png_data(void *detail,
+ unsigned long *length,
+ int image_id,
+ swf_tag_t *tag) {
+ swf_tag_lossless_detail_t *swf_tag_lossless;
+ unsigned char *data;
+ *length = 0;
+ void *index_data = NULL;
+ void *image_data = NULL;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_lossless_get_lossless_data: detail == NULL at line(%d)\n", __LINE__);
+ }
+ swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
+ if (swf_tag_lossless->image_id != image_id) {
+ return NULL;
+ }
+ if ((swf_tag_lossless->format != 3) && (swf_tag_lossless->format != 5)) {
+ fprintf(stderr, "swf_tag_lossless_get_lossless_data: format=%d not implemented yet\n",
+ swf_tag_lossless->format);
+ return NULL;
+ }
+ if (tag->tag == 20) {
+ if (swf_tag_lossless->format == 3) {
+ index_data = (void *) swf_tag_lossless->colormap;
+ image_data = (void *) swf_tag_lossless->indices;
+ } else {
+ image_data = (void *) swf_tag_lossless->bitmap;
+ }
+ } else { // 36
+ if (swf_tag_lossless->format == 3) {
+ index_data = (void *) swf_tag_lossless->colormap2;
+ image_data = (void *) swf_tag_lossless->indices;
+ } else {
+ image_data = (void *) swf_tag_lossless->bitmap2;
+ }
+ }
+ if (image_data == NULL) {
+ fprintf(stderr, "swf_tag_lossless_get_lossless_data: image_data == NULL at line(%d)\n", __LINE__);
+ return NULL;
+ }
+ data = pngconv_lossless2png(image_data,
+ swf_tag_lossless->width,
+ swf_tag_lossless->height,
+ index_data,
+ swf_tag_lossless->colormap_count,
+ tag->tag, swf_tag_lossless->format,
+ length);
+ return data;
+}
+
+int
+swf_tag_lossless_replace_png_data(void *detail, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len, swf_tag_t *tag) {
+ int tag_no, format;
+ unsigned short width, height;
+ unsigned char *result_data;
+ void *colormap = NULL;
+ int colormap_count = 0;
+ swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_lossless_replace_lossless_data: detail == NULL at line(%d)\n", __LINE__);
+ return 1;
+ }
+ if (swf_tag_lossless->image_id != image_id) {
+ return 1;
+ }
+ result_data = pngconv_png2lossless(png_data, png_data_len,
+ &tag_no, &format,
+ &width, &height,
+ &colormap, &colormap_count);
+
+ if (result_data == NULL) {
+ fprintf(stderr, "swf_tag_lossless_replace_lossless_data: pngconv_png2lossless failed at line(%d)\n", __LINE__);
+ return 1;
+ }
+ tag->tag = tag_no;
+ swf_tag_lossless->format = format;
+ swf_tag_lossless->width = width;
+ swf_tag_lossless->height = height;
+ if (format == 3) {
+ free(swf_tag_lossless->colormap);
+ free(swf_tag_lossless->colormap2);
+ free(swf_tag_lossless->indices);
+ free(swf_tag_lossless->bitmap);
+ free(swf_tag_lossless->bitmap2);
+ swf_tag_lossless->colormap = NULL;
+ swf_tag_lossless->colormap2 = NULL;
+ swf_tag_lossless->indices = NULL;
+ swf_tag_lossless->bitmap = NULL;
+ swf_tag_lossless->bitmap2 = NULL;
+ if (tag_no == 20) {
+ swf_tag_lossless->colormap = (swf_rgb_t*) colormap;
+ } else if (tag_no == 36) {
+ swf_tag_lossless->colormap2 = (swf_rgba_t*) colormap;
+ } else {
+ fprintf(stderr, "swf_tag_lossless_replace_lossless_data: internal error tag_no(%d) at line(%d).\n", tag_no, __LINE__);
+ return 1;
+ }
+ swf_tag_lossless->colormap_count = colormap_count;
+ swf_tag_lossless->indices = (unsigned char *) result_data;
+ } else if (format == 5) {
+ free(swf_tag_lossless->colormap);
+ free(swf_tag_lossless->colormap2);
+ free(swf_tag_lossless->indices);
+ free(swf_tag_lossless->bitmap);
+ free(swf_tag_lossless->bitmap2);
+ swf_tag_lossless->colormap = NULL;
+ swf_tag_lossless->colormap2 = NULL;
+ swf_tag_lossless->indices = NULL;
+ swf_tag_lossless->bitmap = NULL;
+ swf_tag_lossless->bitmap2 = NULL;
+ if (tag_no == 20) {
+ swf_tag_lossless->bitmap = (swf_xrgb_t*) result_data;
+ } else if (tag_no == 36) {
+ swf_tag_lossless->bitmap2 = (swf_argb_t*) result_data;
+ } else {
+ fprintf(stderr, "swf_tag_lossless_replace_lossless_data: internal error tag_no(%d) at line(%d).\n", tag_no, __LINE__);
+ return 1;
+ }
+ } else {
+ fprintf(stderr, "swf_tag_lossless_replace_lossless_data: format(%d) not implemented yet. at line(%d)\n", format, __LINE__);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_LOSSLESS__H__
+#define __SWF_TAG_LOSSLESS__H__
+
+#include "swf_rgb.h"
+#include "swf_rgba.h"
+#include "swf_xrgb.h"
+#include "swf_argb.h"
+#include "swf_tag.h"
+
+typedef struct swf_tag_lossless_detail_ {
+ int image_id;
+ unsigned char format;
+ unsigned short width, height;
+ // format: 3
+ unsigned short colormap_count;
+ swf_rgb_t *colormap; // Lossless
+ swf_rgba_t *colormap2; // Lossless2
+ unsigned char *indices;
+ // format: 4,5
+ swf_xrgb_t *bitmap; // Lossless
+ swf_argb_t *bitmap2; // Lossless2
+} swf_tag_lossless_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_lossless_detail_handler(void);
+
+extern void *swf_tag_lossless_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void *swf_tag_lossless2_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern int swf_tag_lossless_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag);
+extern unsigned char *swf_tag_lossless_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern unsigned char *swf_tag_lossless2_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_lossless_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_lossless2_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_lossless_destroy_detail(void *detail);
+
+extern unsigned char *swf_tag_lossless_get_png_data(void *detail,
+ unsigned long *length,
+ int image_id,
+ swf_tag_t *tag);
+extern int swf_tag_lossless_replace_png_data(void *detail, int image_id,
+ unsigned char *png_data,
+ unsigned long png_data_len,
+ swf_tag_t *tag);
+
+#endif /* __SWF_TAG_LOSSLESS__H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "bitstream.h"
+#include "swf_tag_sound.h"
+#include "swf_object.h"
+
+swf_tag_detail_handler_t sound_detail_handler;
+
+swf_tag_detail_handler_t *
+swf_tag_sound_detail_handler(void) {
+ sound_detail_handler.create = swf_tag_sound_create_detail;
+ sound_detail_handler.identity = swf_tag_sound_identity_detail;
+ sound_detail_handler.output = swf_tag_sound_output_detail;
+ sound_detail_handler.print = swf_tag_sound_print_detail;
+ sound_detail_handler.destroy = swf_tag_sound_destroy_detail;
+ return &sound_detail_handler;
+}
+
+void *
+swf_tag_sound_create_detail(unsigned char *data, unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_sound_detail_t *swf_tag_sound;
+ bitstream_t *bs;
+ unsigned long sound_data_len;
+ unsigned char *sound_data;
+ (void) tag;
+ (void) swf;
+ swf_tag_sound = calloc(sizeof(*swf_tag_sound), 1);
+ if (swf_tag_sound == NULL) {
+ fprintf(stderr, "ERROR: swf_tag_sound_create_detail: can't calloc\n");
+ return NULL;
+ }
+ bs = bitstream_open();
+ bitstream_input(bs, data, length);
+ swf_tag_sound->sound_id = bitstream_getbytesLE(bs, 2);
+ swf_tag_sound->sound_format = bitstream_getbits(bs, 4);
+ swf_tag_sound->sound_rate = bitstream_getbits(bs, 2);
+ swf_tag_sound->sound_is_16bits = bitstream_getbit(bs);
+ swf_tag_sound->sound_is_stereo = bitstream_getbit(bs);
+ swf_tag_sound->sound_samples_count = bitstream_getbytesLE(bs, 4);
+ sound_data_len = bitstream_length(bs) - bitstream_getbytepos(bs);
+ swf_tag_sound->sound_data = malloc(sound_data_len);
+ if (swf_tag_sound->sound_data == NULL) {
+ fprintf(stderr, "swf_tag_sound_create_detail: swf_tag_sound->sound_data == NULL at line(%d): sound_data_len=%lu\n",
+ __LINE__, sound_data_len);
+ bitstream_close(bs);
+ return NULL;
+ }
+ sound_data = bitstream_buffer(bs, bitstream_getbytepos(bs));
+ memcpy(swf_tag_sound->sound_data, sound_data, sound_data_len);
+ swf_tag_sound->sound_data_len = sound_data_len;
+ bitstream_close(bs);
+ return (void *) swf_tag_sound;
+}
+
+int
+swf_tag_sound_identity_detail(unsigned char *data, int id, swf_tag_t *tag) {
+ int sound_id;
+ if (tag->detail) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) tag->detail;
+ if (swf_tag_sound->sound_id == id) {
+ return 0;
+ }
+ return 1;
+ }
+ if (data == NULL) {
+ fprintf(stderr, "swf_tag_sound_identity_detail: data==NULL\n");
+ return 1;
+ }
+ sound_id = GetUShortLE(data);
+ if (id == sound_id) {
+ return 0;
+ }
+ return 1;
+}
+
+unsigned char *
+swf_tag_sound_output_detail(void *detail, unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
+ bitstream_t *bs;
+ unsigned char *data;
+ (void) tag;
+ (void) swf;
+ *length = 0;
+ bs = bitstream_open();
+ bitstream_putbytesLE(bs, swf_tag_sound->sound_id, 2);
+ bitstream_putbits(bs, swf_tag_sound->sound_format, 4);
+ bitstream_putbits(bs, swf_tag_sound->sound_rate, 2);
+ bitstream_putbit(bs, swf_tag_sound->sound_is_16bits);
+ bitstream_putbit(bs, swf_tag_sound->sound_is_stereo);
+ bitstream_putbytesLE(bs, swf_tag_sound->sound_samples_count, 4);
+ bitstream_putstring(bs, swf_tag_sound->sound_data,
+ swf_tag_sound->sound_data_len);
+ data = bitstream_steal(bs, length);
+ bitstream_close(bs);
+ return data;
+}
+
+void
+swf_tag_sound_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
+ char *format_name = "Unknown";
+ (void) tag;
+ (void) swf;
+ switch(swf_tag_sound->sound_format & 0x0f) {
+ case 0:
+ format_name = "Raw";
+ break;
+ case 1:
+ format_name = "ADPCM";
+ break;
+ case 2:
+ format_name = "MP3";
+ break;
+ case 3:
+ format_name = "Uncompressed";
+ break;
+ case 6:
+ format_name = "Nellymoser";
+ break;
+
+ }
+ printf("\tsound_id=%d\n", swf_tag_sound->sound_id);
+
+ printf("\tformat=%u(%s) rate=%u is_16bits=%u is_stereo=%u samples_count=%lu\n",
+ swf_tag_sound->sound_format & 0x0f, format_name,
+ swf_tag_sound->sound_rate & 0x03,
+ swf_tag_sound->sound_is_16bits?1:0,
+ swf_tag_sound->sound_is_stereo?1:0,
+ swf_tag_sound->sound_samples_count);
+ printf("\tsound_data(length=%lu)\n",
+ swf_tag_sound->sound_data_len);
+ return ;
+}
+
+void
+swf_tag_sound_destroy_detail(void *detail) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
+ if (swf_tag_sound) {
+ free(swf_tag_sound->sound_data);
+ swf_tag_sound->sound_data = NULL;
+ free(swf_tag_sound);
+ }
+ return ;
+}
+
+unsigned char *
+swf_tag_sound_get_sound_data(void *detail, unsigned long *length,
+ int sound_id) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
+ unsigned char *data;
+ *length = 0;
+ if (detail == NULL) {
+ fprintf(stderr, "swf_tag_sound_get_sound_data: detail == NULL\n");
+ return NULL;
+ }
+ if (swf_tag_sound->sound_id != sound_id) {
+ return NULL;
+ }
+ *length = swf_tag_sound->sound_data_len;
+ data = malloc(*length);
+ memcpy(data, swf_tag_sound->sound_data, *length);
+ return data;
+}
+
+int
+swf_tag_sound_replace_mp3_data(void *detail, int sound_id,
+ unsigned char *mp3_data,
+ unsigned long mp3_data_len) {
+ (void) detail;
+ (void) sound_id;
+ (void) mp3_data;
+ (void) mp3_data_len;
+ // dummy
+ return -1;
+}
+
+int
+swf_tag_sound_replace_melo_data(void *detail, int sound_id,
+ unsigned char *melo_data,
+ unsigned long melo_data_len) {
+ swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
+ (void) melo_data;
+ (void) melo_data_len;
+ swf_tag_sound->sound_id = sound_id;
+ swf_tag_sound->sound_format = 15;
+ swf_tag_sound->sound_rate = 0;
+ swf_tag_sound->sound_is_16bits = 0;
+ swf_tag_sound->sound_is_stereo = 0;
+ swf_tag_sound->sound_samples_count = 0;
+ free(swf_tag_sound->sound_data);
+ swf_tag_sound->sound_data = malloc(melo_data_len);
+ if (swf_tag_sound->sound_data == NULL) {
+ fprintf(stderr, "swf_tag_sound_replace_melo_data: swf_tag_sound->sound_data == NULL\n");
+ return 1;
+ }
+ memcpy(swf_tag_sound->sound_data, melo_data, melo_data_len);
+ swf_tag_sound->sound_data_len = melo_data_len;
+ // dummy
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_SOUND__H__
+#define __SWF_TAG_SOUND__H__
+
+#include "swf_tag.h"
+
+typedef struct swf_tag_sound_detail_ {
+ int sound_id;
+ int sound_format:4;
+ int sound_rate:2;
+ int sound_is_16bits:1;
+ int sound_is_stereo:1;
+ unsigned long sound_samples_count;
+ unsigned char *sound_data;
+ unsigned long sound_data_len;
+} swf_tag_sound_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_sound_detail_handler(void);
+
+extern void *swf_tag_sound_create_detail(unsigned char *data,
+ unsigned long length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern int swf_tag_sound_identity_detail(unsigned char *data, int id,
+ swf_tag_t *tag);
+extern unsigned char *swf_tag_sound_output_detail(void *detail,
+ unsigned long *length,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_sound_print_detail(void *detail,
+ swf_tag_t *tag,
+ struct swf_object_ *swf);
+extern void swf_tag_sound_destroy_detail(void *detail);
+
+extern unsigned char *swf_tag_sound_get_sound_data(void *detail, unsigned long *length,
+ int sound_id);
+extern int swf_tag_sound_replace_mp3_data(void *detail, int sound_id,
+ unsigned char *mp3_data,
+ unsigned long mp3_data_len);
+
+extern int swf_tag_sound_replace_melo_data(void *detail, int sound_id,
+ unsigned char *sound_data,
+ unsigned long sound_data_len);
+
+#endif /* __SWF_TAG_SOUND__H__ */
--- /dev/null
+#include <stdio.h>
+#include <sys/stat.h>
+#include "swf_object.h"
+
+typedef struct _binedit_string {
+ unsigned char *ptr;
+ unsigned long len;
+} binedit_string_t;
+
+int loadfile(binedit_string_t *str, char *filename) {
+ FILE *fp;
+ struct stat sbuf;
+ if (stat(filename, &sbuf)) {
+ return 1;
+ }
+ str->len = sbuf.st_size;
+ str->ptr = calloc(str->len, 1);
+ fp = fopen(filename, "rb");
+ if (fread(str->ptr, 1, str->len, fp) != str->len) {
+ return 1;
+ }
+ fclose(fp);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ swf_object_t *swf;
+ binedit_string_t str;
+ loadfile(&str, "saitama.swf");
+ swf = swf_object_open();
+ swf = swf_object_set(str.ptr, str.len);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_xrgb.h"
+
+int
+swf_xrgb_parse(bitstream_t *bs, swf_xrgb_t *color) {
+ (void) bitstream_getbyte(bs); // pad
+ color->red = bitstream_getbyte(bs);
+ color->green = bitstream_getbyte(bs);
+ color->blue = bitstream_getbyte(bs);
+ return 0;
+}
+
+int
+swf_xrgb_build(bitstream_t *bs, swf_xrgb_t *color) {
+ bitstream_putbyte(bs, 0); // pad
+ bitstream_putbyte(bs, color->red);
+ bitstream_putbyte(bs, color->green);
+ bitstream_putbyte(bs, color->blue);
+ return 0;
+}
+
+int
+swf_xrgb_print(swf_xrgb_t *color) {
+ printf("pad=0xXX red=0x%02x green=0x%02X blue=0x%02x\n",
+ color->red, color->green, color->blue);
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_XRGB_H__
+#define __SWF_XRGB_H__
+
+typedef struct swf_xrgb_ {
+// unsigned char pad;
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+} swf_xrgb_t;
+
+extern int swf_xrgb_parse(bitstream_t *bs, swf_xrgb_t *color);
+extern int swf_xrgb_build(bitstream_t *bs, swf_xrgb_t *color);
+extern int swf_xrgb_print(swf_xrgb_t *color);
+
+#endif /* __SWF_XRGB_H__ */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2006 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: yoya@awm.jp |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id: header,v 1.16.2.1 2006/01/01 12:50:00 sniper Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_swfed.h"
+
+#include "swf_define.h"
+#include "swf_tag_jpeg.h"
+#include "swf_tag_lossless.h"
+#include "swf_tag_edit.h"
+#include "swf_tag_sound.h"
+#include "swf_tag_action.h"
+#include "swf_tag.h"
+#include "swf_object.h"
+
+/* If you declare any globals in php_swfed.h uncomment this:
+ZEND_DECLARE_MODULE_GLOBALS(swfed)
+*/
+
+/* True global resources - no need for thread safety here */
+static int le_swfed;
+
+/* {{{ swfed_functions[]
+ *
+ * Every user visible function must have an entry in swfed_functions[].
+ */
+zend_function_entry swfed_functions[] = {
+ PHP_FE(confirm_swfed_compiled, NULL) /* For testing, remove later. */
+ PHP_ME(swfed, __construct, NULL, 0)
+ PHP_ME(swfed, input, NULL, 0)
+ PHP_ME(swfed, output, NULL, 0)
+ PHP_ME(swfed, getHeaderInfo, NULL, 0)
+ PHP_ME(swfed, setHeaderInfo, NULL, 0)
+ PHP_ME(swfed, getTagList, NULL, 0)
+ PHP_ME(swfed, getTagDetail, NULL, 0)
+ PHP_ME(swfed, getTagData, NULL, 0)
+ PHP_ME(swfed, getJpegData, NULL, 0)
+ PHP_ME(swfed, getJpegAlpha, NULL, 0)
+ PHP_ME(swfed, replaceJpegData, NULL, 0)
+ PHP_ME(swfed, getPNGData, NULL, 0)
+ PHP_ME(swfed, replacePNGData, NULL, 0)
+ PHP_ME(swfed, getSoundData, NULL, 0)
+ PHP_ME(swfed, replaceMLDData, NULL, 0)
+ PHP_ME(swfed, getEditString, NULL, 0)
+ PHP_ME(swfed, replaceEditString, NULL, 0)
+ PHP_ME(swfed, getActionData, NULL, 0)
+ PHP_ME(swfed, disasmActionData, NULL, 0)
+ PHP_ME(swfed, swfInfo, NULL, 0)
+ {NULL, NULL, NULL} /* Must be the last line in swfed_functions[] */
+};
+/* }}} */
+
+/* {{{ swfed_module_entry
+ */
+zend_module_entry swfed_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+ STANDARD_MODULE_HEADER,
+#endif
+ "swfed",
+ swfed_functions,
+ PHP_MINIT(swfed),
+ PHP_MSHUTDOWN(swfed),
+ PHP_RINIT(swfed), /* Replace with NULL if there's nothing to do at request start */
+ PHP_RSHUTDOWN(swfed), /* Replace with NULL if there's nothing to do at request end */
+ PHP_MINFO(swfed),
+#if ZEND_MODULE_API_NO >= 20010901
+ "0.1", /* Replace with version number for your extension */
+#endif
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_SWFED
+ZEND_GET_MODULE(swfed)
+#endif
+
+/* {{{ PHP_INI
+ */
+/* Remove comments and fill if you need to have entries in php.ini
+PHP_INI_BEGIN()
+ STD_PHP_INI_ENTRY("swfed.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_swfed_globals, swfed_globals)
+ STD_PHP_INI_ENTRY("swfed.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_swfed_globals, swfed_globals)
+PHP_INI_END()
+*/
+/* }}} */
+
+/* {{{ php_swfed_init_globals
+ */
+/* Uncomment this function if you have INI entries
+static void php_swfed_init_globals(zend_swfed_globals *swfed_globals)
+{
+ swfed_globals->global_value = 0;
+ swfed_globals->global_string = NULL;
+}
+*/
+/* }}} */
+
+
+static void free_swfed_resource(zend_rsrc_list_entry *resource TSRMLS_DC);
+static swf_object_t *get_swf_object(zval *obj TSRMLS_DC);
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(swfed)
+{
+ /* If you have INI entries, uncomment these lines
+ ZEND_INIT_MODULE_GLOBALS(swfed, php_swfed_init_globals, NULL);
+ REGISTER_INI_ENTRIES();
+ */
+ zend_class_entry ce;
+ INIT_CLASS_ENTRY(ce, "SWFEditor", swfed_functions);
+ swfeditor_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ le_swfed = zend_register_list_destructors_ex(free_swfed_resource, NULL, "SWFEditor", module_number);
+
+ zend_declare_property_stringl(swfeditor_ce,
+ "swf_object", strlen("swf_object"),
+ "", 0, ZEND_ACC_PUBLIC);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(swfed)
+{
+ /* uncomment this line if you have INI entries
+ UNREGISTER_INI_ENTRIES();
+ */
+ return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request start */
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(swfed)
+{
+ return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request end */
+/* {{{ PHP_RSHUTDOWN_FUNCTION
+ */
+PHP_RSHUTDOWN_FUNCTION(swfed)
+{
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(swfed)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "swfed support", "enabled");
+ php_info_print_table_end();
+
+ /* Remove comments if you have entries in php.ini
+ DISPLAY_INI_ENTRIES();
+ */
+}
+/* }}} */
+
+
+/* Remove the following function when you have succesfully modified config.m4
+ so that your module can be compiled into PHP, it exists only for testing
+ purposes. */
+
+/* Every user-visible function in PHP should document itself in the source */
+/* {{{ proto string confirm_swfed_compiled(string arg)
+ Return a string to confirm that the module is compiled in */
+PHP_FUNCTION(confirm_swfed_compiled)
+{
+ char *arg = NULL;
+ int arg_len, len;
+ char string[256];
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
+ return;
+ }
+
+ len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "swfed", arg);
+// RETURN_STRINGL(string, len, 0);
+ RETURN_STRINGL(string, len, 1);
+}
+/* }}} */
+/* The previous line is meant for vim and emacs, so it can correctly fold and
+ unfold functions in source code. See the corresponding marks just before
+ function definition, where the functions purpose is also documented. Please
+ follow this convention for the convenience of others editing your code.
+*/
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
+PHP_METHOD(swfed, __construct) {
+ swf_object_t *swf = swf_object_open();
+ int ret;
+ if (swf == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Couldn't create swf object");
+ }
+ ret = zend_list_insert(swf, le_swfed);
+ object_init_ex(getThis(), swfeditor_ce);
+ add_property_resource(getThis(), "swfed", ret);
+ zend_list_addref(ret);
+}
+
+PHP_METHOD(swfed, input) {
+ char *data;
+ int data_len;
+ swf_object_t *swf;
+ zval *obj = getThis();
+ int result;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "s", &data, &data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(obj TSRMLS_CC);
+ result = swf_object_input(swf, (unsigned char *) data, data_len);
+ if (result) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, output) {
+ unsigned long len = 0;
+ unsigned char *data, *new_buff;
+ swf_object_t *swf;
+ if (ZEND_NUM_ARGS() != 0) {
+ WRONG_PARAM_COUNT;
+ RETURN_FALSE; /* XXX */
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_output(swf, &len);
+ new_buff = emalloc(len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "output: Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, len);
+ free(data);
+ RETURN_STRINGL(new_buff, len, 0);
+}
+
+PHP_METHOD(swfed, getHeaderInfo) {
+ swf_object_t *swf = get_swf_object(getThis());
+ array_init(return_value);
+ if (memcmp(swf->header.magic, "CWS", 3) == 0) {
+ add_assoc_bool(return_value, "compress", 1);
+ } else { // FWS
+ add_assoc_bool(return_value, "compress", 0);
+ }
+ add_assoc_long(return_value, "version", swf->header.version);
+}
+
+PHP_METHOD(swfed, setHeaderInfo) {
+ zval *header_info;
+ swf_object_t *swf;
+ HashTable *header_table;
+ zval **tmp;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a",
+ &header_info) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
+ }
+ swf = get_swf_object(getThis());
+ header_table = Z_ARRVAL_P(header_info);
+ if (zend_hash_find(header_table, "compress", sizeof("compress"), (void**)&tmp) == SUCCESS) {
+ convert_to_boolean_ex(tmp);
+ if (Z_LVAL_PP(tmp) != 0) {
+ memcpy(swf->header.magic, "CWS", 3);
+ } else {
+ memcpy(swf->header.magic, "FWS", 3);
+ }
+ }
+
+ if (zend_hash_find(header_table, "version", sizeof("version"), (void**)&tmp) == SUCCESS) {
+ convert_to_long_ex(tmp);
+ swf->header.version = Z_LVAL_PP(tmp);
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, getTagList) {
+ int i = 0;
+ zval *data;
+ swf_object_t *swf;
+ swf_tag_t *tag;
+ swf_tag_info_t *tag_info;
+ if (ZEND_NUM_ARGS() != 0) {
+ WRONG_PARAM_COUNT;
+ RETURN_FALSE; /* XXX */
+ }
+ swf = get_swf_object(getThis());
+ tag = swf->tag;
+ array_init(return_value);
+ for(tag = swf->tag; tag; tag=tag->next) {
+ ALLOC_INIT_ZVAL(data);
+ array_init(data);
+ add_assoc_long(data, "tag", tag->tag);
+ tag_info = get_swf_tag_info(tag->tag);
+ if (tag_info && tag_info->name) {
+ add_assoc_string_ex(data,
+ "tagName", sizeof("tagName"),
+ (char *)tag_info->name, 1);
+ }
+ add_assoc_long(data, "length", tag->length);
+ if (tag_info && tag_info->detail_handler) {
+ add_assoc_bool(data, "detail", 1);
+ }
+ add_index_zval(return_value, i, data);
+ i++;
+ }
+}
+
+PHP_METHOD(swfed, getTagDetail) {
+ long tag_seqno;
+ swf_object_t *swf;
+ swf_tag_t *tag;
+ swf_tag_info_t *tag_info;
+ int i;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "l", &tag_seqno) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ i = 0;
+ for(tag = swf->tag; tag; tag = tag->next) {
+ if (i == tag_seqno) {
+ break;
+ }
+ i++;
+ }
+ if (tag == NULL) {
+ RETURN_FALSE;
+ }
+ tag_info = get_swf_tag_info(tag->tag);
+ if ((tag_info == NULL) || (tag_info->detail_handler == NULL)) {
+ RETURN_FALSE;
+ }
+ swf_tag_create_detail(tag, swf);
+ switch (tag->tag) {
+ swf_tag_jpeg_detail_t *tag_jpeg;
+ swf_tag_lossless_detail_t *tag_lossless;
+ swf_tag_edit_detail_t *tag_edit;
+ swf_tag_sound_detail_t *tag_sound;
+ swf_tag_action_detail_t *tag_action;
+ case 6: // DefineBitsJPEG
+ case 21: // DefineBitsJPEG2
+ case 35: // DefineBitsJPEG3
+ tag_jpeg = tag->detail;
+ array_init(return_value);
+ add_assoc_long(return_value, "image_id", tag_jpeg->image_id);
+ add_assoc_long(return_value, "jpeg_data_len", tag_jpeg->jpeg_data_len);
+ if ((tag_jpeg->alpha_data != NULL) &&
+ (tag_jpeg->alpha_data_len > 0)) {
+ add_assoc_long(return_value, "alpha_data_len", tag_jpeg->alpha_data_len);
+ }
+ break;
+ case 20: // DefineBitsLossless
+ case 36: // DefineBitsLossless2
+ tag_lossless = tag->detail;
+ array_init(return_value);
+ add_assoc_long(return_value, "image_id", tag_lossless->image_id);
+ add_assoc_long(return_value, "format", tag_lossless->format);
+ add_assoc_long(return_value, "width", tag_lossless->width);
+ add_assoc_long(return_value, "height", tag_lossless->height);
+ if (tag_lossless->format == 3) {
+ add_assoc_long(return_value, "colormap_count", tag_lossless->colormap_count);
+ }
+ break;
+ case 14: // DefineSound
+ tag_sound = tag->detail;
+ array_init(return_value);
+ add_assoc_long(return_value, "sound_id", tag_sound->sound_id);
+ add_assoc_long(return_value, "format", (unsigned long) tag_sound->sound_format);
+ add_assoc_long(return_value, "rate", (unsigned long) tag_sound->sound_rate);
+ add_assoc_long(return_value, "is_16bits", tag_sound->sound_is_16bits?1:0);
+ add_assoc_long(return_value, "is_stereo", tag_sound->sound_is_stereo?1:0);
+ add_assoc_long(return_value, "sound_samples_count", tag_sound->sound_samples_count);
+ add_assoc_long(return_value, "sound_data_len", tag_sound->sound_data_len);
+ break;
+ case 12: // DoAction
+ case 59: // DoInitAction
+ tag_action = tag->detail;
+ array_init(return_value);
+ if (tag->tag == 59) { // DoInitAction
+ add_assoc_long(return_value, "action_sprite", tag_action->action_sprite);
+ }
+ if (tag_action->action_record && tag_action->action_record_len) {
+ add_assoc_long(return_value, "action_record_len", tag_action->action_record_len);
+ }
+ break;
+ case 37: // DefineEditText;
+ tag_edit = tag->detail;
+ array_init(return_value);
+ add_assoc_long(return_value, "edit_id", tag_edit->edit_id);
+ if (tag_edit->edit_variable_name && tag_edit->edit_variable_name[0]){
+ add_assoc_string_ex(return_value, "variable_name",
+ sizeof("variable_name"),
+ (char *)tag_edit->edit_variable_name, 1);
+ }
+ if (tag_edit->edit_initial_text && tag_edit->edit_initial_text[0]) {
+ add_assoc_string_ex(return_value, "initial_text",
+ sizeof("initial_text"),
+ (char *)tag_edit->edit_initial_text, 1);
+ }
+ break;
+ default:
+ RETURN_FALSE;
+ }
+ /* return_value */
+}
+
+PHP_METHOD(swfed, getTagData) {
+ printf("not implemented yet.\n");
+ RETURN_FALSE;
+}
+
+PHP_METHOD(swfed, getJpegData) {
+ unsigned long image_id = 0;
+ unsigned long len = 0;
+ unsigned char *data, *new_buff;
+ zval *obj = getThis();
+ swf_object_t *swf;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "l", &image_id) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_get_jpegdata(swf, &len, image_id);
+ if (data == NULL) {
+ RETURN_FALSE;
+ }
+ new_buff = emalloc(len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getJpegData Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, len);
+ free(data);
+ RETURN_STRINGL(new_buff, (int) len, 0);
+}
+
+PHP_METHOD(swfed, getJpegAlpha) {
+ unsigned long image_id = 0;
+ unsigned long len = 0;
+ unsigned char *data, *new_buff;
+ zval *obj = getThis();
+ swf_object_t *swf;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "l", &image_id) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_get_alphadata(swf, &len, image_id);
+ if (data == NULL) {
+ RETURN_FALSE;
+ }
+ new_buff = emalloc(len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getJpegAlpha Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, len);
+ free(data);
+ RETURN_STRINGL(new_buff, len, 0);
+}
+
+PHP_METHOD(swfed, replaceJpegData) {
+ char *data = NULL, *alpha_data = NULL;
+ int data_len = 0 , alpha_data_len = 0;
+ int image_id;
+ swf_object_t *swf;
+ int result = 0;
+ switch (ZEND_NUM_ARGS()) {
+ default:
+ WRONG_PARAM_COUNT;
+ RETURN_FALSE; /* XXX */
+ case 2:
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &image_id, &data, &data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ break;
+ case 3:
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss", &image_id, &data, &data_len, &alpha_data, &alpha_data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ swf = get_swf_object(getThis());
+ result = swf_object_replace_jpegdata(swf, image_id,
+ (unsigned char *)data,
+ (unsigned long) data_len,
+ (unsigned char *)alpha_data,
+ (unsigned long) alpha_data_len);
+ if (result) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, getPNGData) {
+ unsigned long image_id = 0;
+ unsigned long len = 0;
+ unsigned char *data, *new_buff;
+ zval *obj = getThis();
+ swf_object_t *swf;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "l", &image_id) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_get_pngdata(swf, &len, image_id);
+ if (data == NULL) {
+ RETURN_FALSE;
+ }
+ new_buff = emalloc(len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getPNGData: Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, len);
+ free(data);
+ RETURN_STRINGL(new_buff, (int) len, 0);
+}
+
+PHP_METHOD(swfed, replacePNGData) {
+ char *data = NULL;
+ int data_len = 0;
+ int image_id;
+ swf_object_t *swf;
+ int result = 0;
+ switch (ZEND_NUM_ARGS()) {
+ default:
+ WRONG_PARAM_COUNT;
+ RETURN_FALSE; /* XXX */
+ case 2:
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &image_id, &data, &data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ swf = get_swf_object(getThis());
+ result = swf_object_replace_pngdata(swf, image_id,
+ (unsigned char *)data,
+ (unsigned long) data_len);
+ if (result) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, getSoundData) {
+ unsigned long sound_id = 0;
+ unsigned long len = 0;
+ unsigned char *data, *new_buff;
+ zval *obj = getThis();
+ swf_object_t *swf;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "l", &sound_id) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_get_sounddata(swf, &len, sound_id);
+ if (data == NULL) {
+ RETURN_FALSE;
+ }
+ new_buff = emalloc(len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getSoundData: Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, len);
+ free(data);
+ RETURN_STRINGL(new_buff, (int) len, 0);
+}
+
+PHP_METHOD(swfed, replaceMLDData) {
+ char *data = NULL;
+ int data_len = 0;
+ int sound_id;
+ swf_object_t *swf;
+ int result = 0;
+ switch (ZEND_NUM_ARGS()) {
+ default:
+ WRONG_PARAM_COUNT;
+ RETURN_FALSE; /* XXX */
+ case 2:
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &sound_id, &data, &data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ swf = get_swf_object(getThis());
+ result = swf_object_replace_melodata(swf, sound_id,
+ (unsigned char *)data,
+ (unsigned long) data_len);
+ if (result) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, getEditString) {
+ char *var_name;
+ int var_name_len;
+ swf_object_t *swf;
+ char *data, *new_buff;
+ int str_len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &var_name, &var_name_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+ data = swf_object_get_editstring(swf, var_name, var_name_len);
+ if (data == NULL) {
+ RETURN_FALSE;
+ }
+ str_len = strlen(data);
+ new_buff = emalloc(str_len + 1);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getEditString: Can't emalloc new_buff\n");
+ free(data);
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data, str_len + 1);
+ free(data);
+ RETURN_STRINGL(new_buff, str_len, 0);
+}
+
+PHP_METHOD(swfed, replaceEditString) {
+ char *var_name, *ini_text;
+ int var_name_len, ini_text_len;
+ swf_object_t *swf;
+ int result;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
+ &var_name, &var_name_len,
+ &ini_text, &ini_text_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+
+ result = swf_object_replace_editstring(swf, var_name, var_name_len,
+ ini_text, ini_text_len);
+ if (result) {
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+
+PHP_METHOD(swfed, getActionData) {
+ long tag_seqno;
+ swf_object_t *swf;
+ char *data_ref, *new_buff;
+ unsigned long data_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag_seqno) == FAILURE) {
+ RETURN_FALSE;
+ }
+ swf = get_swf_object(getThis());
+
+ data_ref = swf_object_get_actiondata(swf, &data_len, tag_seqno);
+ if (data_ref == NULL) {
+ fprintf(stderr, "getActionData: Can't get_actiondata\n");
+ RETURN_FALSE;
+ }
+ new_buff = emalloc(data_len);
+ if (new_buff == NULL) {
+ fprintf(stderr, "getActionData: Can't emalloc new_buff\n");
+ RETURN_FALSE;
+ }
+ memcpy(new_buff, data_ref, data_len);
+ RETURN_STRINGL(new_buff, data_len, 0);
+}
+
+PHP_METHOD(swfed, disasmActionData) {
+ char *data;
+ int data_len;
+ bitstream_t *bs;
+ swf_action_list_t *action_list;
+ swf_action_t *action;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "s", &data, &data_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ array_init(return_value);
+ bs = bitstream_open();
+ bitstream_input(bs, data, data_len);
+ action_list = swf_action_list_create(bs);
+ bitstream_close(bs);
+ if (action_list) {
+ swf_action_t *action = action_list->head;
+ while(action) {
+ printf("\t");
+// swf_action_disasm(action);
+ action = action->next;
+ }
+ }
+ swf_action_list_destroy(action_list);
+}
+
+
+PHP_METHOD(swfed, swfInfo) {
+ swf_object_t *swf = get_swf_object(getThis());
+ swf_object_print(swf);
+ RETURN_TRUE;
+}
+
+static swf_object_t *get_swf_object(zval *obj TSRMLS_DC) {
+// zval *data, **tmp;
+ zval **tmp;
+ swf_object_t *swf;
+ int id, type;
+/* XXX: zend_read_property
+ data = zend_read_property(Z_OBJCE_P(obj), obj, "swf_object",
+ strlen("swf_object"), 1 TSRMLS_CC);
+*/
+ if (zend_hash_find(Z_OBJPROP_P(obj), "swfed", strlen("swfed") + 1,
+ (void **)&tmp) == FAILURE) {
+ return NULL;
+ }
+ id = Z_LVAL_PP(tmp);
+ swf = zend_list_find(id, &type);
+ return swf;
+}
+
+static void free_swfed_resource(zend_rsrc_list_entry *resource TSRMLS_DC)
+{
+// printf("SWFEditor->destory\n");
+ swf_object_close(resource->ptr);
+}